1
The following changes since commit ee59483267de29056b5b2ee2421ef3844e5c9932:
1
The following changes since commit 352998df1c53b366413690d95b35f76d0721ebed:
2
2
3
Merge tag 'qemu-openbios-20230307' of https://github.com/mcayland/qemu into staging (2023-03-09 16:55:03 +0000)
3
Merge tag 'i2c-20220314' of https://github.com/philmd/qemu into staging (2022-03-14 14:39:33 +0000)
4
4
5
are available in the git repository at:
5
are available in the git repository at:
6
6
7
https://github.com/jasowang/qemu.git tags/net-pull-request
7
https://github.com/jasowang/qemu.git tags/net-pull-request
8
8
9
for you to fetch changes up to 197a137290103993b33f93c90e788ab4984f103a:
9
for you to fetch changes up to 12a195fa343aae2ead1301ce04727bd0ae25eb15:
10
10
11
ebpf: fix compatibility with libbpf 1.0+ (2023-03-10 17:26:47 +0800)
11
vdpa: Expose VHOST_F_LOG_ALL on SVQ (2022-03-15 13:57:44 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
Changes since V1:
15
Changes since V2:
16
16
- fix 32bit build errros
17
- Drop eepro100 series
18
- Fix igb test on win32
19
- Fix igb abort on MSI(X) initialziation failure
20
17
21
----------------------------------------------------------------
18
----------------------------------------------------------------
22
Akihiko Odaki (43):
19
Eugenio Pérez (14):
23
e1000e: Fix the code style
20
vhost: Add VhostShadowVirtqueue
24
hw/net: Add more MII definitions
21
vhost: Add Shadow VirtQueue kick forwarding capabilities
25
fsl_etsec: Use hw/net/mii.h
22
vhost: Add Shadow VirtQueue call forwarding capabilities
26
e1000: Use hw/net/mii.h
23
vhost: Add vhost_svq_valid_features to shadow vq
27
e1000: Mask registers when writing
24
virtio: Add vhost_svq_get_vring_addr
28
e1000e: Introduce E1000E_LOW_BITS_SET_FUNC
25
vdpa: adapt vhost_ops callbacks to svq
29
e1000e: Mask registers when writing
26
vhost: Shadow virtqueue buffers forwarding
30
e1000: Use more constant definitions
27
util: Add iova_tree_alloc_map
31
e1000e: Use more constant definitions
28
util: add iova_tree_find_iova
32
e1000: Use memcpy to intialize registers
29
vhost: Add VhostIOVATree
33
e1000e: Use memcpy to intialize registers
30
vdpa: Add custom IOTLB translations to SVQ
34
e1000e: Remove pending interrupt flags
31
vdpa: Adapt vhost_vdpa_get_vring_base to SVQ
35
e1000e: Improve software reset
32
vdpa: Never set log_base addr if SVQ is enabled
36
e1000: Configure ResettableClass
33
vdpa: Expose VHOST_F_LOG_ALL on SVQ
37
e1000e: Configure ResettableClass
38
e1000e: Introduce e1000_rx_desc_union
39
e1000e: Set MII_ANER_NWAY
40
e1000e: Remove extra pointer indirection
41
net: Check L4 header size
42
e1000x: Alter the signature of e1000x_is_vlan_packet
43
net: Strip virtio-net header when dumping
44
hw/net/net_tx_pkt: Automatically determine if virtio-net header is used
45
hw/net/net_rx_pkt: Remove net_rx_pkt_has_virt_hdr
46
e1000e: Perform software segmentation for loopback
47
hw/net/net_tx_pkt: Implement TCP segmentation
48
hw/net/net_tx_pkt: Check the payload length
49
e1000e: Do not assert when MSI-X is disabled later
50
MAINTAINERS: Add Akihiko Odaki as a e1000e reviewer
51
MAINTAINERS: Add e1000e test files
52
e1000e: Combine rx traces
53
e1000: Count CRC in Tx statistics
54
e1000e: Count CRC in Tx statistics
55
net/eth: Report if headers are actually present
56
e1000e: Implement system clock
57
net/eth: Introduce EthL4HdrProto
58
pcie: Introduce pcie_sriov_num_vfs
59
e1000: Split header files
60
Intrdocue igb device emulation
61
tests/qtest/e1000e-test: Fabricate ethernet header
62
tests/qtest/libqos/e1000e: Export macreg functions
63
igb: Introduce qtest for igb device
64
tests/avocado: Add igb test
65
docs/system/devices/igb: Add igb documentation
66
34
67
Shreesh Adiga (1):
35
Jason Wang (1):
68
ebpf: fix compatibility with libbpf 1.0+
36
virtio-net: fix map leaking on error during receive
69
37
70
MAINTAINERS | 13 +
38
hw/net/virtio-net.c | 1 +
71
docs/system/device-emulation.rst | 1 +
39
hw/virtio/meson.build | 2 +-
72
docs/system/devices/igb.rst | 71 +
40
hw/virtio/vhost-iova-tree.c | 110 +++++++
73
ebpf/rss.bpf.skeleton.h | 1171 ++++--
41
hw/virtio/vhost-iova-tree.h | 27 ++
74
hw/core/machine.c | 1 +
42
hw/virtio/vhost-shadow-virtqueue.c | 636 +++++++++++++++++++++++++++++++++++++
75
hw/net/Kconfig | 5 +
43
hw/virtio/vhost-shadow-virtqueue.h | 87 +++++
76
hw/net/e1000.c | 259 +-
44
hw/virtio/vhost-vdpa.c | 522 +++++++++++++++++++++++++++++-
77
hw/net/e1000_common.h | 102 +
45
include/hw/virtio/vhost-vdpa.h | 8 +
78
hw/net/e1000_regs.h | 958 +----
46
include/qemu/iova-tree.h | 38 ++-
79
hw/net/e1000e.c | 102 +-
47
util/iova-tree.c | 170 ++++++++++
80
hw/net/e1000e_core.c | 719 ++--
48
10 files changed, 1584 insertions(+), 17 deletions(-)
81
hw/net/e1000e_core.h | 70 +-
49
create mode 100644 hw/virtio/vhost-iova-tree.c
82
hw/net/e1000x_common.c | 38 +-
50
create mode 100644 hw/virtio/vhost-iova-tree.h
83
hw/net/e1000x_common.h | 133 +-
51
create mode 100644 hw/virtio/vhost-shadow-virtqueue.c
84
hw/net/e1000x_regs.h | 967 +++++
52
create mode 100644 hw/virtio/vhost-shadow-virtqueue.h
85
hw/net/fsl_etsec/etsec.c | 11 +-
53
86
hw/net/fsl_etsec/etsec.h | 17 -
54
87
hw/net/fsl_etsec/miim.c | 5 +-
55
88
hw/net/igb.c | 623 +++
89
hw/net/igb_common.h | 146 +
90
hw/net/igb_core.c | 4077 ++++++++++++++++++++
91
hw/net/igb_core.h | 146 +
92
hw/net/igb_regs.h | 648 ++++
93
hw/net/igbvf.c | 327 ++
94
hw/net/meson.build | 2 +
95
hw/net/net_rx_pkt.c | 102 +-
96
hw/net/net_rx_pkt.h | 31 +-
97
hw/net/net_tx_pkt.c | 332 +-
98
hw/net/net_tx_pkt.h | 27 +-
99
hw/net/trace-events | 50 +-
100
hw/net/virtio-net.c | 85 +-
101
hw/net/vmxnet3.c | 58 +-
102
hw/pci/pcie_sriov.c | 5 +
103
include/hw/net/mii.h | 14 +-
104
include/hw/pci/pcie_sriov.h | 3 +
105
include/net/eth.h | 15 +-
106
include/net/net.h | 6 +
107
net/dump.c | 11 +-
108
net/eth.c | 118 +-
109
net/net.c | 18 +
110
net/tap.c | 16 +
111
scripts/ci/org.centos/stream/8/x86_64/test-avocado | 1 +
112
tests/avocado/igb.py | 38 +
113
tests/qtest/e1000e-test.c | 25 +-
114
tests/qtest/fuzz/generic_fuzz_configs.h | 5 +
115
tests/qtest/igb-test.c | 256 ++
116
tests/qtest/libqos/e1000e.c | 12 -
117
tests/qtest/libqos/e1000e.h | 14 +
118
tests/qtest/libqos/igb.c | 185 +
119
tests/qtest/libqos/meson.build | 1 +
120
tests/qtest/meson.build | 1 +
121
tools/ebpf/Makefile.ebpf | 8 +-
122
tools/ebpf/rss.bpf.c | 43 +-
123
53 files changed, 9780 insertions(+), 2312 deletions(-)
124
create mode 100644 docs/system/devices/igb.rst
125
create mode 100644 hw/net/e1000_common.h
126
create mode 100644 hw/net/e1000x_regs.h
127
create mode 100644 hw/net/igb.c
128
create mode 100644 hw/net/igb_common.h
129
create mode 100644 hw/net/igb_core.c
130
create mode 100644 hw/net/igb_core.h
131
create mode 100644 hw/net/igb_regs.h
132
create mode 100644 hw/net/igbvf.c
133
create mode 100644 tests/avocado/igb.py
134
create mode 100644 tests/qtest/igb-test.c
135
create mode 100644 tests/qtest/libqos/igb.c
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
Commit bedd7e93d0196 ("virtio-net: fix use after unmap/free for sg")
2
tries to fix the use after free of the sg by caching the virtqueue
3
elements in an array and unmap them at once after receiving the
4
packets, But it forgot to unmap the cached elements on error which
5
will lead to leaking of mapping and other unexpected results.
2
6
3
The values returned by eth_get_protocols() are used to perform RSS,
7
Fixing this by detaching the cached elements on error. This addresses
4
checksumming and segmentation. Even when a packet signals the use of the
8
CVE-2022-26353.
5
protocols which these operations can be applied to, the headers for them
6
may not be present because of too short packet or fragmentation, for
7
example. In such a case, the operations cannot be applied safely.
8
9
9
Report the presence of headers instead of whether the use of the
10
Reported-by: Victor Tom <vv474172261@gmail.com>
10
protocols are indicated with eth_get_protocols(). This also makes
11
Cc: qemu-stable@nongnu.org
11
corresponding changes to the callers of eth_get_protocols() to match
12
Fixes: CVE-2022-26353
12
with its new signature and to remove redundant checks for fragmentation.
13
Fixes: bedd7e93d0196 ("virtio-net: fix use after unmap/free for sg")
13
14
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
14
Fixes: 75020a7021 ("Common definitions for VMWARE devices")
15
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
16
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
Signed-off-by: Jason Wang <jasowang@redhat.com>
17
---
16
---
18
hw/net/e1000e_core.c | 65 ++++++++++++++++++-------------------
17
hw/net/virtio-net.c | 1 +
19
hw/net/net_rx_pkt.c | 86 ++++++++++++++++++++++++-------------------------
18
1 file changed, 1 insertion(+)
20
hw/net/net_rx_pkt.h | 12 +++----
21
hw/net/trace-events | 6 ++--
22
hw/net/virtio-net.c | 32 ++++++++----------
23
hw/net/vmxnet3.c | 20 ++++++------
24
include/net/eth.h | 4 +--
25
net/eth.c | 91 ++++++++++++++++++++++++----------------------------
26
8 files changed, 150 insertions(+), 166 deletions(-)
27
19
28
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/net/e1000e_core.c
31
+++ b/hw/net/e1000e_core.c
32
@@ -XXX,XX +XXX,XX @@ typedef struct E1000E_RSSInfo_st {
33
static uint32_t
34
e1000e_rss_get_hash_type(E1000ECore *core, struct NetRxPkt *pkt)
35
{
36
- bool isip4, isip6, isudp, istcp;
37
+ bool hasip4, hasip6, hasudp, hastcp;
38
39
assert(e1000e_rss_enabled(core));
40
41
- net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
42
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
43
44
- if (isip4) {
45
- bool fragment = net_rx_pkt_get_ip4_info(pkt)->fragment;
46
-
47
- trace_e1000e_rx_rss_ip4(fragment, istcp, core->mac[MRQC],
48
+ if (hasip4) {
49
+ trace_e1000e_rx_rss_ip4(hastcp, core->mac[MRQC],
50
E1000_MRQC_EN_TCPIPV4(core->mac[MRQC]),
51
E1000_MRQC_EN_IPV4(core->mac[MRQC]));
52
53
- if (!fragment && istcp && E1000_MRQC_EN_TCPIPV4(core->mac[MRQC])) {
54
+ if (hastcp && E1000_MRQC_EN_TCPIPV4(core->mac[MRQC])) {
55
return E1000_MRQ_RSS_TYPE_IPV4TCP;
56
}
57
58
if (E1000_MRQC_EN_IPV4(core->mac[MRQC])) {
59
return E1000_MRQ_RSS_TYPE_IPV4;
60
}
61
- } else if (isip6) {
62
+ } else if (hasip6) {
63
eth_ip6_hdr_info *ip6info = net_rx_pkt_get_ip6_info(pkt);
64
65
bool ex_dis = core->mac[RFCTL] & E1000_RFCTL_IPV6_EX_DIS;
66
@@ -XXX,XX +XXX,XX @@ e1000e_rss_get_hash_type(E1000ECore *core, struct NetRxPkt *pkt)
67
* backends like these.
68
*/
69
trace_e1000e_rx_rss_ip6_rfctl(core->mac[RFCTL]);
70
- trace_e1000e_rx_rss_ip6(ex_dis, new_ex_dis, istcp,
71
+ trace_e1000e_rx_rss_ip6(ex_dis, new_ex_dis, hastcp,
72
ip6info->has_ext_hdrs,
73
ip6info->rss_ex_dst_valid,
74
ip6info->rss_ex_src_valid,
75
@@ -XXX,XX +XXX,XX @@ e1000e_rss_get_hash_type(E1000ECore *core, struct NetRxPkt *pkt)
76
(!new_ex_dis || !(ip6info->rss_ex_dst_valid ||
77
ip6info->rss_ex_src_valid))) {
78
79
- if (istcp && !ip6info->fragment &&
80
- E1000_MRQC_EN_TCPIPV6(core->mac[MRQC])) {
81
+ if (hastcp && E1000_MRQC_EN_TCPIPV6(core->mac[MRQC])) {
82
return E1000_MRQ_RSS_TYPE_IPV6TCP;
83
}
84
85
@@ -XXX,XX +XXX,XX @@ static void
86
e1000e_verify_csum_in_sw(E1000ECore *core,
87
struct NetRxPkt *pkt,
88
uint32_t *status_flags,
89
- bool istcp, bool isudp)
90
+ bool hastcp, bool hasudp)
91
{
92
bool csum_valid;
93
uint32_t csum_error;
94
@@ -XXX,XX +XXX,XX @@ e1000e_verify_csum_in_sw(E1000ECore *core,
95
96
csum_error = csum_valid ? 0 : E1000_RXDEXT_STATERR_TCPE;
97
98
- if (istcp) {
99
+ if (hastcp) {
100
*status_flags |= E1000_RXD_STAT_TCPCS |
101
csum_error;
102
- } else if (isudp) {
103
+ } else if (hasudp) {
104
*status_flags |= E1000_RXD_STAT_TCPCS |
105
E1000_RXD_STAT_UDPCS |
106
csum_error;
107
@@ -XXX,XX +XXX,XX @@ e1000e_build_rx_metadata(E1000ECore *core,
108
uint16_t *vlan_tag)
109
{
110
struct virtio_net_hdr *vhdr;
111
- bool isip4, isip6, istcp, isudp;
112
+ bool hasip4, hasip6, hastcp, hasudp;
113
uint32_t pkt_type;
114
115
*status_flags = E1000_RXD_STAT_DD;
116
@@ -XXX,XX +XXX,XX @@ e1000e_build_rx_metadata(E1000ECore *core,
117
118
*status_flags |= E1000_RXD_STAT_EOP;
119
120
- net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
121
- trace_e1000e_rx_metadata_protocols(isip4, isip6, isudp, istcp);
122
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
123
+ trace_e1000e_rx_metadata_protocols(hasip4, hasip6, hasudp, hastcp);
124
125
/* VLAN state */
126
if (net_rx_pkt_is_vlan_stripped(pkt)) {
127
@@ -XXX,XX +XXX,XX @@ e1000e_build_rx_metadata(E1000ECore *core,
128
*mrq = cpu_to_le32(rss_info->type | (rss_info->queue << 8));
129
trace_e1000e_rx_metadata_rss(*rss, *mrq);
130
}
131
- } else if (isip4) {
132
+ } else if (hasip4) {
133
*status_flags |= E1000_RXD_STAT_IPIDV;
134
*ip_id = cpu_to_le16(net_rx_pkt_get_ip_id(pkt));
135
trace_e1000e_rx_metadata_ip_id(*ip_id);
136
}
137
138
- if (istcp && e1000e_is_tcp_ack(core, pkt)) {
139
+ if (hastcp && e1000e_is_tcp_ack(core, pkt)) {
140
*status_flags |= E1000_RXD_STAT_ACK;
141
trace_e1000e_rx_metadata_ack();
142
}
143
144
- if (isip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_DIS)) {
145
+ if (hasip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_DIS)) {
146
trace_e1000e_rx_metadata_ipv6_filtering_disabled();
147
pkt_type = E1000_RXD_PKT_MAC;
148
- } else if (istcp || isudp) {
149
- pkt_type = isip4 ? E1000_RXD_PKT_IP4_XDP : E1000_RXD_PKT_IP6_XDP;
150
- } else if (isip4 || isip6) {
151
- pkt_type = isip4 ? E1000_RXD_PKT_IP4 : E1000_RXD_PKT_IP6;
152
+ } else if (hastcp || hasudp) {
153
+ pkt_type = hasip4 ? E1000_RXD_PKT_IP4_XDP : E1000_RXD_PKT_IP6_XDP;
154
+ } else if (hasip4 || hasip6) {
155
+ pkt_type = hasip4 ? E1000_RXD_PKT_IP4 : E1000_RXD_PKT_IP6;
156
} else {
157
pkt_type = E1000_RXD_PKT_MAC;
158
}
159
@@ -XXX,XX +XXX,XX @@ e1000e_build_rx_metadata(E1000ECore *core,
160
trace_e1000e_rx_metadata_pkt_type(pkt_type);
161
162
/* RX CSO information */
163
- if (isip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_XSUM_DIS)) {
164
+ if (hasip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_XSUM_DIS)) {
165
trace_e1000e_rx_metadata_ipv6_sum_disabled();
166
goto func_exit;
167
}
168
@@ -XXX,XX +XXX,XX @@ e1000e_build_rx_metadata(E1000ECore *core,
169
if (!(vhdr->flags & VIRTIO_NET_HDR_F_DATA_VALID) &&
170
!(vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM)) {
171
trace_e1000e_rx_metadata_virthdr_no_csum_info();
172
- e1000e_verify_csum_in_sw(core, pkt, status_flags, istcp, isudp);
173
+ e1000e_verify_csum_in_sw(core, pkt, status_flags, hastcp, hasudp);
174
goto func_exit;
175
}
176
177
if (e1000e_rx_l3_cso_enabled(core)) {
178
- *status_flags |= isip4 ? E1000_RXD_STAT_IPCS : 0;
179
+ *status_flags |= hasip4 ? E1000_RXD_STAT_IPCS : 0;
180
} else {
181
trace_e1000e_rx_metadata_l3_cso_disabled();
182
}
183
184
if (e1000e_rx_l4_cso_enabled(core)) {
185
- if (istcp) {
186
+ if (hastcp) {
187
*status_flags |= E1000_RXD_STAT_TCPCS;
188
- } else if (isudp) {
189
+ } else if (hasudp) {
190
*status_flags |= E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS;
191
}
192
} else {
193
@@ -XXX,XX +XXX,XX @@ e1000e_rx_descr_threshold_hit(E1000ECore *core, const E1000E_RingInfo *rxi)
194
static bool
195
e1000e_do_ps(E1000ECore *core, struct NetRxPkt *pkt, size_t *hdr_len)
196
{
197
- bool isip4, isip6, isudp, istcp;
198
+ bool hasip4, hasip6, hasudp, hastcp;
199
bool fragment;
200
201
if (!e1000e_rx_use_ps_descriptor(core)) {
202
return false;
203
}
204
205
- net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
206
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
207
208
- if (isip4) {
209
+ if (hasip4) {
210
fragment = net_rx_pkt_get_ip4_info(pkt)->fragment;
211
- } else if (isip6) {
212
+ } else if (hasip6) {
213
fragment = net_rx_pkt_get_ip6_info(pkt)->fragment;
214
} else {
215
return false;
216
@@ -XXX,XX +XXX,XX @@ e1000e_do_ps(E1000ECore *core, struct NetRxPkt *pkt, size_t *hdr_len)
217
return false;
218
}
219
220
- if (!fragment && (isudp || istcp)) {
221
+ if (hasudp || hastcp) {
222
*hdr_len = net_rx_pkt_get_l5_hdr_offset(pkt);
223
} else {
224
*hdr_len = net_rx_pkt_get_l4_hdr_offset(pkt);
225
diff --git a/hw/net/net_rx_pkt.c b/hw/net/net_rx_pkt.c
226
index XXXXXXX..XXXXXXX 100644
227
--- a/hw/net/net_rx_pkt.c
228
+++ b/hw/net/net_rx_pkt.c
229
@@ -XXX,XX +XXX,XX @@ struct NetRxPkt {
230
eth_pkt_types_e packet_type;
231
232
/* Analysis results */
233
- bool isip4;
234
- bool isip6;
235
- bool isudp;
236
- bool istcp;
237
+ bool hasip4;
238
+ bool hasip6;
239
+ bool hasudp;
240
+ bool hastcp;
241
242
size_t l3hdr_off;
243
size_t l4hdr_off;
244
@@ -XXX,XX +XXX,XX @@ net_rx_pkt_pull_data(struct NetRxPkt *pkt,
245
iov, iovcnt, ploff, pkt->tot_len);
246
}
247
248
- eth_get_protocols(pkt->vec, pkt->vec_len, &pkt->isip4, &pkt->isip6,
249
- &pkt->isudp, &pkt->istcp,
250
+ eth_get_protocols(pkt->vec, pkt->vec_len, &pkt->hasip4, &pkt->hasip6,
251
+ &pkt->hasudp, &pkt->hastcp,
252
&pkt->l3hdr_off, &pkt->l4hdr_off, &pkt->l5hdr_off,
253
&pkt->ip6hdr_info, &pkt->ip4hdr_info, &pkt->l4hdr_info);
254
255
- trace_net_rx_pkt_parsed(pkt->isip4, pkt->isip6, pkt->isudp, pkt->istcp,
256
+ trace_net_rx_pkt_parsed(pkt->hasip4, pkt->hasip6, pkt->hasudp, pkt->hastcp,
257
pkt->l3hdr_off, pkt->l4hdr_off, pkt->l5hdr_off);
258
}
259
260
@@ -XXX,XX +XXX,XX @@ void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data,
261
262
assert(pkt);
263
264
- eth_get_protocols(&iov, 1, &pkt->isip4, &pkt->isip6,
265
- &pkt->isudp, &pkt->istcp,
266
+ eth_get_protocols(&iov, 1, &pkt->hasip4, &pkt->hasip6,
267
+ &pkt->hasudp, &pkt->hastcp,
268
&pkt->l3hdr_off, &pkt->l4hdr_off, &pkt->l5hdr_off,
269
&pkt->ip6hdr_info, &pkt->ip4hdr_info, &pkt->l4hdr_info);
270
}
271
272
void net_rx_pkt_get_protocols(struct NetRxPkt *pkt,
273
- bool *isip4, bool *isip6,
274
- bool *isudp, bool *istcp)
275
+ bool *hasip4, bool *hasip6,
276
+ bool *hasudp, bool *hastcp)
277
{
278
assert(pkt);
279
280
- *isip4 = pkt->isip4;
281
- *isip6 = pkt->isip6;
282
- *isudp = pkt->isudp;
283
- *istcp = pkt->istcp;
284
+ *hasip4 = pkt->hasip4;
285
+ *hasip6 = pkt->hasip6;
286
+ *hasudp = pkt->hasudp;
287
+ *hastcp = pkt->hastcp;
288
}
289
290
size_t net_rx_pkt_get_l3_hdr_offset(struct NetRxPkt *pkt)
291
@@ -XXX,XX +XXX,XX @@ net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt,
292
293
switch (type) {
294
case NetPktRssIpV4:
295
- assert(pkt->isip4);
296
+ assert(pkt->hasip4);
297
trace_net_rx_pkt_rss_ip4();
298
_net_rx_rss_prepare_ip4(&rss_input[0], pkt, &rss_length);
299
break;
300
case NetPktRssIpV4Tcp:
301
- assert(pkt->isip4);
302
- assert(pkt->istcp);
303
+ assert(pkt->hasip4);
304
+ assert(pkt->hastcp);
305
trace_net_rx_pkt_rss_ip4_tcp();
306
_net_rx_rss_prepare_ip4(&rss_input[0], pkt, &rss_length);
307
_net_rx_rss_prepare_tcp(&rss_input[0], pkt, &rss_length);
308
break;
309
case NetPktRssIpV6Tcp:
310
- assert(pkt->isip6);
311
- assert(pkt->istcp);
312
+ assert(pkt->hasip6);
313
+ assert(pkt->hastcp);
314
trace_net_rx_pkt_rss_ip6_tcp();
315
_net_rx_rss_prepare_ip6(&rss_input[0], pkt, false, &rss_length);
316
_net_rx_rss_prepare_tcp(&rss_input[0], pkt, &rss_length);
317
break;
318
case NetPktRssIpV6:
319
- assert(pkt->isip6);
320
+ assert(pkt->hasip6);
321
trace_net_rx_pkt_rss_ip6();
322
_net_rx_rss_prepare_ip6(&rss_input[0], pkt, false, &rss_length);
323
break;
324
case NetPktRssIpV6Ex:
325
- assert(pkt->isip6);
326
+ assert(pkt->hasip6);
327
trace_net_rx_pkt_rss_ip6_ex();
328
_net_rx_rss_prepare_ip6(&rss_input[0], pkt, true, &rss_length);
329
break;
330
case NetPktRssIpV6TcpEx:
331
- assert(pkt->isip6);
332
- assert(pkt->istcp);
333
+ assert(pkt->hasip6);
334
+ assert(pkt->hastcp);
335
trace_net_rx_pkt_rss_ip6_ex_tcp();
336
_net_rx_rss_prepare_ip6(&rss_input[0], pkt, true, &rss_length);
337
_net_rx_rss_prepare_tcp(&rss_input[0], pkt, &rss_length);
338
break;
339
case NetPktRssIpV4Udp:
340
- assert(pkt->isip4);
341
- assert(pkt->isudp);
342
+ assert(pkt->hasip4);
343
+ assert(pkt->hasudp);
344
trace_net_rx_pkt_rss_ip4_udp();
345
_net_rx_rss_prepare_ip4(&rss_input[0], pkt, &rss_length);
346
_net_rx_rss_prepare_udp(&rss_input[0], pkt, &rss_length);
347
break;
348
case NetPktRssIpV6Udp:
349
- assert(pkt->isip6);
350
- assert(pkt->isudp);
351
+ assert(pkt->hasip6);
352
+ assert(pkt->hasudp);
353
trace_net_rx_pkt_rss_ip6_udp();
354
_net_rx_rss_prepare_ip6(&rss_input[0], pkt, false, &rss_length);
355
_net_rx_rss_prepare_udp(&rss_input[0], pkt, &rss_length);
356
break;
357
case NetPktRssIpV6UdpEx:
358
- assert(pkt->isip6);
359
- assert(pkt->isudp);
360
+ assert(pkt->hasip6);
361
+ assert(pkt->hasudp);
362
trace_net_rx_pkt_rss_ip6_ex_udp();
363
_net_rx_rss_prepare_ip6(&rss_input[0], pkt, true, &rss_length);
364
_net_rx_rss_prepare_udp(&rss_input[0], pkt, &rss_length);
365
@@ -XXX,XX +XXX,XX @@ uint16_t net_rx_pkt_get_ip_id(struct NetRxPkt *pkt)
366
{
367
assert(pkt);
368
369
- if (pkt->isip4) {
370
+ if (pkt->hasip4) {
371
return be16_to_cpu(pkt->ip4hdr_info.ip4_hdr.ip_id);
372
}
373
374
@@ -XXX,XX +XXX,XX @@ bool net_rx_pkt_is_tcp_ack(struct NetRxPkt *pkt)
375
{
376
assert(pkt);
377
378
- if (pkt->istcp) {
379
+ if (pkt->hastcp) {
380
return TCP_HEADER_FLAGS(&pkt->l4hdr_info.hdr.tcp) & TCP_FLAG_ACK;
381
}
382
383
@@ -XXX,XX +XXX,XX @@ bool net_rx_pkt_has_tcp_data(struct NetRxPkt *pkt)
384
{
385
assert(pkt);
386
387
- if (pkt->istcp) {
388
+ if (pkt->hastcp) {
389
return pkt->l4hdr_info.has_tcp_data;
390
}
391
392
@@ -XXX,XX +XXX,XX @@ bool net_rx_pkt_validate_l3_csum(struct NetRxPkt *pkt, bool *csum_valid)
393
394
trace_net_rx_pkt_l3_csum_validate_entry();
395
396
- if (!pkt->isip4) {
397
+ if (!pkt->hasip4) {
398
trace_net_rx_pkt_l3_csum_validate_not_ip4();
399
return false;
400
}
401
@@ -XXX,XX +XXX,XX @@ _net_rx_pkt_calc_l4_csum(struct NetRxPkt *pkt)
402
403
trace_net_rx_pkt_l4_csum_calc_entry();
404
405
- if (pkt->isip4) {
406
- if (pkt->isudp) {
407
+ if (pkt->hasip4) {
408
+ if (pkt->hasudp) {
409
csl = be16_to_cpu(pkt->l4hdr_info.hdr.udp.uh_ulen);
410
trace_net_rx_pkt_l4_csum_calc_ip4_udp();
411
} else {
412
@@ -XXX,XX +XXX,XX @@ _net_rx_pkt_calc_l4_csum(struct NetRxPkt *pkt)
413
csl, &cso);
414
trace_net_rx_pkt_l4_csum_calc_ph_csum(cntr, csl);
415
} else {
416
- if (pkt->isudp) {
417
+ if (pkt->hasudp) {
418
csl = be16_to_cpu(pkt->l4hdr_info.hdr.udp.uh_ulen);
419
trace_net_rx_pkt_l4_csum_calc_ip6_udp();
420
} else {
421
@@ -XXX,XX +XXX,XX @@ bool net_rx_pkt_validate_l4_csum(struct NetRxPkt *pkt, bool *csum_valid)
422
423
trace_net_rx_pkt_l4_csum_validate_entry();
424
425
- if (!pkt->istcp && !pkt->isudp) {
426
+ if (!pkt->hastcp && !pkt->hasudp) {
427
trace_net_rx_pkt_l4_csum_validate_not_xxp();
428
return false;
429
}
430
431
- if (pkt->isudp && (pkt->l4hdr_info.hdr.udp.uh_sum == 0)) {
432
+ if (pkt->hasudp && (pkt->l4hdr_info.hdr.udp.uh_sum == 0)) {
433
trace_net_rx_pkt_l4_csum_validate_udp_with_no_checksum();
434
return false;
435
}
436
437
- if (pkt->isip4 && pkt->ip4hdr_info.fragment) {
438
+ if (pkt->hasip4 && pkt->ip4hdr_info.fragment) {
439
trace_net_rx_pkt_l4_csum_validate_ip4_fragment();
440
return false;
441
}
442
@@ -XXX,XX +XXX,XX @@ bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt)
443
444
trace_net_rx_pkt_l4_csum_fix_entry();
445
446
- if (pkt->istcp) {
447
+ if (pkt->hastcp) {
448
l4_cso = offsetof(struct tcp_header, th_sum);
449
trace_net_rx_pkt_l4_csum_fix_tcp(l4_cso);
450
- } else if (pkt->isudp) {
451
+ } else if (pkt->hasudp) {
452
if (pkt->l4hdr_info.hdr.udp.uh_sum == 0) {
453
trace_net_rx_pkt_l4_csum_fix_udp_with_no_checksum();
454
return false;
455
@@ -XXX,XX +XXX,XX @@ bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt)
456
return false;
457
}
458
459
- if (pkt->isip4 && pkt->ip4hdr_info.fragment) {
460
+ if (pkt->hasip4 && pkt->ip4hdr_info.fragment) {
461
trace_net_rx_pkt_l4_csum_fix_ip4_fragment();
462
return false;
463
}
464
diff --git a/hw/net/net_rx_pkt.h b/hw/net/net_rx_pkt.h
465
index XXXXXXX..XXXXXXX 100644
466
--- a/hw/net/net_rx_pkt.h
467
+++ b/hw/net/net_rx_pkt.h
468
@@ -XXX,XX +XXX,XX @@ void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data,
469
* fetches packet analysis results
470
*
471
* @pkt: packet
472
- * @isip4: whether the packet given is IPv4
473
- * @isip6: whether the packet given is IPv6
474
- * @isudp: whether the packet given is UDP
475
- * @istcp: whether the packet given is TCP
476
+ * @hasip4: whether the packet has an IPv4 header
477
+ * @hasip6: whether the packet has an IPv6 header
478
+ * @hasudp: whether the packet has a UDP header
479
+ * @hastcp: whether the packet has a TCP header
480
*
481
*/
482
void net_rx_pkt_get_protocols(struct NetRxPkt *pkt,
483
- bool *isip4, bool *isip6,
484
- bool *isudp, bool *istcp);
485
+ bool *hasip4, bool *hasip6,
486
+ bool *hasudp, bool *hastcp);
487
488
/**
489
* fetches L3 header offset
490
diff --git a/hw/net/trace-events b/hw/net/trace-events
491
index XXXXXXX..XXXXXXX 100644
492
--- a/hw/net/trace-events
493
+++ b/hw/net/trace-events
494
@@ -XXX,XX +XXX,XX @@ e1000e_rx_start_recv(void)
495
e1000e_rx_rss_started(void) "Starting RSS processing"
496
e1000e_rx_rss_disabled(void) "RSS is disabled"
497
e1000e_rx_rss_type(uint32_t type) "RSS type is %u"
498
-e1000e_rx_rss_ip4(bool isfragment, bool istcp, uint32_t mrqc, bool tcpipv4_enabled, bool ipv4_enabled) "RSS IPv4: fragment %d, tcp %d, mrqc 0x%X, tcpipv4 enabled %d, ipv4 enabled %d"
499
+e1000e_rx_rss_ip4(bool hastcp, uint32_t mrqc, bool tcpipv4_enabled, bool ipv4_enabled) "RSS IPv4: tcp %d, mrqc 0x%X, tcpipv4 enabled %d, ipv4 enabled %d"
500
e1000e_rx_rss_ip6_rfctl(uint32_t rfctl) "RSS IPv6: rfctl 0x%X"
501
-e1000e_rx_rss_ip6(bool ex_dis, bool new_ex_dis, bool istcp, bool has_ext_headers, bool ex_dst_valid, bool ex_src_valid, uint32_t mrqc, bool tcpipv6_enabled, bool ipv6ex_enabled, bool ipv6_enabled) "RSS IPv6: ex_dis: %d, new_ex_dis: %d, tcp %d, has_ext_headers %d, ex_dst_valid %d, ex_src_valid %d, mrqc 0x%X, tcpipv6 enabled %d, ipv6ex enabled %d, ipv6 enabled %d"
502
+e1000e_rx_rss_ip6(bool ex_dis, bool new_ex_dis, bool hastcp, bool has_ext_headers, bool ex_dst_valid, bool ex_src_valid, uint32_t mrqc, bool tcpipv6_enabled, bool ipv6ex_enabled, bool ipv6_enabled) "RSS IPv6: ex_dis: %d, new_ex_dis: %d, tcp %d, has_ext_headers %d, ex_dst_valid %d, ex_src_valid %d, mrqc 0x%X, tcpipv6 enabled %d, ipv6ex enabled %d, ipv6 enabled %d"
503
504
-e1000e_rx_metadata_protocols(bool isip4, bool isip6, bool isudp, bool istcp) "protocols: ip4: %d, ip6: %d, udp: %d, tcp: %d"
505
+e1000e_rx_metadata_protocols(bool hasip4, bool hasip6, bool hasudp, bool hastcp) "protocols: ip4: %d, ip6: %d, udp: %d, tcp: %d"
506
e1000e_rx_metadata_vlan(uint16_t vlan_tag) "VLAN tag is 0x%X"
507
e1000e_rx_metadata_rss(uint32_t rss, uint32_t mrq) "RSS data: rss: 0x%X, mrq: 0x%X"
508
e1000e_rx_metadata_ip_id(uint16_t ip_id) "the IPv4 ID is 0x%X"
509
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
20
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
510
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
511
--- a/hw/net/virtio-net.c
22
--- a/hw/net/virtio-net.c
512
+++ b/hw/net/virtio-net.c
23
+++ b/hw/net/virtio-net.c
513
@@ -XXX,XX +XXX,XX @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
24
@@ -XXX,XX +XXX,XX @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
514
return 0;
25
515
}
26
err:
516
27
for (j = 0; j < i; j++) {
517
-static uint8_t virtio_net_get_hash_type(bool isip4,
28
+ virtqueue_detach_element(q->rx_vq, elems[j], lens[j]);
518
- bool isip6,
29
g_free(elems[j]);
519
- bool isudp,
520
- bool istcp,
521
+static uint8_t virtio_net_get_hash_type(bool hasip4,
522
+ bool hasip6,
523
+ bool hasudp,
524
+ bool hastcp,
525
uint32_t types)
526
{
527
- if (isip4) {
528
- if (istcp && (types & VIRTIO_NET_RSS_HASH_TYPE_TCPv4)) {
529
+ if (hasip4) {
530
+ if (hastcp && (types & VIRTIO_NET_RSS_HASH_TYPE_TCPv4)) {
531
return NetPktRssIpV4Tcp;
532
}
533
- if (isudp && (types & VIRTIO_NET_RSS_HASH_TYPE_UDPv4)) {
534
+ if (hasudp && (types & VIRTIO_NET_RSS_HASH_TYPE_UDPv4)) {
535
return NetPktRssIpV4Udp;
536
}
537
if (types & VIRTIO_NET_RSS_HASH_TYPE_IPv4) {
538
return NetPktRssIpV4;
539
}
540
- } else if (isip6) {
541
+ } else if (hasip6) {
542
uint32_t mask = VIRTIO_NET_RSS_HASH_TYPE_TCP_EX |
543
VIRTIO_NET_RSS_HASH_TYPE_TCPv6;
544
545
- if (istcp && (types & mask)) {
546
+ if (hastcp && (types & mask)) {
547
return (types & VIRTIO_NET_RSS_HASH_TYPE_TCP_EX) ?
548
NetPktRssIpV6TcpEx : NetPktRssIpV6Tcp;
549
}
550
mask = VIRTIO_NET_RSS_HASH_TYPE_UDP_EX | VIRTIO_NET_RSS_HASH_TYPE_UDPv6;
551
- if (isudp && (types & mask)) {
552
+ if (hasudp && (types & mask)) {
553
return (types & VIRTIO_NET_RSS_HASH_TYPE_UDP_EX) ?
554
NetPktRssIpV6UdpEx : NetPktRssIpV6Udp;
555
}
556
@@ -XXX,XX +XXX,XX @@ static int virtio_net_process_rss(NetClientState *nc, const uint8_t *buf,
557
struct NetRxPkt *pkt = n->rx_pkt;
558
uint8_t net_hash_type;
559
uint32_t hash;
560
- bool isip4, isip6, isudp, istcp;
561
+ bool hasip4, hasip6, hasudp, hastcp;
562
static const uint8_t reports[NetPktRssIpV6UdpEx + 1] = {
563
VIRTIO_NET_HASH_REPORT_IPv4,
564
VIRTIO_NET_HASH_REPORT_TCPv4,
565
@@ -XXX,XX +XXX,XX @@ static int virtio_net_process_rss(NetClientState *nc, const uint8_t *buf,
566
567
net_rx_pkt_set_protocols(pkt, buf + n->host_hdr_len,
568
size - n->host_hdr_len);
569
- net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
570
- if (isip4 && (net_rx_pkt_get_ip4_info(pkt)->fragment)) {
571
- istcp = isudp = false;
572
- }
573
- if (isip6 && (net_rx_pkt_get_ip6_info(pkt)->fragment)) {
574
- istcp = isudp = false;
575
- }
576
- net_hash_type = virtio_net_get_hash_type(isip4, isip6, isudp, istcp,
577
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
578
+ net_hash_type = virtio_net_get_hash_type(hasip4, hasip6, hasudp, hastcp,
579
n->rss_data.hash_types);
580
if (net_hash_type > NetPktRssIpV6UdpEx) {
581
if (n->rss_data.populate_hash) {
582
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
583
index XXXXXXX..XXXXXXX 100644
584
--- a/hw/net/vmxnet3.c
585
+++ b/hw/net/vmxnet3.c
586
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_rx_need_csum_calculate(struct NetRxPkt *pkt,
587
size_t pkt_len)
588
{
589
struct virtio_net_hdr *vhdr;
590
- bool isip4, isip6, istcp, isudp;
591
+ bool hasip4, hasip6, hastcp, hasudp;
592
uint8_t *data;
593
int len;
594
595
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_rx_need_csum_calculate(struct NetRxPkt *pkt,
596
return;
597
}
30
}
598
599
- net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
600
- if (!(isip4 || isip6) || !(istcp || isudp)) {
601
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
602
+ if (!(hasip4 || hasip6) || !(hastcp || hasudp)) {
603
return;
604
}
605
606
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_rx_update_descr(struct NetRxPkt *pkt,
607
struct Vmxnet3_RxCompDesc *rxcd)
608
{
609
int csum_ok, is_gso;
610
- bool isip4, isip6, istcp, isudp;
611
+ bool hasip4, hasip6, hastcp, hasudp;
612
struct virtio_net_hdr *vhdr;
613
uint8_t offload_type;
614
615
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_rx_update_descr(struct NetRxPkt *pkt,
616
goto nocsum;
617
}
618
619
- net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
620
- if ((!istcp && !isudp) || (!isip4 && !isip6)) {
621
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
622
+ if ((!hastcp && !hasudp) || (!hasip4 && !hasip6)) {
623
goto nocsum;
624
}
625
626
rxcd->cnc = 0;
627
- rxcd->v4 = isip4 ? 1 : 0;
628
- rxcd->v6 = isip6 ? 1 : 0;
629
- rxcd->tcp = istcp ? 1 : 0;
630
- rxcd->udp = isudp ? 1 : 0;
631
+ rxcd->v4 = hasip4 ? 1 : 0;
632
+ rxcd->v6 = hasip6 ? 1 : 0;
633
+ rxcd->tcp = hastcp ? 1 : 0;
634
+ rxcd->udp = hasudp ? 1 : 0;
635
rxcd->fcs = rxcd->tuc = rxcd->ipc = 1;
636
return;
637
638
diff --git a/include/net/eth.h b/include/net/eth.h
639
index XXXXXXX..XXXXXXX 100644
640
--- a/include/net/eth.h
641
+++ b/include/net/eth.h
642
@@ -XXX,XX +XXX,XX @@ typedef struct eth_l4_hdr_info_st {
643
} eth_l4_hdr_info;
644
645
void eth_get_protocols(const struct iovec *iov, int iovcnt,
646
- bool *isip4, bool *isip6,
647
- bool *isudp, bool *istcp,
648
+ bool *hasip4, bool *hasip6,
649
+ bool *hasudp, bool *hastcp,
650
size_t *l3hdr_off,
651
size_t *l4hdr_off,
652
size_t *l5hdr_off,
653
diff --git a/net/eth.c b/net/eth.c
654
index XXXXXXX..XXXXXXX 100644
655
--- a/net/eth.c
656
+++ b/net/eth.c
657
@@ -XXX,XX +XXX,XX @@ _eth_tcp_has_data(bool is_ip4,
658
}
659
660
void eth_get_protocols(const struct iovec *iov, int iovcnt,
661
- bool *isip4, bool *isip6,
662
- bool *isudp, bool *istcp,
663
+ bool *hasip4, bool *hasip6,
664
+ bool *hasudp, bool *hastcp,
665
size_t *l3hdr_off,
666
size_t *l4hdr_off,
667
size_t *l5hdr_off,
668
@@ -XXX,XX +XXX,XX @@ void eth_get_protocols(const struct iovec *iov, int iovcnt,
669
size_t l2hdr_len = eth_get_l2_hdr_length_iov(iov, iovcnt);
670
size_t input_size = iov_size(iov, iovcnt);
671
size_t copied;
672
+ uint8_t ip_p;
673
674
- *isip4 = *isip6 = *isudp = *istcp = false;
675
+ *hasip4 = *hasip6 = *hasudp = *hastcp = false;
676
677
proto = eth_get_l3_proto(iov, iovcnt, l2hdr_len);
678
679
@@ -XXX,XX +XXX,XX @@ void eth_get_protocols(const struct iovec *iov, int iovcnt,
680
}
681
682
copied = iov_to_buf(iov, iovcnt, l2hdr_len, iphdr, sizeof(*iphdr));
683
-
684
- *isip4 = true;
685
-
686
- if (copied < sizeof(*iphdr)) {
687
+ if (copied < sizeof(*iphdr) ||
688
+ IP_HEADER_VERSION(iphdr) != IP_HEADER_VERSION_4) {
689
return;
690
}
691
692
- if (IP_HEADER_VERSION(iphdr) == IP_HEADER_VERSION_4) {
693
- if (iphdr->ip_p == IP_PROTO_TCP) {
694
- *istcp = true;
695
- } else if (iphdr->ip_p == IP_PROTO_UDP) {
696
- *isudp = true;
697
- }
698
- }
699
-
700
+ *hasip4 = true;
701
+ ip_p = iphdr->ip_p;
702
ip4hdr_info->fragment = IP4_IS_FRAGMENT(iphdr);
703
*l4hdr_off = l2hdr_len + IP_HDR_GET_LEN(iphdr);
704
705
fragment = ip4hdr_info->fragment;
706
} else if (proto == ETH_P_IPV6) {
707
-
708
- *isip6 = true;
709
- if (eth_parse_ipv6_hdr(iov, iovcnt, l2hdr_len,
710
- ip6hdr_info)) {
711
- if (ip6hdr_info->l4proto == IP_PROTO_TCP) {
712
- *istcp = true;
713
- } else if (ip6hdr_info->l4proto == IP_PROTO_UDP) {
714
- *isudp = true;
715
- }
716
- } else {
717
+ if (!eth_parse_ipv6_hdr(iov, iovcnt, l2hdr_len, ip6hdr_info)) {
718
return;
719
}
720
721
+ *hasip6 = true;
722
+ ip_p = ip6hdr_info->l4proto;
723
*l4hdr_off = l2hdr_len + ip6hdr_info->full_hdr_len;
724
fragment = ip6hdr_info->fragment;
725
+ } else {
726
+ return;
727
}
728
729
- if (!fragment) {
730
- if (*istcp) {
731
- *istcp = _eth_copy_chunk(input_size,
732
- iov, iovcnt,
733
- *l4hdr_off, sizeof(l4hdr_info->hdr.tcp),
734
- &l4hdr_info->hdr.tcp);
735
-
736
- if (*istcp) {
737
- *l5hdr_off = *l4hdr_off +
738
- TCP_HEADER_DATA_OFFSET(&l4hdr_info->hdr.tcp);
739
-
740
- l4hdr_info->has_tcp_data =
741
- _eth_tcp_has_data(proto == ETH_P_IP,
742
- &ip4hdr_info->ip4_hdr,
743
- &ip6hdr_info->ip6_hdr,
744
- *l4hdr_off - *l3hdr_off,
745
- &l4hdr_info->hdr.tcp);
746
- }
747
- } else if (*isudp) {
748
- *isudp = _eth_copy_chunk(input_size,
749
- iov, iovcnt,
750
- *l4hdr_off, sizeof(l4hdr_info->hdr.udp),
751
- &l4hdr_info->hdr.udp);
752
- *l5hdr_off = *l4hdr_off + sizeof(l4hdr_info->hdr.udp);
753
+ if (fragment) {
754
+ return;
755
+ }
756
+
757
+ switch (ip_p) {
758
+ case IP_PROTO_TCP:
759
+ *hastcp = _eth_copy_chunk(input_size,
760
+ iov, iovcnt,
761
+ *l4hdr_off, sizeof(l4hdr_info->hdr.tcp),
762
+ &l4hdr_info->hdr.tcp);
763
+ if (*hastcp) {
764
+ *l5hdr_off = *l4hdr_off +
765
+ TCP_HEADER_DATA_OFFSET(&l4hdr_info->hdr.tcp);
766
+
767
+ l4hdr_info->has_tcp_data =
768
+ _eth_tcp_has_data(proto == ETH_P_IP,
769
+ &ip4hdr_info->ip4_hdr,
770
+ &ip6hdr_info->ip6_hdr,
771
+ *l4hdr_off - *l3hdr_off,
772
+ &l4hdr_info->hdr.tcp);
773
}
774
+ break;
775
+
776
+ case IP_PROTO_UDP:
777
+ *hasudp = _eth_copy_chunk(input_size,
778
+ iov, iovcnt,
779
+ *l4hdr_off, sizeof(l4hdr_info->hdr.udp),
780
+ &l4hdr_info->hdr.udp);
781
+ *l5hdr_off = *l4hdr_off + sizeof(l4hdr_info->hdr.udp);
782
+ break;
783
}
784
}
785
31
786
--
32
--
787
2.7.4
33
2.7.4
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
Some definitions in the header files are invalid for igb so extract
3
Vhost shadow virtqueue (SVQ) is an intermediate jump for virtqueue
4
them to new header files to keep igb from referring to them.
4
notifications and buffers, allowing qemu to track them. While qemu is
5
forwarding the buffers and virtqueue changes, it is able to commit the
6
memory it's being dirtied, the same way regular qemu's VirtIO devices
7
do.
5
8
6
Signed-off-by: Gal Hammer <gal.hammer@sap.com>
9
This commit only exposes basic SVQ allocation and free. Next patches of
7
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
10
the series add functionality like notifications and buffers forwarding.
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
11
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
13
Acked-by: Michael S. Tsirkin <mst@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
15
---
12
hw/net/e1000.c | 1 +
16
hw/virtio/meson.build | 2 +-
13
hw/net/e1000_common.h | 102 ++++++
17
hw/virtio/vhost-shadow-virtqueue.c | 62 ++++++++++++++++++++++++++++++++++++++
14
hw/net/e1000_regs.h | 954 +-----------------------------------------------
18
hw/virtio/vhost-shadow-virtqueue.h | 28 +++++++++++++++++
15
hw/net/e1000e.c | 3 +-
19
3 files changed, 91 insertions(+), 1 deletion(-)
16
hw/net/e1000e_core.c | 1 +
20
create mode 100644 hw/virtio/vhost-shadow-virtqueue.c
17
hw/net/e1000x_common.c | 1 +
21
create mode 100644 hw/virtio/vhost-shadow-virtqueue.h
18
hw/net/e1000x_common.h | 74 ----
19
hw/net/e1000x_regs.h | 967 +++++++++++++++++++++++++++++++++++++++++++++++++
20
8 files changed, 1076 insertions(+), 1027 deletions(-)
21
create mode 100644 hw/net/e1000_common.h
22
create mode 100644 hw/net/e1000x_regs.h
23
22
24
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
23
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
25
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/net/e1000.c
25
--- a/hw/virtio/meson.build
27
+++ b/hw/net/e1000.c
26
+++ b/hw/virtio/meson.build
28
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('vhost-stub.c'))
29
#include "qemu/module.h"
28
30
#include "qemu/range.h"
29
virtio_ss = ss.source_set()
31
30
virtio_ss.add(files('virtio.c'))
32
+#include "e1000_common.h"
31
-virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c'))
33
#include "e1000x_common.h"
32
+virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c', 'vhost-shadow-virtqueue.c'))
34
#include "trace.h"
33
virtio_ss.add(when: 'CONFIG_VHOST_USER', if_true: files('vhost-user.c'))
35
#include "qom/object.h"
34
virtio_ss.add(when: 'CONFIG_VHOST_VDPA', if_true: files('vhost-vdpa.c'))
36
diff --git a/hw/net/e1000_common.h b/hw/net/e1000_common.h
35
virtio_ss.add(when: 'CONFIG_VIRTIO_BALLOON', if_true: files('virtio-balloon.c'))
36
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
37
new file mode 100644
37
new file mode 100644
38
index XXXXXXX..XXXXXXX
38
index XXXXXXX..XXXXXXX
39
--- /dev/null
39
--- /dev/null
40
+++ b/hw/net/e1000_common.h
40
+++ b/hw/virtio/vhost-shadow-virtqueue.c
41
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@
42
+/*
42
+/*
43
+ * QEMU e1000(e) emulation - shared definitions
43
+ * vhost shadow virtqueue
44
+ *
44
+ *
45
+ * Copyright (c) 2008 Qumranet
45
+ * SPDX-FileCopyrightText: Red Hat, Inc. 2021
46
+ * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
46
+ *
47
+ *
47
+ * Based on work done by:
48
+ * SPDX-License-Identifier: GPL-2.0-or-later
48
+ * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
49
+ * Copyright (c) 2007 Dan Aloni
50
+ * Copyright (c) 2004 Antony T Curtis
51
+ *
52
+ * This library is free software; you can redistribute it and/or
53
+ * modify it under the terms of the GNU Lesser General Public
54
+ * License as published by the Free Software Foundation; either
55
+ * version 2.1 of the License, or (at your option) any later version.
56
+ *
57
+ * This library is distributed in the hope that it will be useful,
58
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
59
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
60
+ * Lesser General Public License for more details.
61
+ *
62
+ * You should have received a copy of the GNU Lesser General Public
63
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
64
+ */
49
+ */
65
+
50
+
66
+#ifndef HW_NET_E1000_COMMON_H
51
+#include "qemu/osdep.h"
67
+#define HW_NET_E1000_COMMON_H
52
+#include "hw/virtio/vhost-shadow-virtqueue.h"
68
+
53
+
69
+#include "e1000_regs.h"
54
+#include "qemu/error-report.h"
70
+
55
+
71
+#define defreg(x) x = (E1000_##x >> 2)
56
+/**
72
+enum {
57
+ * Creates vhost shadow virtqueue, and instructs the vhost device to use the
73
+ defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC),
58
+ * shadow methods and file descriptors.
74
+ defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC),
59
+ *
75
+ defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC),
60
+ * Returns the new virtqueue or NULL.
76
+ defreg(MPC), defreg(PBA), defreg(RCTL), defreg(RDBAH0),
61
+ *
77
+ defreg(RDBAL0), defreg(RDH0), defreg(RDLEN0), defreg(RDT0),
62
+ * In case of error, reason is reported through error_report.
78
+ defreg(STATUS), defreg(SWSM), defreg(TCTL), defreg(TDBAH),
63
+ */
79
+ defreg(TDBAL), defreg(TDH), defreg(TDLEN), defreg(TDT),
64
+VhostShadowVirtqueue *vhost_svq_new(void)
80
+ defreg(TDLEN1), defreg(TDBAL1), defreg(TDBAH1), defreg(TDH1),
65
+{
81
+ defreg(TDT1), defreg(TORH), defreg(TORL), defreg(TOTH),
66
+ g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1);
82
+ defreg(TOTL), defreg(TPR), defreg(TPT), defreg(TXDCTL),
67
+ int r;
83
+ defreg(WUFC), defreg(RA), defreg(MTA), defreg(CRCERRS),
84
+ defreg(VFTA), defreg(VET), defreg(RDTR), defreg(RADV),
85
+ defreg(TADV), defreg(ITR), defreg(SCC), defreg(ECOL),
86
+ defreg(MCC), defreg(LATECOL), defreg(COLC), defreg(DC),
87
+ defreg(TNCRS), defreg(SEQEC), defreg(CEXTERR), defreg(RLEC),
88
+ defreg(XONRXC), defreg(XONTXC), defreg(XOFFRXC), defreg(XOFFTXC),
89
+ defreg(FCRUC), defreg(AIT), defreg(TDFH), defreg(TDFT),
90
+ defreg(TDFHS), defreg(TDFTS), defreg(TDFPC), defreg(WUC),
91
+ defreg(WUS), defreg(POEMB), defreg(PBS), defreg(RDFH),
92
+ defreg(RDFT), defreg(RDFHS), defreg(RDFTS), defreg(RDFPC),
93
+ defreg(PBM), defreg(IPAV), defreg(IP4AT), defreg(IP6AT),
94
+ defreg(WUPM), defreg(FFLT), defreg(FFMT), defreg(FFVT),
95
+ defreg(TARC0), defreg(TARC1), defreg(IAM), defreg(EXTCNF_CTRL),
96
+ defreg(GCR), defreg(TIMINCA), defreg(EIAC), defreg(CTRL_EXT),
97
+ defreg(IVAR), defreg(MFUTP01), defreg(MFUTP23), defreg(MANC2H),
98
+ defreg(MFVAL), defreg(MDEF), defreg(FACTPS), defreg(FTFT),
99
+ defreg(RUC), defreg(ROC), defreg(RFC), defreg(RJC),
100
+ defreg(PRC64), defreg(PRC127), defreg(PRC255), defreg(PRC511),
101
+ defreg(PRC1023), defreg(PRC1522), defreg(PTC64), defreg(PTC127),
102
+ defreg(PTC255), defreg(PTC511), defreg(PTC1023), defreg(PTC1522),
103
+ defreg(GORCL), defreg(GORCH), defreg(GOTCL), defreg(GOTCH),
104
+ defreg(RNBC), defreg(BPRC), defreg(MPRC), defreg(RFCTL),
105
+ defreg(PSRCTL), defreg(MPTC), defreg(BPTC), defreg(TSCTFC),
106
+ defreg(IAC), defreg(MGTPRC), defreg(MGTPDC), defreg(MGTPTC),
107
+ defreg(TSCTC), defreg(RXCSUM), defreg(FUNCTAG), defreg(GSCL_1),
108
+ defreg(GSCL_2), defreg(GSCL_3), defreg(GSCL_4), defreg(GSCN_0),
109
+ defreg(GSCN_1), defreg(GSCN_2), defreg(GSCN_3), defreg(GCR2),
110
+ defreg(RAID), defreg(RSRPD), defreg(TIDV), defreg(EITR),
111
+ defreg(MRQC), defreg(RETA), defreg(RSSRK), defreg(RDBAH1),
112
+ defreg(RDBAL1), defreg(RDLEN1), defreg(RDH1), defreg(RDT1),
113
+ defreg(PBACLR), defreg(FCAL), defreg(FCAH), defreg(FCT),
114
+ defreg(FCRTH), defreg(FCRTL), defreg(FCTTV), defreg(FCRTV),
115
+ defreg(FLA), defreg(EEWR), defreg(FLOP), defreg(FLOL),
116
+ defreg(FLSWCTL), defreg(FLSWCNT), defreg(RXDCTL), defreg(RXDCTL1),
117
+ defreg(MAVTV0), defreg(MAVTV1), defreg(MAVTV2), defreg(MAVTV3),
118
+ defreg(TXSTMPL), defreg(TXSTMPH), defreg(SYSTIML), defreg(SYSTIMH),
119
+ defreg(RXCFGL), defreg(RXUDP), defreg(TIMADJL), defreg(TIMADJH),
120
+ defreg(RXSTMPH), defreg(RXSTMPL), defreg(RXSATRL), defreg(RXSATRH),
121
+ defreg(FLASHT), defreg(TIPG), defreg(RDH), defreg(RDT),
122
+ defreg(RDLEN), defreg(RDBAH), defreg(RDBAL),
123
+ defreg(TXDCTL1),
124
+ defreg(FLSWDATA),
125
+ defreg(CTRL_DUP),
126
+ defreg(EXTCNF_SIZE),
127
+ defreg(EEMNGCTL),
128
+ defreg(EEMNGDATA),
129
+ defreg(FLMNGCTL),
130
+ defreg(FLMNGDATA),
131
+ defreg(FLMNGCNT),
132
+ defreg(TSYNCRXCTL),
133
+ defreg(TSYNCTXCTL),
134
+
68
+
135
+ /* Aliases */
69
+ r = event_notifier_init(&svq->hdev_kick, 0);
136
+ defreg(RDH0_A), defreg(RDT0_A), defreg(RDTR_A), defreg(RDFH_A),
70
+ if (r != 0) {
137
+ defreg(RDFT_A), defreg(TDH_A), defreg(TDT_A), defreg(TIDV_A),
71
+ error_report("Couldn't create kick event notifier: %s (%d)",
138
+ defreg(TDFH_A), defreg(TDFT_A), defreg(RA_A), defreg(RDBAL0_A),
72
+ g_strerror(errno), errno);
139
+ defreg(TDBAL_A), defreg(TDLEN_A), defreg(VFTA_A), defreg(RDLEN0_A),
73
+ goto err_init_hdev_kick;
140
+ defreg(FCRTL_A), defreg(FCRTH_A)
74
+ }
141
+};
142
+
75
+
143
+#endif
76
+ r = event_notifier_init(&svq->hdev_call, 0);
144
diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h
77
+ if (r != 0) {
145
index XXXXXXX..XXXXXXX 100644
78
+ error_report("Couldn't create call event notifier: %s (%d)",
146
--- a/hw/net/e1000_regs.h
79
+ g_strerror(errno), errno);
147
+++ b/hw/net/e1000_regs.h
80
+ goto err_init_hdev_call;
148
@@ -XXX,XX +XXX,XX @@
81
+ }
149
#ifndef HW_E1000_REGS_H
150
#define HW_E1000_REGS_H
151
152
-/* PCI Device IDs */
153
-#define E1000_DEV_ID_82542 0x1000
154
-#define E1000_DEV_ID_82543GC_FIBER 0x1001
155
-#define E1000_DEV_ID_82543GC_COPPER 0x1004
156
-#define E1000_DEV_ID_82544EI_COPPER 0x1008
157
-#define E1000_DEV_ID_82544EI_FIBER 0x1009
158
-#define E1000_DEV_ID_82544GC_COPPER 0x100C
159
-#define E1000_DEV_ID_82544GC_LOM 0x100D
160
-#define E1000_DEV_ID_82540EM 0x100E
161
-#define E1000_DEV_ID_82540EM_LOM 0x1015
162
-#define E1000_DEV_ID_82540EP_LOM 0x1016
163
-#define E1000_DEV_ID_82540EP 0x1017
164
-#define E1000_DEV_ID_82540EP_LP 0x101E
165
-#define E1000_DEV_ID_82545EM_COPPER 0x100F
166
-#define E1000_DEV_ID_82545EM_FIBER 0x1011
167
-#define E1000_DEV_ID_82545GM_COPPER 0x1026
168
-#define E1000_DEV_ID_82545GM_FIBER 0x1027
169
-#define E1000_DEV_ID_82545GM_SERDES 0x1028
170
-#define E1000_DEV_ID_82546EB_COPPER 0x1010
171
-#define E1000_DEV_ID_82546EB_FIBER 0x1012
172
-#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
173
-#define E1000_DEV_ID_82541EI 0x1013
174
-#define E1000_DEV_ID_82541EI_MOBILE 0x1018
175
-#define E1000_DEV_ID_82541ER_LOM 0x1014
176
-#define E1000_DEV_ID_82541ER 0x1078
177
-#define E1000_DEV_ID_82547GI 0x1075
178
-#define E1000_DEV_ID_82541GI 0x1076
179
-#define E1000_DEV_ID_82541GI_MOBILE 0x1077
180
-#define E1000_DEV_ID_82541GI_LF 0x107C
181
-#define E1000_DEV_ID_82546GB_COPPER 0x1079
182
-#define E1000_DEV_ID_82546GB_FIBER 0x107A
183
-#define E1000_DEV_ID_82546GB_SERDES 0x107B
184
-#define E1000_DEV_ID_82546GB_PCIE 0x108A
185
-#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
186
-#define E1000_DEV_ID_82547EI 0x1019
187
-#define E1000_DEV_ID_82547EI_MOBILE 0x101A
188
-#define E1000_DEV_ID_82571EB_COPPER 0x105E
189
-#define E1000_DEV_ID_82571EB_FIBER 0x105F
190
-#define E1000_DEV_ID_82571EB_SERDES 0x1060
191
-#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
192
-#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
193
-#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
194
-#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE 0x10BC
195
-#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
196
-#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
197
-#define E1000_DEV_ID_82572EI_COPPER 0x107D
198
-#define E1000_DEV_ID_82572EI_FIBER 0x107E
199
-#define E1000_DEV_ID_82572EI_SERDES 0x107F
200
-#define E1000_DEV_ID_82572EI 0x10B9
201
-#define E1000_DEV_ID_82573E 0x108B
202
-#define E1000_DEV_ID_82573E_IAMT 0x108C
203
-#define E1000_DEV_ID_82573L 0x109A
204
-#define E1000_DEV_ID_82574L 0x10D3
205
-#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
206
-#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
207
-#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
208
-#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA
209
-#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB
210
+#include "e1000x_regs.h"
211
212
-#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049
213
-#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A
214
-#define E1000_DEV_ID_ICH8_IGP_C 0x104B
215
-#define E1000_DEV_ID_ICH8_IFE 0x104C
216
-#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4
217
-#define E1000_DEV_ID_ICH8_IFE_G 0x10C5
218
-#define E1000_DEV_ID_ICH8_IGP_M 0x104D
219
-
220
-/* Device Specific Register Defaults */
221
-#define E1000_PHY_ID2_82541x 0x380
222
-#define E1000_PHY_ID2_82544x 0xC30
223
-#define E1000_PHY_ID2_8254xx_DEFAULT 0xC20 /* 82540x, 82545x, and 82546x */
224
-#define E1000_PHY_ID2_82573x 0xCC0
225
-#define E1000_PHY_ID2_82574x 0xCB1
226
-
227
-/* Register Set. (82543, 82544)
228
- *
229
- * Registers are defined to be 32 bits and should be accessed as 32 bit values.
230
- * These registers are physically located on the NIC, but are mapped into the
231
- * host memory address space.
232
- *
233
- * RW - register is both readable and writable
234
- * RO - register is read only
235
- * WO - register is write only
236
- * R/clr - register is read only and is cleared when read
237
- * A - register array
238
- */
239
-#define E1000_CTRL 0x00000 /* Device Control - RW */
240
-#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */
241
-#define E1000_STATUS 0x00008 /* Device Status - RO */
242
-#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
243
-#define E1000_EERD 0x00014 /* EEPROM Read - RW */
244
-#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
245
-#define E1000_FLA 0x0001C /* Flash Access - RW */
246
-#define E1000_MDIC 0x00020 /* MDI Control - RW */
247
-#define E1000_SCTL 0x00024 /* SerDes Control - RW */
248
-#define E1000_FEXTNVM 0x00028 /* Future Extended NVM register */
249
-#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
250
-#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
251
-#define E1000_FCT 0x00030 /* Flow Control Type - RW */
252
-#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
253
-#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
254
#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
255
-#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
256
-#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
257
#define E1000_EIAC 0x000DC /* Ext. Interrupt Auto Clear - RW */
258
-#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
259
-#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
260
#define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */
261
#define E1000_EITR 0x000E8 /* Extended Interrupt Throttling Rate - RW */
262
-#define E1000_RCTL 0x00100 /* RX Control - RW */
263
-#define E1000_RDTR1 0x02820 /* RX Delay Timer (1) - RW */
264
#define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW */
265
#define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - RW */
266
#define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */
267
#define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */
268
#define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - RW */
269
-#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
270
#define E1000_FCRTV 0x05F40 /* Flow Control Refresh Timer Value - RW */
271
#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
272
#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */
273
-#define E1000_TCTL 0x00400 /* TX Control - RW */
274
-#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */
275
-#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
276
#define E1000_TBT 0x00448 /* TX Burst Timer - RW */
277
#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
278
-#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
279
#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
280
#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
281
#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
282
-#define FEXTNVM_SW_CONFIG 0x0001
283
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
284
#define E1000_PBM 0x10000 /* Packet Buffer Memory - RW */
285
#define E1000_PBS 0x01008 /* Packet Buffer Size - RW */
286
-#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
287
-#define E1000_EEMNGDATA 0x01014 /* MNG EEPROM Read/Write data */
288
-#define E1000_FLMNGCTL 0x01018 /* MNG Flash Control */
289
-#define E1000_FLMNGDATA 0x0101C /* MNG FLASH Read data */
290
-#define E1000_FLMNGCNT 0x01020 /* MNG FLASH Read Counter */
291
-#define E1000_FLASH_UPDATES 1000
292
-#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
293
#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
294
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
295
#define E1000_FLSWCTL 0x01030 /* FLASH control register */
296
#define E1000_FLSWDATA 0x01034 /* FLASH data register */
297
#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
298
-#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
299
#define E1000_FLOL 0x01050 /* FEEP Auto Load */
300
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
301
-#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
302
-#define E1000_FCRTL_A 0x00168 /* Alias to FCRTL */
303
-#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
304
#define E1000_FCRTH_A 0x00160 /* Alias to FCRTH */
305
#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
306
#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
307
@@ -XXX,XX +XXX,XX @@
308
#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
309
#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
310
#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
311
-#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */
312
-#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
313
#define E1000_POEMB 0x00F10 /* PHY OEM Bits Register - RW */
314
-#define E1000_RDFH 0x02410 /* Receive Data FIFO Head Register - RW */
315
-#define E1000_RDFH_A 0x08000 /* Alias to RDFH */
316
-#define E1000_RDFT 0x02418 /* Receive Data FIFO Tail Register - RW */
317
-#define E1000_RDFT_A 0x08008 /* Alias to RDFT */
318
-#define E1000_RDFHS 0x02420 /* Receive Data FIFO Head Saved Register - RW */
319
-#define E1000_RDFTS 0x02428 /* Receive Data FIFO Tail Saved Register - RW */
320
-#define E1000_RDFPC 0x02430 /* Receive Data FIFO Packet Count - RW */
321
-#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */
322
-#define E1000_TDFH_A 0x08010 /* Alias to TDFH */
323
-#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
324
-#define E1000_TDFT_A 0x08018 /* Alias to TDFT */
325
-#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
326
-#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */
327
-#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */
328
#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
329
#define E1000_TDBAL_A 0x00420 /* Alias to TDBAL */
330
#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */
331
@@ -XXX,XX +XXX,XX @@
332
#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */
333
#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */
334
#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */
335
-#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
336
-#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
337
-#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
338
-#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
339
-#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
340
-#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
341
-#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
342
-#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
343
-#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
344
-#define E1000_COLC 0x04028 /* Collision Count - R/clr */
345
-#define E1000_DC 0x04030 /* Defer Count - R/clr */
346
-#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */
347
#define E1000_SEQEC 0x04038 /* Sequence Error Count - R/clr */
348
#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
349
-#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
350
-#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */
351
-#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */
352
-#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */
353
-#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */
354
-#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */
355
-#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */
356
-#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */
357
-#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */
358
-#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */
359
-#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */
360
-#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */
361
-#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */
362
-#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */
363
-#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */
364
-#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */
365
-#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */
366
-#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */
367
-#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */
368
-#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */
369
-#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */
370
-#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */
371
-#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */
372
-#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */
373
-#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */
374
-#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */
375
-#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
376
-#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */
377
-#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */
378
-#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */
379
-#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */
380
-#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */
381
-#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */
382
-#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */
383
-#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */
384
-#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */
385
-#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */
386
-#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */
387
-#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */
388
-#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */
389
-#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */
390
-#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
391
-#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
392
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
393
-#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
394
-#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire Count */
395
#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Absolute Timer Expire Count */
396
#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Packet Timer Expire Count */
397
#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Absolute Timer Expire Count */
398
#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
399
#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
400
-#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
401
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
402
-#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
403
-#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
404
-#define E1000_MAVTV0 0x05010 /* Management VLAN TAG Value 0 */
405
-#define E1000_MAVTV1 0x05014 /* Management VLAN TAG Value 1 */
406
-#define E1000_MAVTV2 0x05018 /* Management VLAN TAG Value 2 */
407
-#define E1000_MAVTV3 0x0501c /* Management VLAN TAG Value 3 */
408
-#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
409
-#define E1000_RA 0x05400 /* Receive Address - RW Array */
410
-#define E1000_RA_A 0x00040 /* Alias to RA */
411
-#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
412
-#define E1000_VFTA_A 0x00600 /* Alias to VFTA */
413
-#define E1000_WUC 0x05800 /* Wakeup Control - RW */
414
-#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
415
-#define E1000_WUS 0x05810 /* Wakeup Status - RO */
416
-#define E1000_MANC 0x05820 /* Management Control - RW */
417
-#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
418
-#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */
419
-#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */
420
-#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
421
-#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */
422
#define E1000_MFUTP01 0x05828 /* Management Flex UDP/TCP Ports 0/1 - RW */
423
#define E1000_MFUTP23 0x05830 /* Management Flex UDP/TCP Ports 2/3 - RW */
424
-#define E1000_MFVAL 0x05824 /* Manageability Filters Valid - RW */
425
-#define E1000_MDEF 0x05890 /* Manageability Decision Filters - RW Array */
426
#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */
427
#define E1000_HOST_IF 0x08800 /* Host Interface */
428
-#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
429
-#define E1000_FTFT 0x09400 /* Flexible TCO Filter Table - RW Array */
430
#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
431
432
#define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */
433
#define E1000_MDPHYA 0x0003C /* PHY address - RW */
434
-#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
435
-#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
436
437
-#define E1000_GCR 0x05B00 /* PCI-Ex Control */
438
-#define E1000_FUNCTAG 0x05B08 /* Function-Tag Register */
439
-#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
440
-#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
441
-#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
442
-#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
443
-#define E1000_GSCN_0 0x05B20 /* 3GIO Statistic Counter Register #0 */
444
-#define E1000_GSCN_1 0x05B24 /* 3GIO Statistic Counter Register #1 */
445
-#define E1000_GSCN_2 0x05B28 /* 3GIO Statistic Counter Register #2 */
446
-#define E1000_GSCN_3 0x05B2C /* 3GIO Statistic Counter Register #3 */
447
-#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
448
-#define E1000_SWSM 0x05B50 /* SW Semaphore */
449
#define E1000_GCR2 0x05B64 /* 3GIO Control Register 2 */
450
-#define E1000_FWSM 0x05B54 /* FW Semaphore */
451
-#define E1000_PBACLR 0x05B68 /* MSI-X PBA Clear */
452
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
453
#define E1000_HICR 0x08F00 /* Host Inteface Control */
454
455
-#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
456
-#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
457
-#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
458
-#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */
459
-#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */
460
-#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
461
-#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
462
-#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
463
-#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
464
-#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
465
#define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Msg Type - RW */
466
#define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */
467
-#define E1000_RXSATRL 0x0B62C /* Rx timestamp attribute low - RO */
468
-#define E1000_RXSATRH 0x0B630 /* Rx timestamp attribute high - RO */
469
-#define E1000_TIMADJL 0x0B60C /* Time Adjustment Offset register Low - RW */
470
-#define E1000_TIMADJH 0x0B610 /* Time Adjustment Offset register High - RW */
471
#define E1000_RXCFGL 0x0B634 /* RX Ethertype and Message Type - RW*/
472
473
-/* RSS registers */
474
+#define E1000_MRQC_ENABLED(mrqc) (((mrqc) & (BIT(0) | BIT(1))) == BIT(0))
475
+
82
+
476
#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
83
+ return g_steal_pointer(&svq);
477
-#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
84
+
478
-#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */
85
+err_init_hdev_call:
479
-#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */
86
+ event_notifier_cleanup(&svq->hdev_kick);
480
#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
87
+
481
#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
88
+err_init_hdev_kick:
482
89
+ return NULL;
483
-#define E1000_MRQC_ENABLED(mrqc) (((mrqc) & (BIT(0) | BIT(1))) == BIT(0))
90
+}
484
-
91
+
485
-#define E1000_RETA_IDX(hash) ((hash) & (BIT(7) - 1))
92
+/**
486
-#define E1000_RETA_VAL(reta, hash) (((uint8_t *)(reta))[E1000_RETA_IDX(hash)])
93
+ * Free the resources of the shadow virtqueue.
487
#define E1000_RSS_QUEUE(reta, hash) ((E1000_RETA_VAL(reta, hash) & BIT(7)) >> 7)
94
+ *
488
95
+ * @pvq: gpointer to SVQ so it can be used by autofree functions.
489
-#define E1000_MRQC_EN_TCPIPV4(mrqc) ((mrqc) & BIT(16))
96
+ */
490
-#define E1000_MRQC_EN_IPV4(mrqc) ((mrqc) & BIT(17))
97
+void vhost_svq_free(gpointer pvq)
491
-#define E1000_MRQC_EN_TCPIPV6(mrqc) ((mrqc) & BIT(18))
98
+{
492
-#define E1000_MRQC_EN_IPV6EX(mrqc) ((mrqc) & BIT(19))
99
+ VhostShadowVirtqueue *vq = pvq;
493
-#define E1000_MRQC_EN_IPV6(mrqc) ((mrqc) & BIT(20))
100
+ event_notifier_cleanup(&vq->hdev_kick);
494
-
101
+ event_notifier_cleanup(&vq->hdev_call);
495
-#define E1000_MRQ_RSS_TYPE_NONE (0)
102
+ g_free(vq);
496
-#define E1000_MRQ_RSS_TYPE_IPV4TCP (1)
103
+}
497
-#define E1000_MRQ_RSS_TYPE_IPV4 (2)
104
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
498
-#define E1000_MRQ_RSS_TYPE_IPV6TCP (3)
499
-#define E1000_MRQ_RSS_TYPE_IPV6EX (4)
500
-#define E1000_MRQ_RSS_TYPE_IPV6 (5)
501
-
502
-#define E1000_ICR_ASSERTED BIT(31)
503
-#define E1000_EIAC_MASK 0x01F00000
504
-
505
/* [TR]DBAL and [TR]DLEN masks */
506
#define E1000_XDBAL_MASK (~(BIT(4) - 1))
507
#define E1000_XDLEN_MASK ((BIT(20) - 1) & (~(BIT(7) - 1)))
508
@@ -XXX,XX +XXX,XX @@
509
510
#define E1000_IVAR_TX_INT_EVERY_WB BIT(31)
511
512
-/* RFCTL register bits */
513
-#define E1000_RFCTL_ISCSI_DIS 0x00000001
514
-#define E1000_RFCTL_NFSW_DIS 0x00000040
515
-#define E1000_RFCTL_NFSR_DIS 0x00000080
516
-#define E1000_RFCTL_IPV6_DIS 0x00000400
517
-#define E1000_RFCTL_IPV6_XSUM_DIS 0x00000800
518
#define E1000_RFCTL_ACK_DIS 0x00001000
519
#define E1000_RFCTL_ACK_DATA_DIS 0x00002000
520
-#define E1000_RFCTL_IPFRSP_DIS 0x00004000
521
-#define E1000_RFCTL_EXTEN 0x00008000
522
-#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
523
-#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000
524
525
/* PSRCTL parsing */
526
#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F
527
@@ -XXX,XX +XXX,XX @@
528
529
#define E1000_PSRCTL_BUFFS_PER_DESC 4
530
531
-/* TARC* parsing */
532
-#define E1000_TARC_ENABLE BIT(10)
533
-
534
/* PHY 1000 MII Register/Bit Definitions */
535
/* 82574-specific registers */
536
#define PHY_COPPER_CTRL1 0x10 /* Copper Specific Control Register 1 */
537
@@ -XXX,XX +XXX,XX @@
538
#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */
539
#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */
540
541
-/* SW Semaphore Register */
542
-#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
543
-#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
544
-#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
545
-
546
-#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */
547
-
548
-/* Interrupt Cause Read */
549
-#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
550
-#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
551
-#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
552
-#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
553
-#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
554
-#define E1000_ICR_RXO 0x00000040 /* rx overrun */
555
-#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
556
-#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
557
-#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
558
-#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
559
-#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
560
-#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
561
-#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
562
-#define E1000_ICR_TXD_LOW 0x00008000
563
-#define E1000_ICR_SRPD 0x00010000
564
-#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */
565
-#define E1000_ICR_MNG 0x00040000 /* Manageability event */
566
-#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */
567
-#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */
568
-#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* queue 0 Rx descriptor FIFO parity error */
569
-#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* queue 0 Tx descriptor FIFO parity error */
570
-#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity error */
571
-#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */
572
-#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* queue 1 Rx descriptor FIFO parity error */
573
-#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* queue 1 Tx descriptor FIFO parity error */
574
-#define E1000_ICR_ALL_PARITY 0x03F00000 /* all parity error bits */
575
-#define E1000_ICR_DSW 0x00000020 /* FW changed the status of DISSW bit in the FWSM */
576
-#define E1000_ICR_PHYINT 0x00001000 /* LAN connected device generates an interrupt */
577
-#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */
578
-#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */
579
-#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */
580
-#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */
581
-#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */
582
-#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */
583
-
584
-#define E1000_ICR_OTHER_CAUSES (E1000_ICR_LSC | \
585
- E1000_ICR_RXO | \
586
- E1000_ICR_MDAC | \
587
- E1000_ICR_SRPD | \
588
- E1000_ICR_ACK | \
589
- E1000_ICR_MNG)
590
-
591
-/* Interrupt Cause Set */
592
-#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
593
-#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
594
-#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
595
-#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
596
-#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
597
-#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */
598
-#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
599
-#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */
600
-#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
601
-#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
602
-#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
603
-#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
604
-#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
605
-#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
606
-#define E1000_ICS_SRPD E1000_ICR_SRPD
607
-#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */
608
-#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */
609
-#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */
610
-#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
611
-#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
612
-#define E1000_ICS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
613
-#define E1000_ICS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
614
-#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
615
-#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
616
-#define E1000_ICS_DSW E1000_ICR_DSW
617
-#define E1000_ICS_PHYINT E1000_ICR_PHYINT
618
-#define E1000_ICS_EPRST E1000_ICR_EPRST
619
-
620
-/* Interrupt Mask Set */
621
-#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
622
-#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
623
-#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
624
-#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
625
-#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
626
-#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */
627
-#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
628
-#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */
629
-#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
630
-#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
631
-#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
632
-#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
633
-#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
634
-#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
635
-#define E1000_IMS_SRPD E1000_ICR_SRPD
636
-#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */
637
-#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */
638
-#define E1000_IMS_RXQ0 E1000_ICR_RXQ0
639
-#define E1000_IMS_RXQ1 E1000_ICR_RXQ1
640
-#define E1000_IMS_TXQ0 E1000_ICR_TXQ0
641
-#define E1000_IMS_TXQ1 E1000_ICR_TXQ1
642
-#define E1000_IMS_OTHER E1000_ICR_OTHER
643
-#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */
644
-#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
645
-#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
646
-#define E1000_IMS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
647
-#define E1000_IMS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
648
-#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
649
-#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
650
-#define E1000_IMS_DSW E1000_ICR_DSW
651
-#define E1000_IMS_PHYINT E1000_ICR_PHYINT
652
-#define E1000_IMS_EPRST E1000_ICR_EPRST
653
-
654
-/* Interrupt Mask Clear */
655
-#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */
656
-#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
657
-#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */
658
-#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
659
-#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
660
-#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */
661
-#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */
662
-#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */
663
-#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
664
-#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
665
-#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
666
-#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
667
-#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
668
-#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
669
-#define E1000_IMC_SRPD E1000_ICR_SRPD
670
-#define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */
671
-#define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */
672
-#define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */
673
-#define E1000_IMC_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
674
-#define E1000_IMC_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
675
-#define E1000_IMC_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
676
-#define E1000_IMC_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
677
-#define E1000_IMC_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
678
-#define E1000_IMC_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
679
-#define E1000_IMC_DSW E1000_ICR_DSW
680
-#define E1000_IMC_PHYINT E1000_ICR_PHYINT
681
-#define E1000_IMC_EPRST E1000_ICR_EPRST
682
-
683
-/* Receive Control */
684
-#define E1000_RCTL_RST 0x00000001 /* Software reset */
685
-#define E1000_RCTL_EN 0x00000002 /* enable */
686
-#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
687
-#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
688
-#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
689
-#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
690
-#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
691
-#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
692
-#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */
693
-#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
694
-#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */
695
-#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
696
-#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
697
-#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */
698
-#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */
699
-#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
700
-#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */
701
-#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */
702
-#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */
703
-#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
704
-#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */
705
-#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
706
-/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
707
-#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */
708
-#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */
709
-#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */
710
-#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */
711
-/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
712
-#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */
713
-#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */
714
-#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */
715
-#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
716
-#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
717
-#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
718
-#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */
719
-#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
720
-#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
721
-#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
722
-#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */
723
-#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */
724
-
725
-
726
-#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */
727
-#define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */
728
-#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM read/write registers */
729
-#define E1000_EEPROM_RW_REG_DONE 0x10 /* Offset to READ/WRITE done bit */
730
-#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to start operation */
731
-#define E1000_EEPROM_RW_ADDR_SHIFT 8 /* Shift to the address bits */
732
-#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write complete */
733
-#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read complete */
734
-
735
-/* 82574 EERD/EEWR registers layout */
736
-#define E1000_EERW_START BIT(0)
737
-#define E1000_EERW_DONE BIT(1)
738
-#define E1000_EERW_ADDR_SHIFT 2
739
-#define E1000_EERW_ADDR_MASK ((1L << 14) - 1)
740
-#define E1000_EERW_DATA_SHIFT 16
741
-#define E1000_EERW_DATA_MASK ((1L << 16) - 1)
742
-
743
-/* Register Bit Masks */
744
-/* Device Control */
745
-#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
746
-#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */
747
-#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */
748
-#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
749
-#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
750
-#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */
751
-#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */
752
-#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
753
-#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
754
-#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
755
-#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */
756
-#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */
757
-#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */
758
-#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
759
-#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */
760
-#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
761
-#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
762
-#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */
763
-#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
764
-#define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, through PHYRST_N pin */
765
-#define E1000_CTRL_SPD_SHIFT 8 /* Speed Select Shift */
766
-
767
-#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* auto speed detection check */
768
-#define E1000_CTRL_EXT_EE_RST 0x00002000 /* EEPROM reset */
769
-#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external LINK_0 and LINK_1 pins */
770
-#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
771
-#define E1000_CTRL_EXT_EIAME 0x01000000
772
-#define E1000_CTRL_EXT_IAME 0x08000000 /* Int ACK Auto-mask */
773
-#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
774
-#define E1000_CTRL_EXT_INT_TIMERS_CLEAR_ENA 0x20000000
775
-#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
776
-
777
-#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
778
-#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
779
-#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
780
-#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */
781
-#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
782
-#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */
783
-#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */
784
-#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */
785
-#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3 WUC */
786
-#define E1000_CTRL_RST 0x04000000 /* Global reset */
787
-#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
788
-#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
789
-#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */
790
-#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
791
-#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
792
-#define E1000_CTRL_SW2FW_INT 0x02000000 /* Initiate an interrupt to manageability engine */
793
-
794
-/* Device Status */
795
-#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
796
-#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
797
#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
798
#define E1000_STATUS_FUNC_SHIFT 2
799
#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */
800
@@ -XXX,XX +XXX,XX @@
801
#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
802
#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */
803
#define E1000_STATUS_SPEED_MASK 0x000000C0
804
-#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
805
-#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
806
-#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
807
#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion
808
by EEPROM/Flash */
809
#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */
810
@@ -XXX,XX +XXX,XX @@
811
#define E1000_STATUS_ASDV_100 0x00000100 /* ASDV 100Mb */
812
#define E1000_STATUS_ASDV_1000 0x00000200 /* ASDV 1Gb */
813
#define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock state. Clear on write '0'. */
814
-#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */
815
#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */
816
-#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */
817
#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */
818
#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */
819
#define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */
820
@@ -XXX,XX +XXX,XX @@
821
#define E1000_STATUS_SPEED_SHIFT 6
822
#define E1000_STATUS_ASDV_SHIFT 8
823
824
-/* EEPROM/Flash Control */
825
-#define E1000_EECD_SK 0x00000001 /* EEPROM Clock */
826
-#define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */
827
-#define E1000_EECD_DI 0x00000004 /* EEPROM Data In */
828
-#define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */
829
-#define E1000_EECD_FWE_MASK 0x00000030
830
-#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */
831
-#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */
832
-#define E1000_EECD_FWE_SHIFT 4
833
-#define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */
834
-#define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */
835
-#define E1000_EECD_PRES 0x00000100 /* EEPROM Present */
836
-#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
837
-#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
838
- * (0-small, 1-large) */
839
-#define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
840
-#ifndef E1000_EEPROM_GRANT_ATTEMPTS
841
-#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
842
-#endif
843
-#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */
844
-#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */
845
-#define E1000_EECD_SIZE_EX_SHIFT 11
846
-#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */
847
-#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */
848
-#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */
849
-#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
850
-#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
851
-#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */
852
-#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
853
-
854
-
855
-#define E1000_EECD_SECVAL_SHIFT 22
856
-#define E1000_STM_OPCODE 0xDB00
857
-#define E1000_HICR_FW_RESET 0xC0
858
-
859
-#define E1000_SHADOW_RAM_WORDS 2048
860
-#define E1000_ICH_NVM_SIG_WORD 0x13
861
-#define E1000_ICH_NVM_SIG_MASK 0xC0
862
-
863
-/* MDI Control */
864
-#define E1000_MDIC_DATA_MASK 0x0000FFFF
865
-#define E1000_MDIC_REG_MASK 0x001F0000
866
-#define E1000_MDIC_REG_SHIFT 16
867
-#define E1000_MDIC_PHY_MASK 0x03E00000
868
-#define E1000_MDIC_PHY_SHIFT 21
869
-#define E1000_MDIC_OP_WRITE 0x04000000
870
-#define E1000_MDIC_OP_READ 0x08000000
871
-#define E1000_MDIC_READY 0x10000000
872
-#define E1000_MDIC_INT_EN 0x20000000
873
-#define E1000_MDIC_ERROR 0x40000000
874
-
875
-/* Rx Interrupt Delay Timer */
876
-#define E1000_RDTR_FPD BIT(31)
877
-
878
-/* Tx Interrupt Delay Timer */
879
-#define E1000_TIDV_FPD BIT(31)
880
-
881
-/* Delay increments in nanoseconds for delayed interrupts registers */
882
-#define E1000_INTR_DELAY_NS_RES (1024)
883
-
884
-/* Delay increments in nanoseconds for interrupt throttling registers */
885
-#define E1000_INTR_THROTTLING_NS_RES (256)
886
-
887
-/* EEPROM Commands - Microwire */
888
-#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */
889
-#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */
890
-#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7 /* EEPROM erase opcode */
891
-#define EEPROM_EWEN_OPCODE_MICROWIRE 0x13 /* EEPROM erase/write enable */
892
-#define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */
893
-
894
-/* EEPROM Word Offsets */
895
-#define EEPROM_COMPAT 0x0003
896
-#define EEPROM_ID_LED_SETTINGS 0x0004
897
-#define EEPROM_VERSION 0x0005
898
-#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */
899
-#define EEPROM_PHY_CLASS_WORD 0x0007
900
-#define EEPROM_INIT_CONTROL1_REG 0x000A
901
-#define EEPROM_INIT_CONTROL2_REG 0x000F
902
-#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010
903
-#define EEPROM_INIT_CONTROL3_PORT_B 0x0014
904
-#define EEPROM_INIT_3GIO_3 0x001A
905
-#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020
906
-#define EEPROM_INIT_CONTROL3_PORT_A 0x0024
907
-#define EEPROM_CFG 0x0012
908
-#define EEPROM_FLASH_VERSION 0x0032
909
-#define EEPROM_CHECKSUM_REG 0x003F
910
-
911
-#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */
912
-#define E1000_EEPROM_CFG_DONE_PORT_1 0x00080000 /* ...for second port */
913
-
914
-/* HH Time Sync */
915
-#define E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK 0x0000F000 /* max delay */
916
-#define E1000_TSYNCTXCTL_SYNC_COMP 0x40000000 /* sync complete */
917
-#define E1000_TSYNCTXCTL_START_SYNC 0x80000000 /* initiate sync */
918
-
919
-#define E1000_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */
920
-#define E1000_TSYNCTXCTL_ENABLED 0x00000010 /* enable Tx timestamping */
921
-
922
-#define E1000_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */
923
-#define E1000_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */
924
-#define E1000_TSYNCRXCTL_TYPE_L2_V2 0x00
925
-#define E1000_TSYNCRXCTL_TYPE_L4_V1 0x02
926
-#define E1000_TSYNCRXCTL_TYPE_L2_L4_V2 0x04
927
-#define E1000_TSYNCRXCTL_TYPE_ALL 0x08
928
-#define E1000_TSYNCRXCTL_TYPE_EVENT_V2 0x0A
929
-#define E1000_TSYNCRXCTL_ENABLED 0x00000010 /* enable Rx timestamping */
930
-#define E1000_TSYNCRXCTL_SYSCFI 0x00000020 /* Sys clock frequency */
931
-
932
-#define E1000_RXMTRL_PTP_V1_SYNC_MESSAGE 0x00000000
933
-#define E1000_RXMTRL_PTP_V1_DELAY_REQ_MESSAGE 0x00010000
934
-
935
-#define E1000_RXMTRL_PTP_V2_SYNC_MESSAGE 0x00000000
936
-#define E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE 0x01000000
937
-
938
-#define E1000_TIMINCA_INCPERIOD_SHIFT 24
939
-#define E1000_TIMINCA_INCVALUE_MASK 0x00FFFFFF
940
-
941
-/* PCI Express Control */
942
-/* 3GIO Control Register - GCR (0x05B00; RW) */
943
-#define E1000_L0S_ADJUST (1 << 9)
944
-#define E1000_L1_ENTRY_LATENCY_MSB (1 << 23)
945
-#define E1000_L1_ENTRY_LATENCY_LSB (1 << 25 | 1 << 26)
946
-
947
-#define E1000_L0S_ADJUST (1 << 9)
948
-#define E1000_L1_ENTRY_LATENCY_MSB (1 << 23)
949
-#define E1000_L1_ENTRY_LATENCY_LSB (1 << 25 | 1 << 26)
950
-
951
-#define E1000_GCR_RO_BITS (1 << 23 | 1 << 25 | 1 << 26)
952
-
953
-/* MSI-X PBA Clear register */
954
-#define E1000_PBACLR_VALID_MASK (BIT(5) - 1)
955
-
956
/* Transmit Descriptor */
957
struct e1000_tx_desc {
958
uint64_t buffer_addr; /* Address of the descriptor's data buffer */
959
@@ -XXX,XX +XXX,XX @@ struct e1000_tx_desc {
960
} upper;
961
};
962
963
-/* Transmit Descriptor bit definitions */
964
-#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
965
-#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */
966
#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
967
#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
968
-#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
969
-#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
970
-#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */
971
-#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
972
-#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */
973
-#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
974
-#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
975
-#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
976
-#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
977
-#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
978
-#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
979
-#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
980
-#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */
981
-#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */
982
-#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */
983
-#define E1000_TXD_CMD_SNAP 0x40000000 /* Update SNAP header */
984
-#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
985
-#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */
986
-
987
-/* Transmit Control */
988
-#define E1000_TCTL_RST 0x00000001 /* software reset */
989
-#define E1000_TCTL_EN 0x00000002 /* enable tx */
990
-#define E1000_TCTL_BCE 0x00000004 /* busy check enable */
991
-#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
992
-#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
993
-#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
994
-#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */
995
-#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */
996
-#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
997
-#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
998
-#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */
999
-
1000
-/* Legacy Receive Descriptor */
1001
-struct e1000_rx_desc {
1002
- uint64_t buffer_addr; /* Address of the descriptor's data buffer */
1003
- uint16_t length; /* Length of data DMAed into data buffer */
1004
- uint16_t csum; /* Packet checksum */
1005
- uint8_t status; /* Descriptor status */
1006
- uint8_t errors; /* Descriptor Errors */
1007
- uint16_t special;
1008
-};
1009
-
1010
-/* Extended Receive Descriptor */
1011
-union e1000_rx_desc_extended {
1012
- struct {
1013
- uint64_t buffer_addr;
1014
- uint64_t reserved;
1015
- } read;
1016
- struct {
1017
- struct {
1018
- uint32_t mrq; /* Multiple Rx Queues */
1019
- union {
1020
- uint32_t rss; /* RSS Hash */
1021
- struct {
1022
- uint16_t ip_id; /* IP id */
1023
- uint16_t csum; /* Packet Checksum */
1024
- } csum_ip;
1025
- } hi_dword;
1026
- } lower;
1027
- struct {
1028
- uint32_t status_error; /* ext status/error */
1029
- uint16_t length;
1030
- uint16_t vlan; /* VLAN tag */
1031
- } upper;
1032
- } wb; /* writeback */
1033
-};
1034
-
1035
-#define MAX_PS_BUFFERS 4
1036
-
1037
-/* Number of packet split data buffers (not including the header buffer) */
1038
-#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
1039
-
1040
-/* Receive Descriptor - Packet Split */
1041
-union e1000_rx_desc_packet_split {
1042
- struct {
1043
- /* one buffer for protocol header(s), three data buffers */
1044
- uint64_t buffer_addr[MAX_PS_BUFFERS];
1045
- } read;
1046
- struct {
1047
- struct {
1048
- uint32_t mrq; /* Multiple Rx Queues */
1049
- union {
1050
- uint32_t rss; /* RSS Hash */
1051
- struct {
1052
- uint16_t ip_id; /* IP id */
1053
- uint16_t csum; /* Packet Checksum */
1054
- } csum_ip;
1055
- } hi_dword;
1056
- } lower;
1057
- struct {
1058
- uint32_t status_error; /* ext status/error */
1059
- uint16_t length0; /* length of buffer 0 */
1060
- uint16_t vlan; /* VLAN tag */
1061
- } middle;
1062
- struct {
1063
- uint16_t header_status;
1064
- /* length of buffers 1-3 */
1065
- uint16_t length[PS_PAGE_BUFFERS];
1066
- } upper;
1067
- uint64_t reserved;
1068
- } wb; /* writeback */
1069
-};
1070
-
1071
-/* Receive Checksum Control bits */
1072
-#define E1000_RXCSUM_IPOFLD 0x100 /* IP Checksum Offload Enable */
1073
-#define E1000_RXCSUM_TUOFLD 0x200 /* TCP/UDP Checksum Offload Enable */
1074
-#define E1000_RXCSUM_PCSD 0x2000 /* Packet Checksum Disable */
1075
-
1076
-#define E1000_RING_DESC_LEN (16)
1077
-#define E1000_RING_DESC_LEN_SHIFT (4)
1078
-
1079
-#define E1000_MIN_RX_DESC_LEN E1000_RING_DESC_LEN
1080
-
1081
-/* Receive Descriptor bit definitions */
1082
-#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
1083
-#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
1084
-#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
1085
-#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
1086
-#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
1087
-#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
1088
-#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
1089
-#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */
1090
-#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */
1091
-#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
1092
-#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */
1093
-#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
1094
-#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
1095
-#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
1096
-#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
1097
-#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */
1098
-#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */
1099
-#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
1100
-#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
1101
-#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */
1102
-#define E1000_RXD_SPC_PRI_SHIFT 13
1103
-#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */
1104
-#define E1000_RXD_SPC_CFI_SHIFT 12
1105
-
1106
-/* RX packet types */
1107
-#define E1000_RXD_PKT_MAC (0)
1108
-#define E1000_RXD_PKT_IP4 (1)
1109
-#define E1000_RXD_PKT_IP4_XDP (2)
1110
-#define E1000_RXD_PKT_IP6 (5)
1111
-#define E1000_RXD_PKT_IP6_XDP (6)
1112
-
1113
-#define E1000_RXD_PKT_TYPE(t) ((t) << 16)
1114
-
1115
-#define E1000_RXDEXT_STATERR_CE 0x01000000
1116
-#define E1000_RXDEXT_STATERR_SE 0x02000000
1117
-#define E1000_RXDEXT_STATERR_SEQ 0x04000000
1118
-#define E1000_RXDEXT_STATERR_CXE 0x10000000
1119
-#define E1000_RXDEXT_STATERR_TCPE 0x20000000
1120
-#define E1000_RXDEXT_STATERR_IPE 0x40000000
1121
-#define E1000_RXDEXT_STATERR_RXE 0x80000000
1122
-
1123
-#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000
1124
-#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF
1125
-
1126
-/* Receive Address */
1127
-#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
1128
-
1129
-/* Offload Context Descriptor */
1130
-struct e1000_context_desc {
1131
- union {
1132
- uint32_t ip_config;
1133
- struct {
1134
- uint8_t ipcss; /* IP checksum start */
1135
- uint8_t ipcso; /* IP checksum offset */
1136
- uint16_t ipcse; /* IP checksum end */
1137
- } ip_fields;
1138
- } lower_setup;
1139
- union {
1140
- uint32_t tcp_config;
1141
- struct {
1142
- uint8_t tucss; /* TCP checksum start */
1143
- uint8_t tucso; /* TCP checksum offset */
1144
- uint16_t tucse; /* TCP checksum end */
1145
- } tcp_fields;
1146
- } upper_setup;
1147
- uint32_t cmd_and_length; /* */
1148
- union {
1149
- uint32_t data;
1150
- struct {
1151
- uint8_t status; /* Descriptor status */
1152
- uint8_t hdr_len; /* Header length */
1153
- uint16_t mss; /* Maximum segment size */
1154
- } fields;
1155
- } tcp_seg_setup;
1156
-};
1157
-
1158
-/* Offload data descriptor */
1159
-struct e1000_data_desc {
1160
- uint64_t buffer_addr; /* Address of the descriptor's buffer address */
1161
- union {
1162
- uint32_t data;
1163
- struct {
1164
- uint16_t length; /* Data buffer length */
1165
- uint8_t typ_len_ext; /* */
1166
- uint8_t cmd; /* */
1167
- } flags;
1168
- } lower;
1169
- union {
1170
- uint32_t data;
1171
- struct {
1172
- uint8_t status; /* Descriptor status */
1173
- uint8_t popts; /* Packet Options */
1174
- uint16_t special; /* */
1175
- } fields;
1176
- } upper;
1177
-};
1178
-
1179
-/* Filters */
1180
-#define E1000_NUM_UNICAST 16 /* Unicast filter entries */
1181
-#define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
1182
-#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
1183
-
1184
-/* Management Control */
1185
-#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
1186
-#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
1187
-#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */
1188
-#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering */
1189
-#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering */
1190
-#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */
1191
-#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */
1192
-#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */
1193
-#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
1194
-#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery
1195
- * Filtering */
1196
-#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */
1197
-#define E1000_MANC_DIS_IP_CHK_ARP 0x10000000 /* Disable IP address chacking */
1198
- /*for ARP packets - in 82574 */
1199
-#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */
1200
-#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
1201
-#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
1202
-#define E1000_MANC_RCV_ALL 0x00080000 /* Receive All Enabled */
1203
-#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
1204
-#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address
1205
- * filtering */
1206
-#define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host
1207
- * memory */
1208
-#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address
1209
- * filtering */
1210
-#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */
1211
-#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */
1212
-#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */
1213
-#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */
1214
-#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */
1215
-#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */
1216
-#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */
1217
-#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */
1218
-
1219
-#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */
1220
-#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */
1221
-
1222
-/* FACTPS Control */
1223
-#define E1000_FACTPS_LAN0_ON 0x00000004 /* Lan 0 enable */
1224
-
1225
-/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
1226
-#define EEPROM_SUM 0xBABA
1227
-
1228
-/* I/O-Mapped Access to Internal Registers, Memories, and Flash */
1229
-#define E1000_IOADDR 0x00
1230
-#define E1000_IODATA 0x04
1231
-
1232
-#define E1000_VFTA_ENTRY_SHIFT 5
1233
-#define E1000_VFTA_ENTRY_MASK 0x7F
1234
-#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
1235
1236
#endif /* HW_E1000_REGS_H */
1237
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
1238
index XXXXXXX..XXXXXXX 100644
1239
--- a/hw/net/e1000e.c
1240
+++ b/hw/net/e1000e.c
1241
@@ -XXX,XX +XXX,XX @@
1242
#include "hw/qdev-properties.h"
1243
#include "migration/vmstate.h"
1244
1245
-#include "e1000_regs.h"
1246
-
1247
+#include "e1000_common.h"
1248
#include "e1000x_common.h"
1249
#include "e1000e_core.h"
1250
1251
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
1252
index XXXXXXX..XXXXXXX 100644
1253
--- a/hw/net/e1000e_core.c
1254
+++ b/hw/net/e1000e_core.c
1255
@@ -XXX,XX +XXX,XX @@
1256
#include "net_tx_pkt.h"
1257
#include "net_rx_pkt.h"
1258
1259
+#include "e1000_common.h"
1260
#include "e1000x_common.h"
1261
#include "e1000e_core.h"
1262
1263
diff --git a/hw/net/e1000x_common.c b/hw/net/e1000x_common.c
1264
index XXXXXXX..XXXXXXX 100644
1265
--- a/hw/net/e1000x_common.c
1266
+++ b/hw/net/e1000x_common.c
1267
@@ -XXX,XX +XXX,XX @@
1268
#include "net/eth.h"
1269
#include "net/net.h"
1270
1271
+#include "e1000_common.h"
1272
#include "e1000x_common.h"
1273
1274
#include "trace.h"
1275
diff --git a/hw/net/e1000x_common.h b/hw/net/e1000x_common.h
1276
index XXXXXXX..XXXXXXX 100644
1277
--- a/hw/net/e1000x_common.h
1278
+++ b/hw/net/e1000x_common.h
1279
@@ -XXX,XX +XXX,XX @@
1280
#ifndef HW_NET_E1000X_COMMON_H
1281
#define HW_NET_E1000X_COMMON_H
1282
1283
-#include "e1000_regs.h"
1284
-
1285
-#define defreg(x) x = (E1000_##x >> 2)
1286
-enum {
1287
- defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC),
1288
- defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC),
1289
- defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC),
1290
- defreg(MPC), defreg(PBA), defreg(RCTL), defreg(RDBAH0),
1291
- defreg(RDBAL0), defreg(RDH0), defreg(RDLEN0), defreg(RDT0),
1292
- defreg(STATUS), defreg(SWSM), defreg(TCTL), defreg(TDBAH),
1293
- defreg(TDBAL), defreg(TDH), defreg(TDLEN), defreg(TDT),
1294
- defreg(TDLEN1), defreg(TDBAL1), defreg(TDBAH1), defreg(TDH1),
1295
- defreg(TDT1), defreg(TORH), defreg(TORL), defreg(TOTH),
1296
- defreg(TOTL), defreg(TPR), defreg(TPT), defreg(TXDCTL),
1297
- defreg(WUFC), defreg(RA), defreg(MTA), defreg(CRCERRS),
1298
- defreg(VFTA), defreg(VET), defreg(RDTR), defreg(RADV),
1299
- defreg(TADV), defreg(ITR), defreg(SCC), defreg(ECOL),
1300
- defreg(MCC), defreg(LATECOL), defreg(COLC), defreg(DC),
1301
- defreg(TNCRS), defreg(SEQEC), defreg(CEXTERR), defreg(RLEC),
1302
- defreg(XONRXC), defreg(XONTXC), defreg(XOFFRXC), defreg(XOFFTXC),
1303
- defreg(FCRUC), defreg(AIT), defreg(TDFH), defreg(TDFT),
1304
- defreg(TDFHS), defreg(TDFTS), defreg(TDFPC), defreg(WUC),
1305
- defreg(WUS), defreg(POEMB), defreg(PBS), defreg(RDFH),
1306
- defreg(RDFT), defreg(RDFHS), defreg(RDFTS), defreg(RDFPC),
1307
- defreg(PBM), defreg(IPAV), defreg(IP4AT), defreg(IP6AT),
1308
- defreg(WUPM), defreg(FFLT), defreg(FFMT), defreg(FFVT),
1309
- defreg(TARC0), defreg(TARC1), defreg(IAM), defreg(EXTCNF_CTRL),
1310
- defreg(GCR), defreg(TIMINCA), defreg(EIAC), defreg(CTRL_EXT),
1311
- defreg(IVAR), defreg(MFUTP01), defreg(MFUTP23), defreg(MANC2H),
1312
- defreg(MFVAL), defreg(MDEF), defreg(FACTPS), defreg(FTFT),
1313
- defreg(RUC), defreg(ROC), defreg(RFC), defreg(RJC),
1314
- defreg(PRC64), defreg(PRC127), defreg(PRC255), defreg(PRC511),
1315
- defreg(PRC1023), defreg(PRC1522), defreg(PTC64), defreg(PTC127),
1316
- defreg(PTC255), defreg(PTC511), defreg(PTC1023), defreg(PTC1522),
1317
- defreg(GORCL), defreg(GORCH), defreg(GOTCL), defreg(GOTCH),
1318
- defreg(RNBC), defreg(BPRC), defreg(MPRC), defreg(RFCTL),
1319
- defreg(PSRCTL), defreg(MPTC), defreg(BPTC), defreg(TSCTFC),
1320
- defreg(IAC), defreg(MGTPRC), defreg(MGTPDC), defreg(MGTPTC),
1321
- defreg(TSCTC), defreg(RXCSUM), defreg(FUNCTAG), defreg(GSCL_1),
1322
- defreg(GSCL_2), defreg(GSCL_3), defreg(GSCL_4), defreg(GSCN_0),
1323
- defreg(GSCN_1), defreg(GSCN_2), defreg(GSCN_3), defreg(GCR2),
1324
- defreg(RAID), defreg(RSRPD), defreg(TIDV), defreg(EITR),
1325
- defreg(MRQC), defreg(RETA), defreg(RSSRK), defreg(RDBAH1),
1326
- defreg(RDBAL1), defreg(RDLEN1), defreg(RDH1), defreg(RDT1),
1327
- defreg(PBACLR), defreg(FCAL), defreg(FCAH), defreg(FCT),
1328
- defreg(FCRTH), defreg(FCRTL), defreg(FCTTV), defreg(FCRTV),
1329
- defreg(FLA), defreg(EEWR), defreg(FLOP), defreg(FLOL),
1330
- defreg(FLSWCTL), defreg(FLSWCNT), defreg(RXDCTL), defreg(RXDCTL1),
1331
- defreg(MAVTV0), defreg(MAVTV1), defreg(MAVTV2), defreg(MAVTV3),
1332
- defreg(TXSTMPL), defreg(TXSTMPH), defreg(SYSTIML), defreg(SYSTIMH),
1333
- defreg(RXCFGL), defreg(RXUDP), defreg(TIMADJL), defreg(TIMADJH),
1334
- defreg(RXSTMPH), defreg(RXSTMPL), defreg(RXSATRL), defreg(RXSATRH),
1335
- defreg(FLASHT), defreg(TIPG), defreg(RDH), defreg(RDT),
1336
- defreg(RDLEN), defreg(RDBAH), defreg(RDBAL),
1337
- defreg(TXDCTL1),
1338
- defreg(FLSWDATA),
1339
- defreg(CTRL_DUP),
1340
- defreg(EXTCNF_SIZE),
1341
- defreg(EEMNGCTL),
1342
- defreg(EEMNGDATA),
1343
- defreg(FLMNGCTL),
1344
- defreg(FLMNGDATA),
1345
- defreg(FLMNGCNT),
1346
- defreg(TSYNCRXCTL),
1347
- defreg(TSYNCTXCTL),
1348
-
1349
- /* Aliases */
1350
- defreg(RDH0_A), defreg(RDT0_A), defreg(RDTR_A), defreg(RDFH_A),
1351
- defreg(RDFT_A), defreg(TDH_A), defreg(TDT_A), defreg(TIDV_A),
1352
- defreg(TDFH_A), defreg(TDFT_A), defreg(RA_A), defreg(RDBAL0_A),
1353
- defreg(TDBAL_A), defreg(TDLEN_A), defreg(VFTA_A), defreg(RDLEN0_A),
1354
- defreg(FCRTL_A), defreg(FCRTH_A)
1355
-};
1356
-
1357
static inline void
1358
e1000x_inc_reg_if_not_full(uint32_t *mac, int index)
1359
{
1360
diff --git a/hw/net/e1000x_regs.h b/hw/net/e1000x_regs.h
1361
new file mode 100644
105
new file mode 100644
1362
index XXXXXXX..XXXXXXX
106
index XXXXXXX..XXXXXXX
1363
--- /dev/null
107
--- /dev/null
1364
+++ b/hw/net/e1000x_regs.h
108
+++ b/hw/virtio/vhost-shadow-virtqueue.h
1365
@@ -XXX,XX +XXX,XX @@
109
@@ -XXX,XX +XXX,XX @@
1366
+/*******************************************************************************
110
+/*
1367
+
111
+ * vhost shadow virtqueue
1368
+ Intel PRO/1000 Linux driver
112
+ *
1369
+ Copyright(c) 1999 - 2006 Intel Corporation.
113
+ * SPDX-FileCopyrightText: Red Hat, Inc. 2021
1370
+
114
+ * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
1371
+ This program is free software; you can redistribute it and/or modify it
115
+ *
1372
+ under the terms and conditions of the GNU General Public License,
116
+ * SPDX-License-Identifier: GPL-2.0-or-later
1373
+ version 2, as published by the Free Software Foundation.
1374
+
1375
+ This program is distributed in the hope it will be useful, but WITHOUT
1376
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1377
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
1378
+ more details.
1379
+
1380
+ You should have received a copy of the GNU General Public License along with
1381
+ this program; if not, see <http://www.gnu.org/licenses/>.
1382
+
1383
+ The full GNU General Public License is included in this distribution in
1384
+ the file called "COPYING".
1385
+
1386
+ Contact Information:
1387
+ Linux NICS <linux.nics@intel.com>
1388
+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
1389
+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
1390
+
1391
+*******************************************************************************/
1392
+
1393
+/* e1000_hw.h
1394
+ * Structures, enums, and macros for the MAC
1395
+ */
117
+ */
1396
+
118
+
1397
+#ifndef HW_E1000X_REGS_H
119
+#ifndef VHOST_SHADOW_VIRTQUEUE_H
1398
+#define HW_E1000X_REGS_H
120
+#define VHOST_SHADOW_VIRTQUEUE_H
1399
+
121
+
1400
+/* PCI Device IDs */
122
+#include "qemu/event_notifier.h"
1401
+#define E1000_DEV_ID_82542 0x1000
1402
+#define E1000_DEV_ID_82543GC_FIBER 0x1001
1403
+#define E1000_DEV_ID_82543GC_COPPER 0x1004
1404
+#define E1000_DEV_ID_82544EI_COPPER 0x1008
1405
+#define E1000_DEV_ID_82544EI_FIBER 0x1009
1406
+#define E1000_DEV_ID_82544GC_COPPER 0x100C
1407
+#define E1000_DEV_ID_82544GC_LOM 0x100D
1408
+#define E1000_DEV_ID_82540EM 0x100E
1409
+#define E1000_DEV_ID_82540EM_LOM 0x1015
1410
+#define E1000_DEV_ID_82540EP_LOM 0x1016
1411
+#define E1000_DEV_ID_82540EP 0x1017
1412
+#define E1000_DEV_ID_82540EP_LP 0x101E
1413
+#define E1000_DEV_ID_82545EM_COPPER 0x100F
1414
+#define E1000_DEV_ID_82545EM_FIBER 0x1011
1415
+#define E1000_DEV_ID_82545GM_COPPER 0x1026
1416
+#define E1000_DEV_ID_82545GM_FIBER 0x1027
1417
+#define E1000_DEV_ID_82545GM_SERDES 0x1028
1418
+#define E1000_DEV_ID_82546EB_COPPER 0x1010
1419
+#define E1000_DEV_ID_82546EB_FIBER 0x1012
1420
+#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
1421
+#define E1000_DEV_ID_82541EI 0x1013
1422
+#define E1000_DEV_ID_82541EI_MOBILE 0x1018
1423
+#define E1000_DEV_ID_82541ER_LOM 0x1014
1424
+#define E1000_DEV_ID_82541ER 0x1078
1425
+#define E1000_DEV_ID_82547GI 0x1075
1426
+#define E1000_DEV_ID_82541GI 0x1076
1427
+#define E1000_DEV_ID_82541GI_MOBILE 0x1077
1428
+#define E1000_DEV_ID_82541GI_LF 0x107C
1429
+#define E1000_DEV_ID_82546GB_COPPER 0x1079
1430
+#define E1000_DEV_ID_82546GB_FIBER 0x107A
1431
+#define E1000_DEV_ID_82546GB_SERDES 0x107B
1432
+#define E1000_DEV_ID_82546GB_PCIE 0x108A
1433
+#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
1434
+#define E1000_DEV_ID_82547EI 0x1019
1435
+#define E1000_DEV_ID_82547EI_MOBILE 0x101A
1436
+#define E1000_DEV_ID_82571EB_COPPER 0x105E
1437
+#define E1000_DEV_ID_82571EB_FIBER 0x105F
1438
+#define E1000_DEV_ID_82571EB_SERDES 0x1060
1439
+#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
1440
+#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
1441
+#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
1442
+#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE 0x10BC
1443
+#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
1444
+#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
1445
+#define E1000_DEV_ID_82572EI_COPPER 0x107D
1446
+#define E1000_DEV_ID_82572EI_FIBER 0x107E
1447
+#define E1000_DEV_ID_82572EI_SERDES 0x107F
1448
+#define E1000_DEV_ID_82572EI 0x10B9
1449
+#define E1000_DEV_ID_82573E 0x108B
1450
+#define E1000_DEV_ID_82573E_IAMT 0x108C
1451
+#define E1000_DEV_ID_82573L 0x109A
1452
+#define E1000_DEV_ID_82574L 0x10D3
1453
+#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
1454
+#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
1455
+#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
1456
+#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA
1457
+#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB
1458
+
123
+
1459
+#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049
124
+/* Shadow virtqueue to relay notifications */
1460
+#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A
125
+typedef struct VhostShadowVirtqueue {
1461
+#define E1000_DEV_ID_ICH8_IGP_C 0x104B
126
+ /* Shadow kick notifier, sent to vhost */
1462
+#define E1000_DEV_ID_ICH8_IFE 0x104C
127
+ EventNotifier hdev_kick;
1463
+#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4
128
+ /* Shadow call notifier, sent to vhost */
1464
+#define E1000_DEV_ID_ICH8_IFE_G 0x10C5
129
+ EventNotifier hdev_call;
1465
+#define E1000_DEV_ID_ICH8_IGP_M 0x104D
130
+} VhostShadowVirtqueue;
1466
+
131
+
1467
+/* Device Specific Register Defaults */
132
+VhostShadowVirtqueue *vhost_svq_new(void);
1468
+#define E1000_PHY_ID2_82541x 0x380
1469
+#define E1000_PHY_ID2_82544x 0xC30
1470
+#define E1000_PHY_ID2_8254xx_DEFAULT 0xC20 /* 82540x, 82545x, and 82546x */
1471
+#define E1000_PHY_ID2_82573x 0xCC0
1472
+#define E1000_PHY_ID2_82574x 0xCB1
1473
+
133
+
1474
+/* Register Set. (82543, 82544)
134
+void vhost_svq_free(gpointer vq);
1475
+ *
135
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostShadowVirtqueue, vhost_svq_free);
1476
+ * Registers are defined to be 32 bits and should be accessed as 32 bit values.
1477
+ * These registers are physically located on the NIC, but are mapped into the
1478
+ * host memory address space.
1479
+ *
1480
+ * RW - register is both readable and writable
1481
+ * RO - register is read only
1482
+ * WO - register is write only
1483
+ * R/clr - register is read only and is cleared when read
1484
+ * A - register array
1485
+ */
1486
+#define E1000_CTRL 0x00000 /* Device Control - RW */
1487
+#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */
1488
+#define E1000_STATUS 0x00008 /* Device Status - RO */
1489
+#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
1490
+#define E1000_EERD 0x00014 /* EEPROM Read - RW */
1491
+#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
1492
+#define E1000_FLA 0x0001C /* Flash Access - RW */
1493
+#define E1000_MDIC 0x00020 /* MDI Control - RW */
1494
+#define E1000_SCTL 0x00024 /* SerDes Control - RW */
1495
+#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
1496
+#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
1497
+#define E1000_FCT 0x00030 /* Flow Control Type - RW */
1498
+#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
1499
+#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
1500
+#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
1501
+#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
1502
+#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
1503
+#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
1504
+#define E1000_RCTL 0x00100 /* RX Control - RW */
1505
+#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
1506
+#define E1000_TCTL 0x00400 /* TX Control - RW */
1507
+#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */
1508
+#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
1509
+#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
1510
+#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
1511
+#define E1000_EEMNGDATA 0x01014 /* MNG EEPROM Read/Write data */
1512
+#define E1000_FLMNGCTL 0x01018 /* MNG Flash Control */
1513
+#define E1000_FLMNGDATA 0x0101C /* MNG FLASH Read data */
1514
+#define E1000_FLMNGCNT 0x01020 /* MNG FLASH Read Counter */
1515
+#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
1516
+#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
1517
+#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
1518
+#define E1000_FCRTL_A 0x00168 /* Alias to FCRTL */
1519
+#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
1520
+#define E1000_RDFH 0x02410 /* Receive Data FIFO Head Register - RW */
1521
+#define E1000_RDFH_A 0x08000 /* Alias to RDFH */
1522
+#define E1000_RDFT 0x02418 /* Receive Data FIFO Tail Register - RW */
1523
+#define E1000_RDFT_A 0x08008 /* Alias to RDFT */
1524
+#define E1000_RDFHS 0x02420 /* Receive Data FIFO Head Saved Register - RW */
1525
+#define E1000_RDFTS 0x02428 /* Receive Data FIFO Tail Saved Register - RW */
1526
+#define E1000_RDFPC 0x02430 /* Receive Data FIFO Packet Count - RW */
1527
+#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */
1528
+#define E1000_TDFH_A 0x08010 /* Alias to TDFH */
1529
+#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
1530
+#define E1000_TDFT_A 0x08018 /* Alias to TDFT */
1531
+#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
1532
+#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */
1533
+#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */
1534
+#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
1535
+#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
1536
+#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
1537
+#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
1538
+#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
1539
+#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
1540
+#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
1541
+#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
1542
+#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
1543
+#define E1000_COLC 0x04028 /* Collision Count - R/clr */
1544
+#define E1000_DC 0x04030 /* Defer Count - R/clr */
1545
+#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */
1546
+#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
1547
+#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */
1548
+#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */
1549
+#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */
1550
+#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */
1551
+#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */
1552
+#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */
1553
+#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */
1554
+#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */
1555
+#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */
1556
+#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */
1557
+#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */
1558
+#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */
1559
+#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */
1560
+#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */
1561
+#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */
1562
+#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */
1563
+#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */
1564
+#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */
1565
+#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */
1566
+#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */
1567
+#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */
1568
+#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */
1569
+#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */
1570
+#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */
1571
+#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */
1572
+#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
1573
+#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */
1574
+#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */
1575
+#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */
1576
+#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */
1577
+#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */
1578
+#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */
1579
+#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */
1580
+#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */
1581
+#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */
1582
+#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */
1583
+#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */
1584
+#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */
1585
+#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */
1586
+#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */
1587
+#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
1588
+#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
1589
+#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
1590
+#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire Count */
1591
+#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
1592
+#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
1593
+#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
1594
+#define E1000_MAVTV0 0x05010 /* Management VLAN TAG Value 0 */
1595
+#define E1000_MAVTV1 0x05014 /* Management VLAN TAG Value 1 */
1596
+#define E1000_MAVTV2 0x05018 /* Management VLAN TAG Value 2 */
1597
+#define E1000_MAVTV3 0x0501c /* Management VLAN TAG Value 3 */
1598
+#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
1599
+#define E1000_RA 0x05400 /* Receive Address - RW Array */
1600
+#define E1000_RA_A 0x00040 /* Alias to RA */
1601
+#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
1602
+#define E1000_VFTA_A 0x00600 /* Alias to VFTA */
1603
+#define E1000_WUC 0x05800 /* Wakeup Control - RW */
1604
+#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
1605
+#define E1000_WUS 0x05810 /* Wakeup Status - RO */
1606
+#define E1000_MANC 0x05820 /* Management Control - RW */
1607
+#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
1608
+#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */
1609
+#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */
1610
+#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
1611
+#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */
1612
+#define E1000_MFVAL 0x05824 /* Manageability Filters Valid - RW */
1613
+#define E1000_MDEF 0x05890 /* Manageability Decision Filters - RW Array */
1614
+#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
1615
+#define E1000_FTFT 0x09400 /* Flexible TCO Filter Table - RW Array */
1616
+
136
+
1617
+#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
1618
+#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
1619
+
1620
+#define E1000_GCR 0x05B00 /* PCI-Ex Control */
1621
+#define E1000_FUNCTAG 0x05B08 /* Function-Tag Register */
1622
+#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
1623
+#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
1624
+#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
1625
+#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
1626
+#define E1000_GSCN_0 0x05B20 /* 3GIO Statistic Counter Register #0 */
1627
+#define E1000_GSCN_1 0x05B24 /* 3GIO Statistic Counter Register #1 */
1628
+#define E1000_GSCN_2 0x05B28 /* 3GIO Statistic Counter Register #2 */
1629
+#define E1000_GSCN_3 0x05B2C /* 3GIO Statistic Counter Register #3 */
1630
+#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
1631
+#define E1000_SWSM 0x05B50 /* SW Semaphore */
1632
+#define E1000_FWSM 0x05B54 /* FW Semaphore */
1633
+#define E1000_PBACLR 0x05B68 /* MSI-X PBA Clear */
1634
+
1635
+#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
1636
+#define E1000_TSYNCTXCTL 0x0B614 /* Tx Time Sync Control register - RW */
1637
+#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
1638
+#define E1000_RXSTMPL 0x0B624 /* Rx timestamp Low - RO */
1639
+#define E1000_RXSTMPH 0x0B628 /* Rx timestamp High - RO */
1640
+#define E1000_TXSTMPL 0x0B618 /* Tx timestamp value Low - RO */
1641
+#define E1000_TXSTMPH 0x0B61C /* Tx timestamp value High - RO */
1642
+#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
1643
+#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
1644
+#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
1645
+#define E1000_RXSATRL 0x0B62C /* Rx timestamp attribute low - RO */
1646
+#define E1000_RXSATRH 0x0B630 /* Rx timestamp attribute high - RO */
1647
+#define E1000_TIMADJL 0x0B60C /* Time Adjustment Offset register Low - RW */
1648
+#define E1000_TIMADJH 0x0B610 /* Time Adjustment Offset register High - RW */
1649
+
1650
+/* RSS registers */
1651
+#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
1652
+#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */
1653
+#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */
1654
+
1655
+#define E1000_RETA_IDX(hash) ((hash) & (BIT(7) - 1))
1656
+#define E1000_RETA_VAL(reta, hash) (((uint8_t *)(reta))[E1000_RETA_IDX(hash)])
1657
+
1658
+#define E1000_MRQC_EN_TCPIPV4(mrqc) ((mrqc) & BIT(16))
1659
+#define E1000_MRQC_EN_IPV4(mrqc) ((mrqc) & BIT(17))
1660
+#define E1000_MRQC_EN_TCPIPV6(mrqc) ((mrqc) & BIT(18))
1661
+#define E1000_MRQC_EN_IPV6EX(mrqc) ((mrqc) & BIT(19))
1662
+#define E1000_MRQC_EN_IPV6(mrqc) ((mrqc) & BIT(20))
1663
+
1664
+#define E1000_MRQ_RSS_TYPE_NONE (0)
1665
+#define E1000_MRQ_RSS_TYPE_IPV4TCP (1)
1666
+#define E1000_MRQ_RSS_TYPE_IPV4 (2)
1667
+#define E1000_MRQ_RSS_TYPE_IPV6TCP (3)
1668
+#define E1000_MRQ_RSS_TYPE_IPV6EX (4)
1669
+#define E1000_MRQ_RSS_TYPE_IPV6 (5)
1670
+
1671
+#define E1000_ICR_ASSERTED BIT(31)
1672
+#define E1000_EIAC_MASK 0x01F00000
1673
+
1674
+/* RFCTL register bits */
1675
+#define E1000_RFCTL_ISCSI_DIS 0x00000001
1676
+#define E1000_RFCTL_NFSW_DIS 0x00000040
1677
+#define E1000_RFCTL_NFSR_DIS 0x00000080
1678
+#define E1000_RFCTL_IPV6_DIS 0x00000400
1679
+#define E1000_RFCTL_IPV6_XSUM_DIS 0x00000800
1680
+#define E1000_RFCTL_IPFRSP_DIS 0x00004000
1681
+#define E1000_RFCTL_EXTEN 0x00008000
1682
+#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
1683
+#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000
1684
+
1685
+/* TARC* parsing */
1686
+#define E1000_TARC_ENABLE BIT(10)
1687
+
1688
+/* SW Semaphore Register */
1689
+#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
1690
+#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
1691
+#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
1692
+
1693
+#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */
1694
+
1695
+/* Interrupt Cause Read */
1696
+#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
1697
+#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
1698
+#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
1699
+#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
1700
+#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
1701
+#define E1000_ICR_RXO 0x00000040 /* rx overrun */
1702
+#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
1703
+#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
1704
+#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
1705
+#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
1706
+#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
1707
+#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
1708
+#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
1709
+#define E1000_ICR_TXD_LOW 0x00008000
1710
+#define E1000_ICR_SRPD 0x00010000
1711
+#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */
1712
+#define E1000_ICR_MNG 0x00040000 /* Manageability event */
1713
+#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */
1714
+#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */
1715
+#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* queue 0 Rx descriptor FIFO parity error */
1716
+#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* queue 0 Tx descriptor FIFO parity error */
1717
+#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity error */
1718
+#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */
1719
+#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* queue 1 Rx descriptor FIFO parity error */
1720
+#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* queue 1 Tx descriptor FIFO parity error */
1721
+#define E1000_ICR_ALL_PARITY 0x03F00000 /* all parity error bits */
1722
+#define E1000_ICR_DSW 0x00000020 /* FW changed the status of DISSW bit in the FWSM */
1723
+#define E1000_ICR_PHYINT 0x00001000 /* LAN connected device generates an interrupt */
1724
+#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */
1725
+#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */
1726
+#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */
1727
+#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */
1728
+#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */
1729
+#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */
1730
+
1731
+#define E1000_ICR_OTHER_CAUSES (E1000_ICR_LSC | \
1732
+ E1000_ICR_RXO | \
1733
+ E1000_ICR_MDAC | \
1734
+ E1000_ICR_SRPD | \
1735
+ E1000_ICR_ACK | \
1736
+ E1000_ICR_MNG)
1737
+
1738
+/* Interrupt Cause Set */
1739
+#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
1740
+#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
1741
+#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
1742
+#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
1743
+#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
1744
+#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */
1745
+#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
1746
+#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */
1747
+#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
1748
+#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
1749
+#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
1750
+#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
1751
+#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
1752
+#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
1753
+#define E1000_ICS_SRPD E1000_ICR_SRPD
1754
+#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */
1755
+#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */
1756
+#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */
1757
+#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
1758
+#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
1759
+#define E1000_ICS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
1760
+#define E1000_ICS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
1761
+#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
1762
+#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
1763
+#define E1000_ICS_DSW E1000_ICR_DSW
1764
+#define E1000_ICS_PHYINT E1000_ICR_PHYINT
1765
+#define E1000_ICS_EPRST E1000_ICR_EPRST
1766
+
1767
+/* Interrupt Mask Set */
1768
+#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
1769
+#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
1770
+#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
1771
+#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
1772
+#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
1773
+#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */
1774
+#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
1775
+#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */
1776
+#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
1777
+#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
1778
+#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
1779
+#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
1780
+#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
1781
+#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
1782
+#define E1000_IMS_SRPD E1000_ICR_SRPD
1783
+#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */
1784
+#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */
1785
+#define E1000_IMS_RXQ0 E1000_ICR_RXQ0
1786
+#define E1000_IMS_RXQ1 E1000_ICR_RXQ1
1787
+#define E1000_IMS_TXQ0 E1000_ICR_TXQ0
1788
+#define E1000_IMS_TXQ1 E1000_ICR_TXQ1
1789
+#define E1000_IMS_OTHER E1000_ICR_OTHER
1790
+#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */
1791
+#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
1792
+#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
1793
+#define E1000_IMS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
1794
+#define E1000_IMS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
1795
+#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
1796
+#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
1797
+#define E1000_IMS_DSW E1000_ICR_DSW
1798
+#define E1000_IMS_PHYINT E1000_ICR_PHYINT
1799
+#define E1000_IMS_EPRST E1000_ICR_EPRST
1800
+
1801
+/* Interrupt Mask Clear */
1802
+#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */
1803
+#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
1804
+#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */
1805
+#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
1806
+#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
1807
+#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */
1808
+#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */
1809
+#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */
1810
+#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
1811
+#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
1812
+#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
1813
+#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
1814
+#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
1815
+#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
1816
+#define E1000_IMC_SRPD E1000_ICR_SRPD
1817
+#define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */
1818
+#define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */
1819
+#define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */
1820
+#define E1000_IMC_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
1821
+#define E1000_IMC_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
1822
+#define E1000_IMC_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
1823
+#define E1000_IMC_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
1824
+#define E1000_IMC_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
1825
+#define E1000_IMC_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
1826
+#define E1000_IMC_DSW E1000_ICR_DSW
1827
+#define E1000_IMC_PHYINT E1000_ICR_PHYINT
1828
+#define E1000_IMC_EPRST E1000_ICR_EPRST
1829
+
1830
+/* Receive Control */
1831
+#define E1000_RCTL_RST 0x00000001 /* Software reset */
1832
+#define E1000_RCTL_EN 0x00000002 /* enable */
1833
+#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
1834
+#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
1835
+#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
1836
+#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
1837
+#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
1838
+#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
1839
+#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */
1840
+#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
1841
+#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */
1842
+#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
1843
+#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
1844
+#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */
1845
+#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */
1846
+#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
1847
+#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */
1848
+#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */
1849
+#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */
1850
+#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
1851
+#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */
1852
+#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
1853
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
1854
+#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */
1855
+#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */
1856
+#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */
1857
+#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */
1858
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
1859
+#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */
1860
+#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */
1861
+#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */
1862
+#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
1863
+#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
1864
+#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
1865
+#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */
1866
+#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
1867
+#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
1868
+#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
1869
+#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */
1870
+#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */
1871
+
1872
+
1873
+#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */
1874
+#define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */
1875
+#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM read/write registers */
1876
+#define E1000_EEPROM_RW_REG_DONE 0x10 /* Offset to READ/WRITE done bit */
1877
+#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to start operation */
1878
+#define E1000_EEPROM_RW_ADDR_SHIFT 8 /* Shift to the address bits */
1879
+#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write complete */
1880
+#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read complete */
1881
+
1882
+/* 82574 EERD/EEWR registers layout */
1883
+#define E1000_EERW_START BIT(0)
1884
+#define E1000_EERW_DONE BIT(1)
1885
+#define E1000_EERW_ADDR_SHIFT 2
1886
+#define E1000_EERW_ADDR_MASK ((1L << 14) - 1)
1887
+#define E1000_EERW_DATA_SHIFT 16
1888
+#define E1000_EERW_DATA_MASK ((1L << 16) - 1)
1889
+
1890
+/* Register Bit Masks */
1891
+/* Device Control */
1892
+#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
1893
+#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */
1894
+#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */
1895
+#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
1896
+#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
1897
+#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */
1898
+#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */
1899
+#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
1900
+#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
1901
+#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
1902
+#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */
1903
+#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */
1904
+#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */
1905
+#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
1906
+#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */
1907
+#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
1908
+#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
1909
+#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */
1910
+#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
1911
+#define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, through PHYRST_N pin */
1912
+#define E1000_CTRL_SPD_SHIFT 8 /* Speed Select Shift */
1913
+
1914
+#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* auto speed detection check */
1915
+#define E1000_CTRL_EXT_EE_RST 0x00002000 /* EEPROM reset */
1916
+#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external LINK_0 and LINK_1 pins */
1917
+#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
1918
+#define E1000_CTRL_EXT_EIAME 0x01000000
1919
+#define E1000_CTRL_EXT_IAME 0x08000000 /* Int ACK Auto-mask */
1920
+#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
1921
+#define E1000_CTRL_EXT_INT_TIMERS_CLEAR_ENA 0x20000000
1922
+#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
1923
+
1924
+#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
1925
+#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
1926
+#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
1927
+#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */
1928
+#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
1929
+#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */
1930
+#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */
1931
+#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */
1932
+#define E1000_CTRL_ADVD3WUC 0x00100000 /* D3 WUC */
1933
+#define E1000_CTRL_RST 0x04000000 /* Global reset */
1934
+#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
1935
+#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
1936
+#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */
1937
+#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
1938
+#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
1939
+#define E1000_CTRL_SW2FW_INT 0x02000000 /* Initiate an interrupt to manageability engine */
1940
+
1941
+/* Device Status */
1942
+#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
1943
+#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
1944
+#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
1945
+#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
1946
+#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
1947
+#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */
1948
+#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000
1949
+
1950
+/* EEPROM/Flash Control */
1951
+#define E1000_EECD_SK 0x00000001 /* EEPROM Clock */
1952
+#define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */
1953
+#define E1000_EECD_DI 0x00000004 /* EEPROM Data In */
1954
+#define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */
1955
+#define E1000_EECD_FWE_MASK 0x00000030
1956
+#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */
1957
+#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */
1958
+#define E1000_EECD_FWE_SHIFT 4
1959
+#define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */
1960
+#define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */
1961
+#define E1000_EECD_PRES 0x00000100 /* EEPROM Present */
1962
+#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
1963
+#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
1964
+ * (0-small, 1-large) */
1965
+#define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
1966
+#ifndef E1000_EEPROM_GRANT_ATTEMPTS
1967
+#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
1968
+#endif
137
+#endif
1969
+#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */
1970
+#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */
1971
+#define E1000_EECD_SIZE_EX_SHIFT 11
1972
+#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */
1973
+#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */
1974
+#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */
1975
+#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
1976
+#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
1977
+#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */
1978
+#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
1979
+
1980
+
1981
+#define E1000_EECD_SECVAL_SHIFT 22
1982
+#define E1000_STM_OPCODE 0xDB00
1983
+#define E1000_HICR_FW_RESET 0xC0
1984
+
1985
+#define E1000_SHADOW_RAM_WORDS 2048
1986
+#define E1000_ICH_NVM_SIG_WORD 0x13
1987
+#define E1000_ICH_NVM_SIG_MASK 0xC0
1988
+
1989
+/* MDI Control */
1990
+#define E1000_MDIC_DATA_MASK 0x0000FFFF
1991
+#define E1000_MDIC_REG_MASK 0x001F0000
1992
+#define E1000_MDIC_REG_SHIFT 16
1993
+#define E1000_MDIC_PHY_MASK 0x03E00000
1994
+#define E1000_MDIC_PHY_SHIFT 21
1995
+#define E1000_MDIC_OP_WRITE 0x04000000
1996
+#define E1000_MDIC_OP_READ 0x08000000
1997
+#define E1000_MDIC_READY 0x10000000
1998
+#define E1000_MDIC_INT_EN 0x20000000
1999
+#define E1000_MDIC_ERROR 0x40000000
2000
+
2001
+/* Rx Interrupt Delay Timer */
2002
+#define E1000_RDTR_FPD BIT(31)
2003
+
2004
+/* Tx Interrupt Delay Timer */
2005
+#define E1000_TIDV_FPD BIT(31)
2006
+
2007
+/* Delay increments in nanoseconds for delayed interrupts registers */
2008
+#define E1000_INTR_DELAY_NS_RES (1024)
2009
+
2010
+/* Delay increments in nanoseconds for interrupt throttling registers */
2011
+#define E1000_INTR_THROTTLING_NS_RES (256)
2012
+
2013
+/* EEPROM Commands - Microwire */
2014
+#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */
2015
+#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */
2016
+#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7 /* EEPROM erase opcode */
2017
+#define EEPROM_EWEN_OPCODE_MICROWIRE 0x13 /* EEPROM erase/write enable */
2018
+#define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */
2019
+
2020
+/* EEPROM Word Offsets */
2021
+#define EEPROM_COMPAT 0x0003
2022
+#define EEPROM_ID_LED_SETTINGS 0x0004
2023
+#define EEPROM_VERSION 0x0005
2024
+#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */
2025
+#define EEPROM_PHY_CLASS_WORD 0x0007
2026
+#define EEPROM_INIT_CONTROL1_REG 0x000A
2027
+#define EEPROM_INIT_CONTROL2_REG 0x000F
2028
+#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010
2029
+#define EEPROM_INIT_CONTROL3_PORT_B 0x0014
2030
+#define EEPROM_INIT_3GIO_3 0x001A
2031
+#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020
2032
+#define EEPROM_INIT_CONTROL3_PORT_A 0x0024
2033
+#define EEPROM_CFG 0x0012
2034
+#define EEPROM_FLASH_VERSION 0x0032
2035
+#define EEPROM_CHECKSUM_REG 0x003F
2036
+
2037
+#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */
2038
+#define E1000_EEPROM_CFG_DONE_PORT_1 0x00080000 /* ...for second port */
2039
+
2040
+/* HH Time Sync */
2041
+#define E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK 0x0000F000 /* max delay */
2042
+#define E1000_TSYNCTXCTL_SYNC_COMP 0x40000000 /* sync complete */
2043
+#define E1000_TSYNCTXCTL_START_SYNC 0x80000000 /* initiate sync */
2044
+
2045
+#define E1000_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */
2046
+#define E1000_TSYNCTXCTL_ENABLED 0x00000010 /* enable Tx timestamping */
2047
+
2048
+#define E1000_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */
2049
+#define E1000_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */
2050
+#define E1000_TSYNCRXCTL_TYPE_L2_V2 0x00
2051
+#define E1000_TSYNCRXCTL_TYPE_L4_V1 0x02
2052
+#define E1000_TSYNCRXCTL_TYPE_L2_L4_V2 0x04
2053
+#define E1000_TSYNCRXCTL_TYPE_ALL 0x08
2054
+#define E1000_TSYNCRXCTL_TYPE_EVENT_V2 0x0A
2055
+#define E1000_TSYNCRXCTL_ENABLED 0x00000010 /* enable Rx timestamping */
2056
+#define E1000_TSYNCRXCTL_SYSCFI 0x00000020 /* Sys clock frequency */
2057
+
2058
+#define E1000_RXMTRL_PTP_V1_SYNC_MESSAGE 0x00000000
2059
+#define E1000_RXMTRL_PTP_V1_DELAY_REQ_MESSAGE 0x00010000
2060
+
2061
+#define E1000_RXMTRL_PTP_V2_SYNC_MESSAGE 0x00000000
2062
+#define E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE 0x01000000
2063
+
2064
+#define E1000_TIMINCA_INCPERIOD_SHIFT 24
2065
+#define E1000_TIMINCA_INCVALUE_MASK 0x00FFFFFF
2066
+
2067
+/* PCI Express Control */
2068
+/* 3GIO Control Register - GCR (0x05B00; RW) */
2069
+#define E1000_L0S_ADJUST (1 << 9)
2070
+#define E1000_L1_ENTRY_LATENCY_MSB (1 << 23)
2071
+#define E1000_L1_ENTRY_LATENCY_LSB (1 << 25 | 1 << 26)
2072
+
2073
+#define E1000_L0S_ADJUST (1 << 9)
2074
+#define E1000_L1_ENTRY_LATENCY_MSB (1 << 23)
2075
+#define E1000_L1_ENTRY_LATENCY_LSB (1 << 25 | 1 << 26)
2076
+
2077
+#define E1000_GCR_RO_BITS (1 << 23 | 1 << 25 | 1 << 26)
2078
+
2079
+/* MSI-X PBA Clear register */
2080
+#define E1000_PBACLR_VALID_MASK (BIT(5) - 1)
2081
+
2082
+/* Transmit Descriptor bit definitions */
2083
+#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
2084
+#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */
2085
+#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
2086
+#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
2087
+#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */
2088
+#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
2089
+#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */
2090
+#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
2091
+#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
2092
+#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
2093
+#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
2094
+#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
2095
+#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
2096
+#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
2097
+#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */
2098
+#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */
2099
+#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */
2100
+#define E1000_TXD_CMD_SNAP 0x40000000 /* Update SNAP header */
2101
+#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
2102
+#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */
2103
+
2104
+/* Transmit Control */
2105
+#define E1000_TCTL_RST 0x00000001 /* software reset */
2106
+#define E1000_TCTL_EN 0x00000002 /* enable tx */
2107
+#define E1000_TCTL_BCE 0x00000004 /* busy check enable */
2108
+#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
2109
+#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
2110
+#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
2111
+#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */
2112
+#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */
2113
+#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
2114
+#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
2115
+#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */
2116
+
2117
+/* Legacy Receive Descriptor */
2118
+struct e1000_rx_desc {
2119
+ uint64_t buffer_addr; /* Address of the descriptor's data buffer */
2120
+ uint16_t length; /* Length of data DMAed into data buffer */
2121
+ uint16_t csum; /* Packet checksum */
2122
+ uint8_t status; /* Descriptor status */
2123
+ uint8_t errors; /* Descriptor Errors */
2124
+ uint16_t special;
2125
+};
2126
+
2127
+/* Extended Receive Descriptor */
2128
+union e1000_rx_desc_extended {
2129
+ struct {
2130
+ uint64_t buffer_addr;
2131
+ uint64_t reserved;
2132
+ } read;
2133
+ struct {
2134
+ struct {
2135
+ uint32_t mrq; /* Multiple Rx Queues */
2136
+ union {
2137
+ uint32_t rss; /* RSS Hash */
2138
+ struct {
2139
+ uint16_t ip_id; /* IP id */
2140
+ uint16_t csum; /* Packet Checksum */
2141
+ } csum_ip;
2142
+ } hi_dword;
2143
+ } lower;
2144
+ struct {
2145
+ uint32_t status_error; /* ext status/error */
2146
+ uint16_t length;
2147
+ uint16_t vlan; /* VLAN tag */
2148
+ } upper;
2149
+ } wb; /* writeback */
2150
+};
2151
+
2152
+#define MAX_PS_BUFFERS 4
2153
+
2154
+/* Number of packet split data buffers (not including the header buffer) */
2155
+#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
2156
+
2157
+/* Receive Descriptor - Packet Split */
2158
+union e1000_rx_desc_packet_split {
2159
+ struct {
2160
+ /* one buffer for protocol header(s), three data buffers */
2161
+ uint64_t buffer_addr[MAX_PS_BUFFERS];
2162
+ } read;
2163
+ struct {
2164
+ struct {
2165
+ uint32_t mrq; /* Multiple Rx Queues */
2166
+ union {
2167
+ uint32_t rss; /* RSS Hash */
2168
+ struct {
2169
+ uint16_t ip_id; /* IP id */
2170
+ uint16_t csum; /* Packet Checksum */
2171
+ } csum_ip;
2172
+ } hi_dword;
2173
+ } lower;
2174
+ struct {
2175
+ uint32_t status_error; /* ext status/error */
2176
+ uint16_t length0; /* length of buffer 0 */
2177
+ uint16_t vlan; /* VLAN tag */
2178
+ } middle;
2179
+ struct {
2180
+ uint16_t header_status;
2181
+ /* length of buffers 1-3 */
2182
+ uint16_t length[PS_PAGE_BUFFERS];
2183
+ } upper;
2184
+ uint64_t reserved;
2185
+ } wb; /* writeback */
2186
+};
2187
+
2188
+/* Receive Checksum Control bits */
2189
+#define E1000_RXCSUM_IPOFLD 0x100 /* IP Checksum Offload Enable */
2190
+#define E1000_RXCSUM_TUOFLD 0x200 /* TCP/UDP Checksum Offload Enable */
2191
+#define E1000_RXCSUM_PCSD 0x2000 /* Packet Checksum Disable */
2192
+
2193
+#define E1000_RING_DESC_LEN (16)
2194
+#define E1000_RING_DESC_LEN_SHIFT (4)
2195
+
2196
+#define E1000_MIN_RX_DESC_LEN E1000_RING_DESC_LEN
2197
+
2198
+/* Receive Descriptor bit definitions */
2199
+#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
2200
+#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
2201
+#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
2202
+#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
2203
+#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
2204
+#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
2205
+#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
2206
+#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */
2207
+#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */
2208
+#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
2209
+#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */
2210
+#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
2211
+#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
2212
+#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
2213
+#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
2214
+#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */
2215
+#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */
2216
+#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
2217
+#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
2218
+#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */
2219
+#define E1000_RXD_SPC_PRI_SHIFT 13
2220
+#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */
2221
+#define E1000_RXD_SPC_CFI_SHIFT 12
2222
+
2223
+/* RX packet types */
2224
+#define E1000_RXD_PKT_MAC (0)
2225
+#define E1000_RXD_PKT_IP4 (1)
2226
+#define E1000_RXD_PKT_IP4_XDP (2)
2227
+#define E1000_RXD_PKT_IP6 (5)
2228
+#define E1000_RXD_PKT_IP6_XDP (6)
2229
+
2230
+#define E1000_RXD_PKT_TYPE(t) ((t) << 16)
2231
+
2232
+#define E1000_RXDEXT_STATERR_CE 0x01000000
2233
+#define E1000_RXDEXT_STATERR_SE 0x02000000
2234
+#define E1000_RXDEXT_STATERR_SEQ 0x04000000
2235
+#define E1000_RXDEXT_STATERR_CXE 0x10000000
2236
+#define E1000_RXDEXT_STATERR_TCPE 0x20000000
2237
+#define E1000_RXDEXT_STATERR_IPE 0x40000000
2238
+#define E1000_RXDEXT_STATERR_RXE 0x80000000
2239
+
2240
+#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000
2241
+#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF
2242
+
2243
+/* Receive Address */
2244
+#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
2245
+
2246
+/* Offload Context Descriptor */
2247
+struct e1000_context_desc {
2248
+ union {
2249
+ uint32_t ip_config;
2250
+ struct {
2251
+ uint8_t ipcss; /* IP checksum start */
2252
+ uint8_t ipcso; /* IP checksum offset */
2253
+ uint16_t ipcse; /* IP checksum end */
2254
+ } ip_fields;
2255
+ } lower_setup;
2256
+ union {
2257
+ uint32_t tcp_config;
2258
+ struct {
2259
+ uint8_t tucss; /* TCP checksum start */
2260
+ uint8_t tucso; /* TCP checksum offset */
2261
+ uint16_t tucse; /* TCP checksum end */
2262
+ } tcp_fields;
2263
+ } upper_setup;
2264
+ uint32_t cmd_and_length; /* */
2265
+ union {
2266
+ uint32_t data;
2267
+ struct {
2268
+ uint8_t status; /* Descriptor status */
2269
+ uint8_t hdr_len; /* Header length */
2270
+ uint16_t mss; /* Maximum segment size */
2271
+ } fields;
2272
+ } tcp_seg_setup;
2273
+};
2274
+
2275
+/* Filters */
2276
+#define E1000_NUM_UNICAST 16 /* Unicast filter entries */
2277
+#define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
2278
+#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
2279
+
2280
+/* Management Control */
2281
+#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
2282
+#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
2283
+#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */
2284
+#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering */
2285
+#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering */
2286
+#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */
2287
+#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */
2288
+#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */
2289
+#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
2290
+#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery
2291
+ * Filtering */
2292
+#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */
2293
+#define E1000_MANC_DIS_IP_CHK_ARP 0x10000000 /* Disable IP address chacking */
2294
+ /*for ARP packets - in 82574 */
2295
+#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */
2296
+#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
2297
+#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
2298
+#define E1000_MANC_RCV_ALL 0x00080000 /* Receive All Enabled */
2299
+#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
2300
+#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address
2301
+ * filtering */
2302
+#define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host
2303
+ * memory */
2304
+#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address
2305
+ * filtering */
2306
+#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */
2307
+#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */
2308
+#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */
2309
+#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */
2310
+#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */
2311
+#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */
2312
+#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */
2313
+#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */
2314
+
2315
+#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */
2316
+#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */
2317
+
2318
+/* FACTPS Control */
2319
+#define E1000_FACTPS_LAN0_ON 0x00000004 /* Lan 0 enable */
2320
+
2321
+/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
2322
+#define EEPROM_SUM 0xBABA
2323
+
2324
+/* I/O-Mapped Access to Internal Registers, Memories, and Flash */
2325
+#define E1000_IOADDR 0x00
2326
+#define E1000_IODATA 0x04
2327
+
2328
+#define E1000_VFTA_ENTRY_SHIFT 5
2329
+#define E1000_VFTA_ENTRY_MASK 0x7F
2330
+#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
2331
+
2332
+#endif /* HW_E1000_REGS_H */
2333
--
138
--
2334
2.7.4
139
2.7.4
2335
140
2336
141
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
There was no proper implementation of TCP segmentation before this
3
At this mode no buffer forwarding will be performed in SVQ mode: Qemu
4
change, and net_tx_pkt relied solely on IPv4 fragmentation. Not only
4
will just forward the guest's kicks to the device.
5
this is not aligned with the specification, but it also resulted in
5
6
corrupted IPv6 packets.
6
Host memory notifiers regions are left out for simplicity, and they will
7
7
not be addressed in this series.
8
This is particularly problematic for the igb, a new proposed device
8
9
implementation; igb provides loopback feature for VMDq and the feature
9
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
10
relies on software segmentation.
10
Acked-by: Michael S. Tsirkin <mst@redhat.com>
11
12
Implement proper TCP segmentation in net_tx_pkt to fix such a scenario.
13
14
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
15
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
16
---
12
---
17
hw/net/net_tx_pkt.c | 248 +++++++++++++++++++++++++++++++++++++++++++---------
13
hw/virtio/vhost-shadow-virtqueue.c | 55 ++++++++++++++
18
include/net/eth.h | 5 --
14
hw/virtio/vhost-shadow-virtqueue.h | 14 ++++
19
net/eth.c | 27 ------
15
hw/virtio/vhost-vdpa.c | 144 ++++++++++++++++++++++++++++++++++++-
20
3 files changed, 206 insertions(+), 74 deletions(-)
16
include/hw/virtio/vhost-vdpa.h | 4 ++
21
17
4 files changed, 215 insertions(+), 2 deletions(-)
22
diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
18
19
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
23
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/net/net_tx_pkt.c
21
--- a/hw/virtio/vhost-shadow-virtqueue.c
25
+++ b/hw/net/net_tx_pkt.c
22
+++ b/hw/virtio/vhost-shadow-virtqueue.c
26
@@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
23
@@ -XXX,XX +XXX,XX @@
27
case VIRTIO_NET_HDR_GSO_TCPV6:
24
#include "hw/virtio/vhost-shadow-virtqueue.h"
28
bytes_read = iov_to_buf(&pkt->vec[NET_TX_PKT_PL_START_FRAG],
25
29
pkt->payload_frags, 0, &l4hdr, sizeof(l4hdr));
26
#include "qemu/error-report.h"
30
- if (bytes_read < sizeof(l4hdr)) {
27
+#include "qemu/main-loop.h"
31
+ if (bytes_read < sizeof(l4hdr) ||
28
+#include "linux-headers/linux/vhost.h"
32
+ l4hdr.th_off * sizeof(uint32_t) < sizeof(l4hdr)) {
29
+
33
return false;
30
+/**
34
}
31
+ * Forward guest notifications.
35
32
+ *
36
@@ -XXX,XX +XXX,XX @@ void net_tx_pkt_reset(struct NetTxPkt *pkt)
33
+ * @n: guest kick event notifier, the one that guest set to notify svq.
37
pkt->l4proto = 0;
34
+ */
38
}
35
+static void vhost_handle_guest_kick(EventNotifier *n)
39
36
+{
40
-static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt)
37
+ VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue, svq_kick);
41
+static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt,
38
+ event_notifier_test_and_clear(n);
42
+ struct iovec *iov, uint32_t iov_len,
39
+ event_notifier_set(&svq->hdev_kick);
43
+ uint16_t csl)
40
+}
44
{
41
+
45
- struct iovec *iov = &pkt->vec[NET_TX_PKT_L2HDR_FRAG];
42
+/**
46
uint32_t csum_cntr;
43
+ * Set a new file descriptor for the guest to kick the SVQ and notify for avail
47
uint16_t csum = 0;
44
+ *
48
uint32_t cso;
45
+ * @svq: The svq
49
/* num of iovec without vhdr */
46
+ * @svq_kick_fd: The svq kick fd
50
- uint32_t iov_len = pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - 1;
47
+ *
51
- uint16_t csl;
48
+ * Note that the SVQ will never close the old file descriptor.
52
size_t csum_offset = pkt->virt_hdr.csum_start + pkt->virt_hdr.csum_offset;
49
+ */
53
uint16_t l3_proto = eth_get_l3_proto(iov, 1, iov->iov_len);
50
+void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd)
54
51
+{
55
@@ -XXX,XX +XXX,XX @@ static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt)
52
+ EventNotifier *svq_kick = &svq->svq_kick;
56
iov_from_buf(iov, iov_len, csum_offset, &csum, sizeof csum);
53
+ bool poll_stop = VHOST_FILE_UNBIND != event_notifier_get_fd(svq_kick);
57
54
+ bool poll_start = svq_kick_fd != VHOST_FILE_UNBIND;
58
/* Calculate L4 TCP/UDP checksum */
55
+
59
- csl = pkt->payload_len;
56
+ if (poll_stop) {
60
-
57
+ event_notifier_set_handler(svq_kick, NULL);
61
csum_cntr = 0;
58
+ }
62
cso = 0;
59
+
63
/* add pseudo header to csum */
60
+ /*
64
@@ -XXX,XX +XXX,XX @@ static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt)
61
+ * event_notifier_set_handler already checks for guest's notifications if
65
#define NET_MAX_FRAG_SG_LIST (64)
62
+ * they arrive at the new file descriptor in the switch, so there is no
66
63
+ * need to explicitly check for them.
67
static size_t net_tx_pkt_fetch_fragment(struct NetTxPkt *pkt,
64
+ */
68
- int *src_idx, size_t *src_offset, struct iovec *dst, int *dst_idx)
65
+ if (poll_start) {
69
+ int *src_idx, size_t *src_offset, size_t src_len,
66
+ event_notifier_init_fd(svq_kick, svq_kick_fd);
70
+ struct iovec *dst, int *dst_idx)
67
+ event_notifier_set(svq_kick);
71
{
68
+ event_notifier_set_handler(svq_kick, vhost_handle_guest_kick);
72
size_t fetched = 0;
69
+ }
73
struct iovec *src = pkt->vec;
70
+}
74
71
+
75
- *dst_idx = NET_TX_PKT_PL_START_FRAG;
72
+/**
76
-
73
+ * Stop the shadow virtqueue operation.
77
- while (fetched < IP_FRAG_ALIGN_SIZE(pkt->virt_hdr.gso_size)) {
74
+ * @svq: Shadow Virtqueue
78
+ while (fetched < src_len) {
75
+ */
79
76
+void vhost_svq_stop(VhostShadowVirtqueue *svq)
80
/* no more place in fragment iov */
77
+{
81
if (*dst_idx == NET_MAX_FRAG_SG_LIST) {
78
+ event_notifier_set_handler(&svq->svq_kick, NULL);
82
@@ -XXX,XX +XXX,XX @@ static size_t net_tx_pkt_fetch_fragment(struct NetTxPkt *pkt,
79
+}
83
80
84
dst[*dst_idx].iov_base = src[*src_idx].iov_base + *src_offset;
81
/**
85
dst[*dst_idx].iov_len = MIN(src[*src_idx].iov_len - *src_offset,
82
* Creates vhost shadow virtqueue, and instructs the vhost device to use the
86
- IP_FRAG_ALIGN_SIZE(pkt->virt_hdr.gso_size) - fetched);
83
@@ -XXX,XX +XXX,XX @@ VhostShadowVirtqueue *vhost_svq_new(void)
87
+ src_len - fetched);
84
goto err_init_hdev_call;
88
89
*src_offset += dst[*dst_idx].iov_len;
90
fetched += dst[*dst_idx].iov_len;
91
@@ -XXX,XX +XXX,XX @@ static void net_tx_pkt_sendv(
92
}
85
}
93
}
86
94
87
+ event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND);
95
+static bool net_tx_pkt_tcp_fragment_init(struct NetTxPkt *pkt,
88
return g_steal_pointer(&svq);
96
+ struct iovec *fragment,
89
97
+ int *pl_idx,
90
err_init_hdev_call:
98
+ size_t *l4hdr_len,
91
@@ -XXX,XX +XXX,XX @@ err_init_hdev_kick:
99
+ int *src_idx,
92
void vhost_svq_free(gpointer pvq)
100
+ size_t *src_offset,
93
{
101
+ size_t *src_len)
94
VhostShadowVirtqueue *vq = pvq;
102
+{
95
+ vhost_svq_stop(vq);
103
+ struct iovec *l4 = fragment + NET_TX_PKT_PL_START_FRAG;
96
event_notifier_cleanup(&vq->hdev_kick);
104
+ size_t bytes_read = 0;
97
event_notifier_cleanup(&vq->hdev_call);
105
+ struct tcp_hdr *th;
98
g_free(vq);
106
+
99
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
107
+ if (!pkt->payload_frags) {
100
index XXXXXXX..XXXXXXX 100644
108
+ return false;
101
--- a/hw/virtio/vhost-shadow-virtqueue.h
109
+ }
102
+++ b/hw/virtio/vhost-shadow-virtqueue.h
110
+
103
@@ -XXX,XX +XXX,XX @@ typedef struct VhostShadowVirtqueue {
111
+ l4->iov_len = pkt->virt_hdr.hdr_len - pkt->hdr_len;
104
EventNotifier hdev_kick;
112
+ l4->iov_base = g_malloc(l4->iov_len);
105
/* Shadow call notifier, sent to vhost */
113
+
106
EventNotifier hdev_call;
114
+ *src_idx = NET_TX_PKT_PL_START_FRAG;
107
+
115
+ while (pkt->vec[*src_idx].iov_len < l4->iov_len - bytes_read) {
108
+ /*
116
+ memcpy((char *)l4->iov_base + bytes_read, pkt->vec[*src_idx].iov_base,
109
+ * Borrowed virtqueue's guest to host notifier. To borrow it in this event
117
+ pkt->vec[*src_idx].iov_len);
110
+ * notifier allows to recover the VhostShadowVirtqueue from the event loop
118
+
111
+ * easily. If we use the VirtQueue's one, we don't have an easy way to
119
+ bytes_read += pkt->vec[*src_idx].iov_len;
112
+ * retrieve VhostShadowVirtqueue.
120
+
113
+ *
121
+ (*src_idx)++;
114
+ * So shadow virtqueue must not clean it, or we would lose VirtQueue one.
122
+ if (*src_idx >= pkt->payload_frags + NET_TX_PKT_PL_START_FRAG) {
115
+ */
123
+ g_free(l4->iov_base);
116
+ EventNotifier svq_kick;
117
} VhostShadowVirtqueue;
118
119
+void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd);
120
+
121
+void vhost_svq_stop(VhostShadowVirtqueue *svq);
122
+
123
VhostShadowVirtqueue *vhost_svq_new(void);
124
125
void vhost_svq_free(gpointer vq);
126
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/virtio/vhost-vdpa.c
129
+++ b/hw/virtio/vhost-vdpa.c
130
@@ -XXX,XX +XXX,XX @@
131
#include "hw/virtio/vhost.h"
132
#include "hw/virtio/vhost-backend.h"
133
#include "hw/virtio/virtio-net.h"
134
+#include "hw/virtio/vhost-shadow-virtqueue.h"
135
#include "hw/virtio/vhost-vdpa.h"
136
#include "exec/address-spaces.h"
137
#include "qemu/main-loop.h"
138
#include "cpu.h"
139
#include "trace.h"
140
#include "qemu-common.h"
141
+#include "qapi/error.h"
142
143
/*
144
* Return one past the end of the end of section. Be careful with uint64_t
145
@@ -XXX,XX +XXX,XX @@ static bool vhost_vdpa_one_time_request(struct vhost_dev *dev)
146
return v->index != 0;
147
}
148
149
+static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v,
150
+ Error **errp)
151
+{
152
+ g_autoptr(GPtrArray) shadow_vqs = NULL;
153
+
154
+ if (!v->shadow_vqs_enabled) {
155
+ return 0;
156
+ }
157
+
158
+ shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free);
159
+ for (unsigned n = 0; n < hdev->nvqs; ++n) {
160
+ g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new();
161
+
162
+ if (unlikely(!svq)) {
163
+ error_setg(errp, "Cannot create svq %u", n);
164
+ return -1;
165
+ }
166
+ g_ptr_array_add(shadow_vqs, g_steal_pointer(&svq));
167
+ }
168
+
169
+ v->shadow_vqs = g_steal_pointer(&shadow_vqs);
170
+ return 0;
171
+}
172
+
173
static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp)
174
{
175
struct vhost_vdpa *v;
176
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp)
177
dev->opaque = opaque ;
178
v->listener = vhost_vdpa_memory_listener;
179
v->msg_type = VHOST_IOTLB_MSG_V2;
180
+ ret = vhost_vdpa_init_svq(dev, v, errp);
181
+ if (ret) {
182
+ goto err;
183
+ }
184
185
vhost_vdpa_get_iova_range(v);
186
187
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp)
188
VIRTIO_CONFIG_S_DRIVER);
189
190
return 0;
191
+
192
+err:
193
+ ram_block_discard_disable(false);
194
+ return ret;
195
}
196
197
static void vhost_vdpa_host_notifier_uninit(struct vhost_dev *dev,
198
@@ -XXX,XX +XXX,XX @@ static void vhost_vdpa_host_notifiers_uninit(struct vhost_dev *dev, int n)
199
200
static void vhost_vdpa_host_notifiers_init(struct vhost_dev *dev)
201
{
202
+ struct vhost_vdpa *v = dev->opaque;
203
int i;
204
205
+ if (v->shadow_vqs_enabled) {
206
+ /* FIXME SVQ is not compatible with host notifiers mr */
207
+ return;
208
+ }
209
+
210
for (i = dev->vq_index; i < dev->vq_index + dev->nvqs; i++) {
211
if (vhost_vdpa_host_notifier_init(dev, i)) {
212
goto err;
213
@@ -XXX,XX +XXX,XX @@ err:
214
return;
215
}
216
217
+static void vhost_vdpa_svq_cleanup(struct vhost_dev *dev)
218
+{
219
+ struct vhost_vdpa *v = dev->opaque;
220
+ size_t idx;
221
+
222
+ if (!v->shadow_vqs) {
223
+ return;
224
+ }
225
+
226
+ for (idx = 0; idx < v->shadow_vqs->len; ++idx) {
227
+ vhost_svq_stop(g_ptr_array_index(v->shadow_vqs, idx));
228
+ }
229
+ g_ptr_array_free(v->shadow_vqs, true);
230
+}
231
+
232
static int vhost_vdpa_cleanup(struct vhost_dev *dev)
233
{
234
struct vhost_vdpa *v;
235
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_cleanup(struct vhost_dev *dev)
236
trace_vhost_vdpa_cleanup(dev, v);
237
vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
238
memory_listener_unregister(&v->listener);
239
+ vhost_vdpa_svq_cleanup(dev);
240
241
dev->opaque = NULL;
242
ram_block_discard_disable(false);
243
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_get_device_id(struct vhost_dev *dev,
244
return ret;
245
}
246
247
+static void vhost_vdpa_reset_svq(struct vhost_vdpa *v)
248
+{
249
+ if (!v->shadow_vqs_enabled) {
250
+ return;
251
+ }
252
+
253
+ for (unsigned i = 0; i < v->shadow_vqs->len; ++i) {
254
+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
255
+ vhost_svq_stop(svq);
256
+ }
257
+}
258
+
259
static int vhost_vdpa_reset_device(struct vhost_dev *dev)
260
{
261
+ struct vhost_vdpa *v = dev->opaque;
262
int ret;
263
uint8_t status = 0;
264
265
+ vhost_vdpa_reset_svq(v);
266
+
267
ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status);
268
trace_vhost_vdpa_reset_device(dev, status);
269
return ret;
270
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
271
return ret;
272
}
273
274
+static int vhost_vdpa_set_vring_dev_kick(struct vhost_dev *dev,
275
+ struct vhost_vring_file *file)
276
+{
277
+ trace_vhost_vdpa_set_vring_kick(dev, file->index, file->fd);
278
+ return vhost_vdpa_call(dev, VHOST_SET_VRING_KICK, file);
279
+}
280
+
281
+/**
282
+ * Set the shadow virtqueue descriptors to the device
283
+ *
284
+ * @dev: The vhost device model
285
+ * @svq: The shadow virtqueue
286
+ * @idx: The index of the virtqueue in the vhost device
287
+ * @errp: Error
288
+ */
289
+static bool vhost_vdpa_svq_setup(struct vhost_dev *dev,
290
+ VhostShadowVirtqueue *svq, unsigned idx,
291
+ Error **errp)
292
+{
293
+ struct vhost_vring_file file = {
294
+ .index = dev->vq_index + idx,
295
+ };
296
+ const EventNotifier *event_notifier = &svq->hdev_kick;
297
+ int r;
298
+
299
+ file.fd = event_notifier_get_fd(event_notifier);
300
+ r = vhost_vdpa_set_vring_dev_kick(dev, &file);
301
+ if (unlikely(r != 0)) {
302
+ error_setg_errno(errp, -r, "Can't set device kick fd");
303
+ }
304
+
305
+ return r == 0;
306
+}
307
+
308
+static bool vhost_vdpa_svqs_start(struct vhost_dev *dev)
309
+{
310
+ struct vhost_vdpa *v = dev->opaque;
311
+ Error *err = NULL;
312
+ unsigned i;
313
+
314
+ if (!v->shadow_vqs) {
315
+ return true;
316
+ }
317
+
318
+ for (i = 0; i < v->shadow_vqs->len; ++i) {
319
+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
320
+ bool ok = vhost_vdpa_svq_setup(dev, svq, i, &err);
321
+ if (unlikely(!ok)) {
322
+ error_reportf_err(err, "Cannot setup SVQ %u: ", i);
124
+ return false;
323
+ return false;
125
+ }
324
+ }
126
+ }
325
+ }
127
+
326
+
128
+ *src_offset = l4->iov_len - bytes_read;
129
+ memcpy((char *)l4->iov_base + bytes_read, pkt->vec[*src_idx].iov_base,
130
+ *src_offset);
131
+
132
+ th = l4->iov_base;
133
+ th->th_flags &= ~(TH_FIN | TH_PUSH);
134
+
135
+ *pl_idx = NET_TX_PKT_PL_START_FRAG + 1;
136
+ *l4hdr_len = l4->iov_len;
137
+ *src_len = pkt->virt_hdr.gso_size;
138
+
139
+ return true;
327
+ return true;
140
+}
328
+}
141
+
329
+
142
+static void net_tx_pkt_tcp_fragment_deinit(struct iovec *fragment)
330
static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
143
+{
331
{
144
+ g_free(fragment[NET_TX_PKT_PL_START_FRAG].iov_base);
332
struct vhost_vdpa *v = dev->opaque;
145
+}
333
+ bool ok;
146
+
334
trace_vhost_vdpa_dev_start(dev, started);
147
+static void net_tx_pkt_tcp_fragment_fix(struct NetTxPkt *pkt,
335
148
+ struct iovec *fragment,
336
if (started) {
149
+ size_t fragment_len,
337
vhost_vdpa_host_notifiers_init(dev);
150
+ uint8_t gso_type)
338
+ ok = vhost_vdpa_svqs_start(dev);
151
+{
339
+ if (unlikely(!ok)) {
152
+ struct iovec *l3hdr = fragment + NET_TX_PKT_L3HDR_FRAG;
340
+ return -1;
153
+ struct iovec *l4hdr = fragment + NET_TX_PKT_PL_START_FRAG;
154
+ struct ip_header *ip = l3hdr->iov_base;
155
+ struct ip6_header *ip6 = l3hdr->iov_base;
156
+ size_t len = l3hdr->iov_len + l4hdr->iov_len + fragment_len;
157
+
158
+ switch (gso_type) {
159
+ case VIRTIO_NET_HDR_GSO_TCPV4:
160
+ ip->ip_len = cpu_to_be16(len);
161
+ eth_fix_ip4_checksum(l3hdr->iov_base, l3hdr->iov_len);
162
+ break;
163
+
164
+ case VIRTIO_NET_HDR_GSO_TCPV6:
165
+ len -= sizeof(struct ip6_header);
166
+ ip6->ip6_ctlun.ip6_un1.ip6_un1_plen = cpu_to_be16(len);
167
+ break;
168
+ }
169
+}
170
+
171
+static void net_tx_pkt_tcp_fragment_advance(struct NetTxPkt *pkt,
172
+ struct iovec *fragment,
173
+ size_t fragment_len,
174
+ uint8_t gso_type)
175
+{
176
+ struct iovec *l3hdr = fragment + NET_TX_PKT_L3HDR_FRAG;
177
+ struct iovec *l4hdr = fragment + NET_TX_PKT_PL_START_FRAG;
178
+ struct ip_header *ip = l3hdr->iov_base;
179
+ struct tcp_hdr *th = l4hdr->iov_base;
180
+
181
+ if (gso_type == VIRTIO_NET_HDR_GSO_TCPV4) {
182
+ ip->ip_id = cpu_to_be16(be16_to_cpu(ip->ip_id) + 1);
183
+ }
184
+
185
+ th->th_seq = cpu_to_be32(be32_to_cpu(th->th_seq) + fragment_len);
186
+ th->th_flags &= ~TH_CWR;
187
+}
188
+
189
+static void net_tx_pkt_udp_fragment_init(struct NetTxPkt *pkt,
190
+ int *pl_idx,
191
+ size_t *l4hdr_len,
192
+ int *src_idx, size_t *src_offset,
193
+ size_t *src_len)
194
+{
195
+ *pl_idx = NET_TX_PKT_PL_START_FRAG;
196
+ *l4hdr_len = 0;
197
+ *src_idx = NET_TX_PKT_PL_START_FRAG;
198
+ *src_offset = 0;
199
+ *src_len = IP_FRAG_ALIGN_SIZE(pkt->virt_hdr.gso_size);
200
+}
201
+
202
+static void net_tx_pkt_udp_fragment_fix(struct NetTxPkt *pkt,
203
+ struct iovec *fragment,
204
+ size_t fragment_offset,
205
+ size_t fragment_len)
206
+{
207
+ bool more_frags = fragment_offset + fragment_len < pkt->payload_len;
208
+ uint16_t orig_flags;
209
+ struct iovec *l3hdr = fragment + NET_TX_PKT_L3HDR_FRAG;
210
+ struct ip_header *ip = l3hdr->iov_base;
211
+ uint16_t frag_off_units = fragment_offset / IP_FRAG_UNIT_SIZE;
212
+ uint16_t new_ip_off;
213
+
214
+ assert(fragment_offset % IP_FRAG_UNIT_SIZE == 0);
215
+ assert((frag_off_units & ~IP_OFFMASK) == 0);
216
+
217
+ orig_flags = be16_to_cpu(ip->ip_off) & ~(IP_OFFMASK | IP_MF);
218
+ new_ip_off = frag_off_units | orig_flags | (more_frags ? IP_MF : 0);
219
+ ip->ip_off = cpu_to_be16(new_ip_off);
220
+ ip->ip_len = cpu_to_be16(l3hdr->iov_len + fragment_len);
221
+
222
+ eth_fix_ip4_checksum(l3hdr->iov_base, l3hdr->iov_len);
223
+}
224
+
225
static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt,
226
NetTxPktCallback callback,
227
void *context)
228
{
229
+ uint8_t gso_type = pkt->virt_hdr.gso_type & ~VIRTIO_NET_HDR_GSO_ECN;
230
+
231
struct iovec fragment[NET_MAX_FRAG_SG_LIST];
232
- size_t fragment_len = 0;
233
- bool more_frags = false;
234
-
235
- /* some pointers for shorter code */
236
- void *l2_iov_base, *l3_iov_base;
237
- size_t l2_iov_len, l3_iov_len;
238
- int src_idx = NET_TX_PKT_PL_START_FRAG, dst_idx;
239
- size_t src_offset = 0;
240
+ size_t fragment_len;
241
+ size_t l4hdr_len;
242
+ size_t src_len;
243
+
244
+ int src_idx, dst_idx, pl_idx;
245
+ size_t src_offset;
246
size_t fragment_offset = 0;
247
struct virtio_net_hdr virt_hdr = {
248
.flags = pkt->virt_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM ?
249
VIRTIO_NET_HDR_F_DATA_VALID : 0
250
};
251
252
- l2_iov_base = pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_base;
253
- l2_iov_len = pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_len;
254
- l3_iov_base = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base;
255
- l3_iov_len = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len;
256
-
257
/* Copy headers */
258
fragment[NET_TX_PKT_VHDR_FRAG].iov_base = &virt_hdr;
259
fragment[NET_TX_PKT_VHDR_FRAG].iov_len = sizeof(virt_hdr);
260
- fragment[NET_TX_PKT_L2HDR_FRAG].iov_base = l2_iov_base;
261
- fragment[NET_TX_PKT_L2HDR_FRAG].iov_len = l2_iov_len;
262
- fragment[NET_TX_PKT_L3HDR_FRAG].iov_base = l3_iov_base;
263
- fragment[NET_TX_PKT_L3HDR_FRAG].iov_len = l3_iov_len;
264
+ fragment[NET_TX_PKT_L2HDR_FRAG] = pkt->vec[NET_TX_PKT_L2HDR_FRAG];
265
+ fragment[NET_TX_PKT_L3HDR_FRAG] = pkt->vec[NET_TX_PKT_L3HDR_FRAG];
266
267
+ switch (gso_type) {
268
+ case VIRTIO_NET_HDR_GSO_TCPV4:
269
+ case VIRTIO_NET_HDR_GSO_TCPV6:
270
+ if (!net_tx_pkt_tcp_fragment_init(pkt, fragment, &pl_idx, &l4hdr_len,
271
+ &src_idx, &src_offset, &src_len)) {
272
+ return false;
273
+ }
341
+ }
274
+ break;
342
vhost_vdpa_set_vring_ready(dev);
275
343
} else {
276
- /* Put as much data as possible and send */
344
vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
277
- do {
345
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_get_vring_base(struct vhost_dev *dev,
278
- fragment_len = net_tx_pkt_fetch_fragment(pkt, &src_idx, &src_offset,
346
static int vhost_vdpa_set_vring_kick(struct vhost_dev *dev,
279
- fragment, &dst_idx);
347
struct vhost_vring_file *file)
280
+ case VIRTIO_NET_HDR_GSO_UDP:
348
{
281
+ net_tx_pkt_do_sw_csum(pkt, &pkt->vec[NET_TX_PKT_L2HDR_FRAG],
349
- trace_vhost_vdpa_set_vring_kick(dev, file->index, file->fd);
282
+ pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - 1,
350
- return vhost_vdpa_call(dev, VHOST_SET_VRING_KICK, file);
283
+ pkt->payload_len);
351
+ struct vhost_vdpa *v = dev->opaque;
284
+ net_tx_pkt_udp_fragment_init(pkt, &pl_idx, &l4hdr_len,
352
+ int vdpa_idx = file->index - dev->vq_index;
285
+ &src_idx, &src_offset, &src_len);
353
+
286
+ break;
354
+ if (v->shadow_vqs_enabled) {
287
355
+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, vdpa_idx);
288
- more_frags = (fragment_offset + fragment_len < pkt->payload_len);
356
+ vhost_svq_set_svq_kick_fd(svq, file->fd);
289
+ default:
357
+ return 0;
290
+ abort();
358
+ } else {
291
+ }
359
+ return vhost_vdpa_set_vring_dev_kick(dev, file);
292
360
+ }
293
- eth_setup_ip4_fragmentation(l2_iov_base, l2_iov_len, l3_iov_base,
361
}
294
- l3_iov_len, fragment_len, fragment_offset, more_frags);
362
295
+ /* Put as much data as possible and send */
363
static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
296
+ while (true) {
364
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
297
+ dst_idx = pl_idx;
298
+ fragment_len = net_tx_pkt_fetch_fragment(pkt,
299
+ &src_idx, &src_offset, src_len, fragment, &dst_idx);
300
+ if (!fragment_len) {
301
+ break;
302
+ }
303
304
- eth_fix_ip4_checksum(l3_iov_base, l3_iov_len);
305
+ switch (gso_type) {
306
+ case VIRTIO_NET_HDR_GSO_TCPV4:
307
+ case VIRTIO_NET_HDR_GSO_TCPV6:
308
+ net_tx_pkt_tcp_fragment_fix(pkt, fragment, fragment_len, gso_type);
309
+ net_tx_pkt_do_sw_csum(pkt, fragment + NET_TX_PKT_L2HDR_FRAG,
310
+ dst_idx - NET_TX_PKT_L2HDR_FRAG,
311
+ l4hdr_len + fragment_len);
312
+ break;
313
+
314
+ case VIRTIO_NET_HDR_GSO_UDP:
315
+ net_tx_pkt_udp_fragment_fix(pkt, fragment, fragment_offset,
316
+ fragment_len);
317
+ break;
318
+ }
319
320
callback(context,
321
fragment + NET_TX_PKT_L2HDR_FRAG, dst_idx - NET_TX_PKT_L2HDR_FRAG,
322
fragment + NET_TX_PKT_VHDR_FRAG, dst_idx - NET_TX_PKT_VHDR_FRAG);
323
324
+ if (gso_type == VIRTIO_NET_HDR_GSO_TCPV4 ||
325
+ gso_type == VIRTIO_NET_HDR_GSO_TCPV6) {
326
+ net_tx_pkt_tcp_fragment_advance(pkt, fragment, fragment_len,
327
+ gso_type);
328
+ }
329
+
330
fragment_offset += fragment_len;
331
+ }
332
333
- } while (fragment_len && more_frags);
334
+ if (gso_type == VIRTIO_NET_HDR_GSO_TCPV4 ||
335
+ gso_type == VIRTIO_NET_HDR_GSO_TCPV6) {
336
+ net_tx_pkt_tcp_fragment_deinit(fragment);
337
+ }
338
339
return true;
340
}
341
@@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_send_custom(struct NetTxPkt *pkt, bool offload,
342
{
343
assert(pkt);
344
345
- if (!offload && pkt->virt_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
346
- net_tx_pkt_do_sw_csum(pkt);
347
- }
348
-
349
/*
350
* Since underlying infrastructure does not support IP datagrams longer
351
* than 64K we should drop such packets and don't even try to send
352
@@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_send_custom(struct NetTxPkt *pkt, bool offload,
353
}
354
355
if (offload || pkt->virt_hdr.gso_type == VIRTIO_NET_HDR_GSO_NONE) {
356
+ if (!offload && pkt->virt_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
357
+ net_tx_pkt_do_sw_csum(pkt, &pkt->vec[NET_TX_PKT_L2HDR_FRAG],
358
+ pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - 1,
359
+ pkt->payload_len);
360
+ }
361
+
362
net_tx_pkt_fix_ip6_payload_len(pkt);
363
callback(context, pkt->vec + NET_TX_PKT_L2HDR_FRAG,
364
pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - NET_TX_PKT_L2HDR_FRAG,
365
diff --git a/include/net/eth.h b/include/net/eth.h
366
index XXXXXXX..XXXXXXX 100644
365
index XXXXXXX..XXXXXXX 100644
367
--- a/include/net/eth.h
366
--- a/include/hw/virtio/vhost-vdpa.h
368
+++ b/include/net/eth.h
367
+++ b/include/hw/virtio/vhost-vdpa.h
369
@@ -XXX,XX +XXX,XX @@ void eth_get_protocols(const struct iovec *iov, int iovcnt,
368
@@ -XXX,XX +XXX,XX @@
370
eth_ip4_hdr_info *ip4hdr_info,
369
#ifndef HW_VIRTIO_VHOST_VDPA_H
371
eth_l4_hdr_info *l4hdr_info);
370
#define HW_VIRTIO_VHOST_VDPA_H
372
371
373
-void eth_setup_ip4_fragmentation(const void *l2hdr, size_t l2hdr_len,
372
+#include <gmodule.h>
374
- void *l3hdr, size_t l3hdr_len,
373
+
375
- size_t l3payload_len,
374
#include "hw/virtio/virtio.h"
376
- size_t frag_offset, bool more_frags);
375
#include "standard-headers/linux/vhost_types.h"
377
-
376
378
void
377
@@ -XXX,XX +XXX,XX @@ typedef struct vhost_vdpa {
379
eth_fix_ip4_checksum(void *l3hdr, size_t l3hdr_len);
378
bool iotlb_batch_begin_sent;
380
379
MemoryListener listener;
381
diff --git a/net/eth.c b/net/eth.c
380
struct vhost_vdpa_iova_range iova_range;
382
index XXXXXXX..XXXXXXX 100644
381
+ bool shadow_vqs_enabled;
383
--- a/net/eth.c
382
+ GPtrArray *shadow_vqs;
384
+++ b/net/eth.c
383
struct vhost_dev *dev;
385
@@ -XXX,XX +XXX,XX @@ eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, size_t iovoff,
384
VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
386
}
385
} VhostVDPA;
387
388
void
389
-eth_setup_ip4_fragmentation(const void *l2hdr, size_t l2hdr_len,
390
- void *l3hdr, size_t l3hdr_len,
391
- size_t l3payload_len,
392
- size_t frag_offset, bool more_frags)
393
-{
394
- const struct iovec l2vec = {
395
- .iov_base = (void *) l2hdr,
396
- .iov_len = l2hdr_len
397
- };
398
-
399
- if (eth_get_l3_proto(&l2vec, 1, l2hdr_len) == ETH_P_IP) {
400
- uint16_t orig_flags;
401
- struct ip_header *iphdr = (struct ip_header *) l3hdr;
402
- uint16_t frag_off_units = frag_offset / IP_FRAG_UNIT_SIZE;
403
- uint16_t new_ip_off;
404
-
405
- assert(frag_offset % IP_FRAG_UNIT_SIZE == 0);
406
- assert((frag_off_units & ~IP_OFFMASK) == 0);
407
-
408
- orig_flags = be16_to_cpu(iphdr->ip_off) & ~(IP_OFFMASK|IP_MF);
409
- new_ip_off = frag_off_units | orig_flags | (more_frags ? IP_MF : 0);
410
- iphdr->ip_off = cpu_to_be16(new_ip_off);
411
- iphdr->ip_len = cpu_to_be16(l3payload_len + l3hdr_len);
412
- }
413
-}
414
-
415
-void
416
eth_fix_ip4_checksum(void *l3hdr, size_t l3hdr_len)
417
{
418
struct ip_header *iphdr = (struct ip_header *) l3hdr;
419
--
386
--
420
2.7.4
387
2.7.4
388
389
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
net_tx_pkt_build_vheader() inspects TCP header but had no check for
3
This will make qemu aware of the device used buffers, allowing it to
4
the header size, resulting in an undefined behavior. Check the header
4
write the guest memory with its contents if needed.
5
size and drop the packet if the header is too small.
6
5
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
7
Acked-by: Michael S. Tsirkin <mst@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
9
---
10
hw/net/e1000e_core.c | 19 ++++++++++++++-----
10
hw/virtio/vhost-shadow-virtqueue.c | 38 ++++++++++++++++++++++++++++++++++++++
11
hw/net/net_tx_pkt.c | 13 ++++++++++---
11
hw/virtio/vhost-shadow-virtqueue.h | 4 ++++
12
hw/net/net_tx_pkt.h | 3 ++-
12
hw/virtio/vhost-vdpa.c | 31 +++++++++++++++++++++++++++++--
13
hw/net/vmxnet3.c | 14 +++++++-------
13
3 files changed, 71 insertions(+), 2 deletions(-)
14
4 files changed, 33 insertions(+), 16 deletions(-)
15
14
16
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
15
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/e1000e_core.c
17
--- a/hw/virtio/vhost-shadow-virtqueue.c
19
+++ b/hw/net/e1000e_core.c
18
+++ b/hw/virtio/vhost-shadow-virtqueue.c
20
@@ -XXX,XX +XXX,XX @@ e1000e_rss_parse_packet(E1000ECore *core,
19
@@ -XXX,XX +XXX,XX @@ static void vhost_handle_guest_kick(EventNotifier *n)
21
info->queue = E1000_RSS_QUEUE(&core->mac[RETA], info->hash);
22
}
20
}
23
21
24
-static void
22
/**
25
+static bool
23
+ * Forward vhost notifications
26
e1000e_setup_tx_offloads(E1000ECore *core, struct e1000e_tx *tx)
24
+ *
27
{
25
+ * @n: hdev call event notifier, the one that device set to notify svq.
28
if (tx->props.tse && tx->cptse) {
26
+ */
29
- net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->props.mss);
27
+static void vhost_svq_handle_call(EventNotifier *n)
30
+ if (!net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->props.mss)) {
28
+{
31
+ return false;
29
+ VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue,
32
+ }
30
+ hdev_call);
31
+ event_notifier_test_and_clear(n);
32
+ event_notifier_set(&svq->svq_call);
33
+}
33
+
34
+
34
net_tx_pkt_update_ip_checksums(tx->tx_pkt);
35
+/**
35
e1000x_inc_reg_if_not_full(core->mac, TSCTC);
36
+ * Set the call notifier for the SVQ to call the guest
36
- return;
37
+ *
37
+ return true;
38
+ * @svq: Shadow virtqueue
39
+ * @call_fd: call notifier
40
+ *
41
+ * Called on BQL context.
42
+ */
43
+void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd)
44
+{
45
+ if (call_fd == VHOST_FILE_UNBIND) {
46
+ /*
47
+ * Fail event_notifier_set if called handling device call.
48
+ *
49
+ * SVQ still needs device notifications, since it needs to keep
50
+ * forwarding used buffers even with the unbind.
51
+ */
52
+ memset(&svq->svq_call, 0, sizeof(svq->svq_call));
53
+ } else {
54
+ event_notifier_init_fd(&svq->svq_call, call_fd);
55
+ }
56
+}
57
+
58
+/**
59
* Set a new file descriptor for the guest to kick the SVQ and notify for avail
60
*
61
* @svq: The svq
62
@@ -XXX,XX +XXX,XX @@ VhostShadowVirtqueue *vhost_svq_new(void)
38
}
63
}
39
64
40
if (tx->sum_needed & E1000_TXD_POPTS_TXSM) {
65
event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND);
41
- net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0);
66
+ event_notifier_set_handler(&svq->hdev_call, vhost_svq_handle_call);
42
+ if (!net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0)) {
67
return g_steal_pointer(&svq);
43
+ return false;
68
44
+ }
69
err_init_hdev_call:
45
}
70
@@ -XXX,XX +XXX,XX @@ void vhost_svq_free(gpointer pvq)
46
71
VhostShadowVirtqueue *vq = pvq;
47
if (tx->sum_needed & E1000_TXD_POPTS_IXSM) {
72
vhost_svq_stop(vq);
48
net_tx_pkt_update_ip_hdr_checksum(tx->tx_pkt);
73
event_notifier_cleanup(&vq->hdev_kick);
49
}
74
+ event_notifier_set_handler(&vq->hdev_call, NULL);
75
event_notifier_cleanup(&vq->hdev_call);
76
g_free(vq);
77
}
78
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
79
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/virtio/vhost-shadow-virtqueue.h
81
+++ b/hw/virtio/vhost-shadow-virtqueue.h
82
@@ -XXX,XX +XXX,XX @@ typedef struct VhostShadowVirtqueue {
83
* So shadow virtqueue must not clean it, or we would lose VirtQueue one.
84
*/
85
EventNotifier svq_kick;
50
+
86
+
51
+ return true;
87
+ /* Guest's call notifier, where the SVQ calls guest. */
88
+ EventNotifier svq_call;
89
} VhostShadowVirtqueue;
90
91
void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd);
92
+void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd);
93
94
void vhost_svq_stop(VhostShadowVirtqueue *svq);
95
96
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/hw/virtio/vhost-vdpa.c
99
+++ b/hw/virtio/vhost-vdpa.c
100
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_set_vring_dev_kick(struct vhost_dev *dev,
101
return vhost_vdpa_call(dev, VHOST_SET_VRING_KICK, file);
52
}
102
}
53
103
54
static bool
104
+static int vhost_vdpa_set_vring_dev_call(struct vhost_dev *dev,
55
@@ -XXX,XX +XXX,XX @@ e1000e_tx_pkt_send(E1000ECore *core, struct e1000e_tx *tx, int queue_index)
105
+ struct vhost_vring_file *file)
56
int target_queue = MIN(core->max_queue_num, queue_index);
106
+{
57
NetClientState *queue = qemu_get_subqueue(core->owner_nic, target_queue);
107
+ trace_vhost_vdpa_set_vring_call(dev, file->index, file->fd);
58
108
+ return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
59
- e1000e_setup_tx_offloads(core, tx);
109
+}
60
+ if (!e1000e_setup_tx_offloads(core, tx)) {
110
+
111
/**
112
* Set the shadow virtqueue descriptors to the device
113
*
114
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_set_vring_dev_kick(struct vhost_dev *dev,
115
* @svq: The shadow virtqueue
116
* @idx: The index of the virtqueue in the vhost device
117
* @errp: Error
118
+ *
119
+ * Note that this function does not rewind kick file descriptor if cannot set
120
+ * call one.
121
*/
122
static bool vhost_vdpa_svq_setup(struct vhost_dev *dev,
123
VhostShadowVirtqueue *svq, unsigned idx,
124
@@ -XXX,XX +XXX,XX @@ static bool vhost_vdpa_svq_setup(struct vhost_dev *dev,
125
r = vhost_vdpa_set_vring_dev_kick(dev, &file);
126
if (unlikely(r != 0)) {
127
error_setg_errno(errp, -r, "Can't set device kick fd");
61
+ return false;
128
+ return false;
62
+ }
129
+ }
63
130
+
64
net_tx_pkt_dump(tx->tx_pkt);
131
+ event_notifier = &svq->hdev_call;
65
132
+ file.fd = event_notifier_get_fd(event_notifier);
66
diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
133
+ r = vhost_vdpa_set_vring_dev_call(dev, &file);
67
index XXXXXXX..XXXXXXX 100644
134
+ if (unlikely(r != 0)) {
68
--- a/hw/net/net_tx_pkt.c
135
+ error_setg_errno(errp, -r, "Can't set device call fd");
69
+++ b/hw/net/net_tx_pkt.c
136
}
70
@@ -XXX,XX +XXX,XX @@ func_exit:
137
71
return rc;
138
return r == 0;
139
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_set_vring_kick(struct vhost_dev *dev,
140
static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
141
struct vhost_vring_file *file)
142
{
143
- trace_vhost_vdpa_set_vring_call(dev, file->index, file->fd);
144
- return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
145
+ struct vhost_vdpa *v = dev->opaque;
146
+
147
+ if (v->shadow_vqs_enabled) {
148
+ int vdpa_idx = file->index - dev->vq_index;
149
+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, vdpa_idx);
150
+
151
+ vhost_svq_set_svq_call_fd(svq, file->fd);
152
+ return 0;
153
+ } else {
154
+ return vhost_vdpa_set_vring_dev_call(dev, file);
155
+ }
72
}
156
}
73
157
74
-void net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
158
static int vhost_vdpa_get_features(struct vhost_dev *dev,
75
+bool net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
76
bool csum_enable, uint32_t gso_size)
77
{
78
struct tcp_hdr l4hdr;
79
+ size_t bytes_read;
80
assert(pkt);
81
82
/* csum has to be enabled if tso is. */
83
@@ -XXX,XX +XXX,XX @@ void net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
84
85
case VIRTIO_NET_HDR_GSO_TCPV4:
86
case VIRTIO_NET_HDR_GSO_TCPV6:
87
- iov_to_buf(&pkt->vec[NET_TX_PKT_PL_START_FRAG], pkt->payload_frags,
88
- 0, &l4hdr, sizeof(l4hdr));
89
+ bytes_read = iov_to_buf(&pkt->vec[NET_TX_PKT_PL_START_FRAG],
90
+ pkt->payload_frags, 0, &l4hdr, sizeof(l4hdr));
91
+ if (bytes_read < sizeof(l4hdr)) {
92
+ return false;
93
+ }
94
+
95
pkt->virt_hdr.hdr_len = pkt->hdr_len + l4hdr.th_off * sizeof(uint32_t);
96
pkt->virt_hdr.gso_size = gso_size;
97
break;
98
@@ -XXX,XX +XXX,XX @@ void net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
99
break;
100
}
101
}
102
+
103
+ return true;
104
}
105
106
void net_tx_pkt_setup_vlan_header_ex(struct NetTxPkt *pkt,
107
diff --git a/hw/net/net_tx_pkt.h b/hw/net/net_tx_pkt.h
108
index XXXXXXX..XXXXXXX 100644
109
--- a/hw/net/net_tx_pkt.h
110
+++ b/hw/net/net_tx_pkt.h
111
@@ -XXX,XX +XXX,XX @@ struct virtio_net_hdr *net_tx_pkt_get_vhdr(struct NetTxPkt *pkt);
112
* @tso_enable: TSO enabled
113
* @csum_enable: CSO enabled
114
* @gso_size: MSS size for TSO
115
+ * @ret: operation result
116
*
117
*/
118
-void net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
119
+bool net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
120
bool csum_enable, uint32_t gso_size);
121
122
/**
123
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
124
index XXXXXXX..XXXXXXX 100644
125
--- a/hw/net/vmxnet3.c
126
+++ b/hw/net/vmxnet3.c
127
@@ -XXX,XX +XXX,XX @@ vmxnet3_setup_tx_offloads(VMXNET3State *s)
128
{
129
switch (s->offload_mode) {
130
case VMXNET3_OM_NONE:
131
- net_tx_pkt_build_vheader(s->tx_pkt, false, false, 0);
132
- break;
133
+ return net_tx_pkt_build_vheader(s->tx_pkt, false, false, 0);
134
135
case VMXNET3_OM_CSUM:
136
- net_tx_pkt_build_vheader(s->tx_pkt, false, true, 0);
137
VMW_PKPRN("L4 CSO requested\n");
138
- break;
139
+ return net_tx_pkt_build_vheader(s->tx_pkt, false, true, 0);
140
141
case VMXNET3_OM_TSO:
142
- net_tx_pkt_build_vheader(s->tx_pkt, true, true,
143
- s->cso_or_gso_size);
144
- net_tx_pkt_update_ip_checksums(s->tx_pkt);
145
VMW_PKPRN("GSO offload requested.");
146
+ if (!net_tx_pkt_build_vheader(s->tx_pkt, true, true,
147
+ s->cso_or_gso_size)) {
148
+ return false;
149
+ }
150
+ net_tx_pkt_update_ip_checksums(s->tx_pkt);
151
break;
152
153
default:
154
--
159
--
155
2.7.4
160
2.7.4
161
162
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
3
This allows SVQ to negotiate features with the guest and the device. For
4
Reviewed-by: Cédric Le Goater <clg@redhat.com>
4
the device, SVQ is a driver. While this function bypasses all
5
non-transport features, it needs to disable the features that SVQ does
6
not support when forwarding buffers. This includes packed vq layout,
7
indirect descriptors or event idx.
8
9
Future changes can add support to offer more features to the guest,
10
since the use of VirtQueue gives this for free. This is left out at the
11
moment for simplicity.
12
13
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
14
Acked-by: Michael S. Tsirkin <mst@redhat.com>
5
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
Signed-off-by: Jason Wang <jasowang@redhat.com>
6
---
16
---
7
MAINTAINERS | 1 +
17
hw/virtio/vhost-shadow-virtqueue.c | 44 ++++++++++++++++++++++++++++++++++++++
8
docs/system/device-emulation.rst | 1 +
18
hw/virtio/vhost-shadow-virtqueue.h | 2 ++
9
docs/system/devices/igb.rst | 71 ++++++++++++++++++++++++++++++++++++++++
19
hw/virtio/vhost-vdpa.c | 15 +++++++++++++
10
3 files changed, 73 insertions(+)
20
3 files changed, 61 insertions(+)
11
create mode 100644 docs/system/devices/igb.rst
12
21
13
diff --git a/MAINTAINERS b/MAINTAINERS
22
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/MAINTAINERS
24
--- a/hw/virtio/vhost-shadow-virtqueue.c
16
+++ b/MAINTAINERS
25
+++ b/hw/virtio/vhost-shadow-virtqueue.c
17
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/libqos/e1000e.*
26
@@ -XXX,XX +XXX,XX @@
18
igb
27
#include "hw/virtio/vhost-shadow-virtqueue.h"
19
M: Akihiko Odaki <akihiko.odaki@daynix.com>
28
20
S: Maintained
29
#include "qemu/error-report.h"
21
+F: docs/system/devices/igb.rst
30
+#include "qapi/error.h"
22
F: hw/net/igb*
31
#include "qemu/main-loop.h"
23
F: tests/avocado/igb.py
32
#include "linux-headers/linux/vhost.h"
24
F: tests/qtest/igb-test.c
33
25
diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulation.rst
34
/**
35
+ * Validate the transport device features that both guests can use with the SVQ
36
+ * and SVQs can use with the device.
37
+ *
38
+ * @dev_features: The features
39
+ * @errp: Error pointer
40
+ */
41
+bool vhost_svq_valid_features(uint64_t features, Error **errp)
42
+{
43
+ bool ok = true;
44
+ uint64_t svq_features = features;
45
+
46
+ for (uint64_t b = VIRTIO_TRANSPORT_F_START; b <= VIRTIO_TRANSPORT_F_END;
47
+ ++b) {
48
+ switch (b) {
49
+ case VIRTIO_F_ANY_LAYOUT:
50
+ continue;
51
+
52
+ case VIRTIO_F_ACCESS_PLATFORM:
53
+ /* SVQ trust in the host's IOMMU to translate addresses */
54
+ case VIRTIO_F_VERSION_1:
55
+ /* SVQ trust that the guest vring is little endian */
56
+ if (!(svq_features & BIT_ULL(b))) {
57
+ svq_features |= BIT_ULL(b);
58
+ ok = false;
59
+ }
60
+ continue;
61
+
62
+ default:
63
+ if (svq_features & BIT_ULL(b)) {
64
+ svq_features &= ~BIT_ULL(b);
65
+ ok = false;
66
+ }
67
+ }
68
+ }
69
+
70
+ if (!ok) {
71
+ error_setg(errp, "SVQ Invalid device feature flags, offer: 0x%"PRIx64
72
+ ", ok: 0x%"PRIx64, features, svq_features);
73
+ }
74
+ return ok;
75
+}
76
+
77
+/**
78
* Forward guest notifications.
79
*
80
* @n: guest kick event notifier, the one that guest set to notify svq.
81
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
26
index XXXXXXX..XXXXXXX 100644
82
index XXXXXXX..XXXXXXX 100644
27
--- a/docs/system/device-emulation.rst
83
--- a/hw/virtio/vhost-shadow-virtqueue.h
28
+++ b/docs/system/device-emulation.rst
84
+++ b/hw/virtio/vhost-shadow-virtqueue.h
29
@@ -XXX,XX +XXX,XX @@ Emulated Devices
85
@@ -XXX,XX +XXX,XX @@ typedef struct VhostShadowVirtqueue {
30
devices/virtio-pmem.rst
86
EventNotifier svq_call;
31
devices/vhost-user-rng.rst
87
} VhostShadowVirtqueue;
32
devices/canokey.rst
88
33
+ devices/igb.rst
89
+bool vhost_svq_valid_features(uint64_t features, Error **errp);
34
diff --git a/docs/system/devices/igb.rst b/docs/system/devices/igb.rst
35
new file mode 100644
36
index XXXXXXX..XXXXXXX
37
--- /dev/null
38
+++ b/docs/system/devices/igb.rst
39
@@ -XXX,XX +XXX,XX @@
40
+.. SPDX-License-Identifier: GPL-2.0-or-later
41
+.. _igb:
42
+
90
+
43
+igb
91
void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd);
44
+---
92
void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd);
93
94
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/hw/virtio/vhost-vdpa.c
97
+++ b/hw/virtio/vhost-vdpa.c
98
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v,
99
Error **errp)
100
{
101
g_autoptr(GPtrArray) shadow_vqs = NULL;
102
+ uint64_t dev_features, svq_features;
103
+ int r;
104
+ bool ok;
105
106
if (!v->shadow_vqs_enabled) {
107
return 0;
108
}
109
110
+ r = hdev->vhost_ops->vhost_get_features(hdev, &dev_features);
111
+ if (r != 0) {
112
+ error_setg_errno(errp, -r, "Can't get vdpa device features");
113
+ return r;
114
+ }
45
+
115
+
46
+igb is a family of Intel's gigabit ethernet controllers. In QEMU, 82576
116
+ svq_features = dev_features;
47
+emulation is implemented in particular. Its datasheet is available at [1]_.
117
+ ok = vhost_svq_valid_features(svq_features, errp);
118
+ if (unlikely(!ok)) {
119
+ return -1;
120
+ }
48
+
121
+
49
+This implementation is expected to be useful to test SR-IOV networking without
122
shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free);
50
+requiring physical hardware.
123
for (unsigned n = 0; n < hdev->nvqs; ++n) {
51
+
124
g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new();
52
+Limitations
53
+===========
54
+
55
+This igb implementation was tested with Linux Test Project [2]_ and Windows HLK
56
+[3]_ during the initial development. The command used when testing with LTP is:
57
+
58
+.. code-block:: shell
59
+
60
+ network.sh -6mta
61
+
62
+Be aware that this implementation lacks many functionalities available with the
63
+actual hardware, and you may experience various failures if you try to use it
64
+with a different operating system other than Linux and Windows or if you try
65
+functionalities not covered by the tests.
66
+
67
+Using igb
68
+=========
69
+
70
+Using igb should be nothing different from using another network device. See
71
+:ref:`pcsys_005fnetwork` in general.
72
+
73
+However, you may also need to perform additional steps to activate SR-IOV
74
+feature on your guest. For Linux, refer to [4]_.
75
+
76
+Developing igb
77
+==============
78
+
79
+igb is the successor of e1000e, and e1000e is the successor of e1000 in turn.
80
+As these devices are very similar, if you make a change for igb and the same
81
+change can be applied to e1000e and e1000, please do so.
82
+
83
+Please do not forget to run tests before submitting a change. As tests included
84
+in QEMU is very minimal, run some application which is likely to be affected by
85
+the change to confirm it works in an integrated system.
86
+
87
+Testing igb
88
+===========
89
+
90
+A qtest of the basic functionality is available. Run the below at the build
91
+directory:
92
+
93
+.. code-block:: shell
94
+
95
+ meson test qtest-x86_64/qos-test
96
+
97
+ethtool can test register accesses, interrupts, etc. It is automated as an
98
+Avocado test and can be ran with the following command:
99
+
100
+.. code:: shell
101
+
102
+ make check-avocado AVOCADO_TESTS=tests/avocado/igb.py
103
+
104
+References
105
+==========
106
+
107
+.. [1] https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82576eb-gigabit-ethernet-controller-datasheet.pdf
108
+.. [2] https://github.com/linux-test-project/ltp
109
+.. [3] https://learn.microsoft.com/en-us/windows-hardware/test/hlk/
110
+.. [4] https://docs.kernel.org/PCI/pci-iov-howto.html
111
--
125
--
112
2.7.4
126
2.7.4
113
127
114
128
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
This is part of recent efforts of refactoring e1000 and e1000e.
3
It reports the shadow virtqueue address from qemu virtual address space.
4
4
5
DeviceClass's reset member is deprecated so migrate to ResettableClass.
5
Since this will be different from the guest's vaddr, but the device can
6
There is no behavioral difference.
6
access it, SVQ takes special care about its alignment & lack of garbage
7
data. It assumes that IOMMU will work in host_page_size ranges for that.
7
8
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Acked-by: Michael S. Tsirkin <mst@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
12
---
13
hw/net/e1000e.c | 10 ++++++----
13
hw/virtio/vhost-shadow-virtqueue.c | 29 +++++++++++++++++++++++++++++
14
hw/net/trace-events | 2 +-
14
hw/virtio/vhost-shadow-virtqueue.h | 9 +++++++++
15
2 files changed, 7 insertions(+), 5 deletions(-)
15
2 files changed, 38 insertions(+)
16
16
17
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
17
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/net/e1000e.c
19
--- a/hw/virtio/vhost-shadow-virtqueue.c
20
+++ b/hw/net/e1000e.c
20
+++ b/hw/virtio/vhost-shadow-virtqueue.c
21
@@ -XXX,XX +XXX,XX @@ static void e1000e_pci_uninit(PCIDevice *pci_dev)
21
@@ -XXX,XX +XXX,XX @@ void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd)
22
msi_uninit(pci_dev);
23
}
22
}
24
23
25
-static void e1000e_qdev_reset(DeviceState *dev)
24
/**
26
+static void e1000e_qdev_reset_hold(Object *obj)
25
+ * Get the shadow vq vring address.
27
{
26
+ * @svq: Shadow virtqueue
28
- E1000EState *s = E1000E(dev);
27
+ * @addr: Destination to store address
29
+ E1000EState *s = E1000E(obj);
28
+ */
30
29
+void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
31
- trace_e1000e_cb_qdev_reset();
30
+ struct vhost_vring_addr *addr)
32
+ trace_e1000e_cb_qdev_reset_hold();
31
+{
33
32
+ addr->desc_user_addr = (uint64_t)(intptr_t)svq->vring.desc;
34
e1000e_core_reset(&s->core);
33
+ addr->avail_user_addr = (uint64_t)(intptr_t)svq->vring.avail;
35
34
+ addr->used_user_addr = (uint64_t)(intptr_t)svq->vring.used;
36
@@ -XXX,XX +XXX,XX @@ static Property e1000e_properties[] = {
35
+}
37
static void e1000e_class_init(ObjectClass *class, void *data)
38
{
39
DeviceClass *dc = DEVICE_CLASS(class);
40
+ ResettableClass *rc = RESETTABLE_CLASS(class);
41
PCIDeviceClass *c = PCI_DEVICE_CLASS(class);
42
43
c->realize = e1000e_pci_realize;
44
@@ -XXX,XX +XXX,XX @@ static void e1000e_class_init(ObjectClass *class, void *data)
45
c->romfile = "efi-e1000e.rom";
46
c->class_id = PCI_CLASS_NETWORK_ETHERNET;
47
48
+ rc->phases.hold = e1000e_qdev_reset_hold;
49
+
36
+
50
dc->desc = "Intel 82574L GbE Controller";
37
+size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq)
51
- dc->reset = e1000e_qdev_reset;
38
+{
52
dc->vmsd = &e1000e_vmstate;
39
+ size_t desc_size = sizeof(vring_desc_t) * svq->vring.num;
53
40
+ size_t avail_size = offsetof(vring_avail_t, ring) +
54
e1000e_prop_disable_vnet = qdev_prop_uint8;
41
+ sizeof(uint16_t) * svq->vring.num;
55
diff --git a/hw/net/trace-events b/hw/net/trace-events
42
+
43
+ return ROUND_UP(desc_size + avail_size, qemu_real_host_page_size);
44
+}
45
+
46
+size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq)
47
+{
48
+ size_t used_size = offsetof(vring_used_t, ring) +
49
+ sizeof(vring_used_elem_t) * svq->vring.num;
50
+ return ROUND_UP(used_size, qemu_real_host_page_size);
51
+}
52
+
53
+/**
54
* Set a new file descriptor for the guest to kick the SVQ and notify for avail
55
*
56
* @svq: The svq
57
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
56
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/net/trace-events
59
--- a/hw/virtio/vhost-shadow-virtqueue.h
58
+++ b/hw/net/trace-events
60
+++ b/hw/virtio/vhost-shadow-virtqueue.h
59
@@ -XXX,XX +XXX,XX @@ e1000e_vm_state_stopped(void) "VM state is stopped"
61
@@ -XXX,XX +XXX,XX @@
60
# e1000e.c
62
#define VHOST_SHADOW_VIRTQUEUE_H
61
e1000e_cb_pci_realize(void) "E1000E PCI realize entry"
63
62
e1000e_cb_pci_uninit(void) "E1000E PCI unit entry"
64
#include "qemu/event_notifier.h"
63
-e1000e_cb_qdev_reset(void) "E1000E qdev reset entry"
65
+#include "hw/virtio/virtio.h"
64
+e1000e_cb_qdev_reset_hold(void) "E1000E qdev reset hold"
66
+#include "standard-headers/linux/vhost_types.h"
65
e1000e_cb_pre_save(void) "E1000E pre save entry"
67
66
e1000e_cb_post_load(void) "E1000E post load entry"
68
/* Shadow virtqueue to relay notifications */
69
typedef struct VhostShadowVirtqueue {
70
+ /* Shadow vring */
71
+ struct vring vring;
72
+
73
/* Shadow kick notifier, sent to vhost */
74
EventNotifier hdev_kick;
75
/* Shadow call notifier, sent to vhost */
76
@@ -XXX,XX +XXX,XX @@ bool vhost_svq_valid_features(uint64_t features, Error **errp);
77
78
void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd);
79
void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd);
80
+void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
81
+ struct vhost_vring_addr *addr);
82
+size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq);
83
+size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq);
84
85
void vhost_svq_stop(VhostShadowVirtqueue *svq);
67
86
68
--
87
--
69
2.7.4
88
2.7.4
70
89
71
90
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
hw/net/mii.h provides common definitions for MII.
3
First half of the buffers forwarding part, preparing vhost-vdpa
4
callbacks to SVQ to offer it. QEMU cannot enable it at this moment, so
5
this is effectively dead code at the moment, but it helps to reduce
6
patch size.
4
7
5
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Acked-by: Michael S. Tsirkin <mst@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
11
---
9
hw/net/e1000.c | 86 +++++++++++++++++++++----------------------
12
hw/virtio/vhost-vdpa.c | 48 +++++++++++++++++++++++++++++++++++++++++-------
10
hw/net/e1000_regs.h | 46 -----------------------
13
1 file changed, 41 insertions(+), 7 deletions(-)
11
hw/net/e1000e.c | 1 +
12
hw/net/e1000e_core.c | 99 +++++++++++++++++++++++++-------------------------
13
hw/net/e1000x_common.c | 5 ++-
14
hw/net/e1000x_common.h | 8 ++--
15
6 files changed, 101 insertions(+), 144 deletions(-)
16
14
17
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
15
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/net/e1000.c
17
--- a/hw/virtio/vhost-vdpa.c
20
+++ b/hw/net/e1000.c
18
+++ b/hw/virtio/vhost-vdpa.c
21
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_get_config(struct vhost_dev *dev, uint8_t *config,
22
20
return ret;
23
21
}
24
#include "qemu/osdep.h"
22
25
+#include "hw/net/mii.h"
23
+static int vhost_vdpa_set_dev_vring_base(struct vhost_dev *dev,
26
#include "hw/pci/pci_device.h"
24
+ struct vhost_vring_state *ring)
27
#include "hw/qdev-properties.h"
25
+{
28
#include "migration/vmstate.h"
26
+ trace_vhost_vdpa_set_vring_base(dev, ring->index, ring->num);
29
@@ -XXX,XX +XXX,XX @@ e1000_autoneg_done(E1000State *s)
27
+ return vhost_vdpa_call(dev, VHOST_SET_VRING_BASE, ring);
30
static bool
28
+}
31
have_autoneg(E1000State *s)
29
+
30
static int vhost_vdpa_set_vring_dev_kick(struct vhost_dev *dev,
31
struct vhost_vring_file *file)
32
{
32
{
33
- return chkflag(AUTONEG) && (s->phy_reg[PHY_CTRL] & MII_CR_AUTO_NEG_EN);
33
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_set_vring_dev_call(struct vhost_dev *dev,
34
+ return chkflag(AUTONEG) && (s->phy_reg[MII_BMCR] & MII_BMCR_AUTOEN);
34
return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
35
}
35
}
36
36
37
static void
37
+static int vhost_vdpa_set_vring_dev_addr(struct vhost_dev *dev,
38
set_phy_ctrl(E1000State *s, int index, uint16_t val)
38
+ struct vhost_vring_addr *addr)
39
+{
40
+ trace_vhost_vdpa_set_vring_addr(dev, addr->index, addr->flags,
41
+ addr->desc_user_addr, addr->used_user_addr,
42
+ addr->avail_user_addr,
43
+ addr->log_guest_addr);
44
+
45
+ return vhost_vdpa_call(dev, VHOST_SET_VRING_ADDR, addr);
46
+
47
+}
48
+
49
/**
50
* Set the shadow virtqueue descriptors to the device
51
*
52
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base,
53
static int vhost_vdpa_set_vring_addr(struct vhost_dev *dev,
54
struct vhost_vring_addr *addr)
39
{
55
{
40
- /* bits 0-5 reserved; MII_CR_[RESTART_AUTO_NEG,RESET] are self clearing */
56
- trace_vhost_vdpa_set_vring_addr(dev, addr->index, addr->flags,
41
- s->phy_reg[PHY_CTRL] = val & ~(0x3f |
57
- addr->desc_user_addr, addr->used_user_addr,
42
- MII_CR_RESET |
58
- addr->avail_user_addr,
43
- MII_CR_RESTART_AUTO_NEG);
59
- addr->log_guest_addr);
44
+ /* bits 0-5 reserved; MII_BMCR_[ANRESTART,RESET] are self clearing */
60
- return vhost_vdpa_call(dev, VHOST_SET_VRING_ADDR, addr);
45
+ s->phy_reg[MII_BMCR] = val & ~(0x3f |
61
+ struct vhost_vdpa *v = dev->opaque;
46
+ MII_BMCR_RESET |
62
+
47
+ MII_BMCR_ANRESTART);
63
+ if (v->shadow_vqs_enabled) {
48
64
+ /*
49
/*
65
+ * Device vring addr was set at device start. SVQ base is handled by
50
* QEMU 1.3 does not support link auto-negotiation emulation, so if we
66
+ * VirtQueue code.
51
* migrate during auto negotiation, after migration the link will be
67
+ */
52
* down.
68
+ return 0;
53
*/
69
+ }
54
- if (have_autoneg(s) && (val & MII_CR_RESTART_AUTO_NEG)) {
70
+
55
+ if (have_autoneg(s) && (val & MII_BMCR_ANRESTART)) {
71
+ return vhost_vdpa_set_vring_dev_addr(dev, addr);
56
e1000x_restart_autoneg(s->mac_reg, s->phy_reg, s->autoneg_timer);
57
}
58
}
72
}
59
73
60
static void (*phyreg_writeops[])(E1000State *, int, uint16_t) = {
74
static int vhost_vdpa_set_vring_num(struct vhost_dev *dev,
61
- [PHY_CTRL] = set_phy_ctrl,
75
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_set_vring_num(struct vhost_dev *dev,
62
+ [MII_BMCR] = set_phy_ctrl,
76
static int vhost_vdpa_set_vring_base(struct vhost_dev *dev,
63
};
77
struct vhost_vring_state *ring)
64
78
{
65
enum { NPHYWRITEOPS = ARRAY_SIZE(phyreg_writeops) };
79
- trace_vhost_vdpa_set_vring_base(dev, ring->index, ring->num);
66
80
- return vhost_vdpa_call(dev, VHOST_SET_VRING_BASE, ring);
67
enum { PHY_R = 1, PHY_W = 2, PHY_RW = PHY_R | PHY_W };
81
+ struct vhost_vdpa *v = dev->opaque;
68
static const char phy_regcap[0x20] = {
69
- [PHY_STATUS] = PHY_R, [M88E1000_EXT_PHY_SPEC_CTRL] = PHY_RW,
70
- [PHY_ID1] = PHY_R, [M88E1000_PHY_SPEC_CTRL] = PHY_RW,
71
- [PHY_CTRL] = PHY_RW, [PHY_1000T_CTRL] = PHY_RW,
72
- [PHY_LP_ABILITY] = PHY_R, [PHY_1000T_STATUS] = PHY_R,
73
- [PHY_AUTONEG_ADV] = PHY_RW, [M88E1000_RX_ERR_CNTR] = PHY_R,
74
- [PHY_ID2] = PHY_R, [M88E1000_PHY_SPEC_STATUS] = PHY_R,
75
- [PHY_AUTONEG_EXP] = PHY_R,
76
+ [MII_BMSR] = PHY_R, [M88E1000_EXT_PHY_SPEC_CTRL] = PHY_RW,
77
+ [MII_PHYID1] = PHY_R, [M88E1000_PHY_SPEC_CTRL] = PHY_RW,
78
+ [MII_BMCR] = PHY_RW, [MII_CTRL1000] = PHY_RW,
79
+ [MII_ANLPAR] = PHY_R, [MII_STAT1000] = PHY_R,
80
+ [MII_ANAR] = PHY_RW, [M88E1000_RX_ERR_CNTR] = PHY_R,
81
+ [MII_PHYID2] = PHY_R, [M88E1000_PHY_SPEC_STATUS] = PHY_R,
82
+ [MII_ANER] = PHY_R,
83
};
84
85
-/* PHY_ID2 documented in 8254x_GBe_SDM.pdf, pp. 250 */
86
+/* MII_PHYID2 documented in 8254x_GBe_SDM.pdf, pp. 250 */
87
static const uint16_t phy_reg_init[] = {
88
- [PHY_CTRL] = MII_CR_SPEED_SELECT_MSB |
89
- MII_CR_FULL_DUPLEX |
90
- MII_CR_AUTO_NEG_EN,
91
-
92
- [PHY_STATUS] = MII_SR_EXTENDED_CAPS |
93
- MII_SR_LINK_STATUS | /* link initially up */
94
- MII_SR_AUTONEG_CAPS |
95
- /* MII_SR_AUTONEG_COMPLETE: initially NOT completed */
96
- MII_SR_PREAMBLE_SUPPRESS |
97
- MII_SR_EXTENDED_STATUS |
98
- MII_SR_10T_HD_CAPS |
99
- MII_SR_10T_FD_CAPS |
100
- MII_SR_100X_HD_CAPS |
101
- MII_SR_100X_FD_CAPS,
102
-
103
- [PHY_ID1] = 0x141,
104
- /* [PHY_ID2] configured per DevId, from e1000_reset() */
105
- [PHY_AUTONEG_ADV] = 0xde1,
106
- [PHY_LP_ABILITY] = 0x1e0,
107
- [PHY_1000T_CTRL] = 0x0e00,
108
- [PHY_1000T_STATUS] = 0x3c00,
109
+ [MII_BMCR] = MII_BMCR_SPEED1000 |
110
+ MII_BMCR_FD |
111
+ MII_BMCR_AUTOEN,
112
+
82
+
113
+ [MII_BMSR] = MII_BMSR_EXTCAP |
83
+ if (v->shadow_vqs_enabled) {
114
+ MII_BMSR_LINK_ST | /* link initially up */
84
+ /*
115
+ MII_BMSR_AUTONEG |
85
+ * Device vring base was set at device start. SVQ base is handled by
116
+ /* MII_BMSR_AN_COMP: initially NOT completed */
86
+ * VirtQueue code.
117
+ MII_BMSR_MFPS |
87
+ */
118
+ MII_BMSR_EXTSTAT |
88
+ return 0;
119
+ MII_BMSR_10T_HD |
89
+ }
120
+ MII_BMSR_10T_FD |
121
+ MII_BMSR_100TX_HD |
122
+ MII_BMSR_100TX_FD,
123
+
90
+
124
+ [MII_PHYID1] = 0x141,
91
+ return vhost_vdpa_set_dev_vring_base(dev, ring);
125
+ /* [MII_PHYID2] configured per DevId, from e1000_reset() */
126
+ [MII_ANAR] = 0xde1,
127
+ [MII_ANLPAR] = 0x1e0,
128
+ [MII_CTRL1000] = 0x0e00,
129
+ [MII_STAT1000] = 0x3c00,
130
[M88E1000_PHY_SPEC_CTRL] = 0x360,
131
[M88E1000_PHY_SPEC_STATUS] = 0xac00,
132
[M88E1000_EXT_PHY_SPEC_CTRL] = 0x0d60,
133
@@ -XXX,XX +XXX,XX @@ static void e1000_reset(void *opaque)
134
d->mit_ide = 0;
135
memset(d->phy_reg, 0, sizeof d->phy_reg);
136
memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init);
137
- d->phy_reg[PHY_ID2] = edc->phy_id2;
138
+ d->phy_reg[MII_PHYID2] = edc->phy_id2;
139
memset(d->mac_reg, 0, sizeof d->mac_reg);
140
memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init);
141
d->rxbuf_min_shift = 1;
142
@@ -XXX,XX +XXX,XX @@ e1000_send_packet(E1000State *s, const uint8_t *buf, int size)
143
PTC1023, PTC1522 };
144
145
NetClientState *nc = qemu_get_queue(s->nic);
146
- if (s->phy_reg[PHY_CTRL] & MII_CR_LOOPBACK) {
147
+ if (s->phy_reg[MII_BMCR] & MII_BMCR_LOOPBACK) {
148
qemu_receive_packet(nc, buf, size);
149
} else {
150
qemu_send_packet(nc, buf, size);
151
@@ -XXX,XX +XXX,XX @@ e1000_set_link_status(NetClientState *nc)
152
e1000x_update_regs_on_link_down(s->mac_reg, s->phy_reg);
153
} else {
154
if (have_autoneg(s) &&
155
- !(s->phy_reg[PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {
156
+ !(s->phy_reg[MII_BMSR] & MII_BMSR_AN_COMP)) {
157
e1000x_restart_autoneg(s->mac_reg, s->phy_reg, s->autoneg_timer);
158
} else {
159
e1000_link_up(s);
160
@@ -XXX,XX +XXX,XX @@ static int e1000_pre_save(void *opaque)
161
/*
162
* If link is down and auto-negotiation is supported and ongoing,
163
* complete auto-negotiation immediately. This allows us to look
164
- * at MII_SR_AUTONEG_COMPLETE to infer link status on load.
165
+ * at MII_BMSR_AN_COMP to infer link status on load.
166
*/
167
if (nc->link_down && have_autoneg(s)) {
168
- s->phy_reg[PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;
169
+ s->phy_reg[MII_BMSR] |= MII_BMSR_AN_COMP;
170
}
171
172
/* Decide which set of props to migrate in the main structure */
173
@@ -XXX,XX +XXX,XX @@ static int e1000_post_load(void *opaque, int version_id)
174
* Alternatively, restart link negotiation if it was in progress. */
175
nc->link_down = (s->mac_reg[STATUS] & E1000_STATUS_LU) == 0;
176
177
- if (have_autoneg(s) &&
178
- !(s->phy_reg[PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {
179
+ if (have_autoneg(s) && !(s->phy_reg[MII_BMSR] & MII_BMSR_AN_COMP)) {
180
nc->link_down = false;
181
timer_mod(s->autoneg_timer,
182
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
183
diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h
184
index XXXXXXX..XXXXXXX 100644
185
--- a/hw/net/e1000_regs.h
186
+++ b/hw/net/e1000_regs.h
187
@@ -XXX,XX +XXX,XX @@
188
#define E1000_TARC_ENABLE BIT(10)
189
190
/* PHY 1000 MII Register/Bit Definitions */
191
-/* PHY Registers defined by IEEE */
192
-#define PHY_CTRL 0x00 /* Control Register */
193
-#define PHY_STATUS 0x01 /* Status Regiser */
194
-#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
195
-#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
196
-#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
197
-#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */
198
-#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */
199
-#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */
200
-#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */
201
-#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */
202
-#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
203
-#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */
204
-
205
/* 82574-specific registers */
206
#define PHY_COPPER_CTRL1 0x10 /* Copper Specific Control Register 1 */
207
#define PHY_COPPER_STAT1 0x11 /* Copper Specific Status Register 1 */
208
@@ -XXX,XX +XXX,XX @@
209
#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */
210
#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */
211
212
-/* PHY Control Register */
213
-#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
214
-#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
215
-#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
216
-#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
217
-#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */
218
-#define MII_CR_POWER_DOWN 0x0800 /* Power down */
219
-#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
220
-#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
221
-#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
222
-#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
223
-
224
-/* PHY Status Register */
225
-#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
226
-#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
227
-#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
228
-#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
229
-#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
230
-#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
231
-#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
232
-#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
233
-#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
234
-#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
235
-#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
236
-#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
237
-#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
238
-#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
239
-#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
240
-
241
-/* PHY Link Partner Ability Register */
242
-#define MII_LPAR_LPACK 0x4000 /* Acked by link partner */
243
-
244
/* Interrupt Cause Read */
245
#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
246
#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
247
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
248
index XXXXXXX..XXXXXXX 100644
249
--- a/hw/net/e1000e.c
250
+++ b/hw/net/e1000e.c
251
@@ -XXX,XX +XXX,XX @@
252
#include "qemu/range.h"
253
#include "sysemu/sysemu.h"
254
#include "hw/hw.h"
255
+#include "hw/net/mii.h"
256
#include "hw/pci/msi.h"
257
#include "hw/pci/msix.h"
258
#include "hw/qdev-properties.h"
259
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
260
index XXXXXXX..XXXXXXX 100644
261
--- a/hw/net/e1000e_core.c
262
+++ b/hw/net/e1000e_core.c
263
@@ -XXX,XX +XXX,XX @@
264
#include "qemu/log.h"
265
#include "net/net.h"
266
#include "net/tap.h"
267
+#include "hw/net/mii.h"
268
#include "hw/pci/msi.h"
269
#include "hw/pci/msix.h"
270
#include "sysemu/runstate.h"
271
@@ -XXX,XX +XXX,XX @@ e1000e_tx_pkt_send(E1000ECore *core, struct e1000e_tx *tx, int queue_index)
272
273
net_tx_pkt_dump(tx->tx_pkt);
274
275
- if ((core->phy[0][PHY_CTRL] & MII_CR_LOOPBACK) ||
276
+ if ((core->phy[0][MII_BMCR] & MII_BMCR_LOOPBACK) ||
277
((core->mac[RCTL] & E1000_RCTL_LBM_MAC) == E1000_RCTL_LBM_MAC)) {
278
return net_tx_pkt_send_loopback(tx->tx_pkt, queue);
279
} else {
280
@@ -XXX,XX +XXX,XX @@ e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt)
281
static inline bool
282
e1000e_have_autoneg(E1000ECore *core)
283
{
284
- return core->phy[0][PHY_CTRL] & MII_CR_AUTO_NEG_EN;
285
+ return core->phy[0][MII_BMCR] & MII_BMCR_AUTOEN;
286
}
92
}
287
93
288
static void e1000e_update_flowctl_status(E1000ECore *core)
94
static int vhost_vdpa_get_vring_base(struct vhost_dev *dev,
289
{
290
if (e1000e_have_autoneg(core) &&
291
- core->phy[0][PHY_STATUS] & MII_SR_AUTONEG_COMPLETE) {
292
+ core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP) {
293
trace_e1000e_link_autoneg_flowctl(true);
294
core->mac[CTRL] |= E1000_CTRL_TFCE | E1000_CTRL_RFCE;
295
} else {
296
@@ -XXX,XX +XXX,XX @@ e1000e_link_down(E1000ECore *core)
297
static inline void
298
e1000e_set_phy_ctrl(E1000ECore *core, int index, uint16_t val)
299
{
300
- /* bits 0-5 reserved; MII_CR_[RESTART_AUTO_NEG,RESET] are self clearing */
301
- core->phy[0][PHY_CTRL] = val & ~(0x3f |
302
- MII_CR_RESET |
303
- MII_CR_RESTART_AUTO_NEG);
304
+ /* bits 0-5 reserved; MII_BMCR_[ANRESTART,RESET] are self clearing */
305
+ core->phy[0][MII_BMCR] = val & ~(0x3f |
306
+ MII_BMCR_RESET |
307
+ MII_BMCR_ANRESTART);
308
309
- if ((val & MII_CR_RESTART_AUTO_NEG) &&
310
+ if ((val & MII_BMCR_ANRESTART) &&
311
e1000e_have_autoneg(core)) {
312
e1000x_restart_autoneg(core->mac, core->phy[0], core->autoneg_timer);
313
}
314
@@ -XXX,XX +XXX,XX @@ e1000e_core_set_link_status(E1000ECore *core)
315
e1000x_update_regs_on_link_down(core->mac, core->phy[0]);
316
} else {
317
if (e1000e_have_autoneg(core) &&
318
- !(core->phy[0][PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {
319
+ !(core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP)) {
320
e1000x_restart_autoneg(core->mac, core->phy[0],
321
core->autoneg_timer);
322
} else {
323
@@ -XXX,XX +XXX,XX @@ static
324
void(*e1000e_phyreg_writeops[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE])
325
(E1000ECore *, int, uint16_t) = {
326
[0] = {
327
- [PHY_CTRL] = e1000e_set_phy_ctrl,
328
+ [MII_BMCR] = e1000e_set_phy_ctrl,
329
[PHY_PAGE] = e1000e_set_phy_page,
330
[PHY_OEM_BITS] = e1000e_set_phy_oem_bits
331
}
332
@@ -XXX,XX +XXX,XX @@ e1000e_get_reg_index_with_offset(const uint16_t *mac_reg_access, hwaddr addr)
333
334
static const char e1000e_phy_regcap[E1000E_PHY_PAGES][0x20] = {
335
[0] = {
336
- [PHY_CTRL] = PHY_ANYPAGE | PHY_RW,
337
- [PHY_STATUS] = PHY_ANYPAGE | PHY_R,
338
- [PHY_ID1] = PHY_ANYPAGE | PHY_R,
339
- [PHY_ID2] = PHY_ANYPAGE | PHY_R,
340
- [PHY_AUTONEG_ADV] = PHY_ANYPAGE | PHY_RW,
341
- [PHY_LP_ABILITY] = PHY_ANYPAGE | PHY_R,
342
- [PHY_AUTONEG_EXP] = PHY_ANYPAGE | PHY_R,
343
- [PHY_NEXT_PAGE_TX] = PHY_ANYPAGE | PHY_RW,
344
- [PHY_LP_NEXT_PAGE] = PHY_ANYPAGE | PHY_R,
345
- [PHY_1000T_CTRL] = PHY_ANYPAGE | PHY_RW,
346
- [PHY_1000T_STATUS] = PHY_ANYPAGE | PHY_R,
347
- [PHY_EXT_STATUS] = PHY_ANYPAGE | PHY_R,
348
- [PHY_PAGE] = PHY_ANYPAGE | PHY_RW,
349
+ [MII_BMCR] = PHY_ANYPAGE | PHY_RW,
350
+ [MII_BMSR] = PHY_ANYPAGE | PHY_R,
351
+ [MII_PHYID1] = PHY_ANYPAGE | PHY_R,
352
+ [MII_PHYID2] = PHY_ANYPAGE | PHY_R,
353
+ [MII_ANAR] = PHY_ANYPAGE | PHY_RW,
354
+ [MII_ANLPAR] = PHY_ANYPAGE | PHY_R,
355
+ [MII_ANER] = PHY_ANYPAGE | PHY_R,
356
+ [MII_ANNP] = PHY_ANYPAGE | PHY_RW,
357
+ [MII_ANLPRNP] = PHY_ANYPAGE | PHY_R,
358
+ [MII_CTRL1000] = PHY_ANYPAGE | PHY_RW,
359
+ [MII_STAT1000] = PHY_ANYPAGE | PHY_R,
360
+ [MII_EXTSTAT] = PHY_ANYPAGE | PHY_R,
361
+ [PHY_PAGE] = PHY_ANYPAGE | PHY_RW,
362
363
[PHY_COPPER_CTRL1] = PHY_RW,
364
[PHY_COPPER_STAT1] = PHY_R,
365
@@ -XXX,XX +XXX,XX @@ static void
366
e1000e_autoneg_resume(E1000ECore *core)
367
{
368
if (e1000e_have_autoneg(core) &&
369
- !(core->phy[0][PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {
370
+ !(core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP)) {
371
qemu_get_queue(core->owner_nic)->link_down = false;
372
timer_mod(core->autoneg_timer,
373
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
374
@@ -XXX,XX +XXX,XX @@ e1000e_core_pci_uninit(E1000ECore *core)
375
static const uint16_t
376
e1000e_phy_reg_init[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE] = {
377
[0] = {
378
- [PHY_CTRL] = MII_CR_SPEED_SELECT_MSB |
379
- MII_CR_FULL_DUPLEX |
380
- MII_CR_AUTO_NEG_EN,
381
-
382
- [PHY_STATUS] = MII_SR_EXTENDED_CAPS |
383
- MII_SR_LINK_STATUS |
384
- MII_SR_AUTONEG_CAPS |
385
- MII_SR_PREAMBLE_SUPPRESS |
386
- MII_SR_EXTENDED_STATUS |
387
- MII_SR_10T_HD_CAPS |
388
- MII_SR_10T_FD_CAPS |
389
- MII_SR_100X_HD_CAPS |
390
- MII_SR_100X_FD_CAPS,
391
-
392
- [PHY_ID1] = 0x141,
393
- [PHY_ID2] = E1000_PHY_ID2_82574x,
394
- [PHY_AUTONEG_ADV] = 0xde1,
395
- [PHY_LP_ABILITY] = 0x7e0,
396
- [PHY_AUTONEG_EXP] = BIT(2),
397
- [PHY_NEXT_PAGE_TX] = BIT(0) | BIT(13),
398
- [PHY_1000T_CTRL] = BIT(8) | BIT(9) | BIT(10) | BIT(11),
399
- [PHY_1000T_STATUS] = 0x3c00,
400
- [PHY_EXT_STATUS] = BIT(12) | BIT(13),
401
+ [MII_BMCR] = MII_BMCR_SPEED1000 |
402
+ MII_BMCR_FD |
403
+ MII_BMCR_AUTOEN,
404
+
405
+ [MII_BMSR] = MII_BMSR_EXTCAP |
406
+ MII_BMSR_LINK_ST |
407
+ MII_BMSR_AUTONEG |
408
+ MII_BMSR_MFPS |
409
+ MII_BMSR_EXTSTAT |
410
+ MII_BMSR_10T_HD |
411
+ MII_BMSR_10T_FD |
412
+ MII_BMSR_100TX_HD |
413
+ MII_BMSR_100TX_FD,
414
+
415
+ [MII_PHYID1] = 0x141,
416
+ [MII_PHYID2] = E1000_PHY_ID2_82574x,
417
+ [MII_ANAR] = 0xde1,
418
+ [MII_ANLPAR] = 0x7e0,
419
+ [MII_ANER] = BIT(2),
420
+ [MII_ANNP] = BIT(0) | BIT(13),
421
+ [MII_CTRL1000] = BIT(8) | BIT(9) | BIT(10) | BIT(11),
422
+ [MII_STAT1000] = 0x3c00,
423
+ [MII_EXTSTAT] = BIT(12) | BIT(13),
424
425
[PHY_COPPER_CTRL1] = BIT(5) | BIT(6) | BIT(8) | BIT(9) |
426
BIT(12) | BIT(13),
427
@@ -XXX,XX +XXX,XX @@ void e1000e_core_pre_save(E1000ECore *core)
428
/*
429
* If link is down and auto-negotiation is supported and ongoing,
430
* complete auto-negotiation immediately. This allows us to look
431
- * at MII_SR_AUTONEG_COMPLETE to infer link status on load.
432
+ * at MII_BMSR_AN_COMP to infer link status on load.
433
*/
434
if (nc->link_down && e1000e_have_autoneg(core)) {
435
- core->phy[0][PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;
436
+ core->phy[0][MII_BMSR] |= MII_BMSR_AN_COMP;
437
e1000e_update_flowctl_status(core);
438
}
439
440
diff --git a/hw/net/e1000x_common.c b/hw/net/e1000x_common.c
441
index XXXXXXX..XXXXXXX 100644
442
--- a/hw/net/e1000x_common.c
443
+++ b/hw/net/e1000x_common.c
444
@@ -XXX,XX +XXX,XX @@
445
446
#include "qemu/osdep.h"
447
#include "qemu/units.h"
448
+#include "hw/net/mii.h"
449
#include "hw/pci/pci_device.h"
450
#include "net/net.h"
451
452
@@ -XXX,XX +XXX,XX @@ void e1000x_reset_mac_addr(NICState *nic, uint32_t *mac_regs,
453
void e1000x_update_regs_on_autoneg_done(uint32_t *mac, uint16_t *phy)
454
{
455
e1000x_update_regs_on_link_up(mac, phy);
456
- phy[PHY_LP_ABILITY] |= MII_LPAR_LPACK;
457
- phy[PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;
458
+ phy[MII_ANLPAR] |= MII_ANLPAR_ACK;
459
+ phy[MII_BMSR] |= MII_BMSR_AN_COMP;
460
trace_e1000x_link_negotiation_done();
461
}
462
463
diff --git a/hw/net/e1000x_common.h b/hw/net/e1000x_common.h
464
index XXXXXXX..XXXXXXX 100644
465
--- a/hw/net/e1000x_common.h
466
+++ b/hw/net/e1000x_common.h
467
@@ -XXX,XX +XXX,XX @@ static inline void
468
e1000x_update_regs_on_link_down(uint32_t *mac, uint16_t *phy)
469
{
470
mac[STATUS] &= ~E1000_STATUS_LU;
471
- phy[PHY_STATUS] &= ~MII_SR_LINK_STATUS;
472
- phy[PHY_STATUS] &= ~MII_SR_AUTONEG_COMPLETE;
473
- phy[PHY_LP_ABILITY] &= ~MII_LPAR_LPACK;
474
+ phy[MII_BMSR] &= ~MII_BMSR_LINK_ST;
475
+ phy[MII_BMSR] &= ~MII_BMSR_AN_COMP;
476
+ phy[MII_ANLPAR] &= ~MII_ANLPAR_ACK;
477
}
478
479
static inline void
480
e1000x_update_regs_on_link_up(uint32_t *mac, uint16_t *phy)
481
{
482
mac[STATUS] |= E1000_STATUS_LU;
483
- phy[PHY_STATUS] |= MII_SR_LINK_STATUS;
484
+ phy[MII_BMSR] |= MII_BMSR_LINK_ST;
485
}
486
487
void e1000x_update_rx_total_stats(uint32_t *mac,
488
--
95
--
489
2.7.4
96
2.7.4
490
97
491
98
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
e1000e didn't perform software segmentation for loopback if virtio-net
3
Initial version of shadow virtqueue that actually forward buffers. There
4
header is enabled, which is wrong.
4
is no iommu support at the moment, and that will be addressed in future
5
5
patches of this series. Since all vhost-vdpa devices use forced IOMMU,
6
To fix the problem, introduce net_tx_pkt_send_custom(), which allows the
6
this means that SVQ is not usable at this point of the series on any
7
caller to specify whether offloading should be assumed or not.
7
device.
8
8
9
net_tx_pkt_send_custom() also allows the caller to provide a custom
9
For simplicity it only supports modern devices, that expects vring
10
sending function. Packets with virtio-net headers and ones without
10
in little endian, with split ring and no event idx or indirect
11
virtio-net headers will be provided at the same time so the function
11
descriptors. Support for them will not be added in this series.
12
can choose the preferred version. In case of e1000e loopback, it prefers
12
13
to have virtio-net headers as they allows to skip the checksum
13
It reuses the VirtQueue code for the device part. The driver part is
14
verification if VIRTIO_NET_HDR_F_DATA_VALID is set.
14
based on Linux's virtio_ring driver, but with stripped functionality
15
15
and optimizations so it's easier to review.
16
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
16
17
However, forwarding buffers have some particular pieces: One of the most
18
unexpected ones is that a guest's buffer can expand through more than
19
one descriptor in SVQ. While this is handled gracefully by qemu's
20
emulated virtio devices, it may cause unexpected SVQ queue full. This
21
patch also solves it by checking for this condition at both guest's
22
kicks and device's calls. The code may be more elegant in the future if
23
SVQ code runs in its own iocontext.
24
25
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
26
Acked-by: Michael S. Tsirkin <mst@redhat.com>
17
Signed-off-by: Jason Wang <jasowang@redhat.com>
27
Signed-off-by: Jason Wang <jasowang@redhat.com>
18
---
28
---
19
hw/net/e1000e_core.c | 27 +++++++++++++++++--
29
hw/virtio/vhost-shadow-virtqueue.c | 352 ++++++++++++++++++++++++++++++++++++-
20
hw/net/net_rx_pkt.c | 7 +++++
30
hw/virtio/vhost-shadow-virtqueue.h | 26 +++
21
hw/net/net_rx_pkt.h | 8 ++++++
31
hw/virtio/vhost-vdpa.c | 155 +++++++++++++++-
22
hw/net/net_tx_pkt.c | 76 +++++++++++++++++++++++++---------------------------
32
3 files changed, 522 insertions(+), 11 deletions(-)
23
hw/net/net_tx_pkt.h | 21 ++++++++-------
33
24
5 files changed, 88 insertions(+), 51 deletions(-)
34
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
25
26
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
27
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/net/e1000e_core.c
36
--- a/hw/virtio/vhost-shadow-virtqueue.c
29
+++ b/hw/net/e1000e_core.c
37
+++ b/hw/virtio/vhost-shadow-virtqueue.c
30
@@ -XXX,XX +XXX,XX @@ union e1000_rx_desc_union {
38
@@ -XXX,XX +XXX,XX @@
31
union e1000_rx_desc_packet_split packet_split;
39
#include "qemu/error-report.h"
32
};
40
#include "qapi/error.h"
33
41
#include "qemu/main-loop.h"
34
+static ssize_t
42
+#include "qemu/log.h"
35
+e1000e_receive_internal(E1000ECore *core, const struct iovec *iov, int iovcnt,
43
+#include "qemu/memalign.h"
36
+ bool has_vnet);
44
#include "linux-headers/linux/vhost.h"
37
+
45
38
static inline void
46
/**
39
e1000e_set_interrupt_cause(E1000ECore *core, uint32_t val);
47
@@ -XXX,XX +XXX,XX @@ bool vhost_svq_valid_features(uint64_t features, Error **errp)
40
41
@@ -XXX,XX +XXX,XX @@ e1000e_setup_tx_offloads(E1000ECore *core, struct e1000e_tx *tx)
42
return true;
43
}
48
}
44
49
45
+static void e1000e_tx_pkt_callback(void *core,
50
/**
46
+ const struct iovec *iov,
51
- * Forward guest notifications.
47
+ int iovcnt,
52
+ * Number of descriptors that the SVQ can make available from the guest.
48
+ const struct iovec *virt_iov,
53
+ *
49
+ int virt_iovcnt)
54
+ * @svq: The svq
50
+{
55
+ */
51
+ e1000e_receive_internal(core, virt_iov, virt_iovcnt, true);
56
+static uint16_t vhost_svq_available_slots(const VhostShadowVirtqueue *svq)
52
+}
57
+{
53
+
58
+ return svq->vring.num - (svq->shadow_avail_idx - svq->shadow_used_idx);
54
static bool
59
+}
55
e1000e_tx_pkt_send(E1000ECore *core, struct e1000e_tx *tx, int queue_index)
60
+
61
+static void vhost_vring_write_descs(VhostShadowVirtqueue *svq,
62
+ const struct iovec *iovec, size_t num,
63
+ bool more_descs, bool write)
64
+{
65
+ uint16_t i = svq->free_head, last = svq->free_head;
66
+ unsigned n;
67
+ uint16_t flags = write ? cpu_to_le16(VRING_DESC_F_WRITE) : 0;
68
+ vring_desc_t *descs = svq->vring.desc;
69
+
70
+ if (num == 0) {
71
+ return;
72
+ }
73
+
74
+ for (n = 0; n < num; n++) {
75
+ if (more_descs || (n + 1 < num)) {
76
+ descs[i].flags = flags | cpu_to_le16(VRING_DESC_F_NEXT);
77
+ } else {
78
+ descs[i].flags = flags;
79
+ }
80
+ descs[i].addr = cpu_to_le64((hwaddr)(intptr_t)iovec[n].iov_base);
81
+ descs[i].len = cpu_to_le32(iovec[n].iov_len);
82
+
83
+ last = i;
84
+ i = cpu_to_le16(descs[i].next);
85
+ }
86
+
87
+ svq->free_head = le16_to_cpu(descs[last].next);
88
+}
89
+
90
+static bool vhost_svq_add_split(VhostShadowVirtqueue *svq,
91
+ VirtQueueElement *elem, unsigned *head)
92
+{
93
+ unsigned avail_idx;
94
+ vring_avail_t *avail = svq->vring.avail;
95
+
96
+ *head = svq->free_head;
97
+
98
+ /* We need some descriptors here */
99
+ if (unlikely(!elem->out_num && !elem->in_num)) {
100
+ qemu_log_mask(LOG_GUEST_ERROR,
101
+ "Guest provided element with no descriptors");
102
+ return false;
103
+ }
104
+
105
+ vhost_vring_write_descs(svq, elem->out_sg, elem->out_num, elem->in_num > 0,
106
+ false);
107
+ vhost_vring_write_descs(svq, elem->in_sg, elem->in_num, false, true);
108
+
109
+ /*
110
+ * Put the entry in the available array (but don't update avail->idx until
111
+ * they do sync).
112
+ */
113
+ avail_idx = svq->shadow_avail_idx & (svq->vring.num - 1);
114
+ avail->ring[avail_idx] = cpu_to_le16(*head);
115
+ svq->shadow_avail_idx++;
116
+
117
+ /* Update the avail index after write the descriptor */
118
+ smp_wmb();
119
+ avail->idx = cpu_to_le16(svq->shadow_avail_idx);
120
+
121
+ return true;
122
+}
123
+
124
+static bool vhost_svq_add(VhostShadowVirtqueue *svq, VirtQueueElement *elem)
125
+{
126
+ unsigned qemu_head;
127
+ bool ok = vhost_svq_add_split(svq, elem, &qemu_head);
128
+ if (unlikely(!ok)) {
129
+ return false;
130
+ }
131
+
132
+ svq->ring_id_maps[qemu_head] = elem;
133
+ return true;
134
+}
135
+
136
+static void vhost_svq_kick(VhostShadowVirtqueue *svq)
137
+{
138
+ /*
139
+ * We need to expose the available array entries before checking the used
140
+ * flags
141
+ */
142
+ smp_mb();
143
+ if (svq->vring.used->flags & VRING_USED_F_NO_NOTIFY) {
144
+ return;
145
+ }
146
+
147
+ event_notifier_set(&svq->hdev_kick);
148
+}
149
+
150
+/**
151
+ * Forward available buffers.
152
+ *
153
+ * @svq: Shadow VirtQueue
154
+ *
155
+ * Note that this function does not guarantee that all guest's available
156
+ * buffers are available to the device in SVQ avail ring. The guest may have
157
+ * exposed a GPA / GIOVA contiguous buffer, but it may not be contiguous in
158
+ * qemu vaddr.
159
+ *
160
+ * If that happens, guest's kick notifications will be disabled until the
161
+ * device uses some buffers.
162
+ */
163
+static void vhost_handle_guest_kick(VhostShadowVirtqueue *svq)
164
+{
165
+ /* Clear event notifier */
166
+ event_notifier_test_and_clear(&svq->svq_kick);
167
+
168
+ /* Forward to the device as many available buffers as possible */
169
+ do {
170
+ virtio_queue_set_notification(svq->vq, false);
171
+
172
+ while (true) {
173
+ VirtQueueElement *elem;
174
+ bool ok;
175
+
176
+ if (svq->next_guest_avail_elem) {
177
+ elem = g_steal_pointer(&svq->next_guest_avail_elem);
178
+ } else {
179
+ elem = virtqueue_pop(svq->vq, sizeof(*elem));
180
+ }
181
+
182
+ if (!elem) {
183
+ break;
184
+ }
185
+
186
+ if (elem->out_num + elem->in_num > vhost_svq_available_slots(svq)) {
187
+ /*
188
+ * This condition is possible since a contiguous buffer in GPA
189
+ * does not imply a contiguous buffer in qemu's VA
190
+ * scatter-gather segments. If that happens, the buffer exposed
191
+ * to the device needs to be a chain of descriptors at this
192
+ * moment.
193
+ *
194
+ * SVQ cannot hold more available buffers if we are here:
195
+ * queue the current guest descriptor and ignore further kicks
196
+ * until some elements are used.
197
+ */
198
+ svq->next_guest_avail_elem = elem;
199
+ return;
200
+ }
201
+
202
+ ok = vhost_svq_add(svq, elem);
203
+ if (unlikely(!ok)) {
204
+ /* VQ is broken, just return and ignore any other kicks */
205
+ return;
206
+ }
207
+ vhost_svq_kick(svq);
208
+ }
209
+
210
+ virtio_queue_set_notification(svq->vq, true);
211
+ } while (!virtio_queue_empty(svq->vq));
212
+}
213
+
214
+/**
215
+ * Handle guest's kick.
216
*
217
* @n: guest kick event notifier, the one that guest set to notify svq.
218
*/
219
-static void vhost_handle_guest_kick(EventNotifier *n)
220
+static void vhost_handle_guest_kick_notifier(EventNotifier *n)
56
{
221
{
57
@@ -XXX,XX +XXX,XX @@ e1000e_tx_pkt_send(E1000ECore *core, struct e1000e_tx *tx, int queue_index)
222
VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue, svq_kick);
58
223
event_notifier_test_and_clear(n);
59
if ((core->phy[0][MII_BMCR] & MII_BMCR_LOOPBACK) ||
224
- event_notifier_set(&svq->hdev_kick);
60
((core->mac[RCTL] & E1000_RCTL_LBM_MAC) == E1000_RCTL_LBM_MAC)) {
225
+ vhost_handle_guest_kick(svq);
61
- return net_tx_pkt_send_loopback(tx->tx_pkt, queue);
226
+}
62
+ return net_tx_pkt_send_custom(tx->tx_pkt, false,
227
+
63
+ e1000e_tx_pkt_callback, core);
228
+static bool vhost_svq_more_used(VhostShadowVirtqueue *svq)
64
} else {
229
+{
65
return net_tx_pkt_send(tx->tx_pkt, queue);
230
+ if (svq->last_used_idx != svq->shadow_used_idx) {
66
}
231
+ return true;
67
@@ -XXX,XX +XXX,XX @@ e1000e_rx_fix_l4_csum(E1000ECore *core, struct NetRxPkt *pkt)
232
+ }
68
ssize_t
233
+
69
e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt)
234
+ svq->shadow_used_idx = cpu_to_le16(svq->vring.used->idx);
235
+
236
+ return svq->last_used_idx != svq->shadow_used_idx;
237
}
238
239
/**
240
- * Forward vhost notifications
241
+ * Enable vhost device calls after disable them.
242
+ *
243
+ * @svq: The svq
244
+ *
245
+ * It returns false if there are pending used buffers from the vhost device,
246
+ * avoiding the possible races between SVQ checking for more work and enabling
247
+ * callbacks. True if SVQ used vring has no more pending buffers.
248
+ */
249
+static bool vhost_svq_enable_notification(VhostShadowVirtqueue *svq)
250
+{
251
+ svq->vring.avail->flags &= ~cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT);
252
+ /* Make sure the flag is written before the read of used_idx */
253
+ smp_mb();
254
+ return !vhost_svq_more_used(svq);
255
+}
256
+
257
+static void vhost_svq_disable_notification(VhostShadowVirtqueue *svq)
258
+{
259
+ svq->vring.avail->flags |= cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT);
260
+}
261
+
262
+static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq,
263
+ uint32_t *len)
264
+{
265
+ vring_desc_t *descs = svq->vring.desc;
266
+ const vring_used_t *used = svq->vring.used;
267
+ vring_used_elem_t used_elem;
268
+ uint16_t last_used;
269
+
270
+ if (!vhost_svq_more_used(svq)) {
271
+ return NULL;
272
+ }
273
+
274
+ /* Only get used array entries after they have been exposed by dev */
275
+ smp_rmb();
276
+ last_used = svq->last_used_idx & (svq->vring.num - 1);
277
+ used_elem.id = le32_to_cpu(used->ring[last_used].id);
278
+ used_elem.len = le32_to_cpu(used->ring[last_used].len);
279
+
280
+ svq->last_used_idx++;
281
+ if (unlikely(used_elem.id >= svq->vring.num)) {
282
+ qemu_log_mask(LOG_GUEST_ERROR, "Device %s says index %u is used",
283
+ svq->vdev->name, used_elem.id);
284
+ return NULL;
285
+ }
286
+
287
+ if (unlikely(!svq->ring_id_maps[used_elem.id])) {
288
+ qemu_log_mask(LOG_GUEST_ERROR,
289
+ "Device %s says index %u is used, but it was not available",
290
+ svq->vdev->name, used_elem.id);
291
+ return NULL;
292
+ }
293
+
294
+ descs[used_elem.id].next = svq->free_head;
295
+ svq->free_head = used_elem.id;
296
+
297
+ *len = used_elem.len;
298
+ return g_steal_pointer(&svq->ring_id_maps[used_elem.id]);
299
+}
300
+
301
+static void vhost_svq_flush(VhostShadowVirtqueue *svq,
302
+ bool check_for_avail_queue)
303
+{
304
+ VirtQueue *vq = svq->vq;
305
+
306
+ /* Forward as many used buffers as possible. */
307
+ do {
308
+ unsigned i = 0;
309
+
310
+ vhost_svq_disable_notification(svq);
311
+ while (true) {
312
+ uint32_t len;
313
+ g_autofree VirtQueueElement *elem = vhost_svq_get_buf(svq, &len);
314
+ if (!elem) {
315
+ break;
316
+ }
317
+
318
+ if (unlikely(i >= svq->vring.num)) {
319
+ qemu_log_mask(LOG_GUEST_ERROR,
320
+ "More than %u used buffers obtained in a %u size SVQ",
321
+ i, svq->vring.num);
322
+ virtqueue_fill(vq, elem, len, i);
323
+ virtqueue_flush(vq, i);
324
+ return;
325
+ }
326
+ virtqueue_fill(vq, elem, len, i++);
327
+ }
328
+
329
+ virtqueue_flush(vq, i);
330
+ event_notifier_set(&svq->svq_call);
331
+
332
+ if (check_for_avail_queue && svq->next_guest_avail_elem) {
333
+ /*
334
+ * Avail ring was full when vhost_svq_flush was called, so it's a
335
+ * good moment to make more descriptors available if possible.
336
+ */
337
+ vhost_handle_guest_kick(svq);
338
+ }
339
+ } while (!vhost_svq_enable_notification(svq));
340
+}
341
+
342
+/**
343
+ * Forward used buffers.
344
*
345
* @n: hdev call event notifier, the one that device set to notify svq.
346
+ *
347
+ * Note that we are not making any buffers available in the loop, there is no
348
+ * way that it runs more than virtqueue size times.
349
*/
350
static void vhost_svq_handle_call(EventNotifier *n)
70
{
351
{
71
+ return e1000e_receive_internal(core, iov, iovcnt, core->has_vnet);
352
VhostShadowVirtqueue *svq = container_of(n, VhostShadowVirtqueue,
72
+}
353
hdev_call);
73
+
354
event_notifier_test_and_clear(n);
74
+static ssize_t
355
- event_notifier_set(&svq->svq_call);
75
+e1000e_receive_internal(E1000ECore *core, const struct iovec *iov, int iovcnt,
356
+ vhost_svq_flush(svq, true);
76
+ bool has_vnet)
77
+{
78
static const int maximum_ethernet_hdr_len = (ETH_HLEN + 4);
79
80
uint32_t n = 0;
81
@@ -XXX,XX +XXX,XX @@ e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt)
82
}
83
84
/* Pull virtio header in */
85
- if (core->has_vnet) {
86
+ if (has_vnet) {
87
net_rx_pkt_set_vhdr_iovec(core->rx_pkt, iov, iovcnt);
88
iov_ofs = sizeof(struct virtio_net_hdr);
89
+ } else {
90
+ net_rx_pkt_unset_vhdr(core->rx_pkt);
91
}
92
93
filter_buf = iov->iov_base + iov_ofs;
94
diff --git a/hw/net/net_rx_pkt.c b/hw/net/net_rx_pkt.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/hw/net/net_rx_pkt.c
97
+++ b/hw/net/net_rx_pkt.c
98
@@ -XXX,XX +XXX,XX @@ void net_rx_pkt_set_vhdr_iovec(struct NetRxPkt *pkt,
99
iov_to_buf(iov, iovcnt, 0, &pkt->virt_hdr, sizeof pkt->virt_hdr);
100
}
357
}
101
358
102
+void net_rx_pkt_unset_vhdr(struct NetRxPkt *pkt)
103
+{
104
+ assert(pkt);
105
+
106
+ memset(&pkt->virt_hdr, 0, sizeof(pkt->virt_hdr));
107
+}
108
+
109
bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt)
110
{
111
assert(pkt);
112
diff --git a/hw/net/net_rx_pkt.h b/hw/net/net_rx_pkt.h
113
index XXXXXXX..XXXXXXX 100644
114
--- a/hw/net/net_rx_pkt.h
115
+++ b/hw/net/net_rx_pkt.h
116
@@ -XXX,XX +XXX,XX @@ void net_rx_pkt_set_vhdr_iovec(struct NetRxPkt *pkt,
117
const struct iovec *iov, int iovcnt);
118
119
/**
359
/**
120
+ * unset vhdr data from packet context
360
@@ -XXX,XX +XXX,XX @@ void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd)
121
+ *
361
if (poll_start) {
122
+ * @pkt: packet
362
event_notifier_init_fd(svq_kick, svq_kick_fd);
123
+ *
363
event_notifier_set(svq_kick);
364
- event_notifier_set_handler(svq_kick, vhost_handle_guest_kick);
365
+ event_notifier_set_handler(svq_kick, vhost_handle_guest_kick_notifier);
366
+ }
367
+}
368
+
369
+/**
370
+ * Start the shadow virtqueue operation.
371
+ *
372
+ * @svq: Shadow Virtqueue
373
+ * @vdev: VirtIO device
374
+ * @vq: Virtqueue to shadow
124
+ */
375
+ */
125
+void net_rx_pkt_unset_vhdr(struct NetRxPkt *pkt);
376
+void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
126
+
377
+ VirtQueue *vq)
127
+/**
378
+{
128
* save packet type in packet context
379
+ size_t desc_size, driver_size, device_size;
129
*
380
+
130
* @pkt: packet
381
+ svq->next_guest_avail_elem = NULL;
131
diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
382
+ svq->shadow_avail_idx = 0;
132
index XXXXXXX..XXXXXXX 100644
383
+ svq->shadow_used_idx = 0;
133
--- a/hw/net/net_tx_pkt.c
384
+ svq->last_used_idx = 0;
134
+++ b/hw/net/net_tx_pkt.c
385
+ svq->vdev = vdev;
135
@@ -XXX,XX +XXX,XX @@ struct NetTxPkt {
386
+ svq->vq = vq;
136
uint16_t hdr_len;
387
+
137
eth_pkt_types_e packet_type;
388
+ svq->vring.num = virtio_queue_get_num(vdev, virtio_get_queue_index(vq));
138
uint8_t l4proto;
389
+ driver_size = vhost_svq_driver_area_size(svq);
139
-
390
+ device_size = vhost_svq_device_area_size(svq);
140
- bool is_loopback;
391
+ svq->vring.desc = qemu_memalign(qemu_real_host_page_size, driver_size);
141
};
392
+ desc_size = sizeof(vring_desc_t) * svq->vring.num;
142
393
+ svq->vring.avail = (void *)((char *)svq->vring.desc + desc_size);
143
void net_tx_pkt_init(struct NetTxPkt **pkt, PCIDevice *pci_dev,
394
+ memset(svq->vring.desc, 0, driver_size);
144
@@ -XXX,XX +XXX,XX @@ static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt)
395
+ svq->vring.used = qemu_memalign(qemu_real_host_page_size, device_size);
145
iov_from_buf(iov, iov_len, csum_offset, &csum, sizeof csum);
396
+ memset(svq->vring.used, 0, device_size);
146
}
397
+ svq->ring_id_maps = g_new0(VirtQueueElement *, svq->vring.num);
147
398
+ for (unsigned i = 0; i < svq->vring.num - 1; i++) {
148
-enum {
399
+ svq->vring.desc[i].next = cpu_to_le16(i + 1);
149
- NET_TX_PKT_FRAGMENT_L2_HDR_POS = 0,
150
- NET_TX_PKT_FRAGMENT_L3_HDR_POS,
151
- NET_TX_PKT_FRAGMENT_HEADER_NUM
152
-};
153
-
154
#define NET_MAX_FRAG_SG_LIST (64)
155
156
static size_t net_tx_pkt_fetch_fragment(struct NetTxPkt *pkt,
157
@@ -XXX,XX +XXX,XX @@ static size_t net_tx_pkt_fetch_fragment(struct NetTxPkt *pkt,
158
size_t fetched = 0;
159
struct iovec *src = pkt->vec;
160
161
- *dst_idx = NET_TX_PKT_FRAGMENT_HEADER_NUM;
162
+ *dst_idx = NET_TX_PKT_PL_START_FRAG;
163
164
while (fetched < IP_FRAG_ALIGN_SIZE(pkt->virt_hdr.gso_size)) {
165
166
@@ -XXX,XX +XXX,XX @@ static size_t net_tx_pkt_fetch_fragment(struct NetTxPkt *pkt,
167
return fetched;
168
}
169
170
-static inline void net_tx_pkt_sendv(struct NetTxPkt *pkt,
171
- NetClientState *nc, const struct iovec *iov, int iov_cnt)
172
+static void net_tx_pkt_sendv(
173
+ void *opaque, const struct iovec *iov, int iov_cnt,
174
+ const struct iovec *virt_iov, int virt_iov_cnt)
175
{
176
- if (pkt->is_loopback) {
177
- qemu_receive_packet_iov(nc, iov, iov_cnt);
178
+ NetClientState *nc = opaque;
179
+
180
+ if (qemu_get_using_vnet_hdr(nc->peer)) {
181
+ qemu_sendv_packet(nc, virt_iov, virt_iov_cnt);
182
} else {
183
qemu_sendv_packet(nc, iov, iov_cnt);
184
}
400
}
185
}
401
}
186
402
187
static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt,
403
@@ -XXX,XX +XXX,XX @@ void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd)
188
- NetClientState *nc)
404
void vhost_svq_stop(VhostShadowVirtqueue *svq)
189
+ NetTxPktCallback callback,
190
+ void *context)
191
{
405
{
192
struct iovec fragment[NET_MAX_FRAG_SG_LIST];
406
event_notifier_set_handler(&svq->svq_kick, NULL);
193
size_t fragment_len = 0;
407
+ g_autofree VirtQueueElement *next_avail_elem = NULL;
194
@@ -XXX,XX +XXX,XX @@ static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt,
408
+
195
int src_idx = NET_TX_PKT_PL_START_FRAG, dst_idx;
409
+ if (!svq->vq) {
196
size_t src_offset = 0;
410
+ return;
197
size_t fragment_offset = 0;
411
+ }
198
+ struct virtio_net_hdr virt_hdr = {
412
+
199
+ .flags = pkt->virt_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM ?
413
+ /* Send all pending used descriptors to guest */
200
+ VIRTIO_NET_HDR_F_DATA_VALID : 0
414
+ vhost_svq_flush(svq, false);
415
+
416
+ for (unsigned i = 0; i < svq->vring.num; ++i) {
417
+ g_autofree VirtQueueElement *elem = NULL;
418
+ elem = g_steal_pointer(&svq->ring_id_maps[i]);
419
+ if (elem) {
420
+ virtqueue_detach_element(svq->vq, elem, 0);
421
+ }
422
+ }
423
+
424
+ next_avail_elem = g_steal_pointer(&svq->next_guest_avail_elem);
425
+ if (next_avail_elem) {
426
+ virtqueue_detach_element(svq->vq, next_avail_elem, 0);
427
+ }
428
+ svq->vq = NULL;
429
+ g_free(svq->ring_id_maps);
430
+ qemu_vfree(svq->vring.desc);
431
+ qemu_vfree(svq->vring.used);
432
}
433
434
/**
435
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
436
index XXXXXXX..XXXXXXX 100644
437
--- a/hw/virtio/vhost-shadow-virtqueue.h
438
+++ b/hw/virtio/vhost-shadow-virtqueue.h
439
@@ -XXX,XX +XXX,XX @@ typedef struct VhostShadowVirtqueue {
440
441
/* Guest's call notifier, where the SVQ calls guest. */
442
EventNotifier svq_call;
443
+
444
+ /* Virtio queue shadowing */
445
+ VirtQueue *vq;
446
+
447
+ /* Virtio device */
448
+ VirtIODevice *vdev;
449
+
450
+ /* Map for use the guest's descriptors */
451
+ VirtQueueElement **ring_id_maps;
452
+
453
+ /* Next VirtQueue element that guest made available */
454
+ VirtQueueElement *next_guest_avail_elem;
455
+
456
+ /* Next head to expose to the device */
457
+ uint16_t shadow_avail_idx;
458
+
459
+ /* Next free descriptor */
460
+ uint16_t free_head;
461
+
462
+ /* Last seen used idx */
463
+ uint16_t shadow_used_idx;
464
+
465
+ /* Next head to consume from the device */
466
+ uint16_t last_used_idx;
467
} VhostShadowVirtqueue;
468
469
bool vhost_svq_valid_features(uint64_t features, Error **errp);
470
@@ -XXX,XX +XXX,XX @@ void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
471
size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq);
472
size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq);
473
474
+void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
475
+ VirtQueue *vq);
476
void vhost_svq_stop(VhostShadowVirtqueue *svq);
477
478
VhostShadowVirtqueue *vhost_svq_new(void);
479
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
480
index XXXXXXX..XXXXXXX 100644
481
--- a/hw/virtio/vhost-vdpa.c
482
+++ b/hw/virtio/vhost-vdpa.c
483
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_set_vring_dev_addr(struct vhost_dev *dev,
484
* Note that this function does not rewind kick file descriptor if cannot set
485
* call one.
486
*/
487
-static bool vhost_vdpa_svq_setup(struct vhost_dev *dev,
488
- VhostShadowVirtqueue *svq, unsigned idx,
489
- Error **errp)
490
+static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev,
491
+ VhostShadowVirtqueue *svq, unsigned idx,
492
+ Error **errp)
493
{
494
struct vhost_vring_file file = {
495
.index = dev->vq_index + idx,
496
@@ -XXX,XX +XXX,XX @@ static bool vhost_vdpa_svq_setup(struct vhost_dev *dev,
497
r = vhost_vdpa_set_vring_dev_kick(dev, &file);
498
if (unlikely(r != 0)) {
499
error_setg_errno(errp, -r, "Can't set device kick fd");
500
- return false;
501
+ return r;
502
}
503
504
event_notifier = &svq->hdev_call;
505
@@ -XXX,XX +XXX,XX @@ static bool vhost_vdpa_svq_setup(struct vhost_dev *dev,
506
error_setg_errno(errp, -r, "Can't set device call fd");
507
}
508
509
+ return r;
510
+}
511
+
512
+/**
513
+ * Unmap a SVQ area in the device
514
+ */
515
+static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, hwaddr iova,
516
+ hwaddr size)
517
+{
518
+ int r;
519
+
520
+ size = ROUND_UP(size, qemu_real_host_page_size);
521
+ r = vhost_vdpa_dma_unmap(v, iova, size);
522
+ return r == 0;
523
+}
524
+
525
+static bool vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev,
526
+ const VhostShadowVirtqueue *svq)
527
+{
528
+ struct vhost_vdpa *v = dev->opaque;
529
+ struct vhost_vring_addr svq_addr;
530
+ size_t device_size = vhost_svq_device_area_size(svq);
531
+ size_t driver_size = vhost_svq_driver_area_size(svq);
532
+ bool ok;
533
+
534
+ vhost_svq_get_vring_addr(svq, &svq_addr);
535
+
536
+ ok = vhost_vdpa_svq_unmap_ring(v, svq_addr.desc_user_addr, driver_size);
537
+ if (unlikely(!ok)) {
538
+ return false;
539
+ }
540
+
541
+ return vhost_vdpa_svq_unmap_ring(v, svq_addr.used_user_addr, device_size);
542
+}
543
+
544
+/**
545
+ * Map the shadow virtqueue rings in the device
546
+ *
547
+ * @dev: The vhost device
548
+ * @svq: The shadow virtqueue
549
+ * @addr: Assigned IOVA addresses
550
+ * @errp: Error pointer
551
+ */
552
+static bool vhost_vdpa_svq_map_rings(struct vhost_dev *dev,
553
+ const VhostShadowVirtqueue *svq,
554
+ struct vhost_vring_addr *addr,
555
+ Error **errp)
556
+{
557
+ struct vhost_vdpa *v = dev->opaque;
558
+ size_t device_size = vhost_svq_device_area_size(svq);
559
+ size_t driver_size = vhost_svq_driver_area_size(svq);
560
+ int r;
561
+
562
+ ERRP_GUARD();
563
+ vhost_svq_get_vring_addr(svq, addr);
564
+
565
+ r = vhost_vdpa_dma_map(v, addr->desc_user_addr, driver_size,
566
+ (void *)(uintptr_t)addr->desc_user_addr, true);
567
+ if (unlikely(r != 0)) {
568
+ error_setg_errno(errp, -r, "Cannot create vq driver region: ");
569
+ return false;
570
+ }
571
+
572
+ r = vhost_vdpa_dma_map(v, addr->used_user_addr, device_size,
573
+ (void *)(intptr_t)addr->used_user_addr, false);
574
+ if (unlikely(r != 0)) {
575
+ error_setg_errno(errp, -r, "Cannot create vq device region: ");
576
+ }
577
+
578
+ return r == 0;
579
+}
580
+
581
+static bool vhost_vdpa_svq_setup(struct vhost_dev *dev,
582
+ VhostShadowVirtqueue *svq, unsigned idx,
583
+ Error **errp)
584
+{
585
+ uint16_t vq_index = dev->vq_index + idx;
586
+ struct vhost_vring_state s = {
587
+ .index = vq_index,
201
+ };
588
+ };
202
589
+ int r;
203
l2_iov_base = pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_base;
590
+
204
l2_iov_len = pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_len;
591
+ r = vhost_vdpa_set_dev_vring_base(dev, &s);
205
@@ -XXX,XX +XXX,XX @@ static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt,
592
+ if (unlikely(r)) {
206
l3_iov_len = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len;
593
+ error_setg_errno(errp, -r, "Cannot set vring base");
207
594
+ return false;
208
/* Copy headers */
595
+ }
209
- fragment[NET_TX_PKT_FRAGMENT_L2_HDR_POS].iov_base = l2_iov_base;
596
+
210
- fragment[NET_TX_PKT_FRAGMENT_L2_HDR_POS].iov_len = l2_iov_len;
597
+ r = vhost_vdpa_svq_set_fds(dev, svq, idx, errp);
211
- fragment[NET_TX_PKT_FRAGMENT_L3_HDR_POS].iov_base = l3_iov_base;
598
return r == 0;
212
- fragment[NET_TX_PKT_FRAGMENT_L3_HDR_POS].iov_len = l3_iov_len;
599
}
213
+ fragment[NET_TX_PKT_VHDR_FRAG].iov_base = &virt_hdr;
600
214
+ fragment[NET_TX_PKT_VHDR_FRAG].iov_len = sizeof(virt_hdr);
601
@@ -XXX,XX +XXX,XX @@ static bool vhost_vdpa_svqs_start(struct vhost_dev *dev)
215
+ fragment[NET_TX_PKT_L2HDR_FRAG].iov_base = l2_iov_base;
216
+ fragment[NET_TX_PKT_L2HDR_FRAG].iov_len = l2_iov_len;
217
+ fragment[NET_TX_PKT_L3HDR_FRAG].iov_base = l3_iov_base;
218
+ fragment[NET_TX_PKT_L3HDR_FRAG].iov_len = l3_iov_len;
219
220
221
/* Put as much data as possible and send */
222
@@ -XXX,XX +XXX,XX @@ static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt,
223
224
eth_fix_ip4_checksum(l3_iov_base, l3_iov_len);
225
226
- net_tx_pkt_sendv(pkt, nc, fragment, dst_idx);
227
+ callback(context,
228
+ fragment + NET_TX_PKT_L2HDR_FRAG, dst_idx - NET_TX_PKT_L2HDR_FRAG,
229
+ fragment + NET_TX_PKT_VHDR_FRAG, dst_idx - NET_TX_PKT_VHDR_FRAG);
230
231
fragment_offset += fragment_len;
232
233
@@ -XXX,XX +XXX,XX @@ static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt,
234
235
bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc)
236
{
237
- bool using_vnet_hdr = qemu_get_using_vnet_hdr(nc->peer);
238
+ bool offload = qemu_get_using_vnet_hdr(nc->peer);
239
+ return net_tx_pkt_send_custom(pkt, offload, net_tx_pkt_sendv, nc);
240
+}
241
242
+bool net_tx_pkt_send_custom(struct NetTxPkt *pkt, bool offload,
243
+ NetTxPktCallback callback, void *context)
244
+{
245
assert(pkt);
246
247
- if (!using_vnet_hdr &&
248
- pkt->virt_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
249
+ if (!offload && pkt->virt_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
250
net_tx_pkt_do_sw_csum(pkt);
251
}
602
}
252
603
253
@@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc)
604
for (i = 0; i < v->shadow_vqs->len; ++i) {
605
+ VirtQueue *vq = virtio_get_queue(dev->vdev, dev->vq_index + i);
606
VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
607
+ struct vhost_vring_addr addr = {
608
+ .index = i,
609
+ };
610
+ int r;
611
bool ok = vhost_vdpa_svq_setup(dev, svq, i, &err);
612
if (unlikely(!ok)) {
613
- error_reportf_err(err, "Cannot setup SVQ %u: ", i);
614
+ goto err;
615
+ }
616
+
617
+ vhost_svq_start(svq, dev->vdev, vq);
618
+ ok = vhost_vdpa_svq_map_rings(dev, svq, &addr, &err);
619
+ if (unlikely(!ok)) {
620
+ goto err_map;
621
+ }
622
+
623
+ /* Override vring GPA set by vhost subsystem */
624
+ r = vhost_vdpa_set_vring_dev_addr(dev, &addr);
625
+ if (unlikely(r != 0)) {
626
+ error_setg_errno(&err, -r, "Cannot set device address");
627
+ goto err_set_addr;
628
+ }
629
+ }
630
+
631
+ return true;
632
+
633
+err_set_addr:
634
+ vhost_vdpa_svq_unmap_rings(dev, g_ptr_array_index(v->shadow_vqs, i));
635
+
636
+err_map:
637
+ vhost_svq_stop(g_ptr_array_index(v->shadow_vqs, i));
638
+
639
+err:
640
+ error_reportf_err(err, "Cannot setup SVQ %u: ", i);
641
+ for (unsigned j = 0; j < i; ++j) {
642
+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, j);
643
+ vhost_vdpa_svq_unmap_rings(dev, svq);
644
+ vhost_svq_stop(svq);
645
+ }
646
+
647
+ return false;
648
+}
649
+
650
+static bool vhost_vdpa_svqs_stop(struct vhost_dev *dev)
651
+{
652
+ struct vhost_vdpa *v = dev->opaque;
653
+
654
+ if (!v->shadow_vqs) {
655
+ return true;
656
+ }
657
+
658
+ for (unsigned i = 0; i < v->shadow_vqs->len; ++i) {
659
+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs, i);
660
+ bool ok = vhost_vdpa_svq_unmap_rings(dev, svq);
661
+ if (unlikely(!ok)) {
662
return false;
254
}
663
}
255
}
664
}
256
665
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
257
- if (using_vnet_hdr ||
666
}
258
- pkt->virt_hdr.gso_type == VIRTIO_NET_HDR_GSO_NONE) {
667
vhost_vdpa_set_vring_ready(dev);
259
- int index = using_vnet_hdr ?
668
} else {
260
- NET_TX_PKT_VHDR_FRAG : NET_TX_PKT_L2HDR_FRAG;
669
+ ok = vhost_vdpa_svqs_stop(dev);
261
+ if (offload || pkt->virt_hdr.gso_type == VIRTIO_NET_HDR_GSO_NONE) {
670
+ if (unlikely(!ok)) {
262
net_tx_pkt_fix_ip6_payload_len(pkt);
671
+ return -1;
263
- net_tx_pkt_sendv(pkt, nc, pkt->vec + index,
672
+ }
264
- pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - index);
673
vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs);
265
+ callback(context, pkt->vec + NET_TX_PKT_L2HDR_FRAG,
266
+ pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - NET_TX_PKT_L2HDR_FRAG,
267
+ pkt->vec + NET_TX_PKT_VHDR_FRAG,
268
+ pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - NET_TX_PKT_VHDR_FRAG);
269
return true;
270
}
674
}
271
675
272
- return net_tx_pkt_do_sw_fragmentation(pkt, nc);
273
-}
274
-
275
-bool net_tx_pkt_send_loopback(struct NetTxPkt *pkt, NetClientState *nc)
276
-{
277
- bool res;
278
-
279
- pkt->is_loopback = true;
280
- res = net_tx_pkt_send(pkt, nc);
281
- pkt->is_loopback = false;
282
-
283
- return res;
284
+ return net_tx_pkt_do_sw_fragmentation(pkt, callback, context);
285
}
286
287
void net_tx_pkt_fix_ip6_payload_len(struct NetTxPkt *pkt)
288
diff --git a/hw/net/net_tx_pkt.h b/hw/net/net_tx_pkt.h
289
index XXXXXXX..XXXXXXX 100644
290
--- a/hw/net/net_tx_pkt.h
291
+++ b/hw/net/net_tx_pkt.h
292
@@ -XXX,XX +XXX,XX @@
293
294
struct NetTxPkt;
295
296
+typedef void (* NetTxPktCallback)(void *, const struct iovec *, int, const struct iovec *, int);
297
+
298
/**
299
* Init function for tx packet functionality
300
*
301
@@ -XXX,XX +XXX,XX @@ void net_tx_pkt_reset(struct NetTxPkt *pkt);
302
bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc);
303
304
/**
305
-* Redirect packet directly to receive path (emulate loopback phy).
306
-* Handles sw offloads if vhdr is not supported.
307
-*
308
-* @pkt: packet
309
-* @nc: NetClientState
310
-* @ret: operation result
311
-*
312
-*/
313
-bool net_tx_pkt_send_loopback(struct NetTxPkt *pkt, NetClientState *nc);
314
+ * Send packet with a custom function.
315
+ *
316
+ * @pkt: packet
317
+ * @offload: whether the callback implements offloading
318
+ * @callback: a function to be called back for each transformed packet
319
+ * @context: a pointer to be passed to the callback.
320
+ * @ret: operation result
321
+ */
322
+bool net_tx_pkt_send_custom(struct NetTxPkt *pkt, bool offload,
323
+ NetTxPktCallback callback, void *context);
324
325
/**
326
* parse raw packet data and analyze offload requirements.
327
--
676
--
328
2.7.4
677
2.7.4
678
679
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
e1000e_write_packet_to_guest() passes the reference of variable ba as a
3
This iova tree function allows it to look for a hole in allocated
4
pointer to an array, and that pointer indirection is just unnecessary;
4
regions and return a totally new translation for a given translated
5
all functions which uses the passed reference performs no pointer
5
address.
6
operation on the pointer and they simply dereference the passed
6
7
pointer. Remove the extra pointer indirection.
7
It's usage is mainly to allow devices to access qemu address space,
8
8
remapping guest's one into a new iova space where qemu can add chunks of
9
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
addresses.
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
11
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
12
Reviewed-by: Peter Xu <peterx@redhat.com>
13
Acked-by: Michael S. Tsirkin <mst@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
15
---
13
hw/net/e1000e_core.c | 38 +++++++++++++++++++-------------------
16
include/qemu/iova-tree.h | 18 +++++++
14
1 file changed, 19 insertions(+), 19 deletions(-)
17
util/iova-tree.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++
15
18
2 files changed, 154 insertions(+)
16
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
19
20
diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/e1000e_core.c
22
--- a/include/qemu/iova-tree.h
19
+++ b/hw/net/e1000e_core.c
23
+++ b/include/qemu/iova-tree.h
20
@@ -XXX,XX +XXX,XX @@ e1000e_read_ext_rx_descr(E1000ECore *core, union e1000_rx_desc_extended *desc,
24
@@ -XXX,XX +XXX,XX @@
21
static inline void
25
#define IOVA_OK (0)
22
e1000e_read_ps_rx_descr(E1000ECore *core,
26
#define IOVA_ERR_INVALID (-1) /* Invalid parameters */
23
union e1000_rx_desc_packet_split *desc,
27
#define IOVA_ERR_OVERLAP (-2) /* IOVA range overlapped */
24
- hwaddr (*buff_addr)[MAX_PS_BUFFERS])
28
+#define IOVA_ERR_NOMEM (-3) /* Cannot allocate */
25
+ hwaddr buff_addr[MAX_PS_BUFFERS])
29
30
typedef struct IOVATree IOVATree;
31
typedef struct DMAMap {
32
@@ -XXX,XX +XXX,XX @@ const DMAMap *iova_tree_find_address(const IOVATree *tree, hwaddr iova);
33
void iova_tree_foreach(IOVATree *tree, iova_tree_iterator iterator);
34
35
/**
36
+ * iova_tree_alloc_map:
37
+ *
38
+ * @tree: the iova tree to allocate from
39
+ * @map: the new map (as translated addr & size) to allocate in the iova region
40
+ * @iova_begin: the minimum address of the allocation
41
+ * @iova_end: the maximum addressable direction of the allocation
42
+ *
43
+ * Allocates a new region of a given size, between iova_min and iova_max.
44
+ *
45
+ * Return: Same as iova_tree_insert, but cannot overlap and can return error if
46
+ * iova tree is out of free contiguous range. The caller gets the assigned iova
47
+ * in map->iova.
48
+ */
49
+int iova_tree_alloc_map(IOVATree *tree, DMAMap *map, hwaddr iova_begin,
50
+ hwaddr iova_end);
51
+
52
+/**
53
* iova_tree_destroy:
54
*
55
* @tree: the iova tree to destroy
56
diff --git a/util/iova-tree.c b/util/iova-tree.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/util/iova-tree.c
59
+++ b/util/iova-tree.c
60
@@ -XXX,XX +XXX,XX @@ struct IOVATree {
61
GTree *tree;
62
};
63
64
+/* Args to pass to iova_tree_alloc foreach function. */
65
+struct IOVATreeAllocArgs {
66
+ /* Size of the desired allocation */
67
+ size_t new_size;
68
+
69
+ /* The minimum address allowed in the allocation */
70
+ hwaddr iova_begin;
71
+
72
+ /* Map at the left of the hole, can be NULL if "this" is first one */
73
+ const DMAMap *prev;
74
+
75
+ /* Map at the right of the hole, can be NULL if "prev" is the last one */
76
+ const DMAMap *this;
77
+
78
+ /* If found, we fill in the IOVA here */
79
+ hwaddr iova_result;
80
+
81
+ /* Whether have we found a valid IOVA */
82
+ bool iova_found;
83
+};
84
+
85
+/**
86
+ * Iterate args to the next hole
87
+ *
88
+ * @args: The alloc arguments
89
+ * @next: The next mapping in the tree. Can be NULL to signal the last one
90
+ */
91
+static void iova_tree_alloc_args_iterate(struct IOVATreeAllocArgs *args,
92
+ const DMAMap *next)
93
+{
94
+ args->prev = args->this;
95
+ args->this = next;
96
+}
97
+
98
static int iova_tree_compare(gconstpointer a, gconstpointer b, gpointer data)
26
{
99
{
27
int i;
100
const DMAMap *m1 = a, *m2 = b;
28
101
@@ -XXX,XX +XXX,XX @@ int iova_tree_remove(IOVATree *tree, const DMAMap *map)
29
for (i = 0; i < MAX_PS_BUFFERS; i++) {
102
return IOVA_OK;
30
- (*buff_addr)[i] = le64_to_cpu(desc->read.buffer_addr[i]);
31
+ buff_addr[i] = le64_to_cpu(desc->read.buffer_addr[i]);
32
}
33
34
- trace_e1000e_rx_desc_ps_read((*buff_addr)[0], (*buff_addr)[1],
35
- (*buff_addr)[2], (*buff_addr)[3]);
36
+ trace_e1000e_rx_desc_ps_read(buff_addr[0], buff_addr[1],
37
+ buff_addr[2], buff_addr[3]);
38
}
103
}
39
104
40
static inline void
105
+/**
41
e1000e_read_rx_descr(E1000ECore *core, union e1000_rx_desc_union *desc,
106
+ * Try to find an unallocated IOVA range between prev and this elements.
42
- hwaddr (*buff_addr)[MAX_PS_BUFFERS])
107
+ *
43
+ hwaddr buff_addr[MAX_PS_BUFFERS])
108
+ * @args: Arguments to allocation
109
+ *
110
+ * Cases:
111
+ *
112
+ * (1) !prev, !this: No entries allocated, always succeed
113
+ *
114
+ * (2) !prev, this: We're iterating at the 1st element.
115
+ *
116
+ * (3) prev, !this: We're iterating at the last element.
117
+ *
118
+ * (4) prev, this: this is the most common case, we'll try to find a hole
119
+ * between "prev" and "this" mapping.
120
+ *
121
+ * Note that this function assumes the last valid iova is HWADDR_MAX, but it
122
+ * searches linearly so it's easy to discard the result if it's not the case.
123
+ */
124
+static void iova_tree_alloc_map_in_hole(struct IOVATreeAllocArgs *args)
125
+{
126
+ const DMAMap *prev = args->prev, *this = args->this;
127
+ uint64_t hole_start, hole_last;
128
+
129
+ if (this && this->iova + this->size < args->iova_begin) {
130
+ return;
131
+ }
132
+
133
+ hole_start = MAX(prev ? prev->iova + prev->size + 1 : 0, args->iova_begin);
134
+ hole_last = this ? this->iova : HWADDR_MAX;
135
+
136
+ if (hole_last - hole_start > args->new_size) {
137
+ args->iova_result = hole_start;
138
+ args->iova_found = true;
139
+ }
140
+}
141
+
142
+/**
143
+ * Foreach dma node in the tree, compare if there is a hole with its previous
144
+ * node (or minimum iova address allowed) and the node.
145
+ *
146
+ * @key: Node iterating
147
+ * @value: Node iterating
148
+ * @pargs: Struct to communicate with the outside world
149
+ *
150
+ * Return: false to keep iterating, true if needs break.
151
+ */
152
+static gboolean iova_tree_alloc_traverse(gpointer key, gpointer value,
153
+ gpointer pargs)
154
+{
155
+ struct IOVATreeAllocArgs *args = pargs;
156
+ DMAMap *node = value;
157
+
158
+ assert(key == value);
159
+
160
+ iova_tree_alloc_args_iterate(args, node);
161
+ iova_tree_alloc_map_in_hole(args);
162
+ return args->iova_found;
163
+}
164
+
165
+int iova_tree_alloc_map(IOVATree *tree, DMAMap *map, hwaddr iova_begin,
166
+ hwaddr iova_last)
167
+{
168
+ struct IOVATreeAllocArgs args = {
169
+ .new_size = map->size,
170
+ .iova_begin = iova_begin,
171
+ };
172
+
173
+ if (unlikely(iova_last < iova_begin)) {
174
+ return IOVA_ERR_INVALID;
175
+ }
176
+
177
+ /*
178
+ * Find a valid hole for the mapping
179
+ *
180
+ * Assuming low iova_begin, so no need to do a binary search to
181
+ * locate the first node.
182
+ *
183
+ * TODO: Replace all this with g_tree_node_first/next/last when available
184
+ * (from glib since 2.68). To do it with g_tree_foreach complicates the
185
+ * code a lot.
186
+ *
187
+ */
188
+ g_tree_foreach(tree->tree, iova_tree_alloc_traverse, &args);
189
+ if (!args.iova_found) {
190
+ /*
191
+ * Either tree is empty or the last hole is still not checked.
192
+ * g_tree_foreach does not compare (last, iova_last] range, so we check
193
+ * it here.
194
+ */
195
+ iova_tree_alloc_args_iterate(&args, NULL);
196
+ iova_tree_alloc_map_in_hole(&args);
197
+ }
198
+
199
+ if (!args.iova_found || args.iova_result + map->size > iova_last) {
200
+ return IOVA_ERR_NOMEM;
201
+ }
202
+
203
+ map->iova = args.iova_result;
204
+ return iova_tree_insert(tree, map);
205
+}
206
+
207
void iova_tree_destroy(IOVATree *tree)
44
{
208
{
45
if (e1000e_rx_use_legacy_descriptor(core)) {
209
g_tree_destroy(tree->tree);
46
- e1000e_read_lgcy_rx_descr(core, &desc->legacy, &(*buff_addr)[0]);
47
- (*buff_addr)[1] = (*buff_addr)[2] = (*buff_addr)[3] = 0;
48
+ e1000e_read_lgcy_rx_descr(core, &desc->legacy, &buff_addr[0]);
49
+ buff_addr[1] = buff_addr[2] = buff_addr[3] = 0;
50
} else {
51
if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) {
52
e1000e_read_ps_rx_descr(core, &desc->packet_split, buff_addr);
53
} else {
54
- e1000e_read_ext_rx_descr(core, &desc->extended, &(*buff_addr)[0]);
55
- (*buff_addr)[1] = (*buff_addr)[2] = (*buff_addr)[3] = 0;
56
+ e1000e_read_ext_rx_descr(core, &desc->extended, &buff_addr[0]);
57
+ buff_addr[1] = buff_addr[2] = buff_addr[3] = 0;
58
}
59
}
60
}
61
@@ -XXX,XX +XXX,XX @@ typedef struct e1000e_ba_state_st {
62
63
static inline void
64
e1000e_write_hdr_to_rx_buffers(E1000ECore *core,
65
- hwaddr (*ba)[MAX_PS_BUFFERS],
66
+ hwaddr ba[MAX_PS_BUFFERS],
67
e1000e_ba_state *bastate,
68
const char *data,
69
dma_addr_t data_len)
70
{
71
assert(data_len <= core->rxbuf_sizes[0] - bastate->written[0]);
72
73
- pci_dma_write(core->owner, (*ba)[0] + bastate->written[0], data, data_len);
74
+ pci_dma_write(core->owner, ba[0] + bastate->written[0], data, data_len);
75
bastate->written[0] += data_len;
76
77
bastate->cur_idx = 1;
78
@@ -XXX,XX +XXX,XX @@ e1000e_write_hdr_to_rx_buffers(E1000ECore *core,
79
80
static void
81
e1000e_write_to_rx_buffers(E1000ECore *core,
82
- hwaddr (*ba)[MAX_PS_BUFFERS],
83
+ hwaddr ba[MAX_PS_BUFFERS],
84
e1000e_ba_state *bastate,
85
const char *data,
86
dma_addr_t data_len)
87
@@ -XXX,XX +XXX,XX @@ e1000e_write_to_rx_buffers(E1000ECore *core,
88
uint32_t bytes_to_write = MIN(data_len, cur_buf_bytes_left);
89
90
trace_e1000e_rx_desc_buff_write(bastate->cur_idx,
91
- (*ba)[bastate->cur_idx],
92
+ ba[bastate->cur_idx],
93
bastate->written[bastate->cur_idx],
94
data,
95
bytes_to_write);
96
97
pci_dma_write(core->owner,
98
- (*ba)[bastate->cur_idx] + bastate->written[bastate->cur_idx],
99
+ ba[bastate->cur_idx] + bastate->written[bastate->cur_idx],
100
data, bytes_to_write);
101
102
bastate->written[bastate->cur_idx] += bytes_to_write;
103
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
104
105
trace_e1000e_rx_descr(rxi->idx, base, core->rx_desc_len);
106
107
- e1000e_read_rx_descr(core, &desc, &ba);
108
+ e1000e_read_rx_descr(core, &desc, ba);
109
110
if (ba[0]) {
111
if (desc_offset < size) {
112
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
113
iov_copy = MIN(ps_hdr_len - ps_hdr_copied,
114
iov->iov_len - iov_ofs);
115
116
- e1000e_write_hdr_to_rx_buffers(core, &ba, &bastate,
117
+ e1000e_write_hdr_to_rx_buffers(core, ba, &bastate,
118
iov->iov_base, iov_copy);
119
120
copy_size -= iov_copy;
121
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
122
} else {
123
/* Leave buffer 0 of each descriptor except first */
124
/* empty as per spec 7.1.5.1 */
125
- e1000e_write_hdr_to_rx_buffers(core, &ba, &bastate,
126
+ e1000e_write_hdr_to_rx_buffers(core, ba, &bastate,
127
NULL, 0);
128
}
129
}
130
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
131
while (copy_size) {
132
iov_copy = MIN(copy_size, iov->iov_len - iov_ofs);
133
134
- e1000e_write_to_rx_buffers(core, &ba, &bastate,
135
+ e1000e_write_to_rx_buffers(core, ba, &bastate,
136
iov->iov_base + iov_ofs, iov_copy);
137
138
copy_size -= iov_copy;
139
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
140
141
if (desc_offset + desc_size >= total_size) {
142
/* Simulate FCS checksum presence in the last descriptor */
143
- e1000e_write_to_rx_buffers(core, &ba, &bastate,
144
+ e1000e_write_to_rx_buffers(core, ba, &bastate,
145
(const char *) &fcs_pad, e1000x_fcs_len(core->mac));
146
}
147
}
148
--
210
--
149
2.7.4
211
2.7.4
150
212
151
213
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
filter-dump specifiees Ethernet as PCAP LinkType, which does not expect
3
This function does the reverse operation of iova_tree_find: To look for
4
virtio-net header. Having virtio-net header in such PCAP file breaks
4
a mapping that match a translated address so we can do the reverse.
5
PCAP unconsumable. Unfortunately currently there is no LinkType for
6
virtio-net so for now strip virtio-net header to convert the output to
7
Ethernet.
8
5
9
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
This have linear complexity instead of logarithmic, but it supports
7
overlapping HVA. Future developments could reduce it.
8
9
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
10
Acked-by: Michael S. Tsirkin <mst@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
---
12
include/net/net.h | 6 ++++++
13
include/qemu/iova-tree.h | 20 +++++++++++++++++++-
13
net/dump.c | 11 +++++++----
14
util/iova-tree.c | 34 ++++++++++++++++++++++++++++++++++
14
net/net.c | 18 ++++++++++++++++++
15
2 files changed, 53 insertions(+), 1 deletion(-)
15
net/tap.c | 16 ++++++++++++++++
16
4 files changed, 47 insertions(+), 4 deletions(-)
17
16
18
diff --git a/include/net/net.h b/include/net/net.h
17
diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/include/net/net.h
19
--- a/include/qemu/iova-tree.h
21
+++ b/include/net/net.h
20
+++ b/include/qemu/iova-tree.h
22
@@ -XXX,XX +XXX,XX @@ typedef RxFilterInfo *(QueryRxFilter)(NetClientState *);
21
@@ -XXX,XX +XXX,XX @@ int iova_tree_remove(IOVATree *tree, const DMAMap *map);
23
typedef bool (HasUfo)(NetClientState *);
22
* @tree: the iova tree to search from
24
typedef bool (HasVnetHdr)(NetClientState *);
23
* @map: the mapping to search
25
typedef bool (HasVnetHdrLen)(NetClientState *, int);
24
*
26
+typedef bool (GetUsingVnetHdr)(NetClientState *);
25
- * Search for a mapping in the iova tree that overlaps with the
27
typedef void (UsingVnetHdr)(NetClientState *, bool);
26
+ * Search for a mapping in the iova tree that iova overlaps with the
28
typedef void (SetOffload)(NetClientState *, int, int, int, int, int);
27
* mapping range specified. Only the first found mapping will be
29
+typedef int (GetVnetHdrLen)(NetClientState *);
28
* returned.
30
typedef void (SetVnetHdrLen)(NetClientState *, int);
29
*
31
typedef int (SetVnetLE)(NetClientState *, bool);
30
@@ -XXX,XX +XXX,XX @@ int iova_tree_remove(IOVATree *tree, const DMAMap *map);
32
typedef int (SetVnetBE)(NetClientState *, bool);
31
const DMAMap *iova_tree_find(const IOVATree *tree, const DMAMap *map);
33
@@ -XXX,XX +XXX,XX @@ typedef struct NetClientInfo {
32
34
HasUfo *has_ufo;
33
/**
35
HasVnetHdr *has_vnet_hdr;
34
+ * iova_tree_find_iova:
36
HasVnetHdrLen *has_vnet_hdr_len;
35
+ *
37
+ GetUsingVnetHdr *get_using_vnet_hdr;
36
+ * @tree: the iova tree to search from
38
UsingVnetHdr *using_vnet_hdr;
37
+ * @map: the mapping to search
39
SetOffload *set_offload;
38
+ *
40
+ GetVnetHdrLen *get_vnet_hdr_len;
39
+ * Search for a mapping in the iova tree that translated_addr overlaps with the
41
SetVnetHdrLen *set_vnet_hdr_len;
40
+ * mapping range specified. Only the first found mapping will be
42
SetVnetLE *set_vnet_le;
41
+ * returned.
43
SetVnetBE *set_vnet_be;
42
+ *
44
@@ -XXX,XX +XXX,XX @@ void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]);
43
+ * Return: DMAMap pointer if found, or NULL if not found. Note that
45
bool qemu_has_ufo(NetClientState *nc);
44
+ * the returned DMAMap pointer is maintained internally. User should
46
bool qemu_has_vnet_hdr(NetClientState *nc);
45
+ * only read the content but never modify or free the content. Also,
47
bool qemu_has_vnet_hdr_len(NetClientState *nc, int len);
46
+ * user is responsible to make sure the pointer is valid (say, no
48
+bool qemu_get_using_vnet_hdr(NetClientState *nc);
47
+ * concurrent deletion in progress).
49
void qemu_using_vnet_hdr(NetClientState *nc, bool enable);
48
+ */
50
void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
49
+const DMAMap *iova_tree_find_iova(const IOVATree *tree, const DMAMap *map);
51
int ecn, int ufo);
50
+
52
+int qemu_get_vnet_hdr_len(NetClientState *nc);
51
+/**
53
void qemu_set_vnet_hdr_len(NetClientState *nc, int len);
52
* iova_tree_find_address:
54
int qemu_set_vnet_le(NetClientState *nc, bool is_le);
53
*
55
int qemu_set_vnet_be(NetClientState *nc, bool is_be);
54
* @tree: the iova tree to search from
56
diff --git a/net/dump.c b/net/dump.c
55
diff --git a/util/iova-tree.c b/util/iova-tree.c
57
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
58
--- a/net/dump.c
57
--- a/util/iova-tree.c
59
+++ b/net/dump.c
58
+++ b/util/iova-tree.c
60
@@ -XXX,XX +XXX,XX @@ struct pcap_sf_pkthdr {
59
@@ -XXX,XX +XXX,XX @@ struct IOVATreeAllocArgs {
61
uint32_t len;
60
bool iova_found;
62
};
61
};
63
62
64
-static ssize_t dump_receive_iov(DumpState *s, const struct iovec *iov, int cnt)
63
+typedef struct IOVATreeFindIOVAArgs {
65
+static ssize_t dump_receive_iov(DumpState *s, const struct iovec *iov, int cnt,
64
+ const DMAMap *needle;
66
+ int offset)
65
+ const DMAMap *result;
67
{
66
+} IOVATreeFindIOVAArgs;
68
struct pcap_sf_pkthdr hdr;
67
+
69
int64_t ts;
68
/**
70
int caplen;
69
* Iterate args to the next hole
71
- size_t size = iov_size(iov, cnt);
70
*
72
+ size_t size = iov_size(iov, cnt) - offset;
71
@@ -XXX,XX +XXX,XX @@ const DMAMap *iova_tree_find(const IOVATree *tree, const DMAMap *map)
73
struct iovec dumpiov[cnt + 1];
72
return g_tree_lookup(tree->tree, map);
74
75
/* Early return in case of previous error. */
76
@@ -XXX,XX +XXX,XX @@ static ssize_t dump_receive_iov(DumpState *s, const struct iovec *iov, int cnt)
77
78
dumpiov[0].iov_base = &hdr;
79
dumpiov[0].iov_len = sizeof(hdr);
80
- cnt = iov_copy(&dumpiov[1], cnt, iov, cnt, 0, caplen);
81
+ cnt = iov_copy(&dumpiov[1], cnt, iov, cnt, offset, caplen);
82
83
if (writev(s->fd, dumpiov, cnt + 1) != sizeof(hdr) + caplen) {
84
error_report("network dump write error - stopping dump");
85
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_dump_receive_iov(NetFilterState *nf, NetClientState *sndr,
86
int iovcnt, NetPacketSent *sent_cb)
87
{
88
NetFilterDumpState *nfds = FILTER_DUMP(nf);
89
+ int offset = qemu_get_using_vnet_hdr(nf->netdev) ?
90
+ qemu_get_vnet_hdr_len(nf->netdev) : 0;
91
92
- dump_receive_iov(&nfds->ds, iov, iovcnt);
93
+ dump_receive_iov(&nfds->ds, iov, iovcnt, offset);
94
return 0;
95
}
73
}
96
74
97
diff --git a/net/net.c b/net/net.c
75
+static gboolean iova_tree_find_address_iterator(gpointer key, gpointer value,
98
index XXXXXXX..XXXXXXX 100644
76
+ gpointer data)
99
--- a/net/net.c
100
+++ b/net/net.c
101
@@ -XXX,XX +XXX,XX @@ bool qemu_has_vnet_hdr_len(NetClientState *nc, int len)
102
return nc->info->has_vnet_hdr_len(nc, len);
103
}
104
105
+bool qemu_get_using_vnet_hdr(NetClientState *nc)
106
+{
77
+{
107
+ if (!nc || !nc->info->get_using_vnet_hdr) {
78
+ const DMAMap *map = key;
79
+ IOVATreeFindIOVAArgs *args = data;
80
+ const DMAMap *needle;
81
+
82
+ g_assert(key == value);
83
+
84
+ needle = args->needle;
85
+ if (map->translated_addr + map->size < needle->translated_addr ||
86
+ needle->translated_addr + needle->size < map->translated_addr) {
108
+ return false;
87
+ return false;
109
+ }
88
+ }
110
+
89
+
111
+ return nc->info->get_using_vnet_hdr(nc);
90
+ args->result = map;
91
+ return true;
112
+}
92
+}
113
+
93
+
114
void qemu_using_vnet_hdr(NetClientState *nc, bool enable)
94
+const DMAMap *iova_tree_find_iova(const IOVATree *tree, const DMAMap *map)
115
{
116
if (!nc || !nc->info->using_vnet_hdr) {
117
@@ -XXX,XX +XXX,XX @@ void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
118
nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo);
119
}
120
121
+int qemu_get_vnet_hdr_len(NetClientState *nc)
122
+{
95
+{
123
+ if (!nc || !nc->info->get_vnet_hdr_len) {
96
+ IOVATreeFindIOVAArgs args = {
124
+ return 0;
97
+ .needle = map,
125
+ }
98
+ };
126
+
99
+
127
+ return nc->info->get_vnet_hdr_len(nc);
100
+ g_tree_foreach(tree->tree, iova_tree_find_address_iterator, &args);
101
+ return args.result;
128
+}
102
+}
129
+
103
+
130
void qemu_set_vnet_hdr_len(NetClientState *nc, int len)
104
const DMAMap *iova_tree_find_address(const IOVATree *tree, hwaddr iova)
131
{
105
{
132
if (!nc || !nc->info->set_vnet_hdr_len) {
106
const DMAMap map = { .iova = iova, .size = 0 };
133
diff --git a/net/tap.c b/net/tap.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/net/tap.c
136
+++ b/net/tap.c
137
@@ -XXX,XX +XXX,XX @@ static bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
138
return !!tap_probe_vnet_hdr_len(s->fd, len);
139
}
140
141
+static int tap_get_vnet_hdr_len(NetClientState *nc)
142
+{
143
+ TAPState *s = DO_UPCAST(TAPState, nc, nc);
144
+
145
+ return s->host_vnet_hdr_len;
146
+}
147
+
148
static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
149
{
150
TAPState *s = DO_UPCAST(TAPState, nc, nc);
151
@@ -XXX,XX +XXX,XX @@ static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
152
s->host_vnet_hdr_len = len;
153
}
154
155
+static bool tap_get_using_vnet_hdr(NetClientState *nc)
156
+{
157
+ TAPState *s = DO_UPCAST(TAPState, nc, nc);
158
+
159
+ return s->using_vnet_hdr;
160
+}
161
+
162
static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
163
{
164
TAPState *s = DO_UPCAST(TAPState, nc, nc);
165
@@ -XXX,XX +XXX,XX @@ static NetClientInfo net_tap_info = {
166
.has_ufo = tap_has_ufo,
167
.has_vnet_hdr = tap_has_vnet_hdr,
168
.has_vnet_hdr_len = tap_has_vnet_hdr_len,
169
+ .get_using_vnet_hdr = tap_get_using_vnet_hdr,
170
.using_vnet_hdr = tap_using_vnet_hdr,
171
.set_offload = tap_set_offload,
172
+ .get_vnet_hdr_len = tap_get_vnet_hdr_len,
173
.set_vnet_hdr_len = tap_set_vnet_hdr_len,
174
.set_vnet_le = tap_set_vnet_le,
175
.set_vnet_be = tap_set_vnet_be,
176
--
107
--
177
2.7.4
108
2.7.4
109
110
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
This change is derived from qtest for e1000e device.
3
This tree is able to look for a translated address from an IOVA address.
4
4
5
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
5
At first glance it is similar to util/iova-tree. However, SVQ working on
6
Acked-by: Thomas Huth <thuth@redhat.com>
6
devices with limited IOVA space need more capabilities, like allocating
7
[Jason: make qtest work for win32 (only hotplug)]
7
IOVA chunks or performing reverse translations (qemu addresses to iova).
8
9
The allocation capability, as "assign a free IOVA address to this chunk
10
of memory in qemu's address space" allows shadow virtqueue to create a
11
new address space that is not restricted by guest's addressable one, so
12
we can allocate shadow vqs vrings outside of it.
13
14
It duplicates the tree so it can search efficiently in both directions,
15
and it will signal overlap if iova or the translated address is present
16
in any tree.
17
18
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
19
Acked-by: Michael S. Tsirkin <mst@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
20
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
21
---
10
MAINTAINERS | 2 +
22
hw/virtio/meson.build | 2 +-
11
tests/qtest/fuzz/generic_fuzz_configs.h | 5 +
23
hw/virtio/vhost-iova-tree.c | 110 ++++++++++++++++++++++++++++++++++++++++++++
12
tests/qtest/igb-test.c | 256 ++++++++++++++++++++++++++++++++
24
hw/virtio/vhost-iova-tree.h | 27 +++++++++++
13
tests/qtest/libqos/igb.c | 185 +++++++++++++++++++++++
25
3 files changed, 138 insertions(+), 1 deletion(-)
14
tests/qtest/libqos/meson.build | 1 +
26
create mode 100644 hw/virtio/vhost-iova-tree.c
15
tests/qtest/meson.build | 1 +
27
create mode 100644 hw/virtio/vhost-iova-tree.h
16
6 files changed, 450 insertions(+)
17
create mode 100644 tests/qtest/igb-test.c
18
create mode 100644 tests/qtest/libqos/igb.c
19
28
20
diff --git a/MAINTAINERS b/MAINTAINERS
29
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
21
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
22
--- a/MAINTAINERS
31
--- a/hw/virtio/meson.build
23
+++ b/MAINTAINERS
32
+++ b/hw/virtio/meson.build
24
@@ -XXX,XX +XXX,XX @@ igb
33
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('vhost-stub.c'))
25
M: Akihiko Odaki <akihiko.odaki@daynix.com>
34
26
S: Maintained
35
virtio_ss = ss.source_set()
27
F: hw/net/igb*
36
virtio_ss.add(files('virtio.c'))
28
+F: tests/qtest/igb-test.c
37
-virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c', 'vhost-shadow-virtqueue.c'))
29
+F: tests/qtest/libqos/igb.c
38
+virtio_ss.add(when: 'CONFIG_VHOST', if_true: files('vhost.c', 'vhost-backend.c', 'vhost-shadow-virtqueue.c', 'vhost-iova-tree.c'))
30
39
virtio_ss.add(when: 'CONFIG_VHOST_USER', if_true: files('vhost-user.c'))
31
eepro100
40
virtio_ss.add(when: 'CONFIG_VHOST_VDPA', if_true: files('vhost-vdpa.c'))
32
M: Stefan Weil <sw@weilnetz.de>
41
virtio_ss.add(when: 'CONFIG_VIRTIO_BALLOON', if_true: files('virtio-balloon.c'))
33
diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h
42
diff --git a/hw/virtio/vhost-iova-tree.c b/hw/virtio/vhost-iova-tree.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/tests/qtest/fuzz/generic_fuzz_configs.h
36
+++ b/tests/qtest/fuzz/generic_fuzz_configs.h
37
@@ -XXX,XX +XXX,XX @@ const generic_fuzz_config predefined_configs[] = {
38
"-device e1000e,netdev=net0 -netdev user,id=net0",
39
.objects = "e1000e",
40
},{
41
+ .name = "igb",
42
+ .args = "-M q35 -nodefaults "
43
+ "-device igb,netdev=net0 -netdev user,id=net0",
44
+ .objects = "igb",
45
+ },{
46
.name = "cirrus-vga",
47
.args = "-machine q35 -nodefaults -device cirrus-vga",
48
.objects = "cirrus*",
49
diff --git a/tests/qtest/igb-test.c b/tests/qtest/igb-test.c
50
new file mode 100644
43
new file mode 100644
51
index XXXXXXX..XXXXXXX
44
index XXXXXXX..XXXXXXX
52
--- /dev/null
45
--- /dev/null
53
+++ b/tests/qtest/igb-test.c
46
+++ b/hw/virtio/vhost-iova-tree.c
54
@@ -XXX,XX +XXX,XX @@
47
@@ -XXX,XX +XXX,XX @@
55
+/*
48
+/*
56
+ * QTest testcase for igb NIC
49
+ * vhost software live migration iova tree
57
+ *
50
+ *
58
+ * Copyright (c) 2022-2023 Red Hat, Inc.
51
+ * SPDX-FileCopyrightText: Red Hat, Inc. 2021
59
+ * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
52
+ * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
60
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
61
+ *
53
+ *
62
+ * Authors:
54
+ * SPDX-License-Identifier: GPL-2.0-or-later
63
+ * Akihiko Odaki <akihiko.odaki@daynix.com>
64
+ * Dmitry Fleytman <dmitry@daynix.com>
65
+ * Leonid Bloch <leonid@daynix.com>
66
+ * Yan Vugenfirer <yan@daynix.com>
67
+ *
68
+ * This library is free software; you can redistribute it and/or
69
+ * modify it under the terms of the GNU Lesser General Public
70
+ * License as published by the Free Software Foundation; either
71
+ * version 2.1 of the License, or (at your option) any later version.
72
+ *
73
+ * This library is distributed in the hope that it will be useful,
74
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
75
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
76
+ * Lesser General Public License for more details.
77
+ *
78
+ * You should have received a copy of the GNU Lesser General Public
79
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
80
+ */
55
+ */
81
+
56
+
57
+#include "qemu/osdep.h"
58
+#include "qemu/iova-tree.h"
59
+#include "vhost-iova-tree.h"
82
+
60
+
83
+#include "qemu/osdep.h"
61
+#define iova_min_addr qemu_real_host_page_size
84
+#include "libqtest-single.h"
85
+#include "libqos/pci-pc.h"
86
+#include "net/eth.h"
87
+#include "qemu/sockets.h"
88
+#include "qemu/iov.h"
89
+#include "qemu/module.h"
90
+#include "qemu/bitops.h"
91
+#include "libqos/libqos-malloc.h"
92
+#include "libqos/e1000e.h"
93
+#include "hw/net/igb_regs.h"
94
+
62
+
95
+#ifndef _WIN32
63
+/**
64
+ * VhostIOVATree, able to:
65
+ * - Translate iova address
66
+ * - Reverse translate iova address (from translated to iova)
67
+ * - Allocate IOVA regions for translated range (linear operation)
68
+ */
69
+struct VhostIOVATree {
70
+ /* First addressable iova address in the device */
71
+ uint64_t iova_first;
96
+
72
+
97
+static const struct eth_header packet = {
73
+ /* Last addressable iova address in the device */
98
+ .h_dest = E1000E_ADDRESS,
74
+ uint64_t iova_last;
99
+ .h_source = E1000E_ADDRESS,
75
+
76
+ /* IOVA address to qemu memory maps. */
77
+ IOVATree *iova_taddr_map;
100
+};
78
+};
101
+
79
+
102
+static void igb_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
80
+/**
81
+ * Create a new IOVA tree
82
+ *
83
+ * Returns the new IOVA tree
84
+ */
85
+VhostIOVATree *vhost_iova_tree_new(hwaddr iova_first, hwaddr iova_last)
103
+{
86
+{
104
+ union e1000_adv_tx_desc descr;
87
+ VhostIOVATree *tree = g_new(VhostIOVATree, 1);
105
+ char buffer[64];
106
+ int ret;
107
+ uint32_t recv_len;
108
+
88
+
109
+ /* Prepare test data buffer */
89
+ /* Some devices do not like 0 addresses */
110
+ uint64_t data = guest_alloc(alloc, sizeof(buffer));
90
+ tree->iova_first = MAX(iova_first, iova_min_addr);
111
+ memwrite(data, &packet, sizeof(packet));
91
+ tree->iova_last = iova_last;
112
+
92
+
113
+ /* Prepare TX descriptor */
93
+ tree->iova_taddr_map = iova_tree_new();
114
+ memset(&descr, 0, sizeof(descr));
94
+ return tree;
115
+ descr.read.buffer_addr = cpu_to_le64(data);
116
+ descr.read.cmd_type_len = cpu_to_le32(E1000_TXD_CMD_RS |
117
+ E1000_TXD_CMD_EOP |
118
+ E1000_TXD_DTYP_D |
119
+ sizeof(buffer));
120
+
121
+ /* Put descriptor to the ring */
122
+ e1000e_tx_ring_push(d, &descr);
123
+
124
+ /* Wait for TX WB interrupt */
125
+ e1000e_wait_isr(d, E1000E_TX0_MSG_ID);
126
+
127
+ /* Check DD bit */
128
+ g_assert_cmphex(le32_to_cpu(descr.wb.status) & E1000_TXD_STAT_DD, ==,
129
+ E1000_TXD_STAT_DD);
130
+
131
+ /* Check data sent to the backend */
132
+ ret = recv(test_sockets[0], &recv_len, sizeof(recv_len), 0);
133
+ g_assert_cmpint(ret, == , sizeof(recv_len));
134
+ ret = recv(test_sockets[0], buffer, sizeof(buffer), 0);
135
+ g_assert_cmpint(ret, ==, sizeof(buffer));
136
+ g_assert_false(memcmp(buffer, &packet, sizeof(packet)));
137
+
138
+ /* Free test data buffer */
139
+ guest_free(alloc, data);
140
+}
95
+}
141
+
96
+
142
+static void igb_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
97
+/**
98
+ * Delete an iova tree
99
+ */
100
+void vhost_iova_tree_delete(VhostIOVATree *iova_tree)
143
+{
101
+{
144
+ union e1000_adv_rx_desc descr;
102
+ iova_tree_destroy(iova_tree->iova_taddr_map);
145
+
103
+ g_free(iova_tree);
146
+ struct eth_header test_iov = packet;
147
+ int len = htonl(sizeof(packet));
148
+ struct iovec iov[] = {
149
+ {
150
+ .iov_base = &len,
151
+ .iov_len = sizeof(len),
152
+ },{
153
+ .iov_base = &test_iov,
154
+ .iov_len = sizeof(packet),
155
+ },
156
+ };
157
+
158
+ char buffer[64];
159
+ int ret;
160
+
161
+ /* Send a dummy packet to device's socket*/
162
+ ret = iov_send(test_sockets[0], iov, 2, 0, sizeof(len) + sizeof(packet));
163
+ g_assert_cmpint(ret, == , sizeof(packet) + sizeof(len));
164
+
165
+ /* Prepare test data buffer */
166
+ uint64_t data = guest_alloc(alloc, sizeof(buffer));
167
+
168
+ /* Prepare RX descriptor */
169
+ memset(&descr, 0, sizeof(descr));
170
+ descr.read.pkt_addr = cpu_to_le64(data);
171
+
172
+ /* Put descriptor to the ring */
173
+ e1000e_rx_ring_push(d, &descr);
174
+
175
+ /* Wait for TX WB interrupt */
176
+ e1000e_wait_isr(d, E1000E_RX0_MSG_ID);
177
+
178
+ /* Check DD bit */
179
+ g_assert_cmphex(le32_to_cpu(descr.wb.upper.status_error) &
180
+ E1000_RXD_STAT_DD, ==, E1000_RXD_STAT_DD);
181
+
182
+ /* Check data sent to the backend */
183
+ memread(data, buffer, sizeof(buffer));
184
+ g_assert_false(memcmp(buffer, &packet, sizeof(packet)));
185
+
186
+ /* Free test data buffer */
187
+ guest_free(alloc, data);
188
+}
104
+}
189
+
105
+
190
+static void test_e1000e_init(void *obj, void *data, QGuestAllocator * alloc)
106
+/**
107
+ * Find the IOVA address stored from a memory address
108
+ *
109
+ * @tree: The iova tree
110
+ * @map: The map with the memory address
111
+ *
112
+ * Return the stored mapping, or NULL if not found.
113
+ */
114
+const DMAMap *vhost_iova_tree_find_iova(const VhostIOVATree *tree,
115
+ const DMAMap *map)
191
+{
116
+{
192
+ /* init does nothing */
117
+ return iova_tree_find_iova(tree->iova_taddr_map, map);
193
+}
118
+}
194
+
119
+
195
+static void test_igb_tx(void *obj, void *data, QGuestAllocator * alloc)
120
+/**
121
+ * Allocate a new mapping
122
+ *
123
+ * @tree: The iova tree
124
+ * @map: The iova map
125
+ *
126
+ * Returns:
127
+ * - IOVA_OK if the map fits in the container
128
+ * - IOVA_ERR_INVALID if the map does not make sense (like size overflow)
129
+ * - IOVA_ERR_NOMEM if tree cannot allocate more space.
130
+ *
131
+ * It returns assignated iova in map->iova if return value is VHOST_DMA_MAP_OK.
132
+ */
133
+int vhost_iova_tree_map_alloc(VhostIOVATree *tree, DMAMap *map)
196
+{
134
+{
197
+ QE1000E_PCI *e1000e = obj;
135
+ /* Some vhost devices do not like addr 0. Skip first page */
198
+ QE1000E *d = &e1000e->e1000e;
136
+ hwaddr iova_first = tree->iova_first ?: qemu_real_host_page_size;
199
+ QOSGraphObject *e_object = obj;
200
+ QPCIDevice *dev = e_object->get_driver(e_object, "pci-device");
201
+
137
+
202
+ /* FIXME: add spapr support */
138
+ if (map->translated_addr + map->size < map->translated_addr ||
203
+ if (qpci_check_buggy_msi(dev)) {
139
+ map->perm == IOMMU_NONE) {
204
+ return;
140
+ return IOVA_ERR_INVALID;
205
+ }
141
+ }
206
+
142
+
207
+ igb_send_verify(d, data, alloc);
143
+ /* Allocate a node in IOVA address */
144
+ return iova_tree_alloc_map(tree->iova_taddr_map, map, iova_first,
145
+ tree->iova_last);
208
+}
146
+}
209
+
147
+
210
+static void test_igb_rx(void *obj, void *data, QGuestAllocator * alloc)
148
+/**
149
+ * Remove existing mappings from iova tree
150
+ *
151
+ * @iova_tree: The vhost iova tree
152
+ * @map: The map to remove
153
+ */
154
+void vhost_iova_tree_remove(VhostIOVATree *iova_tree, const DMAMap *map)
211
+{
155
+{
212
+ QE1000E_PCI *e1000e = obj;
156
+ iova_tree_remove(iova_tree->iova_taddr_map, map);
213
+ QE1000E *d = &e1000e->e1000e;
214
+ QOSGraphObject *e_object = obj;
215
+ QPCIDevice *dev = e_object->get_driver(e_object, "pci-device");
216
+
217
+ /* FIXME: add spapr support */
218
+ if (qpci_check_buggy_msi(dev)) {
219
+ return;
220
+ }
221
+
222
+ igb_receive_verify(d, data, alloc);
223
+}
157
+}
224
+
158
diff --git a/hw/virtio/vhost-iova-tree.h b/hw/virtio/vhost-iova-tree.h
225
+static void test_igb_multiple_transfers(void *obj, void *data,
226
+ QGuestAllocator *alloc)
227
+{
228
+ static const long iterations = 4 * 1024;
229
+ long i;
230
+
231
+ QE1000E_PCI *e1000e = obj;
232
+ QE1000E *d = &e1000e->e1000e;
233
+ QOSGraphObject *e_object = obj;
234
+ QPCIDevice *dev = e_object->get_driver(e_object, "pci-device");
235
+
236
+ /* FIXME: add spapr support */
237
+ if (qpci_check_buggy_msi(dev)) {
238
+ return;
239
+ }
240
+
241
+ for (i = 0; i < iterations; i++) {
242
+ igb_send_verify(d, data, alloc);
243
+ igb_receive_verify(d, data, alloc);
244
+ }
245
+
246
+}
247
+
248
+static void data_test_clear(void *sockets)
249
+{
250
+ int *test_sockets = sockets;
251
+
252
+ close(test_sockets[0]);
253
+ qos_invalidate_command_line();
254
+ close(test_sockets[1]);
255
+ g_free(test_sockets);
256
+}
257
+
258
+static void *data_test_init(GString *cmd_line, void *arg)
259
+{
260
+ int *test_sockets = g_new(int, 2);
261
+ int ret = socketpair(PF_UNIX, SOCK_STREAM, 0, test_sockets);
262
+ g_assert_cmpint(ret, != , -1);
263
+
264
+ g_string_append_printf(cmd_line, " -netdev socket,fd=%d,id=hs0 ",
265
+ test_sockets[1]);
266
+
267
+ g_test_queue_destroy(data_test_clear, test_sockets);
268
+ return test_sockets;
269
+}
270
+
271
+#endif
272
+
273
+static void *data_test_init_no_socket(GString *cmd_line, void *arg)
274
+{
275
+ g_string_append(cmd_line, " -netdev hubport,hubid=0,id=hs0 ");
276
+ return arg;
277
+}
278
+
279
+static void test_igb_hotplug(void *obj, void *data, QGuestAllocator * alloc)
280
+{
281
+ QTestState *qts = global_qtest; /* TODO: get rid of global_qtest here */
282
+ QE1000E_PCI *dev = obj;
283
+
284
+ if (dev->pci_dev.bus->not_hotpluggable) {
285
+ g_test_skip("pci bus does not support hotplug");
286
+ return;
287
+ }
288
+
289
+ qtest_qmp_device_add(qts, "igb", "igb_net", "{'addr': '0x06'}");
290
+ qpci_unplug_acpi_device_test(qts, "igb_net", 0x06);
291
+}
292
+
293
+static void register_igb_test(void)
294
+{
295
+ QOSGraphTestOptions opts = { 0 };
296
+
297
+#ifndef _WIN32
298
+ opts.before = data_test_init,
299
+ qos_add_test("init", "igb", test_e1000e_init, &opts);
300
+ qos_add_test("tx", "igb", test_igb_tx, &opts);
301
+ qos_add_test("rx", "igb", test_igb_rx, &opts);
302
+ qos_add_test("multiple_transfers", "igb",
303
+ test_igb_multiple_transfers, &opts);
304
+#endif
305
+
306
+ opts.before = data_test_init_no_socket;
307
+ qos_add_test("hotplug", "igb", test_igb_hotplug, &opts);
308
+}
309
+
310
+libqos_init(register_igb_test);
311
diff --git a/tests/qtest/libqos/igb.c b/tests/qtest/libqos/igb.c
312
new file mode 100644
159
new file mode 100644
313
index XXXXXXX..XXXXXXX
160
index XXXXXXX..XXXXXXX
314
--- /dev/null
161
--- /dev/null
315
+++ b/tests/qtest/libqos/igb.c
162
+++ b/hw/virtio/vhost-iova-tree.h
316
@@ -XXX,XX +XXX,XX @@
163
@@ -XXX,XX +XXX,XX @@
317
+/*
164
+/*
318
+ * libqos driver framework
165
+ * vhost software live migration iova tree
319
+ *
166
+ *
320
+ * Copyright (c) 2022-2023 Red Hat, Inc.
167
+ * SPDX-FileCopyrightText: Red Hat, Inc. 2021
321
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
168
+ * SPDX-FileContributor: Author: Eugenio Pérez <eperezma@redhat.com>
322
+ *
169
+ *
323
+ * This library is free software; you can redistribute it and/or
170
+ * SPDX-License-Identifier: GPL-2.0-or-later
324
+ * modify it under the terms of the GNU Lesser General Public
325
+ * License version 2.1 as published by the Free Software Foundation.
326
+ *
327
+ * This library is distributed in the hope that it will be useful,
328
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
329
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
330
+ * Lesser General Public License for more details.
331
+ *
332
+ * You should have received a copy of the GNU Lesser General Public
333
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>
334
+ */
171
+ */
335
+
172
+
336
+#include "qemu/osdep.h"
173
+#ifndef HW_VIRTIO_VHOST_IOVA_TREE_H
337
+#include "hw/net/igb_regs.h"
174
+#define HW_VIRTIO_VHOST_IOVA_TREE_H
338
+#include "hw/net/mii.h"
339
+#include "hw/pci/pci_ids.h"
340
+#include "../libqtest.h"
341
+#include "pci-pc.h"
342
+#include "qemu/sockets.h"
343
+#include "qemu/iov.h"
344
+#include "qemu/module.h"
345
+#include "qemu/bitops.h"
346
+#include "libqos-malloc.h"
347
+#include "qgraph.h"
348
+#include "e1000e.h"
349
+
175
+
350
+#define IGB_IVAR_TEST_CFG \
176
+#include "qemu/iova-tree.h"
351
+ ((E1000E_RX0_MSG_ID | E1000_IVAR_VALID) << (igb_ivar_entry_rx(0) * 8) | \
177
+#include "exec/memory.h"
352
+ ((E1000E_TX0_MSG_ID | E1000_IVAR_VALID) << (igb_ivar_entry_tx(0) * 8)))
353
+
178
+
354
+#define E1000E_RING_LEN (0x1000)
179
+typedef struct VhostIOVATree VhostIOVATree;
355
+
180
+
356
+static void e1000e_foreach_callback(QPCIDevice *dev, int devfn, void *data)
181
+VhostIOVATree *vhost_iova_tree_new(uint64_t iova_first, uint64_t iova_last);
357
+{
182
+void vhost_iova_tree_delete(VhostIOVATree *iova_tree);
358
+ QPCIDevice *res = data;
183
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostIOVATree, vhost_iova_tree_delete);
359
+ memcpy(res, dev, sizeof(QPCIDevice));
360
+ g_free(dev);
361
+}
362
+
184
+
363
+static void e1000e_pci_destructor(QOSGraphObject *obj)
185
+const DMAMap *vhost_iova_tree_find_iova(const VhostIOVATree *iova_tree,
364
+{
186
+ const DMAMap *map);
365
+ QE1000E_PCI *epci = (QE1000E_PCI *) obj;
187
+int vhost_iova_tree_map_alloc(VhostIOVATree *iova_tree, DMAMap *map);
366
+ qpci_iounmap(&epci->pci_dev, epci->mac_regs);
188
+void vhost_iova_tree_remove(VhostIOVATree *iova_tree, const DMAMap *map);
367
+ qpci_msix_disable(&epci->pci_dev);
368
+}
369
+
189
+
370
+static void igb_pci_start_hw(QOSGraphObject *obj)
190
+#endif
371
+{
372
+ static const uint8_t address[] = E1000E_ADDRESS;
373
+ QE1000E_PCI *d = (QE1000E_PCI *) obj;
374
+ uint32_t val;
375
+
376
+ /* Enable the device */
377
+ qpci_device_enable(&d->pci_dev);
378
+
379
+ /* Reset the device */
380
+ val = e1000e_macreg_read(&d->e1000e, E1000_CTRL);
381
+ e1000e_macreg_write(&d->e1000e, E1000_CTRL, val | E1000_CTRL_RST | E1000_CTRL_SLU);
382
+
383
+ /* Setup link */
384
+ e1000e_macreg_write(&d->e1000e, E1000_MDIC,
385
+ MII_BMCR_AUTOEN | MII_BMCR_ANRESTART |
386
+ (MII_BMCR << E1000_MDIC_REG_SHIFT) |
387
+ (1 << E1000_MDIC_PHY_SHIFT) |
388
+ E1000_MDIC_OP_WRITE);
389
+
390
+ qtest_clock_step(d->pci_dev.bus->qts, 900000000);
391
+
392
+ /* Enable and configure MSI-X */
393
+ qpci_msix_enable(&d->pci_dev);
394
+ e1000e_macreg_write(&d->e1000e, E1000_IVAR0, IGB_IVAR_TEST_CFG);
395
+
396
+ /* Check the device link status */
397
+ val = e1000e_macreg_read(&d->e1000e, E1000_STATUS);
398
+ g_assert_cmphex(val & E1000_STATUS_LU, ==, E1000_STATUS_LU);
399
+
400
+ /* Initialize TX/RX logic */
401
+ e1000e_macreg_write(&d->e1000e, E1000_RCTL, 0);
402
+ e1000e_macreg_write(&d->e1000e, E1000_TCTL, 0);
403
+
404
+ e1000e_macreg_write(&d->e1000e, E1000_TDBAL(0),
405
+ (uint32_t) d->e1000e.tx_ring);
406
+ e1000e_macreg_write(&d->e1000e, E1000_TDBAH(0),
407
+ (uint32_t) (d->e1000e.tx_ring >> 32));
408
+ e1000e_macreg_write(&d->e1000e, E1000_TDLEN(0), E1000E_RING_LEN);
409
+ e1000e_macreg_write(&d->e1000e, E1000_TDT(0), 0);
410
+ e1000e_macreg_write(&d->e1000e, E1000_TDH(0), 0);
411
+
412
+ /* Enable transmit */
413
+ e1000e_macreg_write(&d->e1000e, E1000_TCTL, E1000_TCTL_EN);
414
+
415
+ e1000e_macreg_write(&d->e1000e, E1000_RDBAL(0),
416
+ (uint32_t)d->e1000e.rx_ring);
417
+ e1000e_macreg_write(&d->e1000e, E1000_RDBAH(0),
418
+ (uint32_t)(d->e1000e.rx_ring >> 32));
419
+ e1000e_macreg_write(&d->e1000e, E1000_RDLEN(0), E1000E_RING_LEN);
420
+ e1000e_macreg_write(&d->e1000e, E1000_RDT(0), 0);
421
+ e1000e_macreg_write(&d->e1000e, E1000_RDH(0), 0);
422
+ e1000e_macreg_write(&d->e1000e, E1000_RA,
423
+ le32_to_cpu(*(uint32_t *)address));
424
+ e1000e_macreg_write(&d->e1000e, E1000_RA + 4,
425
+ E1000_RAH_AV | E1000_RAH_POOL_1 |
426
+ le16_to_cpu(*(uint16_t *)(address + 4)));
427
+
428
+ /* Enable receive */
429
+ e1000e_macreg_write(&d->e1000e, E1000_RFCTL, E1000_RFCTL_EXTEN);
430
+ e1000e_macreg_write(&d->e1000e, E1000_RCTL, E1000_RCTL_EN);
431
+
432
+ /* Enable all interrupts */
433
+ e1000e_macreg_write(&d->e1000e, E1000_IMS, 0xFFFFFFFF);
434
+ e1000e_macreg_write(&d->e1000e, E1000_EIMS, 0xFFFFFFFF);
435
+
436
+}
437
+
438
+static void *igb_pci_get_driver(void *obj, const char *interface)
439
+{
440
+ QE1000E_PCI *epci = obj;
441
+ if (!g_strcmp0(interface, "igb-if")) {
442
+ return &epci->e1000e;
443
+ }
444
+
445
+ /* implicit contains */
446
+ if (!g_strcmp0(interface, "pci-device")) {
447
+ return &epci->pci_dev;
448
+ }
449
+
450
+ fprintf(stderr, "%s not present in igb\n", interface);
451
+ g_assert_not_reached();
452
+}
453
+
454
+static void *igb_pci_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
455
+{
456
+ QE1000E_PCI *d = g_new0(QE1000E_PCI, 1);
457
+ QPCIBus *bus = pci_bus;
458
+ QPCIAddress *address = addr;
459
+
460
+ qpci_device_foreach(bus, address->vendor_id, address->device_id,
461
+ e1000e_foreach_callback, &d->pci_dev);
462
+
463
+ /* Map BAR0 (mac registers) */
464
+ d->mac_regs = qpci_iomap(&d->pci_dev, 0, NULL);
465
+
466
+ /* Allocate and setup TX ring */
467
+ d->e1000e.tx_ring = guest_alloc(alloc, E1000E_RING_LEN);
468
+ g_assert(d->e1000e.tx_ring != 0);
469
+
470
+ /* Allocate and setup RX ring */
471
+ d->e1000e.rx_ring = guest_alloc(alloc, E1000E_RING_LEN);
472
+ g_assert(d->e1000e.rx_ring != 0);
473
+
474
+ d->obj.get_driver = igb_pci_get_driver;
475
+ d->obj.start_hw = igb_pci_start_hw;
476
+ d->obj.destructor = e1000e_pci_destructor;
477
+
478
+ return &d->obj;
479
+}
480
+
481
+static void igb_register_nodes(void)
482
+{
483
+ QPCIAddress addr = {
484
+ .vendor_id = PCI_VENDOR_ID_INTEL,
485
+ .device_id = E1000_DEV_ID_82576,
486
+ };
487
+
488
+ /*
489
+ * FIXME: every test using this node needs to setup a -netdev socket,id=hs0
490
+ * otherwise QEMU is not going to start
491
+ */
492
+ QOSGraphEdgeOptions opts = {
493
+ .extra_device_opts = "netdev=hs0",
494
+ };
495
+ add_qpci_address(&opts, &addr);
496
+
497
+ qos_node_create_driver("igb", igb_pci_create);
498
+ qos_node_consumes("igb", "pci-bus", &opts);
499
+}
500
+
501
+libqos_init(igb_register_nodes);
502
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
503
index XXXXXXX..XXXXXXX 100644
504
--- a/tests/qtest/libqos/meson.build
505
+++ b/tests/qtest/libqos/meson.build
506
@@ -XXX,XX +XXX,XX @@ libqos_srcs = files(
507
'i2c.c',
508
'i2c-imx.c',
509
'i2c-omap.c',
510
+ 'igb.c',
511
'sdhci.c',
512
'tpci200.c',
513
'virtio.c',
514
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
515
index XXXXXXX..XXXXXXX 100644
516
--- a/tests/qtest/meson.build
517
+++ b/tests/qtest/meson.build
518
@@ -XXX,XX +XXX,XX @@ qos_test_ss.add(
519
'virtio-scsi-test.c',
520
'virtio-iommu-test.c',
521
'vmxnet3-test.c',
522
+ 'igb-test.c',
523
)
524
525
if config_all_devices.has_key('CONFIG_VIRTIO_SERIAL')
526
--
191
--
527
2.7.4
192
2.7.4
193
194
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
This change introduces emulation for the Intel 82576 adapter, AKA igb.
3
Use translations added in VhostIOVATree in SVQ.
4
The details of the device will be provided by the documentation that
4
5
will follow this change.
5
Only introduce usage here, not allocation and deallocation. As with
6
6
previous patches, we use the dead code paths of shadow_vqs_enabled to
7
This initial implementation of igb does not cover the full feature set,
7
avoid commiting too many changes at once. These are impossible to take
8
but it selectively implements changes necessary to pass tests of Linut
8
at the moment.
9
Test Project, and Windows HLK. The below is the list of the implemented
9
10
changes; anything not listed here is not implemented:
10
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
11
11
Acked-by: Michael S. Tsirkin <mst@redhat.com>
12
New features:
13
- igb advanced descriptor handling
14
- Support of 16 queues
15
- SRRCTL.BSIZEPACKET register field
16
- SRRCTL.RDMTS register field
17
- Tx descriptor completion writeback
18
- Extended RA registers
19
- VMDq feature
20
- MRQC "Multiple Receive Queues Enable" register field
21
- DTXSWC.Loopback_en register field
22
- VMOLR.ROMPE register field
23
- VMOLR.AUPE register field
24
- VLVF.VLAN_id register field
25
- VLVF.VI_En register field
26
- VF
27
- Mailbox
28
- Reset
29
- Extended interrupt registers
30
- Default values for IGP01E1000 PHY registers
31
32
Removed features:
33
- e1000e extended descriptor
34
- e1000e packet split descriptor
35
- Legacy descriptor
36
- PHY register paging
37
- MAC Registers
38
- Legacy interrupt timer registers
39
- Legacy EEPROM registers
40
- PBA/POEM registers
41
- RSRPD register
42
- RFCTL.ACKDIS
43
- RCTL.DTYPE
44
- Copper PHY registers
45
46
Misc:
47
- VET register format
48
- ICR register format
49
50
Signed-off-by: Gal Hammer <gal.hammer@sap.com>
51
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
52
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
53
[Jason: don't abort on msi(x)_init()]
54
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
55
---
13
---
56
MAINTAINERS | 5 +
14
hw/virtio/vhost-shadow-virtqueue.c | 86 +++++++++++++++++++++++---
57
hw/net/Kconfig | 5 +
15
hw/virtio/vhost-shadow-virtqueue.h | 6 +-
58
hw/net/igb.c | 623 ++++++++
16
hw/virtio/vhost-vdpa.c | 122 +++++++++++++++++++++++++++++++------
59
hw/net/igb_common.h | 146 ++
17
include/hw/virtio/vhost-vdpa.h | 3 +
60
hw/net/igb_core.c | 4077 +++++++++++++++++++++++++++++++++++++++++++++++++++
18
4 files changed, 187 insertions(+), 30 deletions(-)
61
hw/net/igb_core.h | 146 ++
19
62
hw/net/igb_regs.h | 648 ++++++++
20
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
63
hw/net/igbvf.c | 327 +++++
64
hw/net/meson.build | 2 +
65
hw/net/trace-events | 32 +
66
10 files changed, 6011 insertions(+)
67
create mode 100644 hw/net/igb.c
68
create mode 100644 hw/net/igb_common.h
69
create mode 100644 hw/net/igb_core.c
70
create mode 100644 hw/net/igb_core.h
71
create mode 100644 hw/net/igb_regs.h
72
create mode 100644 hw/net/igbvf.c
73
74
diff --git a/MAINTAINERS b/MAINTAINERS
75
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
76
--- a/MAINTAINERS
22
--- a/hw/virtio/vhost-shadow-virtqueue.c
77
+++ b/MAINTAINERS
23
+++ b/hw/virtio/vhost-shadow-virtqueue.c
78
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-e1000e-test.c
24
@@ -XXX,XX +XXX,XX @@ static uint16_t vhost_svq_available_slots(const VhostShadowVirtqueue *svq)
79
F: tests/qtest/e1000e-test.c
25
return svq->vring.num - (svq->shadow_avail_idx - svq->shadow_used_idx);
80
F: tests/qtest/libqos/e1000e.*
26
}
81
27
82
+igb
28
-static void vhost_vring_write_descs(VhostShadowVirtqueue *svq,
83
+M: Akihiko Odaki <akihiko.odaki@daynix.com>
29
+/**
84
+S: Maintained
30
+ * Translate addresses between the qemu's virtual address and the SVQ IOVA
85
+F: hw/net/igb*
86
+
87
eepro100
88
M: Stefan Weil <sw@weilnetz.de>
89
S: Maintained
90
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
91
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/net/Kconfig
93
+++ b/hw/net/Kconfig
94
@@ -XXX,XX +XXX,XX @@ config E1000E_PCI_EXPRESS
95
default y if PCI_DEVICES
96
depends on PCI_EXPRESS && MSI_NONBROKEN
97
98
+config IGB_PCI_EXPRESS
99
+ bool
100
+ default y if PCI_DEVICES
101
+ depends on PCI_EXPRESS && MSI_NONBROKEN
102
+
103
config RTL8139_PCI
104
bool
105
default y if PCI_DEVICES
106
diff --git a/hw/net/igb.c b/hw/net/igb.c
107
new file mode 100644
108
index XXXXXXX..XXXXXXX
109
--- /dev/null
110
+++ b/hw/net/igb.c
111
@@ -XXX,XX +XXX,XX @@
112
+/*
113
+ * QEMU Intel 82576 SR/IOV Ethernet Controller Emulation
114
+ *
31
+ *
115
+ * Datasheet:
32
+ * @svq: Shadow VirtQueue
116
+ * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82576eg-gbe-datasheet.pdf
33
+ * @vaddr: Translated IOVA addresses
117
+ *
34
+ * @iovec: Source qemu's VA addresses
118
+ * Copyright (c) 2020-2023 Red Hat, Inc.
35
+ * @num: Length of iovec and minimum length of vaddr
119
+ * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
120
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
121
+ *
122
+ * Authors:
123
+ * Akihiko Odaki <akihiko.odaki@daynix.com>
124
+ * Gal Hammmer <gal.hammer@sap.com>
125
+ * Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
126
+ * Dmitry Fleytman <dmitry@daynix.com>
127
+ * Leonid Bloch <leonid@daynix.com>
128
+ * Yan Vugenfirer <yan@daynix.com>
129
+ *
130
+ * Based on work done by:
131
+ * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
132
+ * Copyright (c) 2008 Qumranet
133
+ * Based on work done by:
134
+ * Copyright (c) 2007 Dan Aloni
135
+ * Copyright (c) 2004 Antony T Curtis
136
+ *
137
+ * This library is free software; you can redistribute it and/or
138
+ * modify it under the terms of the GNU Lesser General Public
139
+ * License as published by the Free Software Foundation; either
140
+ * version 2.1 of the License, or (at your option) any later version.
141
+ *
142
+ * This library is distributed in the hope that it will be useful,
143
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
144
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
145
+ * Lesser General Public License for more details.
146
+ *
147
+ * You should have received a copy of the GNU Lesser General Public
148
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
149
+ */
36
+ */
150
+
37
+static bool vhost_svq_translate_addr(const VhostShadowVirtqueue *svq,
151
+#include "qemu/osdep.h"
38
+ hwaddr *addrs, const struct iovec *iovec,
152
+#include "qemu/units.h"
39
+ size_t num)
153
+#include "net/eth.h"
154
+#include "net/net.h"
155
+#include "net/tap.h"
156
+#include "qemu/module.h"
157
+#include "qemu/range.h"
158
+#include "sysemu/sysemu.h"
159
+#include "hw/hw.h"
160
+#include "hw/net/mii.h"
161
+#include "hw/pci/pci.h"
162
+#include "hw/pci/pcie.h"
163
+#include "hw/pci/pcie_sriov.h"
164
+#include "hw/pci/msi.h"
165
+#include "hw/pci/msix.h"
166
+#include "hw/qdev-properties.h"
167
+#include "migration/vmstate.h"
168
+
169
+#include "igb_common.h"
170
+#include "igb_core.h"
171
+
172
+#include "trace.h"
173
+#include "qapi/error.h"
174
+#include "qom/object.h"
175
+
176
+#define TYPE_IGB "igb"
177
+OBJECT_DECLARE_SIMPLE_TYPE(IGBState, IGB)
178
+
179
+struct IGBState {
180
+ PCIDevice parent_obj;
181
+ NICState *nic;
182
+ NICConf conf;
183
+
184
+ MemoryRegion mmio;
185
+ MemoryRegion flash;
186
+ MemoryRegion io;
187
+ MemoryRegion msix;
188
+
189
+ uint32_t ioaddr;
190
+
191
+ IGBCore core;
192
+};
193
+
194
+#define IGB_CAP_SRIOV_OFFSET (0x160)
195
+#define IGB_VF_OFFSET (0x80)
196
+#define IGB_VF_STRIDE (2)
197
+
198
+#define E1000E_MMIO_IDX 0
199
+#define E1000E_FLASH_IDX 1
200
+#define E1000E_IO_IDX 2
201
+#define E1000E_MSIX_IDX 3
202
+
203
+#define E1000E_MMIO_SIZE (128 * KiB)
204
+#define E1000E_FLASH_SIZE (128 * KiB)
205
+#define E1000E_IO_SIZE (32)
206
+#define E1000E_MSIX_SIZE (16 * KiB)
207
+
208
+static void igb_write_config(PCIDevice *dev, uint32_t addr,
209
+ uint32_t val, int len)
210
+{
40
+{
211
+ IGBState *s = IGB(dev);
41
+ if (num == 0) {
212
+
213
+ trace_igb_write_config(addr, val, len);
214
+ pci_default_write_config(dev, addr, val, len);
215
+
216
+ if (range_covers_byte(addr, len, PCI_COMMAND) &&
217
+ (dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
218
+ igb_start_recv(&s->core);
219
+ }
220
+}
221
+
222
+uint64_t
223
+igb_mmio_read(void *opaque, hwaddr addr, unsigned size)
224
+{
225
+ IGBState *s = opaque;
226
+ return igb_core_read(&s->core, addr, size);
227
+}
228
+
229
+void
230
+igb_mmio_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
231
+{
232
+ IGBState *s = opaque;
233
+ igb_core_write(&s->core, addr, val, size);
234
+}
235
+
236
+static bool
237
+igb_io_get_reg_index(IGBState *s, uint32_t *idx)
238
+{
239
+ if (s->ioaddr < 0x1FFFF) {
240
+ *idx = s->ioaddr;
241
+ return true;
42
+ return true;
242
+ }
43
+ }
243
+
44
+
244
+ if (s->ioaddr < 0x7FFFF) {
45
+ for (size_t i = 0; i < num; ++i) {
245
+ trace_e1000e_wrn_io_addr_undefined(s->ioaddr);
46
+ DMAMap needle = {
246
+ return false;
47
+ .translated_addr = (hwaddr)(uintptr_t)iovec[i].iov_base,
247
+ }
48
+ .size = iovec[i].iov_len,
248
+
49
+ };
249
+ if (s->ioaddr < 0xFFFFF) {
50
+ Int128 needle_last, map_last;
250
+ trace_e1000e_wrn_io_addr_flash(s->ioaddr);
51
+ size_t off;
251
+ return false;
52
+
252
+ }
53
+ const DMAMap *map = vhost_iova_tree_find_iova(svq->iova_tree, &needle);
253
+
254
+ trace_e1000e_wrn_io_addr_unknown(s->ioaddr);
255
+ return false;
256
+}
257
+
258
+static uint64_t
259
+igb_io_read(void *opaque, hwaddr addr, unsigned size)
260
+{
261
+ IGBState *s = opaque;
262
+ uint32_t idx = 0;
263
+ uint64_t val;
264
+
265
+ switch (addr) {
266
+ case E1000_IOADDR:
267
+ trace_e1000e_io_read_addr(s->ioaddr);
268
+ return s->ioaddr;
269
+ case E1000_IODATA:
270
+ if (igb_io_get_reg_index(s, &idx)) {
271
+ val = igb_core_read(&s->core, idx, sizeof(val));
272
+ trace_e1000e_io_read_data(idx, val);
273
+ return val;
274
+ }
275
+ return 0;
276
+ default:
277
+ trace_e1000e_wrn_io_read_unknown(addr);
278
+ return 0;
279
+ }
280
+}
281
+
282
+static void
283
+igb_io_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
284
+{
285
+ IGBState *s = opaque;
286
+ uint32_t idx = 0;
287
+
288
+ switch (addr) {
289
+ case E1000_IOADDR:
290
+ trace_e1000e_io_write_addr(val);
291
+ s->ioaddr = (uint32_t) val;
292
+ return;
293
+ case E1000_IODATA:
294
+ if (igb_io_get_reg_index(s, &idx)) {
295
+ trace_e1000e_io_write_data(idx, val);
296
+ igb_core_write(&s->core, idx, val, sizeof(val));
297
+ }
298
+ return;
299
+ default:
300
+ trace_e1000e_wrn_io_write_unknown(addr);
301
+ return;
302
+ }
303
+}
304
+
305
+static const MemoryRegionOps mmio_ops = {
306
+ .read = igb_mmio_read,
307
+ .write = igb_mmio_write,
308
+ .endianness = DEVICE_LITTLE_ENDIAN,
309
+ .impl = {
310
+ .min_access_size = 4,
311
+ .max_access_size = 4,
312
+ },
313
+};
314
+
315
+static const MemoryRegionOps io_ops = {
316
+ .read = igb_io_read,
317
+ .write = igb_io_write,
318
+ .endianness = DEVICE_LITTLE_ENDIAN,
319
+ .impl = {
320
+ .min_access_size = 4,
321
+ .max_access_size = 4,
322
+ },
323
+};
324
+
325
+static bool
326
+igb_nc_can_receive(NetClientState *nc)
327
+{
328
+ IGBState *s = qemu_get_nic_opaque(nc);
329
+ return igb_can_receive(&s->core);
330
+}
331
+
332
+static ssize_t
333
+igb_nc_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
334
+{
335
+ IGBState *s = qemu_get_nic_opaque(nc);
336
+ return igb_receive_iov(&s->core, iov, iovcnt);
337
+}
338
+
339
+static ssize_t
340
+igb_nc_receive(NetClientState *nc, const uint8_t *buf, size_t size)
341
+{
342
+ IGBState *s = qemu_get_nic_opaque(nc);
343
+ return igb_receive(&s->core, buf, size);
344
+}
345
+
346
+static void
347
+igb_set_link_status(NetClientState *nc)
348
+{
349
+ IGBState *s = qemu_get_nic_opaque(nc);
350
+ igb_core_set_link_status(&s->core);
351
+}
352
+
353
+static NetClientInfo net_igb_info = {
354
+ .type = NET_CLIENT_DRIVER_NIC,
355
+ .size = sizeof(NICState),
356
+ .can_receive = igb_nc_can_receive,
357
+ .receive = igb_nc_receive,
358
+ .receive_iov = igb_nc_receive_iov,
359
+ .link_status_changed = igb_set_link_status,
360
+};
361
+
362
+/*
363
+ * EEPROM (NVM) contents documented in section 6.1, table 6-1:
364
+ * and in 6.10 Software accessed words.
365
+ */
366
+static const uint16_t igb_eeprom_template[] = {
367
+ /* Address |Compat.|OEM sp.| ImRev | OEM sp. */
368
+ 0x0000, 0x0000, 0x0000, 0x0d34, 0xffff, 0x2010, 0xffff, 0xffff,
369
+ /* PBA |ICtrl1 | SSID | SVID | DevID |-------|ICtrl2 */
370
+ 0x1040, 0xffff, 0x002b, 0x0000, 0x8086, 0x10c9, 0x0000, 0x70c3,
371
+ /* SwPin0| DevID | EESZ |-------|ICtrl3 |PCI-tc | MSIX | APtr */
372
+ 0x0004, 0x10c9, 0x5c00, 0x0000, 0x2880, 0x0014, 0x4a40, 0x0060,
373
+ /* PCIe Init. Conf 1,2,3 |PCICtrl| LD1,3 |DDevID |DevRev | LD0,2 */
374
+ 0x6cfb, 0xc7b0, 0x0abe, 0x0403, 0x0783, 0x10a6, 0x0001, 0x0602,
375
+ /* SwPin1| FunC |LAN-PWR|ManHwC |ICtrl3 | IOVct |VDevID |-------*/
376
+ 0x0004, 0x0020, 0x0000, 0x004a, 0x2080, 0x00f5, 0x10ca, 0x0000,
377
+ /*---------------| LD1,3 | LD0,2 | ROEnd | ROSta | Wdog | VPD */
378
+ 0x0000, 0x0000, 0x4784, 0x4602, 0x0000, 0x0000, 0x1000, 0xffff,
379
+ /* PCSet0| Ccfg0 |PXEver |IBAcap |PCSet1 | Ccfg1 |iSCVer | ?? */
380
+ 0x0100, 0x4000, 0x131f, 0x4013, 0x0100, 0x4000, 0xffff, 0xffff,
381
+ /* PCSet2| Ccfg2 |PCSet3 | Ccfg3 | ?? |AltMacP| ?? |CHKSUM */
382
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x00e0, 0xffff, 0x0000,
383
+ /* NC-SIC */
384
+ 0x0003,
385
+};
386
+
387
+static void igb_core_realize(IGBState *s)
388
+{
389
+ s->core.owner = &s->parent_obj;
390
+ s->core.owner_nic = s->nic;
391
+}
392
+
393
+static void
394
+igb_init_msix(IGBState *s)
395
+{
396
+ int i, res;
397
+
398
+ res = msix_init(PCI_DEVICE(s), IGB_MSIX_VEC_NUM,
399
+ &s->msix,
400
+ E1000E_MSIX_IDX, 0,
401
+ &s->msix,
402
+ E1000E_MSIX_IDX, 0x2000,
403
+ 0x70, NULL);
404
+
405
+ if (res < 0) {
406
+ trace_e1000e_msix_init_fail(res);
407
+ } else {
408
+ for (i = 0; i < IGB_MSIX_VEC_NUM; i++) {
409
+ msix_vector_use(PCI_DEVICE(s), i);
410
+ }
411
+ }
412
+}
413
+
414
+static void
415
+igb_cleanup_msix(IGBState *s)
416
+{
417
+ msix_unuse_all_vectors(PCI_DEVICE(s));
418
+ msix_uninit(PCI_DEVICE(s), &s->msix, &s->msix);
419
+}
420
+
421
+static void
422
+igb_init_net_peer(IGBState *s, PCIDevice *pci_dev, uint8_t *macaddr)
423
+{
424
+ DeviceState *dev = DEVICE(pci_dev);
425
+ NetClientState *nc;
426
+ int i;
427
+
428
+ s->nic = qemu_new_nic(&net_igb_info, &s->conf,
429
+ object_get_typename(OBJECT(s)), dev->id, s);
430
+
431
+ s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 0;
432
+
433
+ trace_e1000e_mac_set_permanent(MAC_ARG(macaddr));
434
+ memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac));
435
+
436
+ qemu_format_nic_info_str(qemu_get_queue(s->nic), macaddr);
437
+
438
+ /* Setup virtio headers */
439
+ for (i = 0; i < s->conf.peers.queues; i++) {
440
+ nc = qemu_get_subqueue(s->nic, i);
441
+ if (!nc->peer || !qemu_has_vnet_hdr(nc->peer)) {
442
+ trace_e1000e_cfg_support_virtio(false);
443
+ return;
444
+ }
445
+ }
446
+
447
+ trace_e1000e_cfg_support_virtio(true);
448
+ s->core.has_vnet = true;
449
+
450
+ for (i = 0; i < s->conf.peers.queues; i++) {
451
+ nc = qemu_get_subqueue(s->nic, i);
452
+ qemu_set_vnet_hdr_len(nc->peer, sizeof(struct virtio_net_hdr));
453
+ qemu_using_vnet_hdr(nc->peer, true);
454
+ }
455
+}
456
+
457
+static int
458
+igb_add_pm_capability(PCIDevice *pdev, uint8_t offset, uint16_t pmc)
459
+{
460
+ Error *local_err = NULL;
461
+ int ret = pci_add_capability(pdev, PCI_CAP_ID_PM, offset,
462
+ PCI_PM_SIZEOF, &local_err);
463
+
464
+ if (local_err) {
465
+ error_report_err(local_err);
466
+ return ret;
467
+ }
468
+
469
+ pci_set_word(pdev->config + offset + PCI_PM_PMC,
470
+ PCI_PM_CAP_VER_1_1 |
471
+ pmc);
472
+
473
+ pci_set_word(pdev->wmask + offset + PCI_PM_CTRL,
474
+ PCI_PM_CTRL_STATE_MASK |
475
+ PCI_PM_CTRL_PME_ENABLE |
476
+ PCI_PM_CTRL_DATA_SEL_MASK);
477
+
478
+ pci_set_word(pdev->w1cmask + offset + PCI_PM_CTRL,
479
+ PCI_PM_CTRL_PME_STATUS);
480
+
481
+ return ret;
482
+}
483
+
484
+static void igb_pci_realize(PCIDevice *pci_dev, Error **errp)
485
+{
486
+ IGBState *s = IGB(pci_dev);
487
+ uint8_t *macaddr;
488
+ int ret;
489
+
490
+ trace_e1000e_cb_pci_realize();
491
+
492
+ pci_dev->config_write = igb_write_config;
493
+
494
+ pci_dev->config[PCI_CACHE_LINE_SIZE] = 0x10;
495
+ pci_dev->config[PCI_INTERRUPT_PIN] = 1;
496
+
497
+ /* Define IO/MMIO regions */
498
+ memory_region_init_io(&s->mmio, OBJECT(s), &mmio_ops, s,
499
+ "igb-mmio", E1000E_MMIO_SIZE);
500
+ pci_register_bar(pci_dev, E1000E_MMIO_IDX,
501
+ PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
502
+
503
+ /*
504
+ * We provide a dummy implementation for the flash BAR
505
+ * for drivers that may theoretically probe for its presence.
506
+ */
507
+ memory_region_init(&s->flash, OBJECT(s),
508
+ "igb-flash", E1000E_FLASH_SIZE);
509
+ pci_register_bar(pci_dev, E1000E_FLASH_IDX,
510
+ PCI_BASE_ADDRESS_SPACE_MEMORY, &s->flash);
511
+
512
+ memory_region_init_io(&s->io, OBJECT(s), &io_ops, s,
513
+ "igb-io", E1000E_IO_SIZE);
514
+ pci_register_bar(pci_dev, E1000E_IO_IDX,
515
+ PCI_BASE_ADDRESS_SPACE_IO, &s->io);
516
+
517
+ memory_region_init(&s->msix, OBJECT(s), "igb-msix",
518
+ E1000E_MSIX_SIZE);
519
+ pci_register_bar(pci_dev, E1000E_MSIX_IDX,
520
+ PCI_BASE_ADDRESS_MEM_TYPE_64, &s->msix);
521
+
522
+ /* Create networking backend */
523
+ qemu_macaddr_default_if_unset(&s->conf.macaddr);
524
+ macaddr = s->conf.macaddr.a;
525
+
526
+ /* Add PCI capabilities in reverse order */
527
+ assert(pcie_endpoint_cap_init(pci_dev, 0xa0) > 0);
528
+
529
+ igb_init_msix(s);
530
+
531
+ ret = msi_init(pci_dev, 0x50, 1, true, true, NULL);
532
+ if (ret) {
533
+ trace_e1000e_msi_init_fail(ret);
534
+ }
535
+
536
+ if (igb_add_pm_capability(pci_dev, 0x40, PCI_PM_CAP_DSI) < 0) {
537
+ hw_error("Failed to initialize PM capability");
538
+ }
539
+
540
+ /* PCIe extended capabilities (in order) */
541
+ if (pcie_aer_init(pci_dev, 1, 0x100, 0x40, errp) < 0) {
542
+ hw_error("Failed to initialize AER capability");
543
+ }
544
+
545
+ pcie_ari_init(pci_dev, 0x150, 1);
546
+
547
+ pcie_sriov_pf_init(pci_dev, IGB_CAP_SRIOV_OFFSET, "igbvf",
548
+ IGB_82576_VF_DEV_ID, IGB_MAX_VF_FUNCTIONS, IGB_MAX_VF_FUNCTIONS,
549
+ IGB_VF_OFFSET, IGB_VF_STRIDE);
550
+
551
+ pcie_sriov_pf_init_vf_bar(pci_dev, 0,
552
+ PCI_BASE_ADDRESS_MEM_TYPE_64 | PCI_BASE_ADDRESS_MEM_PREFETCH,
553
+ 16 * KiB);
554
+ pcie_sriov_pf_init_vf_bar(pci_dev, 3,
555
+ PCI_BASE_ADDRESS_MEM_TYPE_64 | PCI_BASE_ADDRESS_MEM_PREFETCH,
556
+ 16 * KiB);
557
+
558
+ igb_init_net_peer(s, pci_dev, macaddr);
559
+
560
+ /* Initialize core */
561
+ igb_core_realize(s);
562
+
563
+ igb_core_pci_realize(&s->core,
564
+ igb_eeprom_template,
565
+ sizeof(igb_eeprom_template),
566
+ macaddr);
567
+}
568
+
569
+static void igb_pci_uninit(PCIDevice *pci_dev)
570
+{
571
+ IGBState *s = IGB(pci_dev);
572
+
573
+ trace_e1000e_cb_pci_uninit();
574
+
575
+ igb_core_pci_uninit(&s->core);
576
+
577
+ pcie_sriov_pf_exit(pci_dev);
578
+ pcie_cap_exit(pci_dev);
579
+
580
+ qemu_del_nic(s->nic);
581
+
582
+ igb_cleanup_msix(s);
583
+ msi_uninit(pci_dev);
584
+}
585
+
586
+static void igb_qdev_reset_hold(Object *obj)
587
+{
588
+ PCIDevice *d = PCI_DEVICE(obj);
589
+ IGBState *s = IGB(obj);
590
+
591
+ trace_e1000e_cb_qdev_reset_hold();
592
+
593
+ pcie_sriov_pf_disable_vfs(d);
594
+ igb_core_reset(&s->core);
595
+}
596
+
597
+static int igb_pre_save(void *opaque)
598
+{
599
+ IGBState *s = opaque;
600
+
601
+ trace_e1000e_cb_pre_save();
602
+
603
+ igb_core_pre_save(&s->core);
604
+
605
+ return 0;
606
+}
607
+
608
+static int igb_post_load(void *opaque, int version_id)
609
+{
610
+ IGBState *s = opaque;
611
+
612
+ trace_e1000e_cb_post_load();
613
+ return igb_core_post_load(&s->core);
614
+}
615
+
616
+static const VMStateDescription igb_vmstate_tx = {
617
+ .name = "igb-tx",
618
+ .version_id = 1,
619
+ .minimum_version_id = 1,
620
+ .fields = (VMStateField[]) {
621
+ VMSTATE_UINT16(vlan, struct igb_tx),
622
+ VMSTATE_UINT16(mss, struct igb_tx),
623
+ VMSTATE_BOOL(tse, struct igb_tx),
624
+ VMSTATE_BOOL(ixsm, struct igb_tx),
625
+ VMSTATE_BOOL(txsm, struct igb_tx),
626
+ VMSTATE_BOOL(first, struct igb_tx),
627
+ VMSTATE_BOOL(skip_cp, struct igb_tx),
628
+ VMSTATE_END_OF_LIST()
629
+ }
630
+};
631
+
632
+static const VMStateDescription igb_vmstate_intr_timer = {
633
+ .name = "igb-intr-timer",
634
+ .version_id = 1,
635
+ .minimum_version_id = 1,
636
+ .fields = (VMStateField[]) {
637
+ VMSTATE_TIMER_PTR(timer, IGBIntrDelayTimer),
638
+ VMSTATE_BOOL(running, IGBIntrDelayTimer),
639
+ VMSTATE_END_OF_LIST()
640
+ }
641
+};
642
+
643
+#define VMSTATE_IGB_INTR_DELAY_TIMER(_f, _s) \
644
+ VMSTATE_STRUCT(_f, _s, 0, \
645
+ igb_vmstate_intr_timer, IGBIntrDelayTimer)
646
+
647
+#define VMSTATE_IGB_INTR_DELAY_TIMER_ARRAY(_f, _s, _num) \
648
+ VMSTATE_STRUCT_ARRAY(_f, _s, _num, 0, \
649
+ igb_vmstate_intr_timer, IGBIntrDelayTimer)
650
+
651
+static const VMStateDescription igb_vmstate = {
652
+ .name = "igb",
653
+ .version_id = 1,
654
+ .minimum_version_id = 1,
655
+ .pre_save = igb_pre_save,
656
+ .post_load = igb_post_load,
657
+ .fields = (VMStateField[]) {
658
+ VMSTATE_PCI_DEVICE(parent_obj, IGBState),
659
+ VMSTATE_MSIX(parent_obj, IGBState),
660
+
661
+ VMSTATE_UINT32(ioaddr, IGBState),
662
+ VMSTATE_UINT8(core.rx_desc_len, IGBState),
663
+ VMSTATE_UINT16_ARRAY(core.eeprom, IGBState, IGB_EEPROM_SIZE),
664
+ VMSTATE_UINT16_ARRAY(core.phy, IGBState, MAX_PHY_REG_ADDRESS + 1),
665
+ VMSTATE_UINT32_ARRAY(core.mac, IGBState, E1000E_MAC_SIZE),
666
+ VMSTATE_UINT8_ARRAY(core.permanent_mac, IGBState, ETH_ALEN),
667
+
668
+ VMSTATE_IGB_INTR_DELAY_TIMER_ARRAY(core.eitr, IGBState,
669
+ IGB_INTR_NUM),
670
+
671
+ VMSTATE_UINT32_ARRAY(core.eitr_guest_value, IGBState, IGB_INTR_NUM),
672
+
673
+ VMSTATE_STRUCT_ARRAY(core.tx, IGBState, IGB_NUM_QUEUES, 0,
674
+ igb_vmstate_tx, struct igb_tx),
675
+
676
+ VMSTATE_INT64(core.timadj, IGBState),
677
+
678
+ VMSTATE_END_OF_LIST()
679
+ }
680
+};
681
+
682
+static Property igb_properties[] = {
683
+ DEFINE_NIC_PROPERTIES(IGBState, conf),
684
+ DEFINE_PROP_END_OF_LIST(),
685
+};
686
+
687
+static void igb_class_init(ObjectClass *class, void *data)
688
+{
689
+ DeviceClass *dc = DEVICE_CLASS(class);
690
+ ResettableClass *rc = RESETTABLE_CLASS(class);
691
+ PCIDeviceClass *c = PCI_DEVICE_CLASS(class);
692
+
693
+ c->realize = igb_pci_realize;
694
+ c->exit = igb_pci_uninit;
695
+ c->vendor_id = PCI_VENDOR_ID_INTEL;
696
+ c->device_id = E1000_DEV_ID_82576;
697
+ c->revision = 1;
698
+ c->class_id = PCI_CLASS_NETWORK_ETHERNET;
699
+
700
+ rc->phases.hold = igb_qdev_reset_hold;
701
+
702
+ dc->desc = "Intel 82576 Gigabit Ethernet Controller";
703
+ dc->vmsd = &igb_vmstate;
704
+
705
+ device_class_set_props(dc, igb_properties);
706
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
707
+}
708
+
709
+static void igb_instance_init(Object *obj)
710
+{
711
+ IGBState *s = IGB(obj);
712
+ device_add_bootindex_property(obj, &s->conf.bootindex,
713
+ "bootindex", "/ethernet-phy@0",
714
+ DEVICE(obj));
715
+}
716
+
717
+static const TypeInfo igb_info = {
718
+ .name = TYPE_IGB,
719
+ .parent = TYPE_PCI_DEVICE,
720
+ .instance_size = sizeof(IGBState),
721
+ .class_init = igb_class_init,
722
+ .instance_init = igb_instance_init,
723
+ .interfaces = (InterfaceInfo[]) {
724
+ { INTERFACE_PCIE_DEVICE },
725
+ { }
726
+ },
727
+};
728
+
729
+static void igb_register_types(void)
730
+{
731
+ type_register_static(&igb_info);
732
+}
733
+
734
+type_init(igb_register_types)
735
diff --git a/hw/net/igb_common.h b/hw/net/igb_common.h
736
new file mode 100644
737
index XXXXXXX..XXXXXXX
738
--- /dev/null
739
+++ b/hw/net/igb_common.h
740
@@ -XXX,XX +XXX,XX @@
741
+/*
742
+ * QEMU igb emulation - shared definitions
743
+ *
744
+ * Copyright (c) 2020-2023 Red Hat, Inc.
745
+ * Copyright (c) 2008 Qumranet
746
+ *
747
+ * Based on work done by:
748
+ * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
749
+ * Copyright (c) 2007 Dan Aloni
750
+ * Copyright (c) 2004 Antony T Curtis
751
+ *
752
+ * This library is free software; you can redistribute it and/or
753
+ * modify it under the terms of the GNU Lesser General Public
754
+ * License as published by the Free Software Foundation; either
755
+ * version 2.1 of the License, or (at your option) any later version.
756
+ *
757
+ * This library is distributed in the hope that it will be useful,
758
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
759
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
760
+ * Lesser General Public License for more details.
761
+ *
762
+ * You should have received a copy of the GNU Lesser General Public
763
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
764
+ */
765
+
766
+#ifndef HW_NET_IGB_COMMON_H
767
+#define HW_NET_IGB_COMMON_H
768
+
769
+#include "igb_regs.h"
770
+
771
+#define defreg(x) x = (E1000_##x >> 2)
772
+#define defreg_indexed(x, i) x##i = (E1000_##x(i) >> 2)
773
+#define defreg_indexeda(x, i) x##i##_A = (E1000_##x##_A(i) >> 2)
774
+
775
+#define defregd(x) defreg_indexed(x, 0), defreg_indexed(x, 1), \
776
+ defreg_indexed(x, 2), defreg_indexed(x, 3), \
777
+ defreg_indexed(x, 4), defreg_indexed(x, 5), \
778
+ defreg_indexed(x, 6), defreg_indexed(x, 7), \
779
+ defreg_indexed(x, 8), defreg_indexed(x, 9), \
780
+ defreg_indexed(x, 10), defreg_indexed(x, 11), \
781
+ defreg_indexed(x, 12), defreg_indexed(x, 13), \
782
+ defreg_indexed(x, 14), defreg_indexed(x, 15), \
783
+ defreg_indexeda(x, 0), defreg_indexeda(x, 1), \
784
+ defreg_indexeda(x, 2), defreg_indexeda(x, 3)
785
+
786
+#define defregv(x) defreg_indexed(x, 0), defreg_indexed(x, 1), \
787
+ defreg_indexed(x, 2), defreg_indexed(x, 3), \
788
+ defreg_indexed(x, 4), defreg_indexed(x, 5), \
789
+ defreg_indexed(x, 6), defreg_indexed(x, 7)
790
+
791
+enum {
792
+ defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC),
793
+ defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC),
794
+ defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC),
795
+ defreg(MPC), defreg(RCTL),
796
+ defreg(STATUS), defreg(SWSM), defreg(TCTL),
797
+ defreg(TORH), defreg(TORL), defreg(TOTH),
798
+ defreg(TOTL), defreg(TPR), defreg(TPT),
799
+ defreg(WUFC), defreg(RA), defreg(MTA), defreg(CRCERRS),
800
+ defreg(VFTA), defreg(VET),
801
+ defreg(SCC), defreg(ECOL),
802
+ defreg(MCC), defreg(LATECOL), defreg(COLC), defreg(DC),
803
+ defreg(TNCRS), defreg(RLEC),
804
+ defreg(XONRXC), defreg(XONTXC), defreg(XOFFRXC), defreg(XOFFTXC),
805
+ defreg(FCRUC), defreg(TDFH), defreg(TDFT),
806
+ defreg(TDFHS), defreg(TDFTS), defreg(TDFPC), defreg(WUC),
807
+ defreg(WUS), defreg(RDFH),
808
+ defreg(RDFT), defreg(RDFHS), defreg(RDFTS), defreg(RDFPC),
809
+ defreg(IPAV), defreg(IP4AT), defreg(IP6AT),
810
+ defreg(WUPM), defreg(FFMT),
811
+ defreg(IAM),
812
+ defreg(GCR), defreg(TIMINCA), defreg(EIAC), defreg(CTRL_EXT),
813
+ defreg(IVAR0), defreg(MANC2H),
814
+ defreg(MFVAL), defreg(MDEF), defreg(FACTPS), defreg(FTFT),
815
+ defreg(RUC), defreg(ROC), defreg(RFC), defreg(RJC),
816
+ defreg(PRC64), defreg(PRC127), defreg(PRC255), defreg(PRC511),
817
+ defreg(PRC1023), defreg(PRC1522), defreg(PTC64), defreg(PTC127),
818
+ defreg(PTC255), defreg(PTC511), defreg(PTC1023), defreg(PTC1522),
819
+ defreg(GORCL), defreg(GORCH), defreg(GOTCL), defreg(GOTCH),
820
+ defreg(RNBC), defreg(BPRC), defreg(MPRC), defreg(RFCTL),
821
+ defreg(MPTC), defreg(BPTC),
822
+ defreg(IAC), defreg(MGTPRC), defreg(MGTPDC), defreg(MGTPTC),
823
+ defreg(TSCTC), defreg(RXCSUM), defreg(FUNCTAG), defreg(GSCL_1),
824
+ defreg(GSCL_2), defreg(GSCL_3), defreg(GSCL_4), defreg(GSCN_0),
825
+ defreg(GSCN_1), defreg(GSCN_2), defreg(GSCN_3),
826
+ defreg_indexed(EITR, 0),
827
+ defreg(MRQC), defreg(RETA), defreg(RSSRK),
828
+ defreg(PBACLR), defreg(FCAL), defreg(FCAH), defreg(FCT),
829
+ defreg(FCRTH), defreg(FCRTL), defreg(FCTTV), defreg(FCRTV),
830
+ defreg(FLA), defreg(FLOP),
831
+ defreg(MAVTV0), defreg(MAVTV1), defreg(MAVTV2), defreg(MAVTV3),
832
+ defreg(TXSTMPL), defreg(TXSTMPH), defreg(SYSTIML), defreg(SYSTIMH),
833
+ defreg(TIMADJL), defreg(TIMADJH),
834
+ defreg(RXSTMPH), defreg(RXSTMPL), defreg(RXSATRL), defreg(RXSATRH),
835
+ defreg(TIPG),
836
+ defreg(CTRL_DUP),
837
+ defreg(EEMNGCTL),
838
+ defreg(EEMNGDATA),
839
+ defreg(FLMNGCTL),
840
+ defreg(FLMNGDATA),
841
+ defreg(FLMNGCNT),
842
+ defreg(TSYNCRXCTL),
843
+ defreg(TSYNCTXCTL),
844
+ defreg(RLPML),
845
+ defreg(UTA),
846
+
847
+ /* Aliases */
848
+ defreg(RDFH_A), defreg(RDFT_A), defreg(TDFH_A), defreg(TDFT_A),
849
+ defreg(RA_A), defreg(VFTA_A), defreg(FCRTL_A),
850
+
851
+ /* Additional regs used by IGB */
852
+ defreg(FWSM), defreg(SW_FW_SYNC),
853
+
854
+ defreg(EICS), defreg(EIMS), defreg(EIMC), defreg(EIAM),
855
+ defreg(EICR), defreg(IVAR_MISC), defreg(GPIE),
856
+
857
+ defreg(RXPBS), defregd(RDBAL), defregd(RDBAH), defregd(RDLEN),
858
+ defregd(SRRCTL), defregd(RDH), defregd(RDT),
859
+ defregd(RXDCTL), defregd(RXCTL), defregd(RQDPC), defreg(RA2),
860
+
861
+ defreg(TXPBS), defreg(TCTL_EXT), defreg(DTXCTL), defreg(HTCBDPC),
862
+ defregd(TDBAL), defregd(TDBAH), defregd(TDLEN), defregd(TDH),
863
+ defregd(TDT), defregd(TXDCTL), defregd(TXCTL),
864
+ defregd(TDWBAL), defregd(TDWBAH),
865
+
866
+ defreg(VT_CTL),
867
+
868
+ defregv(P2VMAILBOX), defregv(V2PMAILBOX), defreg(MBVFICR), defreg(MBVFIMR),
869
+ defreg(VFLRE), defreg(VFRE), defreg(VFTE), defreg(WVBR),
870
+ defreg(QDE), defreg(DTXSWC), defreg_indexed(VLVF, 0),
871
+ defregv(VMOLR), defreg(RPLOLR), defregv(VMBMEM), defregv(VMVIR),
872
+
873
+ defregv(PVTCTRL), defregv(PVTEICS), defregv(PVTEIMS), defregv(PVTEIMC),
874
+ defregv(PVTEIAC), defregv(PVTEIAM), defregv(PVTEICR), defregv(PVFGPRC),
875
+ defregv(PVFGPTC), defregv(PVFGORC), defregv(PVFGOTC), defregv(PVFMPRC),
876
+ defregv(PVFGPRLBC), defregv(PVFGPTLBC), defregv(PVFGORLBC), defregv(PVFGOTLBC),
877
+
878
+ defreg(MTA_A),
879
+
880
+ defreg(VTIVAR), defreg(VTIVAR_MISC),
881
+};
882
+
883
+uint64_t igb_mmio_read(void *opaque, hwaddr addr, unsigned size);
884
+void igb_mmio_write(void *opaque, hwaddr addr, uint64_t val, unsigned size);
885
+
886
+#endif
887
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
888
new file mode 100644
889
index XXXXXXX..XXXXXXX
890
--- /dev/null
891
+++ b/hw/net/igb_core.c
892
@@ -XXX,XX +XXX,XX @@
893
+/*
894
+ * Core code for QEMU igb emulation
895
+ *
896
+ * Datasheet:
897
+ * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82576eg-gbe-datasheet.pdf
898
+ *
899
+ * Copyright (c) 2020-2023 Red Hat, Inc.
900
+ * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
901
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
902
+ *
903
+ * Authors:
904
+ * Akihiko Odaki <akihiko.odaki@daynix.com>
905
+ * Gal Hammmer <gal.hammer@sap.com>
906
+ * Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
907
+ * Dmitry Fleytman <dmitry@daynix.com>
908
+ * Leonid Bloch <leonid@daynix.com>
909
+ * Yan Vugenfirer <yan@daynix.com>
910
+ *
911
+ * Based on work done by:
912
+ * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
913
+ * Copyright (c) 2008 Qumranet
914
+ * Based on work done by:
915
+ * Copyright (c) 2007 Dan Aloni
916
+ * Copyright (c) 2004 Antony T Curtis
917
+ *
918
+ * This library is free software; you can redistribute it and/or
919
+ * modify it under the terms of the GNU Lesser General Public
920
+ * License as published by the Free Software Foundation; either
921
+ * version 2.1 of the License, or (at your option) any later version.
922
+ *
923
+ * This library is distributed in the hope that it will be useful,
924
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
925
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
926
+ * Lesser General Public License for more details.
927
+ *
928
+ * You should have received a copy of the GNU Lesser General Public
929
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
930
+ */
931
+
932
+#include "qemu/osdep.h"
933
+#include "qemu/log.h"
934
+#include "net/net.h"
935
+#include "net/tap.h"
936
+#include "hw/net/mii.h"
937
+#include "hw/pci/msi.h"
938
+#include "hw/pci/msix.h"
939
+#include "sysemu/runstate.h"
940
+
941
+#include "net_tx_pkt.h"
942
+#include "net_rx_pkt.h"
943
+
944
+#include "igb_common.h"
945
+#include "e1000x_common.h"
946
+#include "igb_core.h"
947
+
948
+#include "trace.h"
949
+
950
+#define E1000E_MAX_TX_FRAGS (64)
951
+
952
+union e1000_rx_desc_union {
953
+ struct e1000_rx_desc legacy;
954
+ union e1000_adv_rx_desc adv;
955
+};
956
+
957
+typedef struct IGBTxPktVmdqCallbackContext {
958
+ IGBCore *core;
959
+ NetClientState *nc;
960
+} IGBTxPktVmdqCallbackContext;
961
+
962
+static ssize_t
963
+igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
964
+ bool has_vnet, bool *external_tx);
965
+
966
+static inline void
967
+igb_set_interrupt_cause(IGBCore *core, uint32_t val);
968
+
969
+static void igb_update_interrupt_state(IGBCore *core);
970
+static void igb_reset(IGBCore *core, bool sw);
971
+
972
+static inline void
973
+igb_raise_legacy_irq(IGBCore *core)
974
+{
975
+ trace_e1000e_irq_legacy_notify(true);
976
+ e1000x_inc_reg_if_not_full(core->mac, IAC);
977
+ pci_set_irq(core->owner, 1);
978
+}
979
+
980
+static inline void
981
+igb_lower_legacy_irq(IGBCore *core)
982
+{
983
+ trace_e1000e_irq_legacy_notify(false);
984
+ pci_set_irq(core->owner, 0);
985
+}
986
+
987
+static void igb_msix_notify(IGBCore *core, unsigned int vector)
988
+{
989
+ PCIDevice *dev = core->owner;
990
+ uint16_t vfn;
991
+
992
+ vfn = 8 - (vector + 2) / IGBVF_MSIX_VEC_NUM;
993
+ if (vfn < pcie_sriov_num_vfs(core->owner)) {
994
+ dev = pcie_sriov_get_vf_at_index(core->owner, vfn);
995
+ assert(dev);
996
+ vector = (vector + 2) % IGBVF_MSIX_VEC_NUM;
997
+ } else if (vector >= IGB_MSIX_VEC_NUM) {
998
+ qemu_log_mask(LOG_GUEST_ERROR,
999
+ "igb: Tried to use vector unavailable for PF");
1000
+ return;
1001
+ }
1002
+
1003
+ msix_notify(dev, vector);
1004
+}
1005
+
1006
+static inline void
1007
+igb_intrmgr_rearm_timer(IGBIntrDelayTimer *timer)
1008
+{
1009
+ int64_t delay_ns = (int64_t) timer->core->mac[timer->delay_reg] *
1010
+ timer->delay_resolution_ns;
1011
+
1012
+ trace_e1000e_irq_rearm_timer(timer->delay_reg << 2, delay_ns);
1013
+
1014
+ timer_mod(timer->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + delay_ns);
1015
+
1016
+ timer->running = true;
1017
+}
1018
+
1019
+static void
1020
+igb_intmgr_timer_resume(IGBIntrDelayTimer *timer)
1021
+{
1022
+ if (timer->running) {
1023
+ igb_intrmgr_rearm_timer(timer);
1024
+ }
1025
+}
1026
+
1027
+static void
1028
+igb_intmgr_timer_pause(IGBIntrDelayTimer *timer)
1029
+{
1030
+ if (timer->running) {
1031
+ timer_del(timer->timer);
1032
+ }
1033
+}
1034
+
1035
+static void
1036
+igb_intrmgr_on_msix_throttling_timer(void *opaque)
1037
+{
1038
+ IGBIntrDelayTimer *timer = opaque;
1039
+ int idx = timer - &timer->core->eitr[0];
1040
+
1041
+ timer->running = false;
1042
+
1043
+ trace_e1000e_irq_msix_notify_postponed_vec(idx);
1044
+ igb_msix_notify(timer->core, idx);
1045
+}
1046
+
1047
+static void
1048
+igb_intrmgr_initialize_all_timers(IGBCore *core, bool create)
1049
+{
1050
+ int i;
1051
+
1052
+ for (i = 0; i < IGB_INTR_NUM; i++) {
1053
+ core->eitr[i].core = core;
1054
+ core->eitr[i].delay_reg = EITR0 + i;
1055
+ core->eitr[i].delay_resolution_ns = E1000_INTR_DELAY_NS_RES;
1056
+ }
1057
+
1058
+ if (!create) {
1059
+ return;
1060
+ }
1061
+
1062
+ for (i = 0; i < IGB_INTR_NUM; i++) {
1063
+ core->eitr[i].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
1064
+ igb_intrmgr_on_msix_throttling_timer,
1065
+ &core->eitr[i]);
1066
+ }
1067
+}
1068
+
1069
+static void
1070
+igb_intrmgr_resume(IGBCore *core)
1071
+{
1072
+ int i;
1073
+
1074
+ for (i = 0; i < IGB_INTR_NUM; i++) {
1075
+ igb_intmgr_timer_resume(&core->eitr[i]);
1076
+ }
1077
+}
1078
+
1079
+static void
1080
+igb_intrmgr_pause(IGBCore *core)
1081
+{
1082
+ int i;
1083
+
1084
+ for (i = 0; i < IGB_INTR_NUM; i++) {
1085
+ igb_intmgr_timer_pause(&core->eitr[i]);
1086
+ }
1087
+}
1088
+
1089
+static void
1090
+igb_intrmgr_reset(IGBCore *core)
1091
+{
1092
+ int i;
1093
+
1094
+ for (i = 0; i < IGB_INTR_NUM; i++) {
1095
+ if (core->eitr[i].running) {
1096
+ timer_del(core->eitr[i].timer);
1097
+ igb_intrmgr_on_msix_throttling_timer(&core->eitr[i]);
1098
+ }
1099
+ }
1100
+}
1101
+
1102
+static void
1103
+igb_intrmgr_pci_unint(IGBCore *core)
1104
+{
1105
+ int i;
1106
+
1107
+ for (i = 0; i < IGB_INTR_NUM; i++) {
1108
+ timer_free(core->eitr[i].timer);
1109
+ }
1110
+}
1111
+
1112
+static void
1113
+igb_intrmgr_pci_realize(IGBCore *core)
1114
+{
1115
+ igb_intrmgr_initialize_all_timers(core, true);
1116
+}
1117
+
1118
+static inline bool
1119
+igb_rx_csum_enabled(IGBCore *core)
1120
+{
1121
+ return (core->mac[RXCSUM] & E1000_RXCSUM_PCSD) ? false : true;
1122
+}
1123
+
1124
+static inline bool
1125
+igb_rx_use_legacy_descriptor(IGBCore *core)
1126
+{
1127
+ /*
1128
+ * TODO: If SRRCTL[n],DESCTYPE = 000b, the 82576 uses the legacy Rx
1129
+ * descriptor.
1130
+ */
1131
+ return false;
1132
+}
1133
+
1134
+static inline bool
1135
+igb_rss_enabled(IGBCore *core)
1136
+{
1137
+ return (core->mac[MRQC] & 3) == E1000_MRQC_ENABLE_RSS_MQ &&
1138
+ !igb_rx_csum_enabled(core) &&
1139
+ !igb_rx_use_legacy_descriptor(core);
1140
+}
1141
+
1142
+typedef struct E1000E_RSSInfo_st {
1143
+ bool enabled;
1144
+ uint32_t hash;
1145
+ uint32_t queue;
1146
+ uint32_t type;
1147
+} E1000E_RSSInfo;
1148
+
1149
+static uint32_t
1150
+igb_rss_get_hash_type(IGBCore *core, struct NetRxPkt *pkt)
1151
+{
1152
+ bool hasip4, hasip6;
1153
+ EthL4HdrProto l4hdr_proto;
1154
+
1155
+ assert(igb_rss_enabled(core));
1156
+
1157
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
1158
+
1159
+ if (hasip4) {
1160
+ trace_e1000e_rx_rss_ip4(l4hdr_proto, core->mac[MRQC],
1161
+ E1000_MRQC_EN_TCPIPV4(core->mac[MRQC]),
1162
+ E1000_MRQC_EN_IPV4(core->mac[MRQC]));
1163
+
1164
+ if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP &&
1165
+ E1000_MRQC_EN_TCPIPV4(core->mac[MRQC])) {
1166
+ return E1000_MRQ_RSS_TYPE_IPV4TCP;
1167
+ }
1168
+
1169
+ if (E1000_MRQC_EN_IPV4(core->mac[MRQC])) {
1170
+ return E1000_MRQ_RSS_TYPE_IPV4;
1171
+ }
1172
+ } else if (hasip6) {
1173
+ eth_ip6_hdr_info *ip6info = net_rx_pkt_get_ip6_info(pkt);
1174
+
1175
+ bool ex_dis = core->mac[RFCTL] & E1000_RFCTL_IPV6_EX_DIS;
1176
+ bool new_ex_dis = core->mac[RFCTL] & E1000_RFCTL_NEW_IPV6_EXT_DIS;
1177
+
1178
+ /*
54
+ /*
1179
+ * Following two traces must not be combined because resulting
55
+ * Map cannot be NULL since iova map contains all guest space and
1180
+ * event will have 11 arguments totally and some trace backends
56
+ * qemu already has a physical address mapped
1181
+ * (at least "ust") have limitation of maximum 10 arguments per
1182
+ * event. Events with more arguments fail to compile for
1183
+ * backends like these.
1184
+ */
57
+ */
1185
+ trace_e1000e_rx_rss_ip6_rfctl(core->mac[RFCTL]);
58
+ if (unlikely(!map)) {
1186
+ trace_e1000e_rx_rss_ip6(ex_dis, new_ex_dis, l4hdr_proto,
59
+ qemu_log_mask(LOG_GUEST_ERROR,
1187
+ ip6info->has_ext_hdrs,
60
+ "Invalid address 0x%"HWADDR_PRIx" given by guest",
1188
+ ip6info->rss_ex_dst_valid,
61
+ needle.translated_addr);
1189
+ ip6info->rss_ex_src_valid,
1190
+ core->mac[MRQC],
1191
+ E1000_MRQC_EN_TCPIPV6(core->mac[MRQC]),
1192
+ E1000_MRQC_EN_IPV6EX(core->mac[MRQC]),
1193
+ E1000_MRQC_EN_IPV6(core->mac[MRQC]));
1194
+
1195
+ if ((!ex_dis || !ip6info->has_ext_hdrs) &&
1196
+ (!new_ex_dis || !(ip6info->rss_ex_dst_valid ||
1197
+ ip6info->rss_ex_src_valid))) {
1198
+
1199
+ if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP &&
1200
+ E1000_MRQC_EN_TCPIPV6(core->mac[MRQC])) {
1201
+ return E1000_MRQ_RSS_TYPE_IPV6TCP;
1202
+ }
1203
+
1204
+ if (E1000_MRQC_EN_IPV6EX(core->mac[MRQC])) {
1205
+ return E1000_MRQ_RSS_TYPE_IPV6EX;
1206
+ }
1207
+
1208
+ }
1209
+
1210
+ if (E1000_MRQC_EN_IPV6(core->mac[MRQC])) {
1211
+ return E1000_MRQ_RSS_TYPE_IPV6;
1212
+ }
1213
+
1214
+ }
1215
+
1216
+ return E1000_MRQ_RSS_TYPE_NONE;
1217
+}
1218
+
1219
+static uint32_t
1220
+igb_rss_calc_hash(IGBCore *core, struct NetRxPkt *pkt, E1000E_RSSInfo *info)
1221
+{
1222
+ NetRxPktRssType type;
1223
+
1224
+ assert(igb_rss_enabled(core));
1225
+
1226
+ switch (info->type) {
1227
+ case E1000_MRQ_RSS_TYPE_IPV4:
1228
+ type = NetPktRssIpV4;
1229
+ break;
1230
+ case E1000_MRQ_RSS_TYPE_IPV4TCP:
1231
+ type = NetPktRssIpV4Tcp;
1232
+ break;
1233
+ case E1000_MRQ_RSS_TYPE_IPV6TCP:
1234
+ type = NetPktRssIpV6TcpEx;
1235
+ break;
1236
+ case E1000_MRQ_RSS_TYPE_IPV6:
1237
+ type = NetPktRssIpV6;
1238
+ break;
1239
+ case E1000_MRQ_RSS_TYPE_IPV6EX:
1240
+ type = NetPktRssIpV6Ex;
1241
+ break;
1242
+ default:
1243
+ assert(false);
1244
+ return 0;
1245
+ }
1246
+
1247
+ return net_rx_pkt_calc_rss_hash(pkt, type, (uint8_t *) &core->mac[RSSRK]);
1248
+}
1249
+
1250
+static void
1251
+igb_rss_parse_packet(IGBCore *core, struct NetRxPkt *pkt, bool tx,
1252
+ E1000E_RSSInfo *info)
1253
+{
1254
+ trace_e1000e_rx_rss_started();
1255
+
1256
+ if (tx || !igb_rss_enabled(core)) {
1257
+ info->enabled = false;
1258
+ info->hash = 0;
1259
+ info->queue = 0;
1260
+ info->type = 0;
1261
+ trace_e1000e_rx_rss_disabled();
1262
+ return;
1263
+ }
1264
+
1265
+ info->enabled = true;
1266
+
1267
+ info->type = igb_rss_get_hash_type(core, pkt);
1268
+
1269
+ trace_e1000e_rx_rss_type(info->type);
1270
+
1271
+ if (info->type == E1000_MRQ_RSS_TYPE_NONE) {
1272
+ info->hash = 0;
1273
+ info->queue = 0;
1274
+ return;
1275
+ }
1276
+
1277
+ info->hash = igb_rss_calc_hash(core, pkt, info);
1278
+ info->queue = E1000_RSS_QUEUE(&core->mac[RETA], info->hash);
1279
+}
1280
+
1281
+static bool
1282
+igb_setup_tx_offloads(IGBCore *core, struct igb_tx *tx)
1283
+{
1284
+ if (tx->tse) {
1285
+ if (!net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->mss)) {
1286
+ return false;
62
+ return false;
1287
+ }
63
+ }
1288
+
64
+
1289
+ net_tx_pkt_update_ip_checksums(tx->tx_pkt);
65
+ off = needle.translated_addr - map->translated_addr;
1290
+ e1000x_inc_reg_if_not_full(core->mac, TSCTC);
66
+ addrs[i] = map->iova + off;
1291
+ return true;
67
+
1292
+ }
68
+ needle_last = int128_add(int128_make64(needle.translated_addr),
1293
+
69
+ int128_make64(iovec[i].iov_len));
1294
+ if (tx->txsm) {
70
+ map_last = int128_make64(map->translated_addr + map->size);
1295
+ if (!net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0)) {
71
+ if (unlikely(int128_gt(needle_last, map_last))) {
72
+ qemu_log_mask(LOG_GUEST_ERROR,
73
+ "Guest buffer expands over iova range");
1296
+ return false;
74
+ return false;
1297
+ }
75
+ }
1298
+ }
76
+ }
1299
+
77
+
1300
+ if (tx->ixsm) {
1301
+ net_tx_pkt_update_ip_hdr_checksum(tx->tx_pkt);
1302
+ }
1303
+
1304
+ return true;
78
+ return true;
1305
+}
79
+}
1306
+
80
+
1307
+static void igb_tx_pkt_mac_callback(void *core,
81
+static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, hwaddr *sg,
1308
+ const struct iovec *iov,
82
const struct iovec *iovec, size_t num,
1309
+ int iovcnt,
83
bool more_descs, bool write)
1310
+ const struct iovec *virt_iov,
84
{
1311
+ int virt_iovcnt)
85
@@ -XXX,XX +XXX,XX @@ static void vhost_vring_write_descs(VhostShadowVirtqueue *svq,
86
} else {
87
descs[i].flags = flags;
88
}
89
- descs[i].addr = cpu_to_le64((hwaddr)(intptr_t)iovec[n].iov_base);
90
+ descs[i].addr = cpu_to_le64(sg[n]);
91
descs[i].len = cpu_to_le32(iovec[n].iov_len);
92
93
last = i;
94
@@ -XXX,XX +XXX,XX @@ static bool vhost_svq_add_split(VhostShadowVirtqueue *svq,
95
{
96
unsigned avail_idx;
97
vring_avail_t *avail = svq->vring.avail;
98
+ bool ok;
99
+ g_autofree hwaddr *sgs = g_new(hwaddr, MAX(elem->out_num, elem->in_num));
100
101
*head = svq->free_head;
102
103
@@ -XXX,XX +XXX,XX @@ static bool vhost_svq_add_split(VhostShadowVirtqueue *svq,
104
return false;
105
}
106
107
- vhost_vring_write_descs(svq, elem->out_sg, elem->out_num, elem->in_num > 0,
108
- false);
109
- vhost_vring_write_descs(svq, elem->in_sg, elem->in_num, false, true);
110
+ ok = vhost_svq_translate_addr(svq, sgs, elem->out_sg, elem->out_num);
111
+ if (unlikely(!ok)) {
112
+ return false;
113
+ }
114
+ vhost_vring_write_descs(svq, sgs, elem->out_sg, elem->out_num,
115
+ elem->in_num > 0, false);
116
+
117
+
118
+ ok = vhost_svq_translate_addr(svq, sgs, elem->in_sg, elem->in_num);
119
+ if (unlikely(!ok)) {
120
+ return false;
121
+ }
122
+
123
+ vhost_vring_write_descs(svq, sgs, elem->in_sg, elem->in_num, false, true);
124
125
/*
126
* Put the entry in the available array (but don't update avail->idx until
127
@@ -XXX,XX +XXX,XX @@ void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd)
128
void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
129
struct vhost_vring_addr *addr)
130
{
131
- addr->desc_user_addr = (uint64_t)(intptr_t)svq->vring.desc;
132
- addr->avail_user_addr = (uint64_t)(intptr_t)svq->vring.avail;
133
- addr->used_user_addr = (uint64_t)(intptr_t)svq->vring.used;
134
+ addr->desc_user_addr = (uint64_t)(uintptr_t)svq->vring.desc;
135
+ addr->avail_user_addr = (uint64_t)(uintptr_t)svq->vring.avail;
136
+ addr->used_user_addr = (uint64_t)(uintptr_t)svq->vring.used;
137
}
138
139
size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *svq)
140
@@ -XXX,XX +XXX,XX @@ void vhost_svq_stop(VhostShadowVirtqueue *svq)
141
* Creates vhost shadow virtqueue, and instructs the vhost device to use the
142
* shadow methods and file descriptors.
143
*
144
+ * @iova_tree: Tree to perform descriptors translations
145
+ *
146
* Returns the new virtqueue or NULL.
147
*
148
* In case of error, reason is reported through error_report.
149
*/
150
-VhostShadowVirtqueue *vhost_svq_new(void)
151
+VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree)
152
{
153
g_autofree VhostShadowVirtqueue *svq = g_new0(VhostShadowVirtqueue, 1);
154
int r;
155
@@ -XXX,XX +XXX,XX @@ VhostShadowVirtqueue *vhost_svq_new(void)
156
157
event_notifier_init_fd(&svq->svq_kick, VHOST_FILE_UNBIND);
158
event_notifier_set_handler(&svq->hdev_call, vhost_svq_handle_call);
159
+ svq->iova_tree = iova_tree;
160
return g_steal_pointer(&svq);
161
162
err_init_hdev_call:
163
diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
164
index XXXXXXX..XXXXXXX 100644
165
--- a/hw/virtio/vhost-shadow-virtqueue.h
166
+++ b/hw/virtio/vhost-shadow-virtqueue.h
167
@@ -XXX,XX +XXX,XX @@
168
#include "qemu/event_notifier.h"
169
#include "hw/virtio/virtio.h"
170
#include "standard-headers/linux/vhost_types.h"
171
+#include "hw/virtio/vhost-iova-tree.h"
172
173
/* Shadow virtqueue to relay notifications */
174
typedef struct VhostShadowVirtqueue {
175
@@ -XXX,XX +XXX,XX @@ typedef struct VhostShadowVirtqueue {
176
/* Virtio device */
177
VirtIODevice *vdev;
178
179
+ /* IOVA mapping */
180
+ VhostIOVATree *iova_tree;
181
+
182
/* Map for use the guest's descriptors */
183
VirtQueueElement **ring_id_maps;
184
185
@@ -XXX,XX +XXX,XX @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev,
186
VirtQueue *vq);
187
void vhost_svq_stop(VhostShadowVirtqueue *svq);
188
189
-VhostShadowVirtqueue *vhost_svq_new(void);
190
+VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree);
191
192
void vhost_svq_free(gpointer vq);
193
G_DEFINE_AUTOPTR_CLEANUP_FUNC(VhostShadowVirtqueue, vhost_svq_free);
194
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
195
index XXXXXXX..XXXXXXX 100644
196
--- a/hw/virtio/vhost-vdpa.c
197
+++ b/hw/virtio/vhost-vdpa.c
198
@@ -XXX,XX +XXX,XX @@ static void vhost_vdpa_listener_region_add(MemoryListener *listener,
199
vaddr, section->readonly);
200
201
llsize = int128_sub(llend, int128_make64(iova));
202
+ if (v->shadow_vqs_enabled) {
203
+ DMAMap mem_region = {
204
+ .translated_addr = (hwaddr)(uintptr_t)vaddr,
205
+ .size = int128_get64(llsize) - 1,
206
+ .perm = IOMMU_ACCESS_FLAG(true, section->readonly),
207
+ };
208
+
209
+ int r = vhost_iova_tree_map_alloc(v->iova_tree, &mem_region);
210
+ if (unlikely(r != IOVA_OK)) {
211
+ error_report("Can't allocate a mapping (%d)", r);
212
+ goto fail;
213
+ }
214
+
215
+ iova = mem_region.iova;
216
+ }
217
218
vhost_vdpa_iotlb_batch_begin_once(v);
219
ret = vhost_vdpa_dma_map(v, iova, int128_get64(llsize),
220
@@ -XXX,XX +XXX,XX @@ static void vhost_vdpa_listener_region_del(MemoryListener *listener,
221
222
llsize = int128_sub(llend, int128_make64(iova));
223
224
+ if (v->shadow_vqs_enabled) {
225
+ const DMAMap *result;
226
+ const void *vaddr = memory_region_get_ram_ptr(section->mr) +
227
+ section->offset_within_region +
228
+ (iova - section->offset_within_address_space);
229
+ DMAMap mem_region = {
230
+ .translated_addr = (hwaddr)(uintptr_t)vaddr,
231
+ .size = int128_get64(llsize) - 1,
232
+ };
233
+
234
+ result = vhost_iova_tree_find_iova(v->iova_tree, &mem_region);
235
+ iova = result->iova;
236
+ vhost_iova_tree_remove(v->iova_tree, &mem_region);
237
+ }
238
vhost_vdpa_iotlb_batch_begin_once(v);
239
ret = vhost_vdpa_dma_unmap(v, iova, int128_get64(llsize));
240
if (ret) {
241
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v,
242
243
shadow_vqs = g_ptr_array_new_full(hdev->nvqs, vhost_svq_free);
244
for (unsigned n = 0; n < hdev->nvqs; ++n) {
245
- g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new();
246
+ g_autoptr(VhostShadowVirtqueue) svq = vhost_svq_new(v->iova_tree);
247
248
if (unlikely(!svq)) {
249
error_setg(errp, "Cannot create svq %u", n);
250
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev,
251
/**
252
* Unmap a SVQ area in the device
253
*/
254
-static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, hwaddr iova,
255
- hwaddr size)
256
+static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v,
257
+ const DMAMap *needle)
258
{
259
+ const DMAMap *result = vhost_iova_tree_find_iova(v->iova_tree, needle);
260
+ hwaddr size;
261
int r;
262
263
- size = ROUND_UP(size, qemu_real_host_page_size);
264
- r = vhost_vdpa_dma_unmap(v, iova, size);
265
+ if (unlikely(!result)) {
266
+ error_report("Unable to find SVQ address to unmap");
267
+ return false;
268
+ }
269
+
270
+ size = ROUND_UP(result->size, qemu_real_host_page_size);
271
+ r = vhost_vdpa_dma_unmap(v, result->iova, size);
272
return r == 0;
273
}
274
275
static bool vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev,
276
const VhostShadowVirtqueue *svq)
277
{
278
+ DMAMap needle = {};
279
struct vhost_vdpa *v = dev->opaque;
280
struct vhost_vring_addr svq_addr;
281
- size_t device_size = vhost_svq_device_area_size(svq);
282
- size_t driver_size = vhost_svq_driver_area_size(svq);
283
bool ok;
284
285
vhost_svq_get_vring_addr(svq, &svq_addr);
286
287
- ok = vhost_vdpa_svq_unmap_ring(v, svq_addr.desc_user_addr, driver_size);
288
+ needle.translated_addr = svq_addr.desc_user_addr;
289
+ ok = vhost_vdpa_svq_unmap_ring(v, &needle);
290
if (unlikely(!ok)) {
291
return false;
292
}
293
294
- return vhost_vdpa_svq_unmap_ring(v, svq_addr.used_user_addr, device_size);
295
+ needle.translated_addr = svq_addr.used_user_addr;
296
+ return vhost_vdpa_svq_unmap_ring(v, &needle);
297
+}
298
+
299
+/**
300
+ * Map the SVQ area in the device
301
+ *
302
+ * @v: Vhost-vdpa device
303
+ * @needle: The area to search iova
304
+ * @errorp: Error pointer
305
+ */
306
+static bool vhost_vdpa_svq_map_ring(struct vhost_vdpa *v, DMAMap *needle,
307
+ Error **errp)
1312
+{
308
+{
1313
+ igb_receive_internal(core, virt_iov, virt_iovcnt, true, NULL);
309
+ int r;
1314
+}
310
+
1315
+
311
+ r = vhost_iova_tree_map_alloc(v->iova_tree, needle);
1316
+static void igb_tx_pkt_vmdq_callback(void *opaque,
312
+ if (unlikely(r != IOVA_OK)) {
1317
+ const struct iovec *iov,
313
+ error_setg(errp, "Cannot allocate iova (%d)", r);
1318
+ int iovcnt,
1319
+ const struct iovec *virt_iov,
1320
+ int virt_iovcnt)
1321
+{
1322
+ IGBTxPktVmdqCallbackContext *context = opaque;
1323
+ bool external_tx;
1324
+
1325
+ igb_receive_internal(context->core, virt_iov, virt_iovcnt, true,
1326
+ &external_tx);
1327
+
1328
+ if (external_tx) {
1329
+ if (context->core->has_vnet) {
1330
+ qemu_sendv_packet(context->nc, virt_iov, virt_iovcnt);
1331
+ } else {
1332
+ qemu_sendv_packet(context->nc, iov, iovcnt);
1333
+ }
1334
+ }
1335
+}
1336
+
1337
+/* TX Packets Switching (7.10.3.6) */
1338
+static bool igb_tx_pkt_switch(IGBCore *core, struct igb_tx *tx,
1339
+ NetClientState *nc)
1340
+{
1341
+ IGBTxPktVmdqCallbackContext context;
1342
+
1343
+ /* TX switching is only used to serve VM to VM traffic. */
1344
+ if (!(core->mac[MRQC] & 1)) {
1345
+ goto send_out;
1346
+ }
1347
+
1348
+ /* TX switching requires DTXSWC.Loopback_en bit enabled. */
1349
+ if (!(core->mac[DTXSWC] & E1000_DTXSWC_VMDQ_LOOPBACK_EN)) {
1350
+ goto send_out;
1351
+ }
1352
+
1353
+ context.core = core;
1354
+ context.nc = nc;
1355
+
1356
+ return net_tx_pkt_send_custom(tx->tx_pkt, false,
1357
+ igb_tx_pkt_vmdq_callback, &context);
1358
+
1359
+send_out:
1360
+ return net_tx_pkt_send(tx->tx_pkt, nc);
1361
+}
1362
+
1363
+static bool
1364
+igb_tx_pkt_send(IGBCore *core, struct igb_tx *tx, int queue_index)
1365
+{
1366
+ int target_queue = MIN(core->max_queue_num, queue_index);
1367
+ NetClientState *queue = qemu_get_subqueue(core->owner_nic, target_queue);
1368
+
1369
+ if (!igb_setup_tx_offloads(core, tx)) {
1370
+ return false;
314
+ return false;
1371
+ }
315
+ }
1372
+
316
+
1373
+ net_tx_pkt_dump(tx->tx_pkt);
317
+ r = vhost_vdpa_dma_map(v, needle->iova, needle->size + 1,
1374
+
318
+ (void *)(uintptr_t)needle->translated_addr,
1375
+ if ((core->phy[MII_BMCR] & MII_BMCR_LOOPBACK) ||
319
+ needle->perm == IOMMU_RO);
1376
+ ((core->mac[RCTL] & E1000_RCTL_LBM_MAC) == E1000_RCTL_LBM_MAC)) {
320
+ if (unlikely(r != 0)) {
1377
+ return net_tx_pkt_send_custom(tx->tx_pkt, false,
321
+ error_setg_errno(errp, -r, "Cannot map region to device");
1378
+ igb_tx_pkt_mac_callback, core);
322
+ vhost_iova_tree_remove(v->iova_tree, needle);
1379
+ } else {
323
+ }
1380
+ return igb_tx_pkt_switch(core, tx, queue);
324
+
1381
+ }
325
+ return r == 0;
1382
+}
326
}
1383
+
327
1384
+static void
328
/**
1385
+igb_on_tx_done_update_stats(IGBCore *core, struct NetTxPkt *tx_pkt)
329
@@ -XXX,XX +XXX,XX @@ static bool vhost_vdpa_svq_map_rings(struct vhost_dev *dev,
1386
+{
330
struct vhost_vring_addr *addr,
1387
+ static const int PTCregs[6] = { PTC64, PTC127, PTC255, PTC511,
331
Error **errp)
1388
+ PTC1023, PTC1522 };
332
{
1389
+
333
+ DMAMap device_region, driver_region;
1390
+ size_t tot_len = net_tx_pkt_get_total_len(tx_pkt) + 4;
334
+ struct vhost_vring_addr svq_addr;
1391
+
335
struct vhost_vdpa *v = dev->opaque;
1392
+ e1000x_increase_size_stats(core->mac, PTCregs, tot_len);
336
size_t device_size = vhost_svq_device_area_size(svq);
1393
+ e1000x_inc_reg_if_not_full(core->mac, TPT);
337
size_t driver_size = vhost_svq_driver_area_size(svq);
1394
+ e1000x_grow_8reg_if_not_full(core->mac, TOTL, tot_len);
338
- int r;
1395
+
339
+ size_t avail_offset;
1396
+ switch (net_tx_pkt_get_packet_type(tx_pkt)) {
340
+ bool ok;
1397
+ case ETH_PKT_BCAST:
341
1398
+ e1000x_inc_reg_if_not_full(core->mac, BPTC);
342
ERRP_GUARD();
1399
+ break;
343
- vhost_svq_get_vring_addr(svq, addr);
1400
+ case ETH_PKT_MCAST:
344
+ vhost_svq_get_vring_addr(svq, &svq_addr);
1401
+ e1000x_inc_reg_if_not_full(core->mac, MPTC);
345
1402
+ break;
346
- r = vhost_vdpa_dma_map(v, addr->desc_user_addr, driver_size,
1403
+ case ETH_PKT_UCAST:
347
- (void *)(uintptr_t)addr->desc_user_addr, true);
1404
+ break;
348
- if (unlikely(r != 0)) {
1405
+ default:
349
- error_setg_errno(errp, -r, "Cannot create vq driver region: ");
1406
+ g_assert_not_reached();
350
+ driver_region = (DMAMap) {
1407
+ }
351
+ .translated_addr = svq_addr.desc_user_addr,
1408
+
352
+ .size = driver_size - 1,
1409
+ core->mac[GPTC] = core->mac[TPT];
353
+ .perm = IOMMU_RO,
1410
+ core->mac[GOTCL] = core->mac[TOTL];
1411
+ core->mac[GOTCH] = core->mac[TOTH];
1412
+}
1413
+
1414
+static void
1415
+igb_process_tx_desc(IGBCore *core,
1416
+ struct igb_tx *tx,
1417
+ union e1000_adv_tx_desc *tx_desc,
1418
+ int queue_index)
1419
+{
1420
+ struct e1000_adv_tx_context_desc *tx_ctx_desc;
1421
+ uint32_t cmd_type_len;
1422
+ uint32_t olinfo_status;
1423
+ uint64_t buffer_addr;
1424
+ uint16_t length;
1425
+
1426
+ cmd_type_len = le32_to_cpu(tx_desc->read.cmd_type_len);
1427
+
1428
+ if (cmd_type_len & E1000_ADVTXD_DCMD_DEXT) {
1429
+ if ((cmd_type_len & E1000_ADVTXD_DTYP_DATA) ==
1430
+ E1000_ADVTXD_DTYP_DATA) {
1431
+ /* advanced transmit data descriptor */
1432
+ if (tx->first) {
1433
+ olinfo_status = le32_to_cpu(tx_desc->read.olinfo_status);
1434
+
1435
+ tx->tse = !!(cmd_type_len & E1000_ADVTXD_DCMD_TSE);
1436
+ tx->ixsm = !!(olinfo_status & E1000_ADVTXD_POTS_IXSM);
1437
+ tx->txsm = !!(olinfo_status & E1000_ADVTXD_POTS_TXSM);
1438
+
1439
+ tx->first = false;
1440
+ }
1441
+ } else if ((cmd_type_len & E1000_ADVTXD_DTYP_CTXT) ==
1442
+ E1000_ADVTXD_DTYP_CTXT) {
1443
+ /* advanced transmit context descriptor */
1444
+ tx_ctx_desc = (struct e1000_adv_tx_context_desc *)tx_desc;
1445
+ tx->vlan = le32_to_cpu(tx_ctx_desc->vlan_macip_lens) >> 16;
1446
+ tx->mss = le32_to_cpu(tx_ctx_desc->mss_l4len_idx) >> 16;
1447
+ return;
1448
+ } else {
1449
+ /* unknown descriptor type */
1450
+ return;
1451
+ }
1452
+ } else {
1453
+ /* legacy descriptor */
1454
+
1455
+ /* TODO: Implement a support for legacy descriptors (7.2.2.1). */
1456
+ }
1457
+
1458
+ buffer_addr = le64_to_cpu(tx_desc->read.buffer_addr);
1459
+ length = cmd_type_len & 0xFFFF;
1460
+
1461
+ if (!tx->skip_cp) {
1462
+ if (!net_tx_pkt_add_raw_fragment(tx->tx_pkt, buffer_addr, length)) {
1463
+ tx->skip_cp = true;
1464
+ }
1465
+ }
1466
+
1467
+ if (cmd_type_len & E1000_TXD_CMD_EOP) {
1468
+ if (!tx->skip_cp && net_tx_pkt_parse(tx->tx_pkt)) {
1469
+ if (cmd_type_len & E1000_TXD_CMD_VLE) {
1470
+ net_tx_pkt_setup_vlan_header_ex(tx->tx_pkt, tx->vlan,
1471
+ core->mac[VET] & 0xffff);
1472
+ }
1473
+ if (igb_tx_pkt_send(core, tx, queue_index)) {
1474
+ igb_on_tx_done_update_stats(core, tx->tx_pkt);
1475
+ }
1476
+ }
1477
+
1478
+ tx->first = true;
1479
+ tx->skip_cp = false;
1480
+ net_tx_pkt_reset(tx->tx_pkt);
1481
+ }
1482
+}
1483
+
1484
+static uint32_t igb_tx_wb_eic(IGBCore *core, int queue_idx)
1485
+{
1486
+ uint32_t n, ent = 0;
1487
+
1488
+ n = igb_ivar_entry_tx(queue_idx);
1489
+ ent = (core->mac[IVAR0 + n / 4] >> (8 * (n % 4))) & 0xff;
1490
+
1491
+ return (ent & E1000_IVAR_VALID) ? BIT(ent & 0x1f) : 0;
1492
+}
1493
+
1494
+static uint32_t igb_rx_wb_eic(IGBCore *core, int queue_idx)
1495
+{
1496
+ uint32_t n, ent = 0;
1497
+
1498
+ n = igb_ivar_entry_rx(queue_idx);
1499
+ ent = (core->mac[IVAR0 + n / 4] >> (8 * (n % 4))) & 0xff;
1500
+
1501
+ return (ent & E1000_IVAR_VALID) ? BIT(ent & 0x1f) : 0;
1502
+}
1503
+
1504
+typedef struct E1000E_RingInfo_st {
1505
+ int dbah;
1506
+ int dbal;
1507
+ int dlen;
1508
+ int dh;
1509
+ int dt;
1510
+ int idx;
1511
+} E1000E_RingInfo;
1512
+
1513
+static inline bool
1514
+igb_ring_empty(IGBCore *core, const E1000E_RingInfo *r)
1515
+{
1516
+ return core->mac[r->dh] == core->mac[r->dt] ||
1517
+ core->mac[r->dt] >= core->mac[r->dlen] / E1000_RING_DESC_LEN;
1518
+}
1519
+
1520
+static inline uint64_t
1521
+igb_ring_base(IGBCore *core, const E1000E_RingInfo *r)
1522
+{
1523
+ uint64_t bah = core->mac[r->dbah];
1524
+ uint64_t bal = core->mac[r->dbal];
1525
+
1526
+ return (bah << 32) + bal;
1527
+}
1528
+
1529
+static inline uint64_t
1530
+igb_ring_head_descr(IGBCore *core, const E1000E_RingInfo *r)
1531
+{
1532
+ return igb_ring_base(core, r) + E1000_RING_DESC_LEN * core->mac[r->dh];
1533
+}
1534
+
1535
+static inline void
1536
+igb_ring_advance(IGBCore *core, const E1000E_RingInfo *r, uint32_t count)
1537
+{
1538
+ core->mac[r->dh] += count;
1539
+
1540
+ if (core->mac[r->dh] * E1000_RING_DESC_LEN >= core->mac[r->dlen]) {
1541
+ core->mac[r->dh] = 0;
1542
+ }
1543
+}
1544
+
1545
+static inline uint32_t
1546
+igb_ring_free_descr_num(IGBCore *core, const E1000E_RingInfo *r)
1547
+{
1548
+ trace_e1000e_ring_free_space(r->idx, core->mac[r->dlen],
1549
+ core->mac[r->dh], core->mac[r->dt]);
1550
+
1551
+ if (core->mac[r->dh] <= core->mac[r->dt]) {
1552
+ return core->mac[r->dt] - core->mac[r->dh];
1553
+ }
1554
+
1555
+ if (core->mac[r->dh] > core->mac[r->dt]) {
1556
+ return core->mac[r->dlen] / E1000_RING_DESC_LEN +
1557
+ core->mac[r->dt] - core->mac[r->dh];
1558
+ }
1559
+
1560
+ g_assert_not_reached();
1561
+ return 0;
1562
+}
1563
+
1564
+static inline bool
1565
+igb_ring_enabled(IGBCore *core, const E1000E_RingInfo *r)
1566
+{
1567
+ return core->mac[r->dlen] > 0;
1568
+}
1569
+
1570
+typedef struct IGB_TxRing_st {
1571
+ const E1000E_RingInfo *i;
1572
+ struct igb_tx *tx;
1573
+} IGB_TxRing;
1574
+
1575
+static inline int
1576
+igb_mq_queue_idx(int base_reg_idx, int reg_idx)
1577
+{
1578
+ return (reg_idx - base_reg_idx) / 16;
1579
+}
1580
+
1581
+static inline void
1582
+igb_tx_ring_init(IGBCore *core, IGB_TxRing *txr, int idx)
1583
+{
1584
+ static const E1000E_RingInfo i[IGB_NUM_QUEUES] = {
1585
+ { TDBAH0, TDBAL0, TDLEN0, TDH0, TDT0, 0 },
1586
+ { TDBAH1, TDBAL1, TDLEN1, TDH1, TDT1, 1 },
1587
+ { TDBAH2, TDBAL2, TDLEN2, TDH2, TDT2, 2 },
1588
+ { TDBAH3, TDBAL3, TDLEN3, TDH3, TDT3, 3 },
1589
+ { TDBAH4, TDBAL4, TDLEN4, TDH4, TDT4, 4 },
1590
+ { TDBAH5, TDBAL5, TDLEN5, TDH5, TDT5, 5 },
1591
+ { TDBAH6, TDBAL6, TDLEN6, TDH6, TDT6, 6 },
1592
+ { TDBAH7, TDBAL7, TDLEN7, TDH7, TDT7, 7 },
1593
+ { TDBAH8, TDBAL8, TDLEN8, TDH8, TDT8, 8 },
1594
+ { TDBAH9, TDBAL9, TDLEN9, TDH9, TDT9, 9 },
1595
+ { TDBAH10, TDBAL10, TDLEN10, TDH10, TDT10, 10 },
1596
+ { TDBAH11, TDBAL11, TDLEN11, TDH11, TDT11, 11 },
1597
+ { TDBAH12, TDBAL12, TDLEN12, TDH12, TDT12, 12 },
1598
+ { TDBAH13, TDBAL13, TDLEN13, TDH13, TDT13, 13 },
1599
+ { TDBAH14, TDBAL14, TDLEN14, TDH14, TDT14, 14 },
1600
+ { TDBAH15, TDBAL15, TDLEN15, TDH15, TDT15, 15 }
1601
+ };
354
+ };
1602
+
355
+ ok = vhost_vdpa_svq_map_ring(v, &driver_region, errp);
1603
+ assert(idx < ARRAY_SIZE(i));
356
+ if (unlikely(!ok)) {
1604
+
357
+ error_prepend(errp, "Cannot create vq driver region: ");
1605
+ txr->i = &i[idx];
358
return false;
1606
+ txr->tx = &core->tx[idx];
359
}
1607
+}
360
+ addr->desc_user_addr = driver_region.iova;
1608
+
361
+ avail_offset = svq_addr.avail_user_addr - svq_addr.desc_user_addr;
1609
+typedef struct E1000E_RxRing_st {
362
+ addr->avail_user_addr = driver_region.iova + avail_offset;
1610
+ const E1000E_RingInfo *i;
363
1611
+} E1000E_RxRing;
364
- r = vhost_vdpa_dma_map(v, addr->used_user_addr, device_size,
1612
+
365
- (void *)(intptr_t)addr->used_user_addr, false);
1613
+static inline void
366
- if (unlikely(r != 0)) {
1614
+igb_rx_ring_init(IGBCore *core, E1000E_RxRing *rxr, int idx)
367
- error_setg_errno(errp, -r, "Cannot create vq device region: ");
1615
+{
368
+ device_region = (DMAMap) {
1616
+ static const E1000E_RingInfo i[IGB_NUM_QUEUES] = {
369
+ .translated_addr = svq_addr.used_user_addr,
1617
+ { RDBAH0, RDBAL0, RDLEN0, RDH0, RDT0, 0 },
370
+ .size = device_size - 1,
1618
+ { RDBAH1, RDBAL1, RDLEN1, RDH1, RDT1, 1 },
371
+ .perm = IOMMU_RW,
1619
+ { RDBAH2, RDBAL2, RDLEN2, RDH2, RDT2, 2 },
1620
+ { RDBAH3, RDBAL3, RDLEN3, RDH3, RDT3, 3 },
1621
+ { RDBAH4, RDBAL4, RDLEN4, RDH4, RDT4, 4 },
1622
+ { RDBAH5, RDBAL5, RDLEN5, RDH5, RDT5, 5 },
1623
+ { RDBAH6, RDBAL6, RDLEN6, RDH6, RDT6, 6 },
1624
+ { RDBAH7, RDBAL7, RDLEN7, RDH7, RDT7, 7 },
1625
+ { RDBAH8, RDBAL8, RDLEN8, RDH8, RDT8, 8 },
1626
+ { RDBAH9, RDBAL9, RDLEN9, RDH9, RDT9, 9 },
1627
+ { RDBAH10, RDBAL10, RDLEN10, RDH10, RDT10, 10 },
1628
+ { RDBAH11, RDBAL11, RDLEN11, RDH11, RDT11, 11 },
1629
+ { RDBAH12, RDBAL12, RDLEN12, RDH12, RDT12, 12 },
1630
+ { RDBAH13, RDBAL13, RDLEN13, RDH13, RDT13, 13 },
1631
+ { RDBAH14, RDBAL14, RDLEN14, RDH14, RDT14, 14 },
1632
+ { RDBAH15, RDBAL15, RDLEN15, RDH15, RDT15, 15 }
1633
+ };
372
+ };
1634
+
373
+ ok = vhost_vdpa_svq_map_ring(v, &device_region, errp);
1635
+ assert(idx < ARRAY_SIZE(i));
374
+ if (unlikely(!ok)) {
1636
+
375
+ error_prepend(errp, "Cannot create vq device region: ");
1637
+ rxr->i = &i[idx];
376
+ vhost_vdpa_svq_unmap_ring(v, &driver_region);
1638
+}
377
}
1639
+
378
+ addr->used_user_addr = device_region.iova;
1640
+static uint32_t
379
1641
+igb_txdesc_writeback(IGBCore *core, dma_addr_t base,
380
- return r == 0;
1642
+ union e1000_adv_tx_desc *tx_desc,
381
+ return ok;
1643
+ const E1000E_RingInfo *txi)
382
}
1644
+{
383
1645
+ PCIDevice *d;
384
static bool vhost_vdpa_svq_setup(struct vhost_dev *dev,
1646
+ uint32_t cmd_type_len = le32_to_cpu(tx_desc->read.cmd_type_len);
385
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
1647
+ uint64_t tdwba;
386
index XXXXXXX..XXXXXXX 100644
1648
+
387
--- a/include/hw/virtio/vhost-vdpa.h
1649
+ tdwba = core->mac[E1000_TDWBAL(txi->idx) >> 2];
388
+++ b/include/hw/virtio/vhost-vdpa.h
1650
+ tdwba |= (uint64_t)core->mac[E1000_TDWBAH(txi->idx) >> 2] << 32;
1651
+
1652
+ if (!(cmd_type_len & E1000_TXD_CMD_RS)) {
1653
+ return 0;
1654
+ }
1655
+
1656
+ d = pcie_sriov_get_vf_at_index(core->owner, txi->idx % 8);
1657
+ if (!d) {
1658
+ d = core->owner;
1659
+ }
1660
+
1661
+ if (tdwba & 1) {
1662
+ uint32_t buffer = cpu_to_le32(core->mac[txi->dh]);
1663
+ pci_dma_write(d, tdwba & ~3, &buffer, sizeof(buffer));
1664
+ } else {
1665
+ uint32_t status = le32_to_cpu(tx_desc->wb.status) | E1000_TXD_STAT_DD;
1666
+
1667
+ tx_desc->wb.status = cpu_to_le32(status);
1668
+ pci_dma_write(d, base + offsetof(union e1000_adv_tx_desc, wb),
1669
+ &tx_desc->wb, sizeof(tx_desc->wb));
1670
+ }
1671
+
1672
+ return igb_tx_wb_eic(core, txi->idx);
1673
+}
1674
+
1675
+static void
1676
+igb_start_xmit(IGBCore *core, const IGB_TxRing *txr)
1677
+{
1678
+ PCIDevice *d;
1679
+ dma_addr_t base;
1680
+ union e1000_adv_tx_desc desc;
1681
+ const E1000E_RingInfo *txi = txr->i;
1682
+ uint32_t eic = 0;
1683
+
1684
+ /* TODO: check if the queue itself is enabled too. */
1685
+ if (!(core->mac[TCTL] & E1000_TCTL_EN)) {
1686
+ trace_e1000e_tx_disabled();
1687
+ return;
1688
+ }
1689
+
1690
+ d = pcie_sriov_get_vf_at_index(core->owner, txi->idx % 8);
1691
+ if (!d) {
1692
+ d = core->owner;
1693
+ }
1694
+
1695
+ while (!igb_ring_empty(core, txi)) {
1696
+ base = igb_ring_head_descr(core, txi);
1697
+
1698
+ pci_dma_read(d, base, &desc, sizeof(desc));
1699
+
1700
+ trace_e1000e_tx_descr((void *)(intptr_t)desc.read.buffer_addr,
1701
+ desc.read.cmd_type_len, desc.wb.status);
1702
+
1703
+ igb_process_tx_desc(core, txr->tx, &desc, txi->idx);
1704
+ igb_ring_advance(core, txi, 1);
1705
+ eic |= igb_txdesc_writeback(core, base, &desc, txi);
1706
+ }
1707
+
1708
+ if (eic) {
1709
+ core->mac[EICR] |= eic;
1710
+ igb_set_interrupt_cause(core, E1000_ICR_TXDW);
1711
+ }
1712
+}
1713
+
1714
+static uint32_t
1715
+igb_rxbufsize(IGBCore *core, const E1000E_RingInfo *r)
1716
+{
1717
+ uint32_t srrctl = core->mac[E1000_SRRCTL(r->idx) >> 2];
1718
+ uint32_t bsizepkt = srrctl & E1000_SRRCTL_BSIZEPKT_MASK;
1719
+ if (bsizepkt) {
1720
+ return bsizepkt << E1000_SRRCTL_BSIZEPKT_SHIFT;
1721
+ }
1722
+
1723
+ return e1000x_rxbufsize(core->mac[RCTL]);
1724
+}
1725
+
1726
+static bool
1727
+igb_has_rxbufs(IGBCore *core, const E1000E_RingInfo *r, size_t total_size)
1728
+{
1729
+ uint32_t bufs = igb_ring_free_descr_num(core, r);
1730
+ uint32_t bufsize = igb_rxbufsize(core, r);
1731
+
1732
+ trace_e1000e_rx_has_buffers(r->idx, bufs, total_size, bufsize);
1733
+
1734
+ return total_size <= bufs / (core->rx_desc_len / E1000_MIN_RX_DESC_LEN) *
1735
+ bufsize;
1736
+}
1737
+
1738
+void
1739
+igb_start_recv(IGBCore *core)
1740
+{
1741
+ int i;
1742
+
1743
+ trace_e1000e_rx_start_recv();
1744
+
1745
+ for (i = 0; i <= core->max_queue_num; i++) {
1746
+ qemu_flush_queued_packets(qemu_get_subqueue(core->owner_nic, i));
1747
+ }
1748
+}
1749
+
1750
+bool
1751
+igb_can_receive(IGBCore *core)
1752
+{
1753
+ int i;
1754
+
1755
+ if (!e1000x_rx_ready(core->owner, core->mac)) {
1756
+ return false;
1757
+ }
1758
+
1759
+ for (i = 0; i < IGB_NUM_QUEUES; i++) {
1760
+ E1000E_RxRing rxr;
1761
+
1762
+ igb_rx_ring_init(core, &rxr, i);
1763
+ if (igb_ring_enabled(core, rxr.i) && igb_has_rxbufs(core, rxr.i, 1)) {
1764
+ trace_e1000e_rx_can_recv();
1765
+ return true;
1766
+ }
1767
+ }
1768
+
1769
+ trace_e1000e_rx_can_recv_rings_full();
1770
+ return false;
1771
+}
1772
+
1773
+ssize_t
1774
+igb_receive(IGBCore *core, const uint8_t *buf, size_t size)
1775
+{
1776
+ const struct iovec iov = {
1777
+ .iov_base = (uint8_t *)buf,
1778
+ .iov_len = size
1779
+ };
1780
+
1781
+ return igb_receive_iov(core, &iov, 1);
1782
+}
1783
+
1784
+static inline bool
1785
+igb_rx_l3_cso_enabled(IGBCore *core)
1786
+{
1787
+ return !!(core->mac[RXCSUM] & E1000_RXCSUM_IPOFLD);
1788
+}
1789
+
1790
+static inline bool
1791
+igb_rx_l4_cso_enabled(IGBCore *core)
1792
+{
1793
+ return !!(core->mac[RXCSUM] & E1000_RXCSUM_TUOFLD);
1794
+}
1795
+
1796
+static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr,
1797
+ E1000E_RSSInfo *rss_info, bool *external_tx)
1798
+{
1799
+ static const int ta_shift[] = { 4, 3, 2, 0 };
1800
+ uint32_t f, ra[2], *macp, rctl = core->mac[RCTL];
1801
+ uint16_t queues = 0;
1802
+ uint16_t vid = lduw_be_p(&PKT_GET_VLAN_HDR(ehdr)->h_tci) & VLAN_VID_MASK;
1803
+ bool accepted = false;
1804
+ int i;
1805
+
1806
+ memset(rss_info, 0, sizeof(E1000E_RSSInfo));
1807
+
1808
+ if (external_tx) {
1809
+ *external_tx = true;
1810
+ }
1811
+
1812
+ if (e1000x_is_vlan_packet(ehdr, core->mac[VET] & 0xffff) &&
1813
+ e1000x_vlan_rx_filter_enabled(core->mac)) {
1814
+ uint32_t vfta =
1815
+ ldl_le_p((uint32_t *)(core->mac + VFTA) +
1816
+ ((vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK));
1817
+ if ((vfta & (1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK))) == 0) {
1818
+ trace_e1000e_rx_flt_vlan_mismatch(vid);
1819
+ return queues;
1820
+ } else {
1821
+ trace_e1000e_rx_flt_vlan_match(vid);
1822
+ }
1823
+ }
1824
+
1825
+ if (core->mac[MRQC] & 1) {
1826
+ if (is_broadcast_ether_addr(ehdr->h_dest)) {
1827
+ for (i = 0; i < 8; i++) {
1828
+ if (core->mac[VMOLR0 + i] & E1000_VMOLR_BAM) {
1829
+ queues |= BIT(i);
1830
+ }
1831
+ }
1832
+ } else {
1833
+ for (macp = core->mac + RA; macp < core->mac + RA + 32; macp += 2) {
1834
+ if (!(macp[1] & E1000_RAH_AV)) {
1835
+ continue;
1836
+ }
1837
+ ra[0] = cpu_to_le32(macp[0]);
1838
+ ra[1] = cpu_to_le32(macp[1]);
1839
+ if (!memcmp(ehdr->h_dest, (uint8_t *)ra, ETH_ALEN)) {
1840
+ queues |= (macp[1] & E1000_RAH_POOL_MASK) / E1000_RAH_POOL_1;
1841
+ }
1842
+ }
1843
+
1844
+ for (macp = core->mac + RA2; macp < core->mac + RA2 + 16; macp += 2) {
1845
+ if (!(macp[1] & E1000_RAH_AV)) {
1846
+ continue;
1847
+ }
1848
+ ra[0] = cpu_to_le32(macp[0]);
1849
+ ra[1] = cpu_to_le32(macp[1]);
1850
+ if (!memcmp(ehdr->h_dest, (uint8_t *)ra, ETH_ALEN)) {
1851
+ queues |= (macp[1] & E1000_RAH_POOL_MASK) / E1000_RAH_POOL_1;
1852
+ }
1853
+ }
1854
+
1855
+ if (!queues) {
1856
+ macp = core->mac + (is_multicast_ether_addr(ehdr->h_dest) ? MTA : UTA);
1857
+
1858
+ f = ta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3];
1859
+ f = (((ehdr->h_dest[5] << 8) | ehdr->h_dest[4]) >> f) & 0xfff;
1860
+ if (macp[f >> 5] & (1 << (f & 0x1f))) {
1861
+ for (i = 0; i < 8; i++) {
1862
+ if (core->mac[VMOLR0 + i] & E1000_VMOLR_ROMPE) {
1863
+ queues |= BIT(i);
1864
+ }
1865
+ }
1866
+ }
1867
+ } else if (is_unicast_ether_addr(ehdr->h_dest) && external_tx) {
1868
+ *external_tx = false;
1869
+ }
1870
+ }
1871
+
1872
+ if (e1000x_vlan_rx_filter_enabled(core->mac)) {
1873
+ uint16_t mask = 0;
1874
+
1875
+ if (e1000x_is_vlan_packet(ehdr, core->mac[VET] & 0xffff)) {
1876
+ for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) {
1877
+ if ((core->mac[VLVF0 + i] & E1000_VLVF_VLANID_MASK) == vid &&
1878
+ (core->mac[VLVF0 + i] & E1000_VLVF_VLANID_ENABLE)) {
1879
+ uint32_t poolsel = core->mac[VLVF0 + i] & E1000_VLVF_POOLSEL_MASK;
1880
+ mask |= poolsel >> E1000_VLVF_POOLSEL_SHIFT;
1881
+ }
1882
+ }
1883
+ } else {
1884
+ for (i = 0; i < 8; i++) {
1885
+ if (core->mac[VMOLR0 + i] & E1000_VMOLR_AUPE) {
1886
+ mask |= BIT(i);
1887
+ }
1888
+ }
1889
+ }
1890
+
1891
+ queues &= mask;
1892
+ }
1893
+
1894
+ if (is_unicast_ether_addr(ehdr->h_dest) && !queues && !external_tx &&
1895
+ !(core->mac[VT_CTL] & E1000_VT_CTL_DISABLE_DEF_POOL)) {
1896
+ uint32_t def_pl = core->mac[VT_CTL] & E1000_VT_CTL_DEFAULT_POOL_MASK;
1897
+ queues = BIT(def_pl >> E1000_VT_CTL_DEFAULT_POOL_SHIFT);
1898
+ }
1899
+
1900
+ igb_rss_parse_packet(core, core->rx_pkt, external_tx != NULL, rss_info);
1901
+ if (rss_info->queue & 1) {
1902
+ queues <<= 8;
1903
+ }
1904
+ } else {
1905
+ switch (net_rx_pkt_get_packet_type(core->rx_pkt)) {
1906
+ case ETH_PKT_UCAST:
1907
+ if (rctl & E1000_RCTL_UPE) {
1908
+ accepted = true; /* promiscuous ucast */
1909
+ }
1910
+ break;
1911
+
1912
+ case ETH_PKT_BCAST:
1913
+ if (rctl & E1000_RCTL_BAM) {
1914
+ accepted = true; /* broadcast enabled */
1915
+ }
1916
+ break;
1917
+
1918
+ case ETH_PKT_MCAST:
1919
+ if (rctl & E1000_RCTL_MPE) {
1920
+ accepted = true; /* promiscuous mcast */
1921
+ }
1922
+ break;
1923
+
1924
+ default:
1925
+ g_assert_not_reached();
1926
+ }
1927
+
1928
+ if (!accepted) {
1929
+ accepted = e1000x_rx_group_filter(core->mac, ehdr->h_dest);
1930
+ }
1931
+
1932
+ if (!accepted) {
1933
+ for (macp = core->mac + RA2; macp < core->mac + RA2 + 16; macp += 2) {
1934
+ if (!(macp[1] & E1000_RAH_AV)) {
1935
+ continue;
1936
+ }
1937
+ ra[0] = cpu_to_le32(macp[0]);
1938
+ ra[1] = cpu_to_le32(macp[1]);
1939
+ if (!memcmp(ehdr->h_dest, (uint8_t *)ra, ETH_ALEN)) {
1940
+ trace_e1000x_rx_flt_ucast_match((int)(macp - core->mac - RA2) / 2,
1941
+ MAC_ARG(ehdr->h_dest));
1942
+
1943
+ accepted = true;
1944
+ break;
1945
+ }
1946
+ }
1947
+ }
1948
+
1949
+ if (accepted) {
1950
+ igb_rss_parse_packet(core, core->rx_pkt, false, rss_info);
1951
+ queues = BIT(rss_info->queue);
1952
+ }
1953
+ }
1954
+
1955
+ return queues;
1956
+}
1957
+
1958
+static inline void
1959
+igb_read_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc,
1960
+ hwaddr *buff_addr)
1961
+{
1962
+ *buff_addr = le64_to_cpu(desc->buffer_addr);
1963
+}
1964
+
1965
+static inline void
1966
+igb_read_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
1967
+ hwaddr *buff_addr)
1968
+{
1969
+ *buff_addr = le64_to_cpu(desc->read.pkt_addr);
1970
+}
1971
+
1972
+static inline void
1973
+igb_read_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc,
1974
+ hwaddr *buff_addr)
1975
+{
1976
+ if (igb_rx_use_legacy_descriptor(core)) {
1977
+ igb_read_lgcy_rx_descr(core, &desc->legacy, buff_addr);
1978
+ } else {
1979
+ igb_read_adv_rx_descr(core, &desc->adv, buff_addr);
1980
+ }
1981
+}
1982
+
1983
+static void
1984
+igb_verify_csum_in_sw(IGBCore *core,
1985
+ struct NetRxPkt *pkt,
1986
+ uint32_t *status_flags,
1987
+ EthL4HdrProto l4hdr_proto)
1988
+{
1989
+ bool csum_valid;
1990
+ uint32_t csum_error;
1991
+
1992
+ if (igb_rx_l3_cso_enabled(core)) {
1993
+ if (!net_rx_pkt_validate_l3_csum(pkt, &csum_valid)) {
1994
+ trace_e1000e_rx_metadata_l3_csum_validation_failed();
1995
+ } else {
1996
+ csum_error = csum_valid ? 0 : E1000_RXDEXT_STATERR_IPE;
1997
+ *status_flags |= E1000_RXD_STAT_IPCS | csum_error;
1998
+ }
1999
+ } else {
2000
+ trace_e1000e_rx_metadata_l3_cso_disabled();
2001
+ }
2002
+
2003
+ if (!igb_rx_l4_cso_enabled(core)) {
2004
+ trace_e1000e_rx_metadata_l4_cso_disabled();
2005
+ return;
2006
+ }
2007
+
2008
+ if (!net_rx_pkt_validate_l4_csum(pkt, &csum_valid)) {
2009
+ trace_e1000e_rx_metadata_l4_csum_validation_failed();
2010
+ return;
2011
+ }
2012
+
2013
+ csum_error = csum_valid ? 0 : E1000_RXDEXT_STATERR_TCPE;
2014
+ *status_flags |= E1000_RXD_STAT_TCPCS | csum_error;
2015
+
2016
+ if (l4hdr_proto == ETH_L4_HDR_PROTO_UDP) {
2017
+ *status_flags |= E1000_RXD_STAT_UDPCS;
2018
+ }
2019
+}
2020
+
2021
+static void
2022
+igb_build_rx_metadata(IGBCore *core,
2023
+ struct NetRxPkt *pkt,
2024
+ bool is_eop,
2025
+ const E1000E_RSSInfo *rss_info,
2026
+ uint16_t *pkt_info, uint16_t *hdr_info,
2027
+ uint32_t *rss,
2028
+ uint32_t *status_flags,
2029
+ uint16_t *ip_id,
2030
+ uint16_t *vlan_tag)
2031
+{
2032
+ struct virtio_net_hdr *vhdr;
2033
+ bool hasip4, hasip6;
2034
+ EthL4HdrProto l4hdr_proto;
2035
+ uint32_t pkt_type;
2036
+
2037
+ *status_flags = E1000_RXD_STAT_DD;
2038
+
2039
+ /* No additional metadata needed for non-EOP descriptors */
2040
+ /* TODO: EOP apply only to status so don't skip whole function. */
2041
+ if (!is_eop) {
2042
+ goto func_exit;
2043
+ }
2044
+
2045
+ *status_flags |= E1000_RXD_STAT_EOP;
2046
+
2047
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
2048
+ trace_e1000e_rx_metadata_protocols(hasip4, hasip6, l4hdr_proto);
2049
+
2050
+ /* VLAN state */
2051
+ if (net_rx_pkt_is_vlan_stripped(pkt)) {
2052
+ *status_flags |= E1000_RXD_STAT_VP;
2053
+ *vlan_tag = cpu_to_le16(net_rx_pkt_get_vlan_tag(pkt));
2054
+ trace_e1000e_rx_metadata_vlan(*vlan_tag);
2055
+ }
2056
+
2057
+ /* Packet parsing results */
2058
+ if ((core->mac[RXCSUM] & E1000_RXCSUM_PCSD) != 0) {
2059
+ if (rss_info->enabled) {
2060
+ *rss = cpu_to_le32(rss_info->hash);
2061
+ trace_igb_rx_metadata_rss(*rss);
2062
+ }
2063
+ } else if (hasip4) {
2064
+ *status_flags |= E1000_RXD_STAT_IPIDV;
2065
+ *ip_id = cpu_to_le16(net_rx_pkt_get_ip_id(pkt));
2066
+ trace_e1000e_rx_metadata_ip_id(*ip_id);
2067
+ }
2068
+
2069
+ if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP && net_rx_pkt_is_tcp_ack(pkt)) {
2070
+ *status_flags |= E1000_RXD_STAT_ACK;
2071
+ trace_e1000e_rx_metadata_ack();
2072
+ }
2073
+
2074
+ if (hasip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_DIS)) {
2075
+ trace_e1000e_rx_metadata_ipv6_filtering_disabled();
2076
+ pkt_type = E1000_RXD_PKT_MAC;
2077
+ } else if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP ||
2078
+ l4hdr_proto == ETH_L4_HDR_PROTO_UDP) {
2079
+ pkt_type = hasip4 ? E1000_RXD_PKT_IP4_XDP : E1000_RXD_PKT_IP6_XDP;
2080
+ } else if (hasip4 || hasip6) {
2081
+ pkt_type = hasip4 ? E1000_RXD_PKT_IP4 : E1000_RXD_PKT_IP6;
2082
+ } else {
2083
+ pkt_type = E1000_RXD_PKT_MAC;
2084
+ }
2085
+
2086
+ trace_e1000e_rx_metadata_pkt_type(pkt_type);
2087
+
2088
+ if (pkt_info) {
2089
+ if (rss_info->enabled) {
2090
+ *pkt_info = rss_info->type;
2091
+ }
2092
+
2093
+ *pkt_info |= (pkt_type << 4);
2094
+ } else {
2095
+ *status_flags |= E1000_RXD_PKT_TYPE(pkt_type);
2096
+ }
2097
+
2098
+ if (hdr_info) {
2099
+ *hdr_info = 0;
2100
+ }
2101
+
2102
+ /* RX CSO information */
2103
+ if (hasip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_XSUM_DIS)) {
2104
+ trace_e1000e_rx_metadata_ipv6_sum_disabled();
2105
+ goto func_exit;
2106
+ }
2107
+
2108
+ vhdr = net_rx_pkt_get_vhdr(pkt);
2109
+
2110
+ if (!(vhdr->flags & VIRTIO_NET_HDR_F_DATA_VALID) &&
2111
+ !(vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM)) {
2112
+ trace_e1000e_rx_metadata_virthdr_no_csum_info();
2113
+ igb_verify_csum_in_sw(core, pkt, status_flags, l4hdr_proto);
2114
+ goto func_exit;
2115
+ }
2116
+
2117
+ if (igb_rx_l3_cso_enabled(core)) {
2118
+ *status_flags |= hasip4 ? E1000_RXD_STAT_IPCS : 0;
2119
+ } else {
2120
+ trace_e1000e_rx_metadata_l3_cso_disabled();
2121
+ }
2122
+
2123
+ if (igb_rx_l4_cso_enabled(core)) {
2124
+ switch (l4hdr_proto) {
2125
+ case ETH_L4_HDR_PROTO_TCP:
2126
+ *status_flags |= E1000_RXD_STAT_TCPCS;
2127
+ break;
2128
+
2129
+ case ETH_L4_HDR_PROTO_UDP:
2130
+ *status_flags |= E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS;
2131
+ break;
2132
+
2133
+ default:
2134
+ goto func_exit;
2135
+ }
2136
+ } else {
2137
+ trace_e1000e_rx_metadata_l4_cso_disabled();
2138
+ }
2139
+
2140
+ trace_e1000e_rx_metadata_status_flags(*status_flags);
2141
+
2142
+func_exit:
2143
+ *status_flags = cpu_to_le32(*status_flags);
2144
+}
2145
+
2146
+static inline void
2147
+igb_write_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc,
2148
+ struct NetRxPkt *pkt,
2149
+ const E1000E_RSSInfo *rss_info,
2150
+ uint16_t length)
2151
+{
2152
+ uint32_t status_flags, rss;
2153
+ uint16_t ip_id;
2154
+
2155
+ assert(!rss_info->enabled);
2156
+ desc->length = cpu_to_le16(length);
2157
+ desc->csum = 0;
2158
+
2159
+ igb_build_rx_metadata(core, pkt, pkt != NULL,
2160
+ rss_info,
2161
+ NULL, NULL, &rss,
2162
+ &status_flags, &ip_id,
2163
+ &desc->special);
2164
+ desc->errors = (uint8_t) (le32_to_cpu(status_flags) >> 24);
2165
+ desc->status = (uint8_t) le32_to_cpu(status_flags);
2166
+}
2167
+
2168
+static inline void
2169
+igb_write_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
2170
+ struct NetRxPkt *pkt,
2171
+ const E1000E_RSSInfo *rss_info,
2172
+ uint16_t length)
2173
+{
2174
+ memset(&desc->wb, 0, sizeof(desc->wb));
2175
+
2176
+ desc->wb.upper.length = cpu_to_le16(length);
2177
+
2178
+ igb_build_rx_metadata(core, pkt, pkt != NULL,
2179
+ rss_info,
2180
+ &desc->wb.lower.lo_dword.pkt_info,
2181
+ &desc->wb.lower.lo_dword.hdr_info,
2182
+ &desc->wb.lower.hi_dword.rss,
2183
+ &desc->wb.upper.status_error,
2184
+ &desc->wb.lower.hi_dword.csum_ip.ip_id,
2185
+ &desc->wb.upper.vlan);
2186
+}
2187
+
2188
+static inline void
2189
+igb_write_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc,
2190
+struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info, uint16_t length)
2191
+{
2192
+ if (igb_rx_use_legacy_descriptor(core)) {
2193
+ igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info, length);
2194
+ } else {
2195
+ igb_write_adv_rx_descr(core, &desc->adv, pkt, rss_info, length);
2196
+ }
2197
+}
2198
+
2199
+static inline void
2200
+igb_pci_dma_write_rx_desc(IGBCore *core, PCIDevice *dev, dma_addr_t addr,
2201
+ union e1000_rx_desc_union *desc, dma_addr_t len)
2202
+{
2203
+ if (igb_rx_use_legacy_descriptor(core)) {
2204
+ struct e1000_rx_desc *d = &desc->legacy;
2205
+ size_t offset = offsetof(struct e1000_rx_desc, status);
2206
+ uint8_t status = d->status;
2207
+
2208
+ d->status &= ~E1000_RXD_STAT_DD;
2209
+ pci_dma_write(dev, addr, desc, len);
2210
+
2211
+ if (status & E1000_RXD_STAT_DD) {
2212
+ d->status = status;
2213
+ pci_dma_write(dev, addr + offset, &status, sizeof(status));
2214
+ }
2215
+ } else {
2216
+ union e1000_adv_rx_desc *d = &desc->adv;
2217
+ size_t offset =
2218
+ offsetof(union e1000_adv_rx_desc, wb.upper.status_error);
2219
+ uint32_t status = d->wb.upper.status_error;
2220
+
2221
+ d->wb.upper.status_error &= ~E1000_RXD_STAT_DD;
2222
+ pci_dma_write(dev, addr, desc, len);
2223
+
2224
+ if (status & E1000_RXD_STAT_DD) {
2225
+ d->wb.upper.status_error = status;
2226
+ pci_dma_write(dev, addr + offset, &status, sizeof(status));
2227
+ }
2228
+ }
2229
+}
2230
+
2231
+static void
2232
+igb_write_to_rx_buffers(IGBCore *core,
2233
+ PCIDevice *d,
2234
+ hwaddr ba,
2235
+ uint16_t *written,
2236
+ const char *data,
2237
+ dma_addr_t data_len)
2238
+{
2239
+ trace_igb_rx_desc_buff_write(ba, *written, data, data_len);
2240
+ pci_dma_write(d, ba + *written, data, data_len);
2241
+ *written += data_len;
2242
+}
2243
+
2244
+static void
2245
+igb_update_rx_stats(IGBCore *core, size_t data_size, size_t data_fcs_size)
2246
+{
2247
+ e1000x_update_rx_total_stats(core->mac, data_size, data_fcs_size);
2248
+
2249
+ switch (net_rx_pkt_get_packet_type(core->rx_pkt)) {
2250
+ case ETH_PKT_BCAST:
2251
+ e1000x_inc_reg_if_not_full(core->mac, BPRC);
2252
+ break;
2253
+
2254
+ case ETH_PKT_MCAST:
2255
+ e1000x_inc_reg_if_not_full(core->mac, MPRC);
2256
+ break;
2257
+
2258
+ default:
2259
+ break;
2260
+ }
2261
+}
2262
+
2263
+static inline bool
2264
+igb_rx_descr_threshold_hit(IGBCore *core, const E1000E_RingInfo *rxi)
2265
+{
2266
+ return igb_ring_free_descr_num(core, rxi) ==
2267
+ ((core->mac[E1000_SRRCTL(rxi->idx) >> 2] >> 20) & 31) * 16;
2268
+}
2269
+
2270
+static void
2271
+igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt,
2272
+ const E1000E_RxRing *rxr,
2273
+ const E1000E_RSSInfo *rss_info)
2274
+{
2275
+ PCIDevice *d;
2276
+ dma_addr_t base;
2277
+ union e1000_rx_desc_union desc;
2278
+ size_t desc_size;
2279
+ size_t desc_offset = 0;
2280
+ size_t iov_ofs = 0;
2281
+
2282
+ struct iovec *iov = net_rx_pkt_get_iovec(pkt);
2283
+ size_t size = net_rx_pkt_get_total_len(pkt);
2284
+ size_t total_size = size + e1000x_fcs_len(core->mac);
2285
+ const E1000E_RingInfo *rxi = rxr->i;
2286
+ size_t bufsize = igb_rxbufsize(core, rxi);
2287
+
2288
+ d = pcie_sriov_get_vf_at_index(core->owner, rxi->idx % 8);
2289
+ if (!d) {
2290
+ d = core->owner;
2291
+ }
2292
+
2293
+ do {
2294
+ hwaddr ba;
2295
+ uint16_t written = 0;
2296
+ bool is_last = false;
2297
+
2298
+ desc_size = total_size - desc_offset;
2299
+
2300
+ if (desc_size > bufsize) {
2301
+ desc_size = bufsize;
2302
+ }
2303
+
2304
+ if (igb_ring_empty(core, rxi)) {
2305
+ return;
2306
+ }
2307
+
2308
+ base = igb_ring_head_descr(core, rxi);
2309
+
2310
+ pci_dma_read(d, base, &desc, core->rx_desc_len);
2311
+
2312
+ trace_e1000e_rx_descr(rxi->idx, base, core->rx_desc_len);
2313
+
2314
+ igb_read_rx_descr(core, &desc, &ba);
2315
+
2316
+ if (ba) {
2317
+ if (desc_offset < size) {
2318
+ static const uint32_t fcs_pad;
2319
+ size_t iov_copy;
2320
+ size_t copy_size = size - desc_offset;
2321
+ if (copy_size > bufsize) {
2322
+ copy_size = bufsize;
2323
+ }
2324
+
2325
+ /* Copy packet payload */
2326
+ while (copy_size) {
2327
+ iov_copy = MIN(copy_size, iov->iov_len - iov_ofs);
2328
+
2329
+ igb_write_to_rx_buffers(core, d, ba, &written,
2330
+ iov->iov_base + iov_ofs, iov_copy);
2331
+
2332
+ copy_size -= iov_copy;
2333
+ iov_ofs += iov_copy;
2334
+ if (iov_ofs == iov->iov_len) {
2335
+ iov++;
2336
+ iov_ofs = 0;
2337
+ }
2338
+ }
2339
+
2340
+ if (desc_offset + desc_size >= total_size) {
2341
+ /* Simulate FCS checksum presence in the last descriptor */
2342
+ igb_write_to_rx_buffers(core, d, ba, &written,
2343
+ (const char *) &fcs_pad, e1000x_fcs_len(core->mac));
2344
+ }
2345
+ }
2346
+ } else { /* as per intel docs; skip descriptors with null buf addr */
2347
+ trace_e1000e_rx_null_descriptor();
2348
+ }
2349
+ desc_offset += desc_size;
2350
+ if (desc_offset >= total_size) {
2351
+ is_last = true;
2352
+ }
2353
+
2354
+ igb_write_rx_descr(core, &desc, is_last ? core->rx_pkt : NULL,
2355
+ rss_info, written);
2356
+ igb_pci_dma_write_rx_desc(core, d, base, &desc, core->rx_desc_len);
2357
+
2358
+ igb_ring_advance(core, rxi, core->rx_desc_len / E1000_MIN_RX_DESC_LEN);
2359
+
2360
+ } while (desc_offset < total_size);
2361
+
2362
+ igb_update_rx_stats(core, size, total_size);
2363
+}
2364
+
2365
+static inline void
2366
+igb_rx_fix_l4_csum(IGBCore *core, struct NetRxPkt *pkt)
2367
+{
2368
+ struct virtio_net_hdr *vhdr = net_rx_pkt_get_vhdr(pkt);
2369
+
2370
+ if (vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
2371
+ net_rx_pkt_fix_l4_csum(pkt);
2372
+ }
2373
+}
2374
+
2375
+ssize_t
2376
+igb_receive_iov(IGBCore *core, const struct iovec *iov, int iovcnt)
2377
+{
2378
+ return igb_receive_internal(core, iov, iovcnt, core->has_vnet, NULL);
2379
+}
2380
+
2381
+static ssize_t
2382
+igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
2383
+ bool has_vnet, bool *external_tx)
2384
+{
2385
+ static const int maximum_ethernet_hdr_len = (ETH_HLEN + 4);
2386
+
2387
+ uint16_t queues = 0;
2388
+ uint32_t n = 0;
2389
+ uint8_t min_buf[ETH_ZLEN];
2390
+ struct iovec min_iov;
2391
+ struct eth_header *ehdr;
2392
+ uint8_t *filter_buf;
2393
+ size_t size, orig_size;
2394
+ size_t iov_ofs = 0;
2395
+ E1000E_RxRing rxr;
2396
+ E1000E_RSSInfo rss_info;
2397
+ size_t total_size;
2398
+ int i;
2399
+
2400
+ trace_e1000e_rx_receive_iov(iovcnt);
2401
+
2402
+ if (external_tx) {
2403
+ *external_tx = true;
2404
+ }
2405
+
2406
+ if (!e1000x_hw_rx_enabled(core->mac)) {
2407
+ return -1;
2408
+ }
2409
+
2410
+ /* Pull virtio header in */
2411
+ if (has_vnet) {
2412
+ net_rx_pkt_set_vhdr_iovec(core->rx_pkt, iov, iovcnt);
2413
+ iov_ofs = sizeof(struct virtio_net_hdr);
2414
+ } else {
2415
+ net_rx_pkt_unset_vhdr(core->rx_pkt);
2416
+ }
2417
+
2418
+ filter_buf = iov->iov_base + iov_ofs;
2419
+ orig_size = iov_size(iov, iovcnt);
2420
+ size = orig_size - iov_ofs;
2421
+
2422
+ /* Pad to minimum Ethernet frame length */
2423
+ if (size < sizeof(min_buf)) {
2424
+ iov_to_buf(iov, iovcnt, iov_ofs, min_buf, size);
2425
+ memset(&min_buf[size], 0, sizeof(min_buf) - size);
2426
+ e1000x_inc_reg_if_not_full(core->mac, RUC);
2427
+ min_iov.iov_base = filter_buf = min_buf;
2428
+ min_iov.iov_len = size = sizeof(min_buf);
2429
+ iovcnt = 1;
2430
+ iov = &min_iov;
2431
+ iov_ofs = 0;
2432
+ } else if (iov->iov_len < maximum_ethernet_hdr_len) {
2433
+ /* This is very unlikely, but may happen. */
2434
+ iov_to_buf(iov, iovcnt, iov_ofs, min_buf, maximum_ethernet_hdr_len);
2435
+ filter_buf = min_buf;
2436
+ }
2437
+
2438
+ /* Discard oversized packets if !LPE and !SBP. */
2439
+ if (e1000x_is_oversized(core->mac, size)) {
2440
+ return orig_size;
2441
+ }
2442
+
2443
+ ehdr = PKT_GET_ETH_HDR(filter_buf);
2444
+ net_rx_pkt_set_packet_type(core->rx_pkt, get_eth_packet_type(ehdr));
2445
+
2446
+ net_rx_pkt_attach_iovec_ex(core->rx_pkt, iov, iovcnt, iov_ofs,
2447
+ e1000x_vlan_enabled(core->mac),
2448
+ core->mac[VET] & 0xffff);
2449
+
2450
+ queues = igb_receive_assign(core, ehdr, &rss_info, external_tx);
2451
+ if (!queues) {
2452
+ trace_e1000e_rx_flt_dropped();
2453
+ return orig_size;
2454
+ }
2455
+
2456
+ total_size = net_rx_pkt_get_total_len(core->rx_pkt) +
2457
+ e1000x_fcs_len(core->mac);
2458
+
2459
+ for (i = 0; i < IGB_NUM_QUEUES; i++) {
2460
+ if (!(queues & BIT(i))) {
2461
+ continue;
2462
+ }
2463
+
2464
+ igb_rx_ring_init(core, &rxr, i);
2465
+
2466
+ if (!igb_has_rxbufs(core, rxr.i, total_size)) {
2467
+ n |= E1000_ICS_RXO;
2468
+ trace_e1000e_rx_not_written_to_guest(rxr.i->idx);
2469
+ continue;
2470
+ }
2471
+
2472
+ n |= E1000_ICR_RXT0;
2473
+
2474
+ igb_rx_fix_l4_csum(core, core->rx_pkt);
2475
+ igb_write_packet_to_guest(core, core->rx_pkt, &rxr, &rss_info);
2476
+
2477
+ /* Check if receive descriptor minimum threshold hit */
2478
+ if (igb_rx_descr_threshold_hit(core, rxr.i)) {
2479
+ n |= E1000_ICS_RXDMT0;
2480
+ }
2481
+
2482
+ core->mac[EICR] |= igb_rx_wb_eic(core, rxr.i->idx);
2483
+
2484
+ trace_e1000e_rx_written_to_guest(rxr.i->idx);
2485
+ }
2486
+
2487
+ trace_e1000e_rx_interrupt_set(n);
2488
+ igb_set_interrupt_cause(core, n);
2489
+
2490
+ return orig_size;
2491
+}
2492
+
2493
+static inline bool
2494
+igb_have_autoneg(IGBCore *core)
2495
+{
2496
+ return core->phy[MII_BMCR] & MII_BMCR_AUTOEN;
2497
+}
2498
+
2499
+static void igb_update_flowctl_status(IGBCore *core)
2500
+{
2501
+ if (igb_have_autoneg(core) && core->phy[MII_BMSR] & MII_BMSR_AN_COMP) {
2502
+ trace_e1000e_link_autoneg_flowctl(true);
2503
+ core->mac[CTRL] |= E1000_CTRL_TFCE | E1000_CTRL_RFCE;
2504
+ } else {
2505
+ trace_e1000e_link_autoneg_flowctl(false);
2506
+ }
2507
+}
2508
+
2509
+static inline void
2510
+igb_link_down(IGBCore *core)
2511
+{
2512
+ e1000x_update_regs_on_link_down(core->mac, core->phy);
2513
+ igb_update_flowctl_status(core);
2514
+}
2515
+
2516
+static inline void
2517
+igb_set_phy_ctrl(IGBCore *core, uint16_t val)
2518
+{
2519
+ /* bits 0-5 reserved; MII_BMCR_[ANRESTART,RESET] are self clearing */
2520
+ core->phy[MII_BMCR] = val & ~(0x3f | MII_BMCR_RESET | MII_BMCR_ANRESTART);
2521
+
2522
+ if ((val & MII_BMCR_ANRESTART) && igb_have_autoneg(core)) {
2523
+ e1000x_restart_autoneg(core->mac, core->phy, core->autoneg_timer);
2524
+ }
2525
+}
2526
+
2527
+void igb_core_set_link_status(IGBCore *core)
2528
+{
2529
+ NetClientState *nc = qemu_get_queue(core->owner_nic);
2530
+ uint32_t old_status = core->mac[STATUS];
2531
+
2532
+ trace_e1000e_link_status_changed(nc->link_down ? false : true);
2533
+
2534
+ if (nc->link_down) {
2535
+ e1000x_update_regs_on_link_down(core->mac, core->phy);
2536
+ } else {
2537
+ if (igb_have_autoneg(core) &&
2538
+ !(core->phy[MII_BMSR] & MII_BMSR_AN_COMP)) {
2539
+ e1000x_restart_autoneg(core->mac, core->phy,
2540
+ core->autoneg_timer);
2541
+ } else {
2542
+ e1000x_update_regs_on_link_up(core->mac, core->phy);
2543
+ igb_start_recv(core);
2544
+ }
2545
+ }
2546
+
2547
+ if (core->mac[STATUS] != old_status) {
2548
+ igb_set_interrupt_cause(core, E1000_ICR_LSC);
2549
+ }
2550
+}
2551
+
2552
+static void
2553
+igb_set_ctrl(IGBCore *core, int index, uint32_t val)
2554
+{
2555
+ trace_e1000e_core_ctrl_write(index, val);
2556
+
2557
+ /* RST is self clearing */
2558
+ core->mac[CTRL] = val & ~E1000_CTRL_RST;
2559
+ core->mac[CTRL_DUP] = core->mac[CTRL];
2560
+
2561
+ trace_e1000e_link_set_params(
2562
+ !!(val & E1000_CTRL_ASDE),
2563
+ (val & E1000_CTRL_SPD_SEL) >> E1000_CTRL_SPD_SHIFT,
2564
+ !!(val & E1000_CTRL_FRCSPD),
2565
+ !!(val & E1000_CTRL_FRCDPX),
2566
+ !!(val & E1000_CTRL_RFCE),
2567
+ !!(val & E1000_CTRL_TFCE));
2568
+
2569
+ if (val & E1000_CTRL_RST) {
2570
+ trace_e1000e_core_ctrl_sw_reset();
2571
+ igb_reset(core, true);
2572
+ }
2573
+
2574
+ if (val & E1000_CTRL_PHY_RST) {
2575
+ trace_e1000e_core_ctrl_phy_reset();
2576
+ core->mac[STATUS] |= E1000_STATUS_PHYRA;
2577
+ }
2578
+}
2579
+
2580
+static void
2581
+igb_set_rfctl(IGBCore *core, int index, uint32_t val)
2582
+{
2583
+ trace_e1000e_rx_set_rfctl(val);
2584
+
2585
+ if (!(val & E1000_RFCTL_ISCSI_DIS)) {
2586
+ trace_e1000e_wrn_iscsi_filtering_not_supported();
2587
+ }
2588
+
2589
+ if (!(val & E1000_RFCTL_NFSW_DIS)) {
2590
+ trace_e1000e_wrn_nfsw_filtering_not_supported();
2591
+ }
2592
+
2593
+ if (!(val & E1000_RFCTL_NFSR_DIS)) {
2594
+ trace_e1000e_wrn_nfsr_filtering_not_supported();
2595
+ }
2596
+
2597
+ core->mac[RFCTL] = val;
2598
+}
2599
+
2600
+static void
2601
+igb_calc_rxdesclen(IGBCore *core)
2602
+{
2603
+ if (igb_rx_use_legacy_descriptor(core)) {
2604
+ core->rx_desc_len = sizeof(struct e1000_rx_desc);
2605
+ } else {
2606
+ core->rx_desc_len = sizeof(union e1000_adv_rx_desc);
2607
+ }
2608
+ trace_e1000e_rx_desc_len(core->rx_desc_len);
2609
+}
2610
+
2611
+static void
2612
+igb_set_rx_control(IGBCore *core, int index, uint32_t val)
2613
+{
2614
+ core->mac[RCTL] = val;
2615
+ trace_e1000e_rx_set_rctl(core->mac[RCTL]);
2616
+
2617
+ if (val & E1000_RCTL_DTYP_MASK) {
2618
+ qemu_log_mask(LOG_GUEST_ERROR,
2619
+ "igb: RCTL.DTYP must be zero for compatibility");
2620
+ }
2621
+
2622
+ if (val & E1000_RCTL_EN) {
2623
+ igb_calc_rxdesclen(core);
2624
+ igb_start_recv(core);
2625
+ }
2626
+}
2627
+
2628
+static inline void
2629
+igb_clear_ims_bits(IGBCore *core, uint32_t bits)
2630
+{
2631
+ trace_e1000e_irq_clear_ims(bits, core->mac[IMS], core->mac[IMS] & ~bits);
2632
+ core->mac[IMS] &= ~bits;
2633
+}
2634
+
2635
+static inline bool
2636
+igb_postpone_interrupt(IGBIntrDelayTimer *timer)
2637
+{
2638
+ if (timer->running) {
2639
+ trace_e1000e_irq_postponed_by_xitr(timer->delay_reg << 2);
2640
+
2641
+ return true;
2642
+ }
2643
+
2644
+ if (timer->core->mac[timer->delay_reg] != 0) {
2645
+ igb_intrmgr_rearm_timer(timer);
2646
+ }
2647
+
2648
+ return false;
2649
+}
2650
+
2651
+static inline bool
2652
+igb_eitr_should_postpone(IGBCore *core, int idx)
2653
+{
2654
+ return igb_postpone_interrupt(&core->eitr[idx]);
2655
+}
2656
+
2657
+static void igb_send_msix(IGBCore *core)
2658
+{
2659
+ uint32_t causes = core->mac[EICR] & core->mac[EIMS];
2660
+ uint32_t effective_eiac;
2661
+ int vector;
2662
+
2663
+ for (vector = 0; vector < IGB_INTR_NUM; ++vector) {
2664
+ if ((causes & BIT(vector)) && !igb_eitr_should_postpone(core, vector)) {
2665
+
2666
+ trace_e1000e_irq_msix_notify_vec(vector);
2667
+ igb_msix_notify(core, vector);
2668
+
2669
+ trace_e1000e_irq_icr_clear_eiac(core->mac[EICR], core->mac[EIAC]);
2670
+ effective_eiac = core->mac[EIAC] & BIT(vector);
2671
+ core->mac[EICR] &= ~effective_eiac;
2672
+ }
2673
+ }
2674
+}
2675
+
2676
+static inline void
2677
+igb_fix_icr_asserted(IGBCore *core)
2678
+{
2679
+ core->mac[ICR] &= ~E1000_ICR_ASSERTED;
2680
+ if (core->mac[ICR]) {
2681
+ core->mac[ICR] |= E1000_ICR_ASSERTED;
2682
+ }
2683
+
2684
+ trace_e1000e_irq_fix_icr_asserted(core->mac[ICR]);
2685
+}
2686
+
2687
+static void
2688
+igb_update_interrupt_state(IGBCore *core)
2689
+{
2690
+ uint32_t icr;
2691
+ uint32_t causes;
2692
+ uint32_t int_alloc;
2693
+
2694
+ icr = core->mac[ICR] & core->mac[IMS];
2695
+
2696
+ if (msix_enabled(core->owner)) {
2697
+ if (icr) {
2698
+ causes = 0;
2699
+ if (icr & E1000_ICR_DRSTA) {
2700
+ int_alloc = core->mac[IVAR_MISC] & 0xff;
2701
+ if (int_alloc & E1000_IVAR_VALID) {
2702
+ causes |= BIT(int_alloc & 0x1f);
2703
+ }
2704
+ }
2705
+ /* Check if other bits (excluding the TCP Timer) are enabled. */
2706
+ if (icr & ~E1000_ICR_DRSTA) {
2707
+ int_alloc = (core->mac[IVAR_MISC] >> 8) & 0xff;
2708
+ if (int_alloc & E1000_IVAR_VALID) {
2709
+ causes |= BIT(int_alloc & 0x1f);
2710
+ }
2711
+ trace_e1000e_irq_add_msi_other(core->mac[EICR]);
2712
+ }
2713
+ core->mac[EICR] |= causes;
2714
+ }
2715
+
2716
+ if ((core->mac[EICR] & core->mac[EIMS])) {
2717
+ igb_send_msix(core);
2718
+ }
2719
+ } else {
2720
+ igb_fix_icr_asserted(core);
2721
+
2722
+ if (icr) {
2723
+ core->mac[EICR] |= (icr & E1000_ICR_DRSTA) | E1000_EICR_OTHER;
2724
+ } else {
2725
+ core->mac[EICR] &= ~E1000_EICR_OTHER;
2726
+ }
2727
+
2728
+ trace_e1000e_irq_pending_interrupts(core->mac[ICR] & core->mac[IMS],
2729
+ core->mac[ICR], core->mac[IMS]);
2730
+
2731
+ if (msi_enabled(core->owner)) {
2732
+ if (icr) {
2733
+ msi_notify(core->owner, 0);
2734
+ }
2735
+ } else {
2736
+ if (icr) {
2737
+ igb_raise_legacy_irq(core);
2738
+ } else {
2739
+ igb_lower_legacy_irq(core);
2740
+ }
2741
+ }
2742
+ }
2743
+}
2744
+
2745
+static void
2746
+igb_set_interrupt_cause(IGBCore *core, uint32_t val)
2747
+{
2748
+ trace_e1000e_irq_set_cause_entry(val, core->mac[ICR]);
2749
+
2750
+ core->mac[ICR] |= val;
2751
+
2752
+ trace_e1000e_irq_set_cause_exit(val, core->mac[ICR]);
2753
+
2754
+ igb_update_interrupt_state(core);
2755
+}
2756
+
2757
+static void igb_set_eics(IGBCore *core, int index, uint32_t val)
2758
+{
2759
+ bool msix = !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE);
2760
+
2761
+ trace_igb_irq_write_eics(val, msix);
2762
+
2763
+ core->mac[EICS] |=
2764
+ val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK);
2765
+
2766
+ /*
2767
+ * TODO: Move to igb_update_interrupt_state if EICS is modified in other
2768
+ * places.
2769
+ */
2770
+ core->mac[EICR] = core->mac[EICS];
2771
+
2772
+ igb_update_interrupt_state(core);
2773
+}
2774
+
2775
+static void igb_set_eims(IGBCore *core, int index, uint32_t val)
2776
+{
2777
+ bool msix = !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE);
2778
+
2779
+ trace_igb_irq_write_eims(val, msix);
2780
+
2781
+ core->mac[EIMS] |=
2782
+ val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK);
2783
+
2784
+ igb_update_interrupt_state(core);
2785
+}
2786
+
2787
+static void igb_vf_reset(IGBCore *core, uint16_t vfn)
2788
+{
2789
+ /* TODO: Reset of the queue enable and the interrupt registers of the VF. */
2790
+
2791
+ core->mac[V2PMAILBOX0 + vfn] &= ~E1000_V2PMAILBOX_RSTI;
2792
+ core->mac[V2PMAILBOX0 + vfn] = E1000_V2PMAILBOX_RSTD;
2793
+}
2794
+
2795
+static void mailbox_interrupt_to_vf(IGBCore *core, uint16_t vfn)
2796
+{
2797
+ uint32_t ent = core->mac[VTIVAR_MISC + vfn];
2798
+
2799
+ if ((ent & E1000_IVAR_VALID)) {
2800
+ core->mac[EICR] |= (ent & 0x3) << (22 - vfn * IGBVF_MSIX_VEC_NUM);
2801
+ igb_update_interrupt_state(core);
2802
+ }
2803
+}
2804
+
2805
+static void mailbox_interrupt_to_pf(IGBCore *core)
2806
+{
2807
+ igb_set_interrupt_cause(core, E1000_ICR_VMMB);
2808
+}
2809
+
2810
+static void igb_set_pfmailbox(IGBCore *core, int index, uint32_t val)
2811
+{
2812
+ uint16_t vfn = index - P2VMAILBOX0;
2813
+
2814
+ trace_igb_set_pfmailbox(vfn, val);
2815
+
2816
+ if (val & E1000_P2VMAILBOX_STS) {
2817
+ core->mac[V2PMAILBOX0 + vfn] |= E1000_V2PMAILBOX_PFSTS;
2818
+ mailbox_interrupt_to_vf(core, vfn);
2819
+ }
2820
+
2821
+ if (val & E1000_P2VMAILBOX_ACK) {
2822
+ core->mac[V2PMAILBOX0 + vfn] |= E1000_V2PMAILBOX_PFACK;
2823
+ mailbox_interrupt_to_vf(core, vfn);
2824
+ }
2825
+
2826
+ /* Buffer Taken by PF (can be set only if the VFU is cleared). */
2827
+ if (val & E1000_P2VMAILBOX_PFU) {
2828
+ if (!(core->mac[index] & E1000_P2VMAILBOX_VFU)) {
2829
+ core->mac[index] |= E1000_P2VMAILBOX_PFU;
2830
+ core->mac[V2PMAILBOX0 + vfn] |= E1000_V2PMAILBOX_PFU;
2831
+ }
2832
+ } else {
2833
+ core->mac[index] &= ~E1000_P2VMAILBOX_PFU;
2834
+ core->mac[V2PMAILBOX0 + vfn] &= ~E1000_V2PMAILBOX_PFU;
2835
+ }
2836
+
2837
+ if (val & E1000_P2VMAILBOX_RVFU) {
2838
+ core->mac[V2PMAILBOX0 + vfn] &= ~E1000_V2PMAILBOX_VFU;
2839
+ core->mac[MBVFICR] &= ~((E1000_MBVFICR_VFACK_VF1 << vfn) |
2840
+ (E1000_MBVFICR_VFREQ_VF1 << vfn));
2841
+ }
2842
+}
2843
+
2844
+static void igb_set_vfmailbox(IGBCore *core, int index, uint32_t val)
2845
+{
2846
+ uint16_t vfn = index - V2PMAILBOX0;
2847
+
2848
+ trace_igb_set_vfmailbox(vfn, val);
2849
+
2850
+ if (val & E1000_V2PMAILBOX_REQ) {
2851
+ core->mac[MBVFICR] |= E1000_MBVFICR_VFREQ_VF1 << vfn;
2852
+ mailbox_interrupt_to_pf(core);
2853
+ }
2854
+
2855
+ if (val & E1000_V2PMAILBOX_ACK) {
2856
+ core->mac[MBVFICR] |= E1000_MBVFICR_VFACK_VF1 << vfn;
2857
+ mailbox_interrupt_to_pf(core);
2858
+ }
2859
+
2860
+ /* Buffer Taken by VF (can be set only if the PFU is cleared). */
2861
+ if (val & E1000_V2PMAILBOX_VFU) {
2862
+ if (!(core->mac[index] & E1000_V2PMAILBOX_PFU)) {
2863
+ core->mac[index] |= E1000_V2PMAILBOX_VFU;
2864
+ core->mac[P2VMAILBOX0 + vfn] |= E1000_P2VMAILBOX_VFU;
2865
+ }
2866
+ } else {
2867
+ core->mac[index] &= ~E1000_V2PMAILBOX_VFU;
2868
+ core->mac[P2VMAILBOX0 + vfn] &= ~E1000_P2VMAILBOX_VFU;
2869
+ }
2870
+}
2871
+
2872
+static void igb_w1c(IGBCore *core, int index, uint32_t val)
2873
+{
2874
+ core->mac[index] &= ~val;
2875
+}
2876
+
2877
+static void igb_set_eimc(IGBCore *core, int index, uint32_t val)
2878
+{
2879
+ bool msix = !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE);
2880
+
2881
+ /* Interrupts are disabled via a write to EIMC and reflected in EIMS. */
2882
+ core->mac[EIMS] &=
2883
+ ~(val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK));
2884
+
2885
+ trace_igb_irq_write_eimc(val, core->mac[EIMS], msix);
2886
+ igb_update_interrupt_state(core);
2887
+}
2888
+
2889
+static void igb_set_eiac(IGBCore *core, int index, uint32_t val)
2890
+{
2891
+ bool msix = !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE);
2892
+
2893
+ if (msix) {
2894
+ trace_igb_irq_write_eiac(val);
2895
+
2896
+ /*
2897
+ * TODO: When using IOV, the bits that correspond to MSI-X vectors
2898
+ * that are assigned to a VF are read-only.
2899
+ */
2900
+ core->mac[EIAC] |= (val & E1000_EICR_MSIX_MASK);
2901
+ }
2902
+}
2903
+
2904
+static void igb_set_eiam(IGBCore *core, int index, uint32_t val)
2905
+{
2906
+ bool msix = !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE);
2907
+
2908
+ /*
2909
+ * TODO: When using IOV, the bits that correspond to MSI-X vectors that
2910
+ * are assigned to a VF are read-only.
2911
+ */
2912
+ core->mac[EIAM] |=
2913
+ ~(val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK));
2914
+
2915
+ trace_igb_irq_write_eiam(val, msix);
2916
+}
2917
+
2918
+static void igb_set_eicr(IGBCore *core, int index, uint32_t val)
2919
+{
2920
+ bool msix = !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE);
2921
+
2922
+ /*
2923
+ * TODO: In IOV mode, only bit zero of this vector is available for the PF
2924
+ * function.
2925
+ */
2926
+ core->mac[EICR] &=
2927
+ ~(val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK));
2928
+
2929
+ trace_igb_irq_write_eicr(val, msix);
2930
+ igb_update_interrupt_state(core);
2931
+}
2932
+
2933
+static void igb_set_vtctrl(IGBCore *core, int index, uint32_t val)
2934
+{
2935
+ uint16_t vfn;
2936
+
2937
+ if (val & E1000_CTRL_RST) {
2938
+ vfn = (index - PVTCTRL0) / 0x40;
2939
+ igb_vf_reset(core, vfn);
2940
+ }
2941
+}
2942
+
2943
+static void igb_set_vteics(IGBCore *core, int index, uint32_t val)
2944
+{
2945
+ uint16_t vfn = (index - PVTEICS0) / 0x40;
2946
+
2947
+ core->mac[index] = val;
2948
+ igb_set_eics(core, EICS, (val & 0x7) << (22 - vfn * IGBVF_MSIX_VEC_NUM));
2949
+}
2950
+
2951
+static void igb_set_vteims(IGBCore *core, int index, uint32_t val)
2952
+{
2953
+ uint16_t vfn = (index - PVTEIMS0) / 0x40;
2954
+
2955
+ core->mac[index] = val;
2956
+ igb_set_eims(core, EIMS, (val & 0x7) << (22 - vfn * IGBVF_MSIX_VEC_NUM));
2957
+}
2958
+
2959
+static void igb_set_vteimc(IGBCore *core, int index, uint32_t val)
2960
+{
2961
+ uint16_t vfn = (index - PVTEIMC0) / 0x40;
2962
+
2963
+ core->mac[index] = val;
2964
+ igb_set_eimc(core, EIMC, (val & 0x7) << (22 - vfn * IGBVF_MSIX_VEC_NUM));
2965
+}
2966
+
2967
+static void igb_set_vteiac(IGBCore *core, int index, uint32_t val)
2968
+{
2969
+ uint16_t vfn = (index - PVTEIAC0) / 0x40;
2970
+
2971
+ core->mac[index] = val;
2972
+ igb_set_eiac(core, EIAC, (val & 0x7) << (22 - vfn * IGBVF_MSIX_VEC_NUM));
2973
+}
2974
+
2975
+static void igb_set_vteiam(IGBCore *core, int index, uint32_t val)
2976
+{
2977
+ uint16_t vfn = (index - PVTEIAM0) / 0x40;
2978
+
2979
+ core->mac[index] = val;
2980
+ igb_set_eiam(core, EIAM, (val & 0x7) << (22 - vfn * IGBVF_MSIX_VEC_NUM));
2981
+}
2982
+
2983
+static void igb_set_vteicr(IGBCore *core, int index, uint32_t val)
2984
+{
2985
+ uint16_t vfn = (index - PVTEICR0) / 0x40;
2986
+
2987
+ core->mac[index] = val;
2988
+ igb_set_eicr(core, EICR, (val & 0x7) << (22 - vfn * IGBVF_MSIX_VEC_NUM));
2989
+}
2990
+
2991
+static void igb_set_vtivar(IGBCore *core, int index, uint32_t val)
2992
+{
2993
+ uint16_t vfn = (index - VTIVAR);
2994
+ uint16_t qn = vfn;
2995
+ uint8_t ent;
2996
+ int n;
2997
+
2998
+ core->mac[index] = val;
2999
+
3000
+ /* Get assigned vector associated with queue Rx#0. */
3001
+ if ((val & E1000_IVAR_VALID)) {
3002
+ n = igb_ivar_entry_rx(qn);
3003
+ ent = E1000_IVAR_VALID | (24 - vfn * IGBVF_MSIX_VEC_NUM - (2 - (val & 0x7)));
3004
+ core->mac[IVAR0 + n / 4] |= ent << 8 * (n % 4);
3005
+ }
3006
+
3007
+ /* Get assigned vector associated with queue Tx#0 */
3008
+ ent = val >> 8;
3009
+ if ((ent & E1000_IVAR_VALID)) {
3010
+ n = igb_ivar_entry_tx(qn);
3011
+ ent = E1000_IVAR_VALID | (24 - vfn * IGBVF_MSIX_VEC_NUM - (2 - (ent & 0x7)));
3012
+ core->mac[IVAR0 + n / 4] |= ent << 8 * (n % 4);
3013
+ }
3014
+
3015
+ /*
3016
+ * Ignoring assigned vectors associated with queues Rx#1 and Tx#1 for now.
3017
+ */
3018
+}
3019
+
3020
+static inline void
3021
+igb_autoneg_timer(void *opaque)
3022
+{
3023
+ IGBCore *core = opaque;
3024
+ if (!qemu_get_queue(core->owner_nic)->link_down) {
3025
+ e1000x_update_regs_on_autoneg_done(core->mac, core->phy);
3026
+ igb_start_recv(core);
3027
+
3028
+ igb_update_flowctl_status(core);
3029
+ /* signal link status change to the guest */
3030
+ igb_set_interrupt_cause(core, E1000_ICR_LSC);
3031
+ }
3032
+}
3033
+
3034
+static inline uint16_t
3035
+igb_get_reg_index_with_offset(const uint16_t *mac_reg_access, hwaddr addr)
3036
+{
3037
+ uint16_t index = (addr & 0x1ffff) >> 2;
3038
+ return index + (mac_reg_access[index] & 0xfffe);
3039
+}
3040
+
3041
+static const char igb_phy_regcap[MAX_PHY_REG_ADDRESS + 1] = {
3042
+ [MII_BMCR] = PHY_RW,
3043
+ [MII_BMSR] = PHY_R,
3044
+ [MII_PHYID1] = PHY_R,
3045
+ [MII_PHYID2] = PHY_R,
3046
+ [MII_ANAR] = PHY_RW,
3047
+ [MII_ANLPAR] = PHY_R,
3048
+ [MII_ANER] = PHY_R,
3049
+ [MII_ANNP] = PHY_RW,
3050
+ [MII_ANLPRNP] = PHY_R,
3051
+ [MII_CTRL1000] = PHY_RW,
3052
+ [MII_STAT1000] = PHY_R,
3053
+ [MII_EXTSTAT] = PHY_R,
3054
+
3055
+ [IGP01E1000_PHY_PORT_CONFIG] = PHY_RW,
3056
+ [IGP01E1000_PHY_PORT_STATUS] = PHY_R,
3057
+ [IGP01E1000_PHY_PORT_CTRL] = PHY_RW,
3058
+ [IGP01E1000_PHY_LINK_HEALTH] = PHY_R,
3059
+ [IGP02E1000_PHY_POWER_MGMT] = PHY_RW,
3060
+ [IGP01E1000_PHY_PAGE_SELECT] = PHY_W
3061
+};
3062
+
3063
+static void
3064
+igb_phy_reg_write(IGBCore *core, uint32_t addr, uint16_t data)
3065
+{
3066
+ assert(addr <= MAX_PHY_REG_ADDRESS);
3067
+
3068
+ if (addr == MII_BMCR) {
3069
+ igb_set_phy_ctrl(core, data);
3070
+ } else {
3071
+ core->phy[addr] = data;
3072
+ }
3073
+}
3074
+
3075
+static void
3076
+igb_set_mdic(IGBCore *core, int index, uint32_t val)
3077
+{
3078
+ uint32_t data = val & E1000_MDIC_DATA_MASK;
3079
+ uint32_t addr = ((val & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
3080
+
3081
+ if ((val & E1000_MDIC_PHY_MASK) >> E1000_MDIC_PHY_SHIFT != 1) { /* phy # */
3082
+ val = core->mac[MDIC] | E1000_MDIC_ERROR;
3083
+ } else if (val & E1000_MDIC_OP_READ) {
3084
+ if (!(igb_phy_regcap[addr] & PHY_R)) {
3085
+ trace_igb_core_mdic_read_unhandled(addr);
3086
+ val |= E1000_MDIC_ERROR;
3087
+ } else {
3088
+ val = (val ^ data) | core->phy[addr];
3089
+ trace_igb_core_mdic_read(addr, val);
3090
+ }
3091
+ } else if (val & E1000_MDIC_OP_WRITE) {
3092
+ if (!(igb_phy_regcap[addr] & PHY_W)) {
3093
+ trace_igb_core_mdic_write_unhandled(addr);
3094
+ val |= E1000_MDIC_ERROR;
3095
+ } else {
3096
+ trace_igb_core_mdic_write(addr, data);
3097
+ igb_phy_reg_write(core, addr, data);
3098
+ }
3099
+ }
3100
+ core->mac[MDIC] = val | E1000_MDIC_READY;
3101
+
3102
+ if (val & E1000_MDIC_INT_EN) {
3103
+ igb_set_interrupt_cause(core, E1000_ICR_MDAC);
3104
+ }
3105
+}
3106
+
3107
+static void
3108
+igb_set_rdt(IGBCore *core, int index, uint32_t val)
3109
+{
3110
+ core->mac[index] = val & 0xffff;
3111
+ trace_e1000e_rx_set_rdt(igb_mq_queue_idx(RDT0, index), val);
3112
+ igb_start_recv(core);
3113
+}
3114
+
3115
+static void
3116
+igb_set_status(IGBCore *core, int index, uint32_t val)
3117
+{
3118
+ if ((val & E1000_STATUS_PHYRA) == 0) {
3119
+ core->mac[index] &= ~E1000_STATUS_PHYRA;
3120
+ }
3121
+}
3122
+
3123
+static void
3124
+igb_set_ctrlext(IGBCore *core, int index, uint32_t val)
3125
+{
3126
+ trace_e1000e_link_set_ext_params(!!(val & E1000_CTRL_EXT_ASDCHK),
3127
+ !!(val & E1000_CTRL_EXT_SPD_BYPS));
3128
+
3129
+ /* TODO: PFRSTD */
3130
+
3131
+ /* Zero self-clearing bits */
3132
+ val &= ~(E1000_CTRL_EXT_ASDCHK | E1000_CTRL_EXT_EE_RST);
3133
+ core->mac[CTRL_EXT] = val;
3134
+}
3135
+
3136
+static void
3137
+igb_set_pbaclr(IGBCore *core, int index, uint32_t val)
3138
+{
3139
+ int i;
3140
+
3141
+ core->mac[PBACLR] = val & E1000_PBACLR_VALID_MASK;
3142
+
3143
+ if (!msix_enabled(core->owner)) {
3144
+ return;
3145
+ }
3146
+
3147
+ for (i = 0; i < IGB_INTR_NUM; i++) {
3148
+ if (core->mac[PBACLR] & BIT(i)) {
3149
+ msix_clr_pending(core->owner, i);
3150
+ }
3151
+ }
3152
+}
3153
+
3154
+static void
3155
+igb_set_fcrth(IGBCore *core, int index, uint32_t val)
3156
+{
3157
+ core->mac[FCRTH] = val & 0xFFF8;
3158
+}
3159
+
3160
+static void
3161
+igb_set_fcrtl(IGBCore *core, int index, uint32_t val)
3162
+{
3163
+ core->mac[FCRTL] = val & 0x8000FFF8;
3164
+}
3165
+
3166
+#define IGB_LOW_BITS_SET_FUNC(num) \
3167
+ static void \
3168
+ igb_set_##num##bit(IGBCore *core, int index, uint32_t val) \
3169
+ { \
3170
+ core->mac[index] = val & (BIT(num) - 1); \
3171
+ }
3172
+
3173
+IGB_LOW_BITS_SET_FUNC(4)
3174
+IGB_LOW_BITS_SET_FUNC(13)
3175
+IGB_LOW_BITS_SET_FUNC(16)
3176
+
3177
+static void
3178
+igb_set_dlen(IGBCore *core, int index, uint32_t val)
3179
+{
3180
+ core->mac[index] = val & 0xffff0;
3181
+}
3182
+
3183
+static void
3184
+igb_set_dbal(IGBCore *core, int index, uint32_t val)
3185
+{
3186
+ core->mac[index] = val & E1000_XDBAL_MASK;
3187
+}
3188
+
3189
+static void
3190
+igb_set_tdt(IGBCore *core, int index, uint32_t val)
3191
+{
3192
+ IGB_TxRing txr;
3193
+ int qn = igb_mq_queue_idx(TDT0, index);
3194
+
3195
+ core->mac[index] = val & 0xffff;
3196
+
3197
+ igb_tx_ring_init(core, &txr, qn);
3198
+ igb_start_xmit(core, &txr);
3199
+}
3200
+
3201
+static void
3202
+igb_set_ics(IGBCore *core, int index, uint32_t val)
3203
+{
3204
+ trace_e1000e_irq_write_ics(val);
3205
+ igb_set_interrupt_cause(core, val);
3206
+}
3207
+
3208
+static void
3209
+igb_set_imc(IGBCore *core, int index, uint32_t val)
3210
+{
3211
+ trace_e1000e_irq_ims_clear_set_imc(val);
3212
+ igb_clear_ims_bits(core, val);
3213
+ igb_update_interrupt_state(core);
3214
+}
3215
+
3216
+static void
3217
+igb_set_ims(IGBCore *core, int index, uint32_t val)
3218
+{
3219
+ uint32_t valid_val = val & 0x77D4FBFD;
3220
+
3221
+ trace_e1000e_irq_set_ims(val, core->mac[IMS], core->mac[IMS] | valid_val);
3222
+ core->mac[IMS] |= valid_val;
3223
+ igb_update_interrupt_state(core);
3224
+}
3225
+
3226
+static void igb_commit_icr(IGBCore *core)
3227
+{
3228
+ /*
3229
+ * If GPIE.NSICR = 0, then the copy of IAM to IMS will occur only if at
3230
+ * least one bit is set in the IMS and there is a true interrupt as
3231
+ * reflected in ICR.INTA.
3232
+ */
3233
+ if ((core->mac[GPIE] & E1000_GPIE_NSICR) ||
3234
+ (core->mac[IMS] && (core->mac[ICR] & E1000_ICR_INT_ASSERTED))) {
3235
+ igb_set_ims(core, IMS, core->mac[IAM]);
3236
+ } else {
3237
+ igb_update_interrupt_state(core);
3238
+ }
3239
+}
3240
+
3241
+static void igb_set_icr(IGBCore *core, int index, uint32_t val)
3242
+{
3243
+ uint32_t icr = core->mac[ICR] & ~val;
3244
+
3245
+ trace_igb_irq_icr_write(val, core->mac[ICR], icr);
3246
+ core->mac[ICR] = icr;
3247
+ igb_commit_icr(core);
3248
+}
3249
+
3250
+static uint32_t
3251
+igb_mac_readreg(IGBCore *core, int index)
3252
+{
3253
+ return core->mac[index];
3254
+}
3255
+
3256
+static uint32_t
3257
+igb_mac_ics_read(IGBCore *core, int index)
3258
+{
3259
+ trace_e1000e_irq_read_ics(core->mac[ICS]);
3260
+ return core->mac[ICS];
3261
+}
3262
+
3263
+static uint32_t
3264
+igb_mac_ims_read(IGBCore *core, int index)
3265
+{
3266
+ trace_e1000e_irq_read_ims(core->mac[IMS]);
3267
+ return core->mac[IMS];
3268
+}
3269
+
3270
+static uint32_t
3271
+igb_mac_swsm_read(IGBCore *core, int index)
3272
+{
3273
+ uint32_t val = core->mac[SWSM];
3274
+ core->mac[SWSM] = val | E1000_SWSM_SMBI;
3275
+ return val;
3276
+}
3277
+
3278
+static uint32_t
3279
+igb_mac_eitr_read(IGBCore *core, int index)
3280
+{
3281
+ return core->eitr_guest_value[index - EITR0];
3282
+}
3283
+
3284
+static uint32_t igb_mac_vfmailbox_read(IGBCore *core, int index)
3285
+{
3286
+ uint32_t val = core->mac[index];
3287
+
3288
+ core->mac[index] &= ~(E1000_V2PMAILBOX_PFSTS | E1000_V2PMAILBOX_PFACK |
3289
+ E1000_V2PMAILBOX_RSTD);
3290
+
3291
+ return val;
3292
+}
3293
+
3294
+static uint32_t
3295
+igb_mac_icr_read(IGBCore *core, int index)
3296
+{
3297
+ uint32_t ret = core->mac[ICR];
3298
+ trace_e1000e_irq_icr_read_entry(ret);
3299
+
3300
+ if (core->mac[GPIE] & E1000_GPIE_NSICR) {
3301
+ trace_igb_irq_icr_clear_gpie_nsicr();
3302
+ core->mac[ICR] = 0;
3303
+ } else if (core->mac[IMS] == 0) {
3304
+ trace_e1000e_irq_icr_clear_zero_ims();
3305
+ core->mac[ICR] = 0;
3306
+ } else if (!msix_enabled(core->owner)) {
3307
+ trace_e1000e_irq_icr_clear_nonmsix_icr_read();
3308
+ core->mac[ICR] = 0;
3309
+ }
3310
+
3311
+ trace_e1000e_irq_icr_read_exit(core->mac[ICR]);
3312
+ igb_commit_icr(core);
3313
+ return ret;
3314
+}
3315
+
3316
+static uint32_t
3317
+igb_mac_read_clr4(IGBCore *core, int index)
3318
+{
3319
+ uint32_t ret = core->mac[index];
3320
+
3321
+ core->mac[index] = 0;
3322
+ return ret;
3323
+}
3324
+
3325
+static uint32_t
3326
+igb_mac_read_clr8(IGBCore *core, int index)
3327
+{
3328
+ uint32_t ret = core->mac[index];
3329
+
3330
+ core->mac[index] = 0;
3331
+ core->mac[index - 1] = 0;
3332
+ return ret;
3333
+}
3334
+
3335
+static uint32_t
3336
+igb_get_ctrl(IGBCore *core, int index)
3337
+{
3338
+ uint32_t val = core->mac[CTRL];
3339
+
3340
+ trace_e1000e_link_read_params(
3341
+ !!(val & E1000_CTRL_ASDE),
3342
+ (val & E1000_CTRL_SPD_SEL) >> E1000_CTRL_SPD_SHIFT,
3343
+ !!(val & E1000_CTRL_FRCSPD),
3344
+ !!(val & E1000_CTRL_FRCDPX),
3345
+ !!(val & E1000_CTRL_RFCE),
3346
+ !!(val & E1000_CTRL_TFCE));
3347
+
3348
+ return val;
3349
+}
3350
+
3351
+static uint32_t igb_get_status(IGBCore *core, int index)
3352
+{
3353
+ uint32_t res = core->mac[STATUS];
3354
+ uint16_t num_vfs = pcie_sriov_num_vfs(core->owner);
3355
+
3356
+ if (core->mac[CTRL] & E1000_CTRL_FRCDPX) {
3357
+ res |= (core->mac[CTRL] & E1000_CTRL_FD) ? E1000_STATUS_FD : 0;
3358
+ } else {
3359
+ res |= E1000_STATUS_FD;
3360
+ }
3361
+
3362
+ if ((core->mac[CTRL] & E1000_CTRL_FRCSPD) ||
3363
+ (core->mac[CTRL_EXT] & E1000_CTRL_EXT_SPD_BYPS)) {
3364
+ switch (core->mac[CTRL] & E1000_CTRL_SPD_SEL) {
3365
+ case E1000_CTRL_SPD_10:
3366
+ res |= E1000_STATUS_SPEED_10;
3367
+ break;
3368
+ case E1000_CTRL_SPD_100:
3369
+ res |= E1000_STATUS_SPEED_100;
3370
+ break;
3371
+ case E1000_CTRL_SPD_1000:
3372
+ default:
3373
+ res |= E1000_STATUS_SPEED_1000;
3374
+ break;
3375
+ }
3376
+ } else {
3377
+ res |= E1000_STATUS_SPEED_1000;
3378
+ }
3379
+
3380
+ if (num_vfs) {
3381
+ res |= num_vfs << E1000_STATUS_NUM_VFS_SHIFT;
3382
+ res |= E1000_STATUS_IOV_MODE;
3383
+ }
3384
+
3385
+ /*
3386
+ * Windows driver 12.18.9.23 resets if E1000_STATUS_GIO_MASTER_ENABLE is
3387
+ * left set after E1000_CTRL_LRST is set.
3388
+ */
3389
+ if (!(core->mac[CTRL] & E1000_CTRL_GIO_MASTER_DISABLE) &&
3390
+ !(core->mac[CTRL] & E1000_CTRL_LRST)) {
3391
+ res |= E1000_STATUS_GIO_MASTER_ENABLE;
3392
+ }
3393
+
3394
+ return res;
3395
+}
3396
+
3397
+static void
3398
+igb_mac_writereg(IGBCore *core, int index, uint32_t val)
3399
+{
3400
+ core->mac[index] = val;
3401
+}
3402
+
3403
+static void
3404
+igb_mac_setmacaddr(IGBCore *core, int index, uint32_t val)
3405
+{
3406
+ uint32_t macaddr[2];
3407
+
3408
+ core->mac[index] = val;
3409
+
3410
+ macaddr[0] = cpu_to_le32(core->mac[RA]);
3411
+ macaddr[1] = cpu_to_le32(core->mac[RA + 1]);
3412
+ qemu_format_nic_info_str(qemu_get_queue(core->owner_nic),
3413
+ (uint8_t *) macaddr);
3414
+
3415
+ trace_e1000e_mac_set_sw(MAC_ARG(macaddr));
3416
+}
3417
+
3418
+static void
3419
+igb_set_eecd(IGBCore *core, int index, uint32_t val)
3420
+{
3421
+ static const uint32_t ro_bits = E1000_EECD_PRES |
3422
+ E1000_EECD_AUTO_RD |
3423
+ E1000_EECD_SIZE_EX_MASK;
3424
+
3425
+ core->mac[EECD] = (core->mac[EECD] & ro_bits) | (val & ~ro_bits);
3426
+}
3427
+
3428
+static void
3429
+igb_set_eerd(IGBCore *core, int index, uint32_t val)
3430
+{
3431
+ uint32_t addr = (val >> E1000_EERW_ADDR_SHIFT) & E1000_EERW_ADDR_MASK;
3432
+ uint32_t flags = 0;
3433
+ uint32_t data = 0;
3434
+
3435
+ if ((addr < IGB_EEPROM_SIZE) && (val & E1000_EERW_START)) {
3436
+ data = core->eeprom[addr];
3437
+ flags = E1000_EERW_DONE;
3438
+ }
3439
+
3440
+ core->mac[EERD] = flags |
3441
+ (addr << E1000_EERW_ADDR_SHIFT) |
3442
+ (data << E1000_EERW_DATA_SHIFT);
3443
+}
3444
+
3445
+static void
3446
+igb_set_eitr(IGBCore *core, int index, uint32_t val)
3447
+{
3448
+ uint32_t eitr_num = index - EITR0;
3449
+
3450
+ trace_igb_irq_eitr_set(eitr_num, val);
3451
+
3452
+ core->eitr_guest_value[eitr_num] = val & ~E1000_EITR_CNT_IGNR;
3453
+ core->mac[index] = val & 0x7FFE;
3454
+}
3455
+
3456
+static void
3457
+igb_update_rx_offloads(IGBCore *core)
3458
+{
3459
+ int cso_state = igb_rx_l4_cso_enabled(core);
3460
+
3461
+ trace_e1000e_rx_set_cso(cso_state);
3462
+
3463
+ if (core->has_vnet) {
3464
+ qemu_set_offload(qemu_get_queue(core->owner_nic)->peer,
3465
+ cso_state, 0, 0, 0, 0);
3466
+ }
3467
+}
3468
+
3469
+static void
3470
+igb_set_rxcsum(IGBCore *core, int index, uint32_t val)
3471
+{
3472
+ core->mac[RXCSUM] = val;
3473
+ igb_update_rx_offloads(core);
3474
+}
3475
+
3476
+static void
3477
+igb_set_gcr(IGBCore *core, int index, uint32_t val)
3478
+{
3479
+ uint32_t ro_bits = core->mac[GCR] & E1000_GCR_RO_BITS;
3480
+ core->mac[GCR] = (val & ~E1000_GCR_RO_BITS) | ro_bits;
3481
+}
3482
+
3483
+static uint32_t igb_get_systiml(IGBCore *core, int index)
3484
+{
3485
+ e1000x_timestamp(core->mac, core->timadj, SYSTIML, SYSTIMH);
3486
+ return core->mac[SYSTIML];
3487
+}
3488
+
3489
+static uint32_t igb_get_rxsatrh(IGBCore *core, int index)
3490
+{
3491
+ core->mac[TSYNCRXCTL] &= ~E1000_TSYNCRXCTL_VALID;
3492
+ return core->mac[RXSATRH];
3493
+}
3494
+
3495
+static uint32_t igb_get_txstmph(IGBCore *core, int index)
3496
+{
3497
+ core->mac[TSYNCTXCTL] &= ~E1000_TSYNCTXCTL_VALID;
3498
+ return core->mac[TXSTMPH];
3499
+}
3500
+
3501
+static void igb_set_timinca(IGBCore *core, int index, uint32_t val)
3502
+{
3503
+ e1000x_set_timinca(core->mac, &core->timadj, val);
3504
+}
3505
+
3506
+static void igb_set_timadjh(IGBCore *core, int index, uint32_t val)
3507
+{
3508
+ core->mac[TIMADJH] = val;
3509
+ core->timadj += core->mac[TIMADJL] | ((int64_t)core->mac[TIMADJH] << 32);
3510
+}
3511
+
3512
+#define igb_getreg(x) [x] = igb_mac_readreg
3513
+typedef uint32_t (*readops)(IGBCore *, int);
3514
+static const readops igb_macreg_readops[] = {
3515
+ igb_getreg(WUFC),
3516
+ igb_getreg(MANC),
3517
+ igb_getreg(TOTL),
3518
+ igb_getreg(RDT0),
3519
+ igb_getreg(RDT1),
3520
+ igb_getreg(RDT2),
3521
+ igb_getreg(RDT3),
3522
+ igb_getreg(RDT4),
3523
+ igb_getreg(RDT5),
3524
+ igb_getreg(RDT6),
3525
+ igb_getreg(RDT7),
3526
+ igb_getreg(RDT8),
3527
+ igb_getreg(RDT9),
3528
+ igb_getreg(RDT10),
3529
+ igb_getreg(RDT11),
3530
+ igb_getreg(RDT12),
3531
+ igb_getreg(RDT13),
3532
+ igb_getreg(RDT14),
3533
+ igb_getreg(RDT15),
3534
+ igb_getreg(RDBAH0),
3535
+ igb_getreg(RDBAH1),
3536
+ igb_getreg(RDBAH2),
3537
+ igb_getreg(RDBAH3),
3538
+ igb_getreg(RDBAH4),
3539
+ igb_getreg(RDBAH5),
3540
+ igb_getreg(RDBAH6),
3541
+ igb_getreg(RDBAH7),
3542
+ igb_getreg(RDBAH8),
3543
+ igb_getreg(RDBAH9),
3544
+ igb_getreg(RDBAH10),
3545
+ igb_getreg(RDBAH11),
3546
+ igb_getreg(RDBAH12),
3547
+ igb_getreg(RDBAH13),
3548
+ igb_getreg(RDBAH14),
3549
+ igb_getreg(RDBAH15),
3550
+ igb_getreg(TDBAL0),
3551
+ igb_getreg(TDBAL1),
3552
+ igb_getreg(TDBAL2),
3553
+ igb_getreg(TDBAL3),
3554
+ igb_getreg(TDBAL4),
3555
+ igb_getreg(TDBAL5),
3556
+ igb_getreg(TDBAL6),
3557
+ igb_getreg(TDBAL7),
3558
+ igb_getreg(TDBAL8),
3559
+ igb_getreg(TDBAL9),
3560
+ igb_getreg(TDBAL10),
3561
+ igb_getreg(TDBAL11),
3562
+ igb_getreg(TDBAL12),
3563
+ igb_getreg(TDBAL13),
3564
+ igb_getreg(TDBAL14),
3565
+ igb_getreg(TDBAL15),
3566
+ igb_getreg(RDLEN0),
3567
+ igb_getreg(RDLEN1),
3568
+ igb_getreg(RDLEN2),
3569
+ igb_getreg(RDLEN3),
3570
+ igb_getreg(RDLEN4),
3571
+ igb_getreg(RDLEN5),
3572
+ igb_getreg(RDLEN6),
3573
+ igb_getreg(RDLEN7),
3574
+ igb_getreg(RDLEN8),
3575
+ igb_getreg(RDLEN9),
3576
+ igb_getreg(RDLEN10),
3577
+ igb_getreg(RDLEN11),
3578
+ igb_getreg(RDLEN12),
3579
+ igb_getreg(RDLEN13),
3580
+ igb_getreg(RDLEN14),
3581
+ igb_getreg(RDLEN15),
3582
+ igb_getreg(SRRCTL0),
3583
+ igb_getreg(SRRCTL1),
3584
+ igb_getreg(SRRCTL2),
3585
+ igb_getreg(SRRCTL3),
3586
+ igb_getreg(SRRCTL4),
3587
+ igb_getreg(SRRCTL5),
3588
+ igb_getreg(SRRCTL6),
3589
+ igb_getreg(SRRCTL7),
3590
+ igb_getreg(SRRCTL8),
3591
+ igb_getreg(SRRCTL9),
3592
+ igb_getreg(SRRCTL10),
3593
+ igb_getreg(SRRCTL11),
3594
+ igb_getreg(SRRCTL12),
3595
+ igb_getreg(SRRCTL13),
3596
+ igb_getreg(SRRCTL14),
3597
+ igb_getreg(SRRCTL15),
3598
+ igb_getreg(LATECOL),
3599
+ igb_getreg(XONTXC),
3600
+ igb_getreg(TDFH),
3601
+ igb_getreg(TDFT),
3602
+ igb_getreg(TDFHS),
3603
+ igb_getreg(TDFTS),
3604
+ igb_getreg(TDFPC),
3605
+ igb_getreg(WUS),
3606
+ igb_getreg(RDFH),
3607
+ igb_getreg(RDFT),
3608
+ igb_getreg(RDFHS),
3609
+ igb_getreg(RDFTS),
3610
+ igb_getreg(RDFPC),
3611
+ igb_getreg(GORCL),
3612
+ igb_getreg(MGTPRC),
3613
+ igb_getreg(EERD),
3614
+ igb_getreg(EIAC),
3615
+ igb_getreg(MANC2H),
3616
+ igb_getreg(RXCSUM),
3617
+ igb_getreg(GSCL_3),
3618
+ igb_getreg(GSCN_2),
3619
+ igb_getreg(FCAH),
3620
+ igb_getreg(FCRTH),
3621
+ igb_getreg(FLOP),
3622
+ igb_getreg(RXSTMPH),
3623
+ igb_getreg(TXSTMPL),
3624
+ igb_getreg(TIMADJL),
3625
+ igb_getreg(RDH0),
3626
+ igb_getreg(RDH1),
3627
+ igb_getreg(RDH2),
3628
+ igb_getreg(RDH3),
3629
+ igb_getreg(RDH4),
3630
+ igb_getreg(RDH5),
3631
+ igb_getreg(RDH6),
3632
+ igb_getreg(RDH7),
3633
+ igb_getreg(RDH8),
3634
+ igb_getreg(RDH9),
3635
+ igb_getreg(RDH10),
3636
+ igb_getreg(RDH11),
3637
+ igb_getreg(RDH12),
3638
+ igb_getreg(RDH13),
3639
+ igb_getreg(RDH14),
3640
+ igb_getreg(RDH15),
3641
+ igb_getreg(TDT0),
3642
+ igb_getreg(TDT1),
3643
+ igb_getreg(TDT2),
3644
+ igb_getreg(TDT3),
3645
+ igb_getreg(TDT4),
3646
+ igb_getreg(TDT5),
3647
+ igb_getreg(TDT6),
3648
+ igb_getreg(TDT7),
3649
+ igb_getreg(TDT8),
3650
+ igb_getreg(TDT9),
3651
+ igb_getreg(TDT10),
3652
+ igb_getreg(TDT11),
3653
+ igb_getreg(TDT12),
3654
+ igb_getreg(TDT13),
3655
+ igb_getreg(TDT14),
3656
+ igb_getreg(TDT15),
3657
+ igb_getreg(TNCRS),
3658
+ igb_getreg(RJC),
3659
+ igb_getreg(IAM),
3660
+ igb_getreg(GSCL_2),
3661
+ igb_getreg(TIPG),
3662
+ igb_getreg(FLMNGCTL),
3663
+ igb_getreg(FLMNGCNT),
3664
+ igb_getreg(TSYNCTXCTL),
3665
+ igb_getreg(EEMNGDATA),
3666
+ igb_getreg(CTRL_EXT),
3667
+ igb_getreg(SYSTIMH),
3668
+ igb_getreg(EEMNGCTL),
3669
+ igb_getreg(FLMNGDATA),
3670
+ igb_getreg(TSYNCRXCTL),
3671
+ igb_getreg(LEDCTL),
3672
+ igb_getreg(TCTL),
3673
+ igb_getreg(TCTL_EXT),
3674
+ igb_getreg(DTXCTL),
3675
+ igb_getreg(RXPBS),
3676
+ igb_getreg(TDH0),
3677
+ igb_getreg(TDH1),
3678
+ igb_getreg(TDH2),
3679
+ igb_getreg(TDH3),
3680
+ igb_getreg(TDH4),
3681
+ igb_getreg(TDH5),
3682
+ igb_getreg(TDH6),
3683
+ igb_getreg(TDH7),
3684
+ igb_getreg(TDH8),
3685
+ igb_getreg(TDH9),
3686
+ igb_getreg(TDH10),
3687
+ igb_getreg(TDH11),
3688
+ igb_getreg(TDH12),
3689
+ igb_getreg(TDH13),
3690
+ igb_getreg(TDH14),
3691
+ igb_getreg(TDH15),
3692
+ igb_getreg(ECOL),
3693
+ igb_getreg(DC),
3694
+ igb_getreg(RLEC),
3695
+ igb_getreg(XOFFTXC),
3696
+ igb_getreg(RFC),
3697
+ igb_getreg(RNBC),
3698
+ igb_getreg(MGTPTC),
3699
+ igb_getreg(TIMINCA),
3700
+ igb_getreg(FACTPS),
3701
+ igb_getreg(GSCL_1),
3702
+ igb_getreg(GSCN_0),
3703
+ igb_getreg(PBACLR),
3704
+ igb_getreg(FCTTV),
3705
+ igb_getreg(RXSATRL),
3706
+ igb_getreg(TORL),
3707
+ igb_getreg(TDLEN0),
3708
+ igb_getreg(TDLEN1),
3709
+ igb_getreg(TDLEN2),
3710
+ igb_getreg(TDLEN3),
3711
+ igb_getreg(TDLEN4),
3712
+ igb_getreg(TDLEN5),
3713
+ igb_getreg(TDLEN6),
3714
+ igb_getreg(TDLEN7),
3715
+ igb_getreg(TDLEN8),
3716
+ igb_getreg(TDLEN9),
3717
+ igb_getreg(TDLEN10),
3718
+ igb_getreg(TDLEN11),
3719
+ igb_getreg(TDLEN12),
3720
+ igb_getreg(TDLEN13),
3721
+ igb_getreg(TDLEN14),
3722
+ igb_getreg(TDLEN15),
3723
+ igb_getreg(MCC),
3724
+ igb_getreg(WUC),
3725
+ igb_getreg(EECD),
3726
+ igb_getreg(FCRTV),
3727
+ igb_getreg(TXDCTL0),
3728
+ igb_getreg(TXDCTL1),
3729
+ igb_getreg(TXDCTL2),
3730
+ igb_getreg(TXDCTL3),
3731
+ igb_getreg(TXDCTL4),
3732
+ igb_getreg(TXDCTL5),
3733
+ igb_getreg(TXDCTL6),
3734
+ igb_getreg(TXDCTL7),
3735
+ igb_getreg(TXDCTL8),
3736
+ igb_getreg(TXDCTL9),
3737
+ igb_getreg(TXDCTL10),
3738
+ igb_getreg(TXDCTL11),
3739
+ igb_getreg(TXDCTL12),
3740
+ igb_getreg(TXDCTL13),
3741
+ igb_getreg(TXDCTL14),
3742
+ igb_getreg(TXDCTL15),
3743
+ igb_getreg(TXCTL0),
3744
+ igb_getreg(TXCTL1),
3745
+ igb_getreg(TXCTL2),
3746
+ igb_getreg(TXCTL3),
3747
+ igb_getreg(TXCTL4),
3748
+ igb_getreg(TXCTL5),
3749
+ igb_getreg(TXCTL6),
3750
+ igb_getreg(TXCTL7),
3751
+ igb_getreg(TXCTL8),
3752
+ igb_getreg(TXCTL9),
3753
+ igb_getreg(TXCTL10),
3754
+ igb_getreg(TXCTL11),
3755
+ igb_getreg(TXCTL12),
3756
+ igb_getreg(TXCTL13),
3757
+ igb_getreg(TXCTL14),
3758
+ igb_getreg(TXCTL15),
3759
+ igb_getreg(TDWBAL0),
3760
+ igb_getreg(TDWBAL1),
3761
+ igb_getreg(TDWBAL2),
3762
+ igb_getreg(TDWBAL3),
3763
+ igb_getreg(TDWBAL4),
3764
+ igb_getreg(TDWBAL5),
3765
+ igb_getreg(TDWBAL6),
3766
+ igb_getreg(TDWBAL7),
3767
+ igb_getreg(TDWBAL8),
3768
+ igb_getreg(TDWBAL9),
3769
+ igb_getreg(TDWBAL10),
3770
+ igb_getreg(TDWBAL11),
3771
+ igb_getreg(TDWBAL12),
3772
+ igb_getreg(TDWBAL13),
3773
+ igb_getreg(TDWBAL14),
3774
+ igb_getreg(TDWBAL15),
3775
+ igb_getreg(TDWBAH0),
3776
+ igb_getreg(TDWBAH1),
3777
+ igb_getreg(TDWBAH2),
3778
+ igb_getreg(TDWBAH3),
3779
+ igb_getreg(TDWBAH4),
3780
+ igb_getreg(TDWBAH5),
3781
+ igb_getreg(TDWBAH6),
3782
+ igb_getreg(TDWBAH7),
3783
+ igb_getreg(TDWBAH8),
3784
+ igb_getreg(TDWBAH9),
3785
+ igb_getreg(TDWBAH10),
3786
+ igb_getreg(TDWBAH11),
3787
+ igb_getreg(TDWBAH12),
3788
+ igb_getreg(TDWBAH13),
3789
+ igb_getreg(TDWBAH14),
3790
+ igb_getreg(TDWBAH15),
3791
+ igb_getreg(PVTCTRL0),
3792
+ igb_getreg(PVTCTRL1),
3793
+ igb_getreg(PVTCTRL2),
3794
+ igb_getreg(PVTCTRL3),
3795
+ igb_getreg(PVTCTRL4),
3796
+ igb_getreg(PVTCTRL5),
3797
+ igb_getreg(PVTCTRL6),
3798
+ igb_getreg(PVTCTRL7),
3799
+ igb_getreg(PVTEIMS0),
3800
+ igb_getreg(PVTEIMS1),
3801
+ igb_getreg(PVTEIMS2),
3802
+ igb_getreg(PVTEIMS3),
3803
+ igb_getreg(PVTEIMS4),
3804
+ igb_getreg(PVTEIMS5),
3805
+ igb_getreg(PVTEIMS6),
3806
+ igb_getreg(PVTEIMS7),
3807
+ igb_getreg(PVTEIAC0),
3808
+ igb_getreg(PVTEIAC1),
3809
+ igb_getreg(PVTEIAC2),
3810
+ igb_getreg(PVTEIAC3),
3811
+ igb_getreg(PVTEIAC4),
3812
+ igb_getreg(PVTEIAC5),
3813
+ igb_getreg(PVTEIAC6),
3814
+ igb_getreg(PVTEIAC7),
3815
+ igb_getreg(PVTEIAM0),
3816
+ igb_getreg(PVTEIAM1),
3817
+ igb_getreg(PVTEIAM2),
3818
+ igb_getreg(PVTEIAM3),
3819
+ igb_getreg(PVTEIAM4),
3820
+ igb_getreg(PVTEIAM5),
3821
+ igb_getreg(PVTEIAM6),
3822
+ igb_getreg(PVTEIAM7),
3823
+ igb_getreg(PVFGPRC0),
3824
+ igb_getreg(PVFGPRC1),
3825
+ igb_getreg(PVFGPRC2),
3826
+ igb_getreg(PVFGPRC3),
3827
+ igb_getreg(PVFGPRC4),
3828
+ igb_getreg(PVFGPRC5),
3829
+ igb_getreg(PVFGPRC6),
3830
+ igb_getreg(PVFGPRC7),
3831
+ igb_getreg(PVFGPTC0),
3832
+ igb_getreg(PVFGPTC1),
3833
+ igb_getreg(PVFGPTC2),
3834
+ igb_getreg(PVFGPTC3),
3835
+ igb_getreg(PVFGPTC4),
3836
+ igb_getreg(PVFGPTC5),
3837
+ igb_getreg(PVFGPTC6),
3838
+ igb_getreg(PVFGPTC7),
3839
+ igb_getreg(PVFGORC0),
3840
+ igb_getreg(PVFGORC1),
3841
+ igb_getreg(PVFGORC2),
3842
+ igb_getreg(PVFGORC3),
3843
+ igb_getreg(PVFGORC4),
3844
+ igb_getreg(PVFGORC5),
3845
+ igb_getreg(PVFGORC6),
3846
+ igb_getreg(PVFGORC7),
3847
+ igb_getreg(PVFGOTC0),
3848
+ igb_getreg(PVFGOTC1),
3849
+ igb_getreg(PVFGOTC2),
3850
+ igb_getreg(PVFGOTC3),
3851
+ igb_getreg(PVFGOTC4),
3852
+ igb_getreg(PVFGOTC5),
3853
+ igb_getreg(PVFGOTC6),
3854
+ igb_getreg(PVFGOTC7),
3855
+ igb_getreg(PVFMPRC0),
3856
+ igb_getreg(PVFMPRC1),
3857
+ igb_getreg(PVFMPRC2),
3858
+ igb_getreg(PVFMPRC3),
3859
+ igb_getreg(PVFMPRC4),
3860
+ igb_getreg(PVFMPRC5),
3861
+ igb_getreg(PVFMPRC6),
3862
+ igb_getreg(PVFMPRC7),
3863
+ igb_getreg(PVFGPRLBC0),
3864
+ igb_getreg(PVFGPRLBC1),
3865
+ igb_getreg(PVFGPRLBC2),
3866
+ igb_getreg(PVFGPRLBC3),
3867
+ igb_getreg(PVFGPRLBC4),
3868
+ igb_getreg(PVFGPRLBC5),
3869
+ igb_getreg(PVFGPRLBC6),
3870
+ igb_getreg(PVFGPRLBC7),
3871
+ igb_getreg(PVFGPTLBC0),
3872
+ igb_getreg(PVFGPTLBC1),
3873
+ igb_getreg(PVFGPTLBC2),
3874
+ igb_getreg(PVFGPTLBC3),
3875
+ igb_getreg(PVFGPTLBC4),
3876
+ igb_getreg(PVFGPTLBC5),
3877
+ igb_getreg(PVFGPTLBC6),
3878
+ igb_getreg(PVFGPTLBC7),
3879
+ igb_getreg(PVFGORLBC0),
3880
+ igb_getreg(PVFGORLBC1),
3881
+ igb_getreg(PVFGORLBC2),
3882
+ igb_getreg(PVFGORLBC3),
3883
+ igb_getreg(PVFGORLBC4),
3884
+ igb_getreg(PVFGORLBC5),
3885
+ igb_getreg(PVFGORLBC6),
3886
+ igb_getreg(PVFGORLBC7),
3887
+ igb_getreg(PVFGOTLBC0),
3888
+ igb_getreg(PVFGOTLBC1),
3889
+ igb_getreg(PVFGOTLBC2),
3890
+ igb_getreg(PVFGOTLBC3),
3891
+ igb_getreg(PVFGOTLBC4),
3892
+ igb_getreg(PVFGOTLBC5),
3893
+ igb_getreg(PVFGOTLBC6),
3894
+ igb_getreg(PVFGOTLBC7),
3895
+ igb_getreg(RCTL),
3896
+ igb_getreg(MDIC),
3897
+ igb_getreg(FCRUC),
3898
+ igb_getreg(VET),
3899
+ igb_getreg(RDBAL0),
3900
+ igb_getreg(RDBAL1),
3901
+ igb_getreg(RDBAL2),
3902
+ igb_getreg(RDBAL3),
3903
+ igb_getreg(RDBAL4),
3904
+ igb_getreg(RDBAL5),
3905
+ igb_getreg(RDBAL6),
3906
+ igb_getreg(RDBAL7),
3907
+ igb_getreg(RDBAL8),
3908
+ igb_getreg(RDBAL9),
3909
+ igb_getreg(RDBAL10),
3910
+ igb_getreg(RDBAL11),
3911
+ igb_getreg(RDBAL12),
3912
+ igb_getreg(RDBAL13),
3913
+ igb_getreg(RDBAL14),
3914
+ igb_getreg(RDBAL15),
3915
+ igb_getreg(TDBAH0),
3916
+ igb_getreg(TDBAH1),
3917
+ igb_getreg(TDBAH2),
3918
+ igb_getreg(TDBAH3),
3919
+ igb_getreg(TDBAH4),
3920
+ igb_getreg(TDBAH5),
3921
+ igb_getreg(TDBAH6),
3922
+ igb_getreg(TDBAH7),
3923
+ igb_getreg(TDBAH8),
3924
+ igb_getreg(TDBAH9),
3925
+ igb_getreg(TDBAH10),
3926
+ igb_getreg(TDBAH11),
3927
+ igb_getreg(TDBAH12),
3928
+ igb_getreg(TDBAH13),
3929
+ igb_getreg(TDBAH14),
3930
+ igb_getreg(TDBAH15),
3931
+ igb_getreg(SCC),
3932
+ igb_getreg(COLC),
3933
+ igb_getreg(XOFFRXC),
3934
+ igb_getreg(IPAV),
3935
+ igb_getreg(GOTCL),
3936
+ igb_getreg(MGTPDC),
3937
+ igb_getreg(GCR),
3938
+ igb_getreg(MFVAL),
3939
+ igb_getreg(FUNCTAG),
3940
+ igb_getreg(GSCL_4),
3941
+ igb_getreg(GSCN_3),
3942
+ igb_getreg(MRQC),
3943
+ igb_getreg(FCT),
3944
+ igb_getreg(FLA),
3945
+ igb_getreg(RXDCTL0),
3946
+ igb_getreg(RXDCTL1),
3947
+ igb_getreg(RXDCTL2),
3948
+ igb_getreg(RXDCTL3),
3949
+ igb_getreg(RXDCTL4),
3950
+ igb_getreg(RXDCTL5),
3951
+ igb_getreg(RXDCTL6),
3952
+ igb_getreg(RXDCTL7),
3953
+ igb_getreg(RXDCTL8),
3954
+ igb_getreg(RXDCTL9),
3955
+ igb_getreg(RXDCTL10),
3956
+ igb_getreg(RXDCTL11),
3957
+ igb_getreg(RXDCTL12),
3958
+ igb_getreg(RXDCTL13),
3959
+ igb_getreg(RXDCTL14),
3960
+ igb_getreg(RXDCTL15),
3961
+ igb_getreg(RXSTMPL),
3962
+ igb_getreg(TIMADJH),
3963
+ igb_getreg(FCRTL),
3964
+ igb_getreg(XONRXC),
3965
+ igb_getreg(RFCTL),
3966
+ igb_getreg(GSCN_1),
3967
+ igb_getreg(FCAL),
3968
+ igb_getreg(GPIE),
3969
+ igb_getreg(TXPBS),
3970
+ igb_getreg(RLPML),
3971
+
3972
+ [TOTH] = igb_mac_read_clr8,
3973
+ [GOTCH] = igb_mac_read_clr8,
3974
+ [PRC64] = igb_mac_read_clr4,
3975
+ [PRC255] = igb_mac_read_clr4,
3976
+ [PRC1023] = igb_mac_read_clr4,
3977
+ [PTC64] = igb_mac_read_clr4,
3978
+ [PTC255] = igb_mac_read_clr4,
3979
+ [PTC1023] = igb_mac_read_clr4,
3980
+ [GPRC] = igb_mac_read_clr4,
3981
+ [TPT] = igb_mac_read_clr4,
3982
+ [RUC] = igb_mac_read_clr4,
3983
+ [BPRC] = igb_mac_read_clr4,
3984
+ [MPTC] = igb_mac_read_clr4,
3985
+ [IAC] = igb_mac_read_clr4,
3986
+ [ICR] = igb_mac_icr_read,
3987
+ [STATUS] = igb_get_status,
3988
+ [ICS] = igb_mac_ics_read,
3989
+ /*
3990
+ * 8.8.10: Reading the IMC register returns the value of the IMS register.
3991
+ */
3992
+ [IMC] = igb_mac_ims_read,
3993
+ [TORH] = igb_mac_read_clr8,
3994
+ [GORCH] = igb_mac_read_clr8,
3995
+ [PRC127] = igb_mac_read_clr4,
3996
+ [PRC511] = igb_mac_read_clr4,
3997
+ [PRC1522] = igb_mac_read_clr4,
3998
+ [PTC127] = igb_mac_read_clr4,
3999
+ [PTC511] = igb_mac_read_clr4,
4000
+ [PTC1522] = igb_mac_read_clr4,
4001
+ [GPTC] = igb_mac_read_clr4,
4002
+ [TPR] = igb_mac_read_clr4,
4003
+ [ROC] = igb_mac_read_clr4,
4004
+ [MPRC] = igb_mac_read_clr4,
4005
+ [BPTC] = igb_mac_read_clr4,
4006
+ [TSCTC] = igb_mac_read_clr4,
4007
+ [CTRL] = igb_get_ctrl,
4008
+ [SWSM] = igb_mac_swsm_read,
4009
+ [IMS] = igb_mac_ims_read,
4010
+ [SYSTIML] = igb_get_systiml,
4011
+ [RXSATRH] = igb_get_rxsatrh,
4012
+ [TXSTMPH] = igb_get_txstmph,
4013
+
4014
+ [CRCERRS ... MPC] = igb_mac_readreg,
4015
+ [IP6AT ... IP6AT + 3] = igb_mac_readreg,
4016
+ [IP4AT ... IP4AT + 6] = igb_mac_readreg,
4017
+ [RA ... RA + 31] = igb_mac_readreg,
4018
+ [RA2 ... RA2 + 31] = igb_mac_readreg,
4019
+ [WUPM ... WUPM + 31] = igb_mac_readreg,
4020
+ [MTA ... MTA + E1000_MC_TBL_SIZE - 1] = igb_mac_readreg,
4021
+ [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] = igb_mac_readreg,
4022
+ [FFMT ... FFMT + 254] = igb_mac_readreg,
4023
+ [MDEF ... MDEF + 7] = igb_mac_readreg,
4024
+ [FTFT ... FTFT + 254] = igb_mac_readreg,
4025
+ [RETA ... RETA + 31] = igb_mac_readreg,
4026
+ [RSSRK ... RSSRK + 9] = igb_mac_readreg,
4027
+ [MAVTV0 ... MAVTV3] = igb_mac_readreg,
4028
+ [EITR0 ... EITR0 + IGB_INTR_NUM - 1] = igb_mac_eitr_read,
4029
+ [PVTEICR0] = igb_mac_read_clr4,
4030
+ [PVTEICR1] = igb_mac_read_clr4,
4031
+ [PVTEICR2] = igb_mac_read_clr4,
4032
+ [PVTEICR3] = igb_mac_read_clr4,
4033
+ [PVTEICR4] = igb_mac_read_clr4,
4034
+ [PVTEICR5] = igb_mac_read_clr4,
4035
+ [PVTEICR6] = igb_mac_read_clr4,
4036
+ [PVTEICR7] = igb_mac_read_clr4,
4037
+
4038
+ /* IGB specific: */
4039
+ [FWSM] = igb_mac_readreg,
4040
+ [SW_FW_SYNC] = igb_mac_readreg,
4041
+ [HTCBDPC] = igb_mac_read_clr4,
4042
+ [EICR] = igb_mac_read_clr4,
4043
+ [EIMS] = igb_mac_readreg,
4044
+ [EIAM] = igb_mac_readreg,
4045
+ [IVAR0 ... IVAR0 + 7] = igb_mac_readreg,
4046
+ igb_getreg(IVAR_MISC),
4047
+ igb_getreg(VT_CTL),
4048
+ [P2VMAILBOX0 ... P2VMAILBOX7] = igb_mac_readreg,
4049
+ [V2PMAILBOX0 ... V2PMAILBOX7] = igb_mac_vfmailbox_read,
4050
+ igb_getreg(MBVFICR),
4051
+ [VMBMEM0 ... VMBMEM0 + 127] = igb_mac_readreg,
4052
+ igb_getreg(MBVFIMR),
4053
+ igb_getreg(VFLRE),
4054
+ igb_getreg(VFRE),
4055
+ igb_getreg(VFTE),
4056
+ igb_getreg(QDE),
4057
+ igb_getreg(DTXSWC),
4058
+ igb_getreg(RPLOLR),
4059
+ [VLVF0 ... VLVF0 + E1000_VLVF_ARRAY_SIZE - 1] = igb_mac_readreg,
4060
+ [VMVIR0 ... VMVIR7] = igb_mac_readreg,
4061
+ [VMOLR0 ... VMOLR7] = igb_mac_readreg,
4062
+ [WVBR] = igb_mac_read_clr4,
4063
+ [RQDPC0] = igb_mac_read_clr4,
4064
+ [RQDPC1] = igb_mac_read_clr4,
4065
+ [RQDPC2] = igb_mac_read_clr4,
4066
+ [RQDPC3] = igb_mac_read_clr4,
4067
+ [RQDPC4] = igb_mac_read_clr4,
4068
+ [RQDPC5] = igb_mac_read_clr4,
4069
+ [RQDPC6] = igb_mac_read_clr4,
4070
+ [RQDPC7] = igb_mac_read_clr4,
4071
+ [RQDPC8] = igb_mac_read_clr4,
4072
+ [RQDPC9] = igb_mac_read_clr4,
4073
+ [RQDPC10] = igb_mac_read_clr4,
4074
+ [RQDPC11] = igb_mac_read_clr4,
4075
+ [RQDPC12] = igb_mac_read_clr4,
4076
+ [RQDPC13] = igb_mac_read_clr4,
4077
+ [RQDPC14] = igb_mac_read_clr4,
4078
+ [RQDPC15] = igb_mac_read_clr4,
4079
+ [VTIVAR ... VTIVAR + 7] = igb_mac_readreg,
4080
+ [VTIVAR_MISC ... VTIVAR_MISC + 7] = igb_mac_readreg,
4081
+};
4082
+enum { IGB_NREADOPS = ARRAY_SIZE(igb_macreg_readops) };
4083
+
4084
+#define igb_putreg(x) [x] = igb_mac_writereg
4085
+typedef void (*writeops)(IGBCore *, int, uint32_t);
4086
+static const writeops igb_macreg_writeops[] = {
4087
+ igb_putreg(SWSM),
4088
+ igb_putreg(WUFC),
4089
+ igb_putreg(RDBAH0),
4090
+ igb_putreg(RDBAH1),
4091
+ igb_putreg(RDBAH2),
4092
+ igb_putreg(RDBAH3),
4093
+ igb_putreg(RDBAH4),
4094
+ igb_putreg(RDBAH5),
4095
+ igb_putreg(RDBAH6),
4096
+ igb_putreg(RDBAH7),
4097
+ igb_putreg(RDBAH8),
4098
+ igb_putreg(RDBAH9),
4099
+ igb_putreg(RDBAH10),
4100
+ igb_putreg(RDBAH11),
4101
+ igb_putreg(RDBAH12),
4102
+ igb_putreg(RDBAH13),
4103
+ igb_putreg(RDBAH14),
4104
+ igb_putreg(RDBAH15),
4105
+ igb_putreg(SRRCTL0),
4106
+ igb_putreg(SRRCTL1),
4107
+ igb_putreg(SRRCTL2),
4108
+ igb_putreg(SRRCTL3),
4109
+ igb_putreg(SRRCTL4),
4110
+ igb_putreg(SRRCTL5),
4111
+ igb_putreg(SRRCTL6),
4112
+ igb_putreg(SRRCTL7),
4113
+ igb_putreg(SRRCTL8),
4114
+ igb_putreg(SRRCTL9),
4115
+ igb_putreg(SRRCTL10),
4116
+ igb_putreg(SRRCTL11),
4117
+ igb_putreg(SRRCTL12),
4118
+ igb_putreg(SRRCTL13),
4119
+ igb_putreg(SRRCTL14),
4120
+ igb_putreg(SRRCTL15),
4121
+ igb_putreg(RXDCTL0),
4122
+ igb_putreg(RXDCTL1),
4123
+ igb_putreg(RXDCTL2),
4124
+ igb_putreg(RXDCTL3),
4125
+ igb_putreg(RXDCTL4),
4126
+ igb_putreg(RXDCTL5),
4127
+ igb_putreg(RXDCTL6),
4128
+ igb_putreg(RXDCTL7),
4129
+ igb_putreg(RXDCTL8),
4130
+ igb_putreg(RXDCTL9),
4131
+ igb_putreg(RXDCTL10),
4132
+ igb_putreg(RXDCTL11),
4133
+ igb_putreg(RXDCTL12),
4134
+ igb_putreg(RXDCTL13),
4135
+ igb_putreg(RXDCTL14),
4136
+ igb_putreg(RXDCTL15),
4137
+ igb_putreg(LEDCTL),
4138
+ igb_putreg(TCTL),
4139
+ igb_putreg(TCTL_EXT),
4140
+ igb_putreg(DTXCTL),
4141
+ igb_putreg(RXPBS),
4142
+ igb_putreg(RQDPC0),
4143
+ igb_putreg(FCAL),
4144
+ igb_putreg(FCRUC),
4145
+ igb_putreg(WUC),
4146
+ igb_putreg(WUS),
4147
+ igb_putreg(IPAV),
4148
+ igb_putreg(TDBAH0),
4149
+ igb_putreg(TDBAH1),
4150
+ igb_putreg(TDBAH2),
4151
+ igb_putreg(TDBAH3),
4152
+ igb_putreg(TDBAH4),
4153
+ igb_putreg(TDBAH5),
4154
+ igb_putreg(TDBAH6),
4155
+ igb_putreg(TDBAH7),
4156
+ igb_putreg(TDBAH8),
4157
+ igb_putreg(TDBAH9),
4158
+ igb_putreg(TDBAH10),
4159
+ igb_putreg(TDBAH11),
4160
+ igb_putreg(TDBAH12),
4161
+ igb_putreg(TDBAH13),
4162
+ igb_putreg(TDBAH14),
4163
+ igb_putreg(TDBAH15),
4164
+ igb_putreg(IAM),
4165
+ igb_putreg(MANC),
4166
+ igb_putreg(MANC2H),
4167
+ igb_putreg(MFVAL),
4168
+ igb_putreg(FACTPS),
4169
+ igb_putreg(FUNCTAG),
4170
+ igb_putreg(GSCL_1),
4171
+ igb_putreg(GSCL_2),
4172
+ igb_putreg(GSCL_3),
4173
+ igb_putreg(GSCL_4),
4174
+ igb_putreg(GSCN_0),
4175
+ igb_putreg(GSCN_1),
4176
+ igb_putreg(GSCN_2),
4177
+ igb_putreg(GSCN_3),
4178
+ igb_putreg(MRQC),
4179
+ igb_putreg(FLOP),
4180
+ igb_putreg(FLA),
4181
+ igb_putreg(TXDCTL0),
4182
+ igb_putreg(TXDCTL1),
4183
+ igb_putreg(TXDCTL2),
4184
+ igb_putreg(TXDCTL3),
4185
+ igb_putreg(TXDCTL4),
4186
+ igb_putreg(TXDCTL5),
4187
+ igb_putreg(TXDCTL6),
4188
+ igb_putreg(TXDCTL7),
4189
+ igb_putreg(TXDCTL8),
4190
+ igb_putreg(TXDCTL9),
4191
+ igb_putreg(TXDCTL10),
4192
+ igb_putreg(TXDCTL11),
4193
+ igb_putreg(TXDCTL12),
4194
+ igb_putreg(TXDCTL13),
4195
+ igb_putreg(TXDCTL14),
4196
+ igb_putreg(TXDCTL15),
4197
+ igb_putreg(TXCTL0),
4198
+ igb_putreg(TXCTL1),
4199
+ igb_putreg(TXCTL2),
4200
+ igb_putreg(TXCTL3),
4201
+ igb_putreg(TXCTL4),
4202
+ igb_putreg(TXCTL5),
4203
+ igb_putreg(TXCTL6),
4204
+ igb_putreg(TXCTL7),
4205
+ igb_putreg(TXCTL8),
4206
+ igb_putreg(TXCTL9),
4207
+ igb_putreg(TXCTL10),
4208
+ igb_putreg(TXCTL11),
4209
+ igb_putreg(TXCTL12),
4210
+ igb_putreg(TXCTL13),
4211
+ igb_putreg(TXCTL14),
4212
+ igb_putreg(TXCTL15),
4213
+ igb_putreg(TDWBAL0),
4214
+ igb_putreg(TDWBAL1),
4215
+ igb_putreg(TDWBAL2),
4216
+ igb_putreg(TDWBAL3),
4217
+ igb_putreg(TDWBAL4),
4218
+ igb_putreg(TDWBAL5),
4219
+ igb_putreg(TDWBAL6),
4220
+ igb_putreg(TDWBAL7),
4221
+ igb_putreg(TDWBAL8),
4222
+ igb_putreg(TDWBAL9),
4223
+ igb_putreg(TDWBAL10),
4224
+ igb_putreg(TDWBAL11),
4225
+ igb_putreg(TDWBAL12),
4226
+ igb_putreg(TDWBAL13),
4227
+ igb_putreg(TDWBAL14),
4228
+ igb_putreg(TDWBAL15),
4229
+ igb_putreg(TDWBAH0),
4230
+ igb_putreg(TDWBAH1),
4231
+ igb_putreg(TDWBAH2),
4232
+ igb_putreg(TDWBAH3),
4233
+ igb_putreg(TDWBAH4),
4234
+ igb_putreg(TDWBAH5),
4235
+ igb_putreg(TDWBAH6),
4236
+ igb_putreg(TDWBAH7),
4237
+ igb_putreg(TDWBAH8),
4238
+ igb_putreg(TDWBAH9),
4239
+ igb_putreg(TDWBAH10),
4240
+ igb_putreg(TDWBAH11),
4241
+ igb_putreg(TDWBAH12),
4242
+ igb_putreg(TDWBAH13),
4243
+ igb_putreg(TDWBAH14),
4244
+ igb_putreg(TDWBAH15),
4245
+ igb_putreg(TIPG),
4246
+ igb_putreg(RXSTMPH),
4247
+ igb_putreg(RXSTMPL),
4248
+ igb_putreg(RXSATRL),
4249
+ igb_putreg(RXSATRH),
4250
+ igb_putreg(TXSTMPL),
4251
+ igb_putreg(TXSTMPH),
4252
+ igb_putreg(SYSTIML),
4253
+ igb_putreg(SYSTIMH),
4254
+ igb_putreg(TIMADJL),
4255
+ igb_putreg(TSYNCRXCTL),
4256
+ igb_putreg(TSYNCTXCTL),
4257
+ igb_putreg(EEMNGCTL),
4258
+ igb_putreg(GPIE),
4259
+ igb_putreg(TXPBS),
4260
+ igb_putreg(RLPML),
4261
+ igb_putreg(VET),
4262
+
4263
+ [TDH0] = igb_set_16bit,
4264
+ [TDH1] = igb_set_16bit,
4265
+ [TDH2] = igb_set_16bit,
4266
+ [TDH3] = igb_set_16bit,
4267
+ [TDH4] = igb_set_16bit,
4268
+ [TDH5] = igb_set_16bit,
4269
+ [TDH6] = igb_set_16bit,
4270
+ [TDH7] = igb_set_16bit,
4271
+ [TDH8] = igb_set_16bit,
4272
+ [TDH9] = igb_set_16bit,
4273
+ [TDH10] = igb_set_16bit,
4274
+ [TDH11] = igb_set_16bit,
4275
+ [TDH12] = igb_set_16bit,
4276
+ [TDH13] = igb_set_16bit,
4277
+ [TDH14] = igb_set_16bit,
4278
+ [TDH15] = igb_set_16bit,
4279
+ [TDT0] = igb_set_tdt,
4280
+ [TDT1] = igb_set_tdt,
4281
+ [TDT2] = igb_set_tdt,
4282
+ [TDT3] = igb_set_tdt,
4283
+ [TDT4] = igb_set_tdt,
4284
+ [TDT5] = igb_set_tdt,
4285
+ [TDT6] = igb_set_tdt,
4286
+ [TDT7] = igb_set_tdt,
4287
+ [TDT8] = igb_set_tdt,
4288
+ [TDT9] = igb_set_tdt,
4289
+ [TDT10] = igb_set_tdt,
4290
+ [TDT11] = igb_set_tdt,
4291
+ [TDT12] = igb_set_tdt,
4292
+ [TDT13] = igb_set_tdt,
4293
+ [TDT14] = igb_set_tdt,
4294
+ [TDT15] = igb_set_tdt,
4295
+ [MDIC] = igb_set_mdic,
4296
+ [ICS] = igb_set_ics,
4297
+ [RDH0] = igb_set_16bit,
4298
+ [RDH1] = igb_set_16bit,
4299
+ [RDH2] = igb_set_16bit,
4300
+ [RDH3] = igb_set_16bit,
4301
+ [RDH4] = igb_set_16bit,
4302
+ [RDH5] = igb_set_16bit,
4303
+ [RDH6] = igb_set_16bit,
4304
+ [RDH7] = igb_set_16bit,
4305
+ [RDH8] = igb_set_16bit,
4306
+ [RDH9] = igb_set_16bit,
4307
+ [RDH10] = igb_set_16bit,
4308
+ [RDH11] = igb_set_16bit,
4309
+ [RDH12] = igb_set_16bit,
4310
+ [RDH13] = igb_set_16bit,
4311
+ [RDH14] = igb_set_16bit,
4312
+ [RDH15] = igb_set_16bit,
4313
+ [RDT0] = igb_set_rdt,
4314
+ [RDT1] = igb_set_rdt,
4315
+ [RDT2] = igb_set_rdt,
4316
+ [RDT3] = igb_set_rdt,
4317
+ [RDT4] = igb_set_rdt,
4318
+ [RDT5] = igb_set_rdt,
4319
+ [RDT6] = igb_set_rdt,
4320
+ [RDT7] = igb_set_rdt,
4321
+ [RDT8] = igb_set_rdt,
4322
+ [RDT9] = igb_set_rdt,
4323
+ [RDT10] = igb_set_rdt,
4324
+ [RDT11] = igb_set_rdt,
4325
+ [RDT12] = igb_set_rdt,
4326
+ [RDT13] = igb_set_rdt,
4327
+ [RDT14] = igb_set_rdt,
4328
+ [RDT15] = igb_set_rdt,
4329
+ [IMC] = igb_set_imc,
4330
+ [IMS] = igb_set_ims,
4331
+ [ICR] = igb_set_icr,
4332
+ [EECD] = igb_set_eecd,
4333
+ [RCTL] = igb_set_rx_control,
4334
+ [CTRL] = igb_set_ctrl,
4335
+ [EERD] = igb_set_eerd,
4336
+ [TDFH] = igb_set_13bit,
4337
+ [TDFT] = igb_set_13bit,
4338
+ [TDFHS] = igb_set_13bit,
4339
+ [TDFTS] = igb_set_13bit,
4340
+ [TDFPC] = igb_set_13bit,
4341
+ [RDFH] = igb_set_13bit,
4342
+ [RDFT] = igb_set_13bit,
4343
+ [RDFHS] = igb_set_13bit,
4344
+ [RDFTS] = igb_set_13bit,
4345
+ [RDFPC] = igb_set_13bit,
4346
+ [GCR] = igb_set_gcr,
4347
+ [RXCSUM] = igb_set_rxcsum,
4348
+ [TDLEN0] = igb_set_dlen,
4349
+ [TDLEN1] = igb_set_dlen,
4350
+ [TDLEN2] = igb_set_dlen,
4351
+ [TDLEN3] = igb_set_dlen,
4352
+ [TDLEN4] = igb_set_dlen,
4353
+ [TDLEN5] = igb_set_dlen,
4354
+ [TDLEN6] = igb_set_dlen,
4355
+ [TDLEN7] = igb_set_dlen,
4356
+ [TDLEN8] = igb_set_dlen,
4357
+ [TDLEN9] = igb_set_dlen,
4358
+ [TDLEN10] = igb_set_dlen,
4359
+ [TDLEN11] = igb_set_dlen,
4360
+ [TDLEN12] = igb_set_dlen,
4361
+ [TDLEN13] = igb_set_dlen,
4362
+ [TDLEN14] = igb_set_dlen,
4363
+ [TDLEN15] = igb_set_dlen,
4364
+ [RDLEN0] = igb_set_dlen,
4365
+ [RDLEN1] = igb_set_dlen,
4366
+ [RDLEN2] = igb_set_dlen,
4367
+ [RDLEN3] = igb_set_dlen,
4368
+ [RDLEN4] = igb_set_dlen,
4369
+ [RDLEN5] = igb_set_dlen,
4370
+ [RDLEN6] = igb_set_dlen,
4371
+ [RDLEN7] = igb_set_dlen,
4372
+ [RDLEN8] = igb_set_dlen,
4373
+ [RDLEN9] = igb_set_dlen,
4374
+ [RDLEN10] = igb_set_dlen,
4375
+ [RDLEN11] = igb_set_dlen,
4376
+ [RDLEN12] = igb_set_dlen,
4377
+ [RDLEN13] = igb_set_dlen,
4378
+ [RDLEN14] = igb_set_dlen,
4379
+ [RDLEN15] = igb_set_dlen,
4380
+ [TDBAL0] = igb_set_dbal,
4381
+ [TDBAL1] = igb_set_dbal,
4382
+ [TDBAL2] = igb_set_dbal,
4383
+ [TDBAL3] = igb_set_dbal,
4384
+ [TDBAL4] = igb_set_dbal,
4385
+ [TDBAL5] = igb_set_dbal,
4386
+ [TDBAL6] = igb_set_dbal,
4387
+ [TDBAL7] = igb_set_dbal,
4388
+ [TDBAL8] = igb_set_dbal,
4389
+ [TDBAL9] = igb_set_dbal,
4390
+ [TDBAL10] = igb_set_dbal,
4391
+ [TDBAL11] = igb_set_dbal,
4392
+ [TDBAL12] = igb_set_dbal,
4393
+ [TDBAL13] = igb_set_dbal,
4394
+ [TDBAL14] = igb_set_dbal,
4395
+ [TDBAL15] = igb_set_dbal,
4396
+ [RDBAL0] = igb_set_dbal,
4397
+ [RDBAL1] = igb_set_dbal,
4398
+ [RDBAL2] = igb_set_dbal,
4399
+ [RDBAL3] = igb_set_dbal,
4400
+ [RDBAL4] = igb_set_dbal,
4401
+ [RDBAL5] = igb_set_dbal,
4402
+ [RDBAL6] = igb_set_dbal,
4403
+ [RDBAL7] = igb_set_dbal,
4404
+ [RDBAL8] = igb_set_dbal,
4405
+ [RDBAL9] = igb_set_dbal,
4406
+ [RDBAL10] = igb_set_dbal,
4407
+ [RDBAL11] = igb_set_dbal,
4408
+ [RDBAL12] = igb_set_dbal,
4409
+ [RDBAL13] = igb_set_dbal,
4410
+ [RDBAL14] = igb_set_dbal,
4411
+ [RDBAL15] = igb_set_dbal,
4412
+ [STATUS] = igb_set_status,
4413
+ [PBACLR] = igb_set_pbaclr,
4414
+ [CTRL_EXT] = igb_set_ctrlext,
4415
+ [FCAH] = igb_set_16bit,
4416
+ [FCT] = igb_set_16bit,
4417
+ [FCTTV] = igb_set_16bit,
4418
+ [FCRTV] = igb_set_16bit,
4419
+ [FCRTH] = igb_set_fcrth,
4420
+ [FCRTL] = igb_set_fcrtl,
4421
+ [CTRL_DUP] = igb_set_ctrl,
4422
+ [RFCTL] = igb_set_rfctl,
4423
+ [TIMINCA] = igb_set_timinca,
4424
+ [TIMADJH] = igb_set_timadjh,
4425
+
4426
+ [IP6AT ... IP6AT + 3] = igb_mac_writereg,
4427
+ [IP4AT ... IP4AT + 6] = igb_mac_writereg,
4428
+ [RA] = igb_mac_writereg,
4429
+ [RA + 1] = igb_mac_setmacaddr,
4430
+ [RA + 2 ... RA + 31] = igb_mac_writereg,
4431
+ [RA2 ... RA2 + 31] = igb_mac_writereg,
4432
+ [WUPM ... WUPM + 31] = igb_mac_writereg,
4433
+ [MTA ... MTA + E1000_MC_TBL_SIZE - 1] = igb_mac_writereg,
4434
+ [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] = igb_mac_writereg,
4435
+ [FFMT ... FFMT + 254] = igb_set_4bit,
4436
+ [MDEF ... MDEF + 7] = igb_mac_writereg,
4437
+ [FTFT ... FTFT + 254] = igb_mac_writereg,
4438
+ [RETA ... RETA + 31] = igb_mac_writereg,
4439
+ [RSSRK ... RSSRK + 9] = igb_mac_writereg,
4440
+ [MAVTV0 ... MAVTV3] = igb_mac_writereg,
4441
+ [EITR0 ... EITR0 + IGB_INTR_NUM - 1] = igb_set_eitr,
4442
+
4443
+ /* IGB specific: */
4444
+ [FWSM] = igb_mac_writereg,
4445
+ [SW_FW_SYNC] = igb_mac_writereg,
4446
+ [EICR] = igb_set_eicr,
4447
+ [EICS] = igb_set_eics,
4448
+ [EIAC] = igb_set_eiac,
4449
+ [EIAM] = igb_set_eiam,
4450
+ [EIMC] = igb_set_eimc,
4451
+ [EIMS] = igb_set_eims,
4452
+ [IVAR0 ... IVAR0 + 7] = igb_mac_writereg,
4453
+ igb_putreg(IVAR_MISC),
4454
+ igb_putreg(VT_CTL),
4455
+ [P2VMAILBOX0 ... P2VMAILBOX7] = igb_set_pfmailbox,
4456
+ [V2PMAILBOX0 ... V2PMAILBOX7] = igb_set_vfmailbox,
4457
+ [MBVFICR] = igb_w1c,
4458
+ [VMBMEM0 ... VMBMEM0 + 127] = igb_mac_writereg,
4459
+ igb_putreg(MBVFIMR),
4460
+ [VFLRE] = igb_w1c,
4461
+ igb_putreg(VFRE),
4462
+ igb_putreg(VFTE),
4463
+ igb_putreg(QDE),
4464
+ igb_putreg(DTXSWC),
4465
+ igb_putreg(RPLOLR),
4466
+ [VLVF0 ... VLVF0 + E1000_VLVF_ARRAY_SIZE - 1] = igb_mac_writereg,
4467
+ [VMVIR0 ... VMVIR7] = igb_mac_writereg,
4468
+ [VMOLR0 ... VMOLR7] = igb_mac_writereg,
4469
+ [UTA ... UTA + E1000_MC_TBL_SIZE - 1] = igb_mac_writereg,
4470
+ [PVTCTRL0] = igb_set_vtctrl,
4471
+ [PVTCTRL1] = igb_set_vtctrl,
4472
+ [PVTCTRL2] = igb_set_vtctrl,
4473
+ [PVTCTRL3] = igb_set_vtctrl,
4474
+ [PVTCTRL4] = igb_set_vtctrl,
4475
+ [PVTCTRL5] = igb_set_vtctrl,
4476
+ [PVTCTRL6] = igb_set_vtctrl,
4477
+ [PVTCTRL7] = igb_set_vtctrl,
4478
+ [PVTEICS0] = igb_set_vteics,
4479
+ [PVTEICS1] = igb_set_vteics,
4480
+ [PVTEICS2] = igb_set_vteics,
4481
+ [PVTEICS3] = igb_set_vteics,
4482
+ [PVTEICS4] = igb_set_vteics,
4483
+ [PVTEICS5] = igb_set_vteics,
4484
+ [PVTEICS6] = igb_set_vteics,
4485
+ [PVTEICS7] = igb_set_vteics,
4486
+ [PVTEIMS0] = igb_set_vteims,
4487
+ [PVTEIMS1] = igb_set_vteims,
4488
+ [PVTEIMS2] = igb_set_vteims,
4489
+ [PVTEIMS3] = igb_set_vteims,
4490
+ [PVTEIMS4] = igb_set_vteims,
4491
+ [PVTEIMS5] = igb_set_vteims,
4492
+ [PVTEIMS6] = igb_set_vteims,
4493
+ [PVTEIMS7] = igb_set_vteims,
4494
+ [PVTEIMC0] = igb_set_vteimc,
4495
+ [PVTEIMC1] = igb_set_vteimc,
4496
+ [PVTEIMC2] = igb_set_vteimc,
4497
+ [PVTEIMC3] = igb_set_vteimc,
4498
+ [PVTEIMC4] = igb_set_vteimc,
4499
+ [PVTEIMC5] = igb_set_vteimc,
4500
+ [PVTEIMC6] = igb_set_vteimc,
4501
+ [PVTEIMC7] = igb_set_vteimc,
4502
+ [PVTEIAC0] = igb_set_vteiac,
4503
+ [PVTEIAC1] = igb_set_vteiac,
4504
+ [PVTEIAC2] = igb_set_vteiac,
4505
+ [PVTEIAC3] = igb_set_vteiac,
4506
+ [PVTEIAC4] = igb_set_vteiac,
4507
+ [PVTEIAC5] = igb_set_vteiac,
4508
+ [PVTEIAC6] = igb_set_vteiac,
4509
+ [PVTEIAC7] = igb_set_vteiac,
4510
+ [PVTEIAM0] = igb_set_vteiam,
4511
+ [PVTEIAM1] = igb_set_vteiam,
4512
+ [PVTEIAM2] = igb_set_vteiam,
4513
+ [PVTEIAM3] = igb_set_vteiam,
4514
+ [PVTEIAM4] = igb_set_vteiam,
4515
+ [PVTEIAM5] = igb_set_vteiam,
4516
+ [PVTEIAM6] = igb_set_vteiam,
4517
+ [PVTEIAM7] = igb_set_vteiam,
4518
+ [PVTEICR0] = igb_set_vteicr,
4519
+ [PVTEICR1] = igb_set_vteicr,
4520
+ [PVTEICR2] = igb_set_vteicr,
4521
+ [PVTEICR3] = igb_set_vteicr,
4522
+ [PVTEICR4] = igb_set_vteicr,
4523
+ [PVTEICR5] = igb_set_vteicr,
4524
+ [PVTEICR6] = igb_set_vteicr,
4525
+ [PVTEICR7] = igb_set_vteicr,
4526
+ [VTIVAR ... VTIVAR + 7] = igb_set_vtivar,
4527
+ [VTIVAR_MISC ... VTIVAR_MISC + 7] = igb_mac_writereg
4528
+};
4529
+enum { IGB_NWRITEOPS = ARRAY_SIZE(igb_macreg_writeops) };
4530
+
4531
+enum { MAC_ACCESS_PARTIAL = 1 };
4532
+
4533
+/*
4534
+ * The array below combines alias offsets of the index values for the
4535
+ * MAC registers that have aliases, with the indication of not fully
4536
+ * implemented registers (lowest bit). This combination is possible
4537
+ * because all of the offsets are even.
4538
+ */
4539
+static const uint16_t mac_reg_access[E1000E_MAC_SIZE] = {
4540
+ /* Alias index offsets */
4541
+ [FCRTL_A] = 0x07fe,
4542
+ [RDFH_A] = 0xe904, [RDFT_A] = 0xe904,
4543
+ [TDFH_A] = 0xed00, [TDFT_A] = 0xed00,
4544
+ [RA_A ... RA_A + 31] = 0x14f0,
4545
+ [VFTA_A ... VFTA_A + E1000_VLAN_FILTER_TBL_SIZE - 1] = 0x1400,
4546
+
4547
+ [RDBAL0_A] = 0x2600,
4548
+ [RDBAH0_A] = 0x2600,
4549
+ [RDLEN0_A] = 0x2600,
4550
+ [SRRCTL0_A] = 0x2600,
4551
+ [RDH0_A] = 0x2600,
4552
+ [RDT0_A] = 0x2600,
4553
+ [RXDCTL0_A] = 0x2600,
4554
+ [RXCTL0_A] = 0x2600,
4555
+ [RQDPC0_A] = 0x2600,
4556
+ [RDBAL1_A] = 0x25D0,
4557
+ [RDBAL2_A] = 0x25A0,
4558
+ [RDBAL3_A] = 0x2570,
4559
+ [RDBAH1_A] = 0x25D0,
4560
+ [RDBAH2_A] = 0x25A0,
4561
+ [RDBAH3_A] = 0x2570,
4562
+ [RDLEN1_A] = 0x25D0,
4563
+ [RDLEN2_A] = 0x25A0,
4564
+ [RDLEN3_A] = 0x2570,
4565
+ [SRRCTL1_A] = 0x25D0,
4566
+ [SRRCTL2_A] = 0x25A0,
4567
+ [SRRCTL3_A] = 0x2570,
4568
+ [RDH1_A] = 0x25D0,
4569
+ [RDH2_A] = 0x25A0,
4570
+ [RDH3_A] = 0x2570,
4571
+ [RDT1_A] = 0x25D0,
4572
+ [RDT2_A] = 0x25A0,
4573
+ [RDT3_A] = 0x2570,
4574
+ [RXDCTL1_A] = 0x25D0,
4575
+ [RXDCTL2_A] = 0x25A0,
4576
+ [RXDCTL3_A] = 0x2570,
4577
+ [RXCTL1_A] = 0x25D0,
4578
+ [RXCTL2_A] = 0x25A0,
4579
+ [RXCTL3_A] = 0x2570,
4580
+ [RQDPC1_A] = 0x25D0,
4581
+ [RQDPC2_A] = 0x25A0,
4582
+ [RQDPC3_A] = 0x2570,
4583
+ [TDBAL0_A] = 0x2A00,
4584
+ [TDBAH0_A] = 0x2A00,
4585
+ [TDLEN0_A] = 0x2A00,
4586
+ [TDH0_A] = 0x2A00,
4587
+ [TDT0_A] = 0x2A00,
4588
+ [TXCTL0_A] = 0x2A00,
4589
+ [TDWBAL0_A] = 0x2A00,
4590
+ [TDWBAH0_A] = 0x2A00,
4591
+ [TDBAL1_A] = 0x29D0,
4592
+ [TDBAL2_A] = 0x29A0,
4593
+ [TDBAL3_A] = 0x2970,
4594
+ [TDBAH1_A] = 0x29D0,
4595
+ [TDBAH2_A] = 0x29A0,
4596
+ [TDBAH3_A] = 0x2970,
4597
+ [TDLEN1_A] = 0x29D0,
4598
+ [TDLEN2_A] = 0x29A0,
4599
+ [TDLEN3_A] = 0x2970,
4600
+ [TDH1_A] = 0x29D0,
4601
+ [TDH2_A] = 0x29A0,
4602
+ [TDH3_A] = 0x2970,
4603
+ [TDT1_A] = 0x29D0,
4604
+ [TDT2_A] = 0x29A0,
4605
+ [TDT3_A] = 0x2970,
4606
+ [TXDCTL0_A] = 0x2A00,
4607
+ [TXDCTL1_A] = 0x29D0,
4608
+ [TXDCTL2_A] = 0x29A0,
4609
+ [TXDCTL3_A] = 0x2970,
4610
+ [TXCTL1_A] = 0x29D0,
4611
+ [TXCTL2_A] = 0x29A0,
4612
+ [TXCTL3_A] = 0x29D0,
4613
+ [TDWBAL1_A] = 0x29D0,
4614
+ [TDWBAL2_A] = 0x29A0,
4615
+ [TDWBAL3_A] = 0x2970,
4616
+ [TDWBAH1_A] = 0x29D0,
4617
+ [TDWBAH2_A] = 0x29A0,
4618
+ [TDWBAH3_A] = 0x2970,
4619
+
4620
+ /* Access options */
4621
+ [RDFH] = MAC_ACCESS_PARTIAL, [RDFT] = MAC_ACCESS_PARTIAL,
4622
+ [RDFHS] = MAC_ACCESS_PARTIAL, [RDFTS] = MAC_ACCESS_PARTIAL,
4623
+ [RDFPC] = MAC_ACCESS_PARTIAL,
4624
+ [TDFH] = MAC_ACCESS_PARTIAL, [TDFT] = MAC_ACCESS_PARTIAL,
4625
+ [TDFHS] = MAC_ACCESS_PARTIAL, [TDFTS] = MAC_ACCESS_PARTIAL,
4626
+ [TDFPC] = MAC_ACCESS_PARTIAL, [EECD] = MAC_ACCESS_PARTIAL,
4627
+ [FLA] = MAC_ACCESS_PARTIAL,
4628
+ [FCAL] = MAC_ACCESS_PARTIAL, [FCAH] = MAC_ACCESS_PARTIAL,
4629
+ [FCT] = MAC_ACCESS_PARTIAL, [FCTTV] = MAC_ACCESS_PARTIAL,
4630
+ [FCRTV] = MAC_ACCESS_PARTIAL, [FCRTL] = MAC_ACCESS_PARTIAL,
4631
+ [FCRTH] = MAC_ACCESS_PARTIAL,
4632
+ [MAVTV0 ... MAVTV3] = MAC_ACCESS_PARTIAL
4633
+};
4634
+
4635
+void
4636
+igb_core_write(IGBCore *core, hwaddr addr, uint64_t val, unsigned size)
4637
+{
4638
+ uint16_t index = igb_get_reg_index_with_offset(mac_reg_access, addr);
4639
+
4640
+ if (index < IGB_NWRITEOPS && igb_macreg_writeops[index]) {
4641
+ if (mac_reg_access[index] & MAC_ACCESS_PARTIAL) {
4642
+ trace_e1000e_wrn_regs_write_trivial(index << 2);
4643
+ }
4644
+ trace_e1000e_core_write(index << 2, size, val);
4645
+ igb_macreg_writeops[index](core, index, val);
4646
+ } else if (index < IGB_NREADOPS && igb_macreg_readops[index]) {
4647
+ trace_e1000e_wrn_regs_write_ro(index << 2, size, val);
4648
+ } else {
4649
+ trace_e1000e_wrn_regs_write_unknown(index << 2, size, val);
4650
+ }
4651
+}
4652
+
4653
+uint64_t
4654
+igb_core_read(IGBCore *core, hwaddr addr, unsigned size)
4655
+{
4656
+ uint64_t val;
4657
+ uint16_t index = igb_get_reg_index_with_offset(mac_reg_access, addr);
4658
+
4659
+ if (index < IGB_NREADOPS && igb_macreg_readops[index]) {
4660
+ if (mac_reg_access[index] & MAC_ACCESS_PARTIAL) {
4661
+ trace_e1000e_wrn_regs_read_trivial(index << 2);
4662
+ }
4663
+ val = igb_macreg_readops[index](core, index);
4664
+ trace_e1000e_core_read(index << 2, size, val);
4665
+ return val;
4666
+ } else {
4667
+ trace_e1000e_wrn_regs_read_unknown(index << 2, size);
4668
+ }
4669
+ return 0;
4670
+}
4671
+
4672
+static inline void
4673
+igb_autoneg_pause(IGBCore *core)
4674
+{
4675
+ timer_del(core->autoneg_timer);
4676
+}
4677
+
4678
+static void
4679
+igb_autoneg_resume(IGBCore *core)
4680
+{
4681
+ if (igb_have_autoneg(core) &&
4682
+ !(core->phy[MII_BMSR] & MII_BMSR_AN_COMP)) {
4683
+ qemu_get_queue(core->owner_nic)->link_down = false;
4684
+ timer_mod(core->autoneg_timer,
4685
+ qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
4686
+ }
4687
+}
4688
+
4689
+static void
4690
+igb_vm_state_change(void *opaque, bool running, RunState state)
4691
+{
4692
+ IGBCore *core = opaque;
4693
+
4694
+ if (running) {
4695
+ trace_e1000e_vm_state_running();
4696
+ igb_intrmgr_resume(core);
4697
+ igb_autoneg_resume(core);
4698
+ } else {
4699
+ trace_e1000e_vm_state_stopped();
4700
+ igb_autoneg_pause(core);
4701
+ igb_intrmgr_pause(core);
4702
+ }
4703
+}
4704
+
4705
+void
4706
+igb_core_pci_realize(IGBCore *core,
4707
+ const uint16_t *eeprom_templ,
4708
+ uint32_t eeprom_size,
4709
+ const uint8_t *macaddr)
4710
+{
4711
+ int i;
4712
+
4713
+ core->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
4714
+ igb_autoneg_timer, core);
4715
+ igb_intrmgr_pci_realize(core);
4716
+
4717
+ core->vmstate = qemu_add_vm_change_state_handler(igb_vm_state_change, core);
4718
+
4719
+ for (i = 0; i < IGB_NUM_QUEUES; i++) {
4720
+ net_tx_pkt_init(&core->tx[i].tx_pkt, core->owner, E1000E_MAX_TX_FRAGS);
4721
+ }
4722
+
4723
+ net_rx_pkt_init(&core->rx_pkt);
4724
+
4725
+ e1000x_core_prepare_eeprom(core->eeprom,
4726
+ eeprom_templ,
4727
+ eeprom_size,
4728
+ PCI_DEVICE_GET_CLASS(core->owner)->device_id,
4729
+ macaddr);
4730
+ igb_update_rx_offloads(core);
4731
+}
4732
+
4733
+void
4734
+igb_core_pci_uninit(IGBCore *core)
4735
+{
4736
+ int i;
4737
+
4738
+ timer_free(core->autoneg_timer);
4739
+
4740
+ igb_intrmgr_pci_unint(core);
4741
+
4742
+ qemu_del_vm_change_state_handler(core->vmstate);
4743
+
4744
+ for (i = 0; i < IGB_NUM_QUEUES; i++) {
4745
+ net_tx_pkt_reset(core->tx[i].tx_pkt);
4746
+ net_tx_pkt_uninit(core->tx[i].tx_pkt);
4747
+ }
4748
+
4749
+ net_rx_pkt_uninit(core->rx_pkt);
4750
+}
4751
+
4752
+static const uint16_t
4753
+igb_phy_reg_init[] = {
4754
+ [MII_BMCR] = MII_BMCR_SPEED1000 |
4755
+ MII_BMCR_FD |
4756
+ MII_BMCR_AUTOEN,
4757
+
4758
+ [MII_BMSR] = MII_BMSR_EXTCAP |
4759
+ MII_BMSR_LINK_ST |
4760
+ MII_BMSR_AUTONEG |
4761
+ MII_BMSR_MFPS |
4762
+ MII_BMSR_EXTSTAT |
4763
+ MII_BMSR_10T_HD |
4764
+ MII_BMSR_10T_FD |
4765
+ MII_BMSR_100TX_HD |
4766
+ MII_BMSR_100TX_FD,
4767
+
4768
+ [MII_PHYID1] = IGP03E1000_E_PHY_ID >> 16,
4769
+ [MII_PHYID2] = (IGP03E1000_E_PHY_ID & 0xfff0) | 1,
4770
+ [MII_ANAR] = MII_ANAR_CSMACD | MII_ANAR_10 |
4771
+ MII_ANAR_10FD | MII_ANAR_TX |
4772
+ MII_ANAR_TXFD | MII_ANAR_PAUSE |
4773
+ MII_ANAR_PAUSE_ASYM,
4774
+ [MII_ANLPAR] = MII_ANLPAR_10 | MII_ANLPAR_10FD |
4775
+ MII_ANLPAR_TX | MII_ANLPAR_TXFD |
4776
+ MII_ANLPAR_T4 | MII_ANLPAR_PAUSE,
4777
+ [MII_ANER] = MII_ANER_NP | MII_ANER_NWAY,
4778
+ [MII_ANNP] = 0x1 | MII_ANNP_MP,
4779
+ [MII_CTRL1000] = MII_CTRL1000_HALF | MII_CTRL1000_FULL |
4780
+ MII_CTRL1000_PORT | MII_CTRL1000_MASTER,
4781
+ [MII_STAT1000] = MII_STAT1000_HALF | MII_STAT1000_FULL |
4782
+ MII_STAT1000_ROK | MII_STAT1000_LOK,
4783
+ [MII_EXTSTAT] = MII_EXTSTAT_1000T_HD | MII_EXTSTAT_1000T_FD,
4784
+
4785
+ [IGP01E1000_PHY_PORT_CONFIG] = BIT(5) | BIT(8),
4786
+ [IGP01E1000_PHY_PORT_STATUS] = IGP01E1000_PSSR_SPEED_1000MBPS,
4787
+ [IGP02E1000_PHY_POWER_MGMT] = BIT(0) | BIT(3) | IGP02E1000_PM_D3_LPLU |
4788
+ IGP01E1000_PSCFR_SMART_SPEED
4789
+};
4790
+
4791
+static const uint32_t igb_mac_reg_init[] = {
4792
+ [LEDCTL] = 2 | (3 << 8) | BIT(15) | (6 << 16) | (7 << 24),
4793
+ [EEMNGCTL] = BIT(31),
4794
+ [RXDCTL0] = E1000_RXDCTL_QUEUE_ENABLE | (1 << 16),
4795
+ [RXDCTL1] = 1 << 16,
4796
+ [RXDCTL2] = 1 << 16,
4797
+ [RXDCTL3] = 1 << 16,
4798
+ [RXDCTL4] = 1 << 16,
4799
+ [RXDCTL5] = 1 << 16,
4800
+ [RXDCTL6] = 1 << 16,
4801
+ [RXDCTL7] = 1 << 16,
4802
+ [RXDCTL8] = 1 << 16,
4803
+ [RXDCTL9] = 1 << 16,
4804
+ [RXDCTL10] = 1 << 16,
4805
+ [RXDCTL11] = 1 << 16,
4806
+ [RXDCTL12] = 1 << 16,
4807
+ [RXDCTL13] = 1 << 16,
4808
+ [RXDCTL14] = 1 << 16,
4809
+ [RXDCTL15] = 1 << 16,
4810
+ [TIPG] = 0x08 | (0x04 << 10) | (0x06 << 20),
4811
+ [CTRL] = E1000_CTRL_FD | E1000_CTRL_LRST | E1000_CTRL_SPD_1000 |
4812
+ E1000_CTRL_ADVD3WUC,
4813
+ [STATUS] = E1000_STATUS_PHYRA | BIT(31),
4814
+ [EECD] = E1000_EECD_FWE_DIS | E1000_EECD_PRES |
4815
+ (2 << E1000_EECD_SIZE_EX_SHIFT),
4816
+ [GCR] = E1000_L0S_ADJUST |
4817
+ E1000_GCR_CMPL_TMOUT_RESEND |
4818
+ E1000_GCR_CAP_VER2 |
4819
+ E1000_L1_ENTRY_LATENCY_MSB |
4820
+ E1000_L1_ENTRY_LATENCY_LSB,
4821
+ [RXCSUM] = E1000_RXCSUM_IPOFLD | E1000_RXCSUM_TUOFLD,
4822
+ [TXPBS] = 0x28,
4823
+ [RXPBS] = 0x40,
4824
+ [TCTL] = E1000_TCTL_PSP | (0xF << E1000_CT_SHIFT) |
4825
+ (0x40 << E1000_COLD_SHIFT) | (0x1 << 26) | (0xA << 28),
4826
+ [TCTL_EXT] = 0x40 | (0x42 << 10),
4827
+ [DTXCTL] = E1000_DTXCTL_8023LL | E1000_DTXCTL_SPOOF_INT,
4828
+ [VET] = ETH_P_VLAN | (ETH_P_VLAN << 16),
4829
+
4830
+ [V2PMAILBOX0 ... V2PMAILBOX0 + IGB_MAX_VF_FUNCTIONS - 1] = E1000_V2PMAILBOX_RSTI,
4831
+ [MBVFIMR] = 0xFF,
4832
+ [VFRE] = 0xFF,
4833
+ [VFTE] = 0xFF,
4834
+ [VMOLR0 ... VMOLR0 + 7] = 0x2600 | E1000_VMOLR_STRCRC,
4835
+ [RPLOLR] = E1000_RPLOLR_STRCRC,
4836
+ [RLPML] = 0x2600,
4837
+ [TXCTL0] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4838
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4839
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4840
+ [TXCTL1] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4841
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4842
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4843
+ [TXCTL2] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4844
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4845
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4846
+ [TXCTL3] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4847
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4848
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4849
+ [TXCTL4] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4850
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4851
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4852
+ [TXCTL5] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4853
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4854
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4855
+ [TXCTL6] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4856
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4857
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4858
+ [TXCTL7] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4859
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4860
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4861
+ [TXCTL8] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4862
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4863
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4864
+ [TXCTL9] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4865
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4866
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4867
+ [TXCTL10] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4868
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4869
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4870
+ [TXCTL11] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4871
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4872
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4873
+ [TXCTL12] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4874
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4875
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4876
+ [TXCTL13] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4877
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4878
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4879
+ [TXCTL14] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4880
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4881
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4882
+ [TXCTL15] = E1000_DCA_TXCTRL_DATA_RRO_EN |
4883
+ E1000_DCA_TXCTRL_TX_WB_RO_EN |
4884
+ E1000_DCA_TXCTRL_DESC_RRO_EN,
4885
+};
4886
+
4887
+static void igb_reset(IGBCore *core, bool sw)
4888
+{
4889
+ struct igb_tx *tx;
4890
+ int i;
4891
+
4892
+ timer_del(core->autoneg_timer);
4893
+
4894
+ igb_intrmgr_reset(core);
4895
+
4896
+ memset(core->phy, 0, sizeof core->phy);
4897
+ memcpy(core->phy, igb_phy_reg_init, sizeof igb_phy_reg_init);
4898
+
4899
+ for (i = 0; i < E1000E_MAC_SIZE; i++) {
4900
+ if (sw &&
4901
+ (i == RXPBS || i == TXPBS ||
4902
+ (i >= EITR0 && i < EITR0 + IGB_INTR_NUM))) {
4903
+ continue;
4904
+ }
4905
+
4906
+ core->mac[i] = i < ARRAY_SIZE(igb_mac_reg_init) ?
4907
+ igb_mac_reg_init[i] : 0;
4908
+ }
4909
+
4910
+ if (qemu_get_queue(core->owner_nic)->link_down) {
4911
+ igb_link_down(core);
4912
+ }
4913
+
4914
+ e1000x_reset_mac_addr(core->owner_nic, core->mac, core->permanent_mac);
4915
+
4916
+ for (i = 0; i < ARRAY_SIZE(core->tx); i++) {
4917
+ tx = &core->tx[i];
4918
+ net_tx_pkt_reset(tx->tx_pkt);
4919
+ tx->vlan = 0;
4920
+ tx->mss = 0;
4921
+ tx->tse = false;
4922
+ tx->ixsm = false;
4923
+ tx->txsm = false;
4924
+ tx->first = true;
4925
+ tx->skip_cp = false;
4926
+ }
4927
+}
4928
+
4929
+void
4930
+igb_core_reset(IGBCore *core)
4931
+{
4932
+ igb_reset(core, false);
4933
+}
4934
+
4935
+void igb_core_pre_save(IGBCore *core)
4936
+{
4937
+ int i;
4938
+ NetClientState *nc = qemu_get_queue(core->owner_nic);
4939
+
4940
+ /*
4941
+ * If link is down and auto-negotiation is supported and ongoing,
4942
+ * complete auto-negotiation immediately. This allows us to look
4943
+ * at MII_BMSR_AN_COMP to infer link status on load.
4944
+ */
4945
+ if (nc->link_down && igb_have_autoneg(core)) {
4946
+ core->phy[MII_BMSR] |= MII_BMSR_AN_COMP;
4947
+ igb_update_flowctl_status(core);
4948
+ }
4949
+
4950
+ for (i = 0; i < ARRAY_SIZE(core->tx); i++) {
4951
+ if (net_tx_pkt_has_fragments(core->tx[i].tx_pkt)) {
4952
+ core->tx[i].skip_cp = true;
4953
+ }
4954
+ }
4955
+}
4956
+
4957
+int
4958
+igb_core_post_load(IGBCore *core)
4959
+{
4960
+ NetClientState *nc = qemu_get_queue(core->owner_nic);
4961
+
4962
+ /*
4963
+ * nc.link_down can't be migrated, so infer link_down according
4964
+ * to link status bit in core.mac[STATUS].
4965
+ */
4966
+ nc->link_down = (core->mac[STATUS] & E1000_STATUS_LU) == 0;
4967
+
4968
+ return 0;
4969
+}
4970
diff --git a/hw/net/igb_core.h b/hw/net/igb_core.h
4971
new file mode 100644
4972
index XXXXXXX..XXXXXXX
4973
--- /dev/null
4974
+++ b/hw/net/igb_core.h
4975
@@ -XXX,XX +XXX,XX @@
389
@@ -XXX,XX +XXX,XX @@
4976
+/*
390
4977
+ * Core code for QEMU igb emulation
391
#include <gmodule.h>
4978
+ *
392
4979
+ * Datasheet:
393
+#include "hw/virtio/vhost-iova-tree.h"
4980
+ * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82576eg-gbe-datasheet.pdf
394
#include "hw/virtio/virtio.h"
4981
+ *
395
#include "standard-headers/linux/vhost_types.h"
4982
+ * Copyright (c) 2020-2023 Red Hat, Inc.
396
4983
+ * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
397
@@ -XXX,XX +XXX,XX @@ typedef struct vhost_vdpa {
4984
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
398
MemoryListener listener;
4985
+ *
399
struct vhost_vdpa_iova_range iova_range;
4986
+ * Authors:
400
bool shadow_vqs_enabled;
4987
+ * Akihiko Odaki <akihiko.odaki@daynix.com>
401
+ /* IOVA mapping used by the Shadow Virtqueue */
4988
+ * Gal Hammmer <gal.hammer@sap.com>
402
+ VhostIOVATree *iova_tree;
4989
+ * Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
403
GPtrArray *shadow_vqs;
4990
+ * Dmitry Fleytman <dmitry@daynix.com>
404
struct vhost_dev *dev;
4991
+ * Leonid Bloch <leonid@daynix.com>
405
VhostVDPAHostNotifier notifier[VIRTIO_QUEUE_MAX];
4992
+ * Yan Vugenfirer <yan@daynix.com>
4993
+ *
4994
+ * Based on work done by:
4995
+ * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
4996
+ * Copyright (c) 2008 Qumranet
4997
+ * Based on work done by:
4998
+ * Copyright (c) 2007 Dan Aloni
4999
+ * Copyright (c) 2004 Antony T Curtis
5000
+ *
5001
+ * This library is free software; you can redistribute it and/or
5002
+ * modify it under the terms of the GNU Lesser General Public
5003
+ * License as published by the Free Software Foundation; either
5004
+ * version 2.1 of the License, or (at your option) any later version.
5005
+ *
5006
+ * This library is distributed in the hope that it will be useful,
5007
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5008
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5009
+ * Lesser General Public License for more details.
5010
+ *
5011
+ * You should have received a copy of the GNU Lesser General Public
5012
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
5013
+ */
5014
+
5015
+#ifndef HW_NET_IGB_CORE_H
5016
+#define HW_NET_IGB_CORE_H
5017
+
5018
+#define E1000E_MAC_SIZE (0x8000)
5019
+#define IGB_EEPROM_SIZE (1024)
5020
+
5021
+#define IGB_INTR_NUM (25)
5022
+#define IGB_MSIX_VEC_NUM (10)
5023
+#define IGBVF_MSIX_VEC_NUM (3)
5024
+#define IGB_NUM_QUEUES (16)
5025
+
5026
+typedef struct IGBCore IGBCore;
5027
+
5028
+enum { PHY_R = BIT(0),
5029
+ PHY_W = BIT(1),
5030
+ PHY_RW = PHY_R | PHY_W };
5031
+
5032
+typedef struct IGBIntrDelayTimer_st {
5033
+ QEMUTimer *timer;
5034
+ bool running;
5035
+ uint32_t delay_reg;
5036
+ uint32_t delay_resolution_ns;
5037
+ IGBCore *core;
5038
+} IGBIntrDelayTimer;
5039
+
5040
+struct IGBCore {
5041
+ uint32_t mac[E1000E_MAC_SIZE];
5042
+ uint16_t phy[MAX_PHY_REG_ADDRESS + 1];
5043
+ uint16_t eeprom[IGB_EEPROM_SIZE];
5044
+
5045
+ uint8_t rx_desc_len;
5046
+
5047
+ QEMUTimer *autoneg_timer;
5048
+
5049
+ struct igb_tx {
5050
+ uint16_t vlan; /* VLAN Tag */
5051
+ uint16_t mss; /* Maximum Segment Size */
5052
+ bool tse; /* TCP/UDP Segmentation Enable */
5053
+ bool ixsm; /* Insert IP Checksum */
5054
+ bool txsm; /* Insert TCP/UDP Checksum */
5055
+
5056
+ bool first;
5057
+ bool skip_cp;
5058
+
5059
+ struct NetTxPkt *tx_pkt;
5060
+ } tx[IGB_NUM_QUEUES];
5061
+
5062
+ struct NetRxPkt *rx_pkt;
5063
+
5064
+ bool has_vnet;
5065
+ int max_queue_num;
5066
+
5067
+ IGBIntrDelayTimer eitr[IGB_INTR_NUM];
5068
+
5069
+ VMChangeStateEntry *vmstate;
5070
+
5071
+ uint32_t eitr_guest_value[IGB_INTR_NUM];
5072
+
5073
+ uint8_t permanent_mac[ETH_ALEN];
5074
+
5075
+ NICState *owner_nic;
5076
+ PCIDevice *owner;
5077
+ void (*owner_start_recv)(PCIDevice *d);
5078
+
5079
+ int64_t timadj;
5080
+};
5081
+
5082
+void
5083
+igb_core_write(IGBCore *core, hwaddr addr, uint64_t val, unsigned size);
5084
+
5085
+uint64_t
5086
+igb_core_read(IGBCore *core, hwaddr addr, unsigned size);
5087
+
5088
+void
5089
+igb_core_pci_realize(IGBCore *regs,
5090
+ const uint16_t *eeprom_templ,
5091
+ uint32_t eeprom_size,
5092
+ const uint8_t *macaddr);
5093
+
5094
+void
5095
+igb_core_reset(IGBCore *core);
5096
+
5097
+void
5098
+igb_core_pre_save(IGBCore *core);
5099
+
5100
+int
5101
+igb_core_post_load(IGBCore *core);
5102
+
5103
+void
5104
+igb_core_set_link_status(IGBCore *core);
5105
+
5106
+void
5107
+igb_core_pci_uninit(IGBCore *core);
5108
+
5109
+bool
5110
+igb_can_receive(IGBCore *core);
5111
+
5112
+ssize_t
5113
+igb_receive(IGBCore *core, const uint8_t *buf, size_t size);
5114
+
5115
+ssize_t
5116
+igb_receive_iov(IGBCore *core, const struct iovec *iov, int iovcnt);
5117
+
5118
+void
5119
+igb_start_recv(IGBCore *core);
5120
+
5121
+#endif
5122
diff --git a/hw/net/igb_regs.h b/hw/net/igb_regs.h
5123
new file mode 100644
5124
index XXXXXXX..XXXXXXX
5125
--- /dev/null
5126
+++ b/hw/net/igb_regs.h
5127
@@ -XXX,XX +XXX,XX @@
5128
+/* SPDX-License-Identifier: GPL-2.0 */
5129
+/*
5130
+ * This is copied + edited from kernel header files in
5131
+ * drivers/net/ethernet/intel/igb
5132
+ */
5133
+
5134
+#ifndef HW_IGB_REGS_H_
5135
+#define HW_IGB_REGS_H_
5136
+
5137
+#include "e1000x_regs.h"
5138
+
5139
+/* from igb/e1000_hw.h */
5140
+
5141
+#define E1000_DEV_ID_82576 0x10C9
5142
+#define E1000_DEV_ID_82576_FIBER 0x10E6
5143
+#define E1000_DEV_ID_82576_SERDES 0x10E7
5144
+#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
5145
+#define E1000_DEV_ID_82576_QUAD_COPPER_ET2 0x1526
5146
+#define E1000_DEV_ID_82576_NS 0x150A
5147
+#define E1000_DEV_ID_82576_NS_SERDES 0x1518
5148
+#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D
5149
+
5150
+/* Context Descriptor */
5151
+struct e1000_adv_tx_context_desc {
5152
+ uint32_t vlan_macip_lens;
5153
+ uint32_t seqnum_seed;
5154
+ uint32_t type_tucmd_mlhl;
5155
+ uint32_t mss_l4len_idx;
5156
+};
5157
+
5158
+/* Advanced Transmit Descriptor */
5159
+union e1000_adv_tx_desc {
5160
+ struct {
5161
+ uint64_t buffer_addr; /* Address of descriptor's data buffer */
5162
+ uint32_t cmd_type_len;
5163
+ uint32_t olinfo_status;
5164
+ } read;
5165
+ struct {
5166
+ uint64_t rsvd; /* Reserved */
5167
+ uint32_t nxtseq_seed;
5168
+ uint32_t status;
5169
+ } wb;
5170
+};
5171
+
5172
+#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
5173
+#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
5174
+#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor Extension (1=Adv) */
5175
+#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP/UDP Segmentation Enable */
5176
+
5177
+#define E1000_ADVTXD_POTS_IXSM 0x00000100 /* Insert TCP/UDP Checksum */
5178
+#define E1000_ADVTXD_POTS_TXSM 0x00000200 /* Insert TCP/UDP Checksum */
5179
+
5180
+#define E1000_TXD_POPTS_IXSM 0x00000001 /* Insert IP checksum */
5181
+#define E1000_TXD_POPTS_TXSM 0x00000002 /* Insert TCP/UDP checksum */
5182
+
5183
+/* Receive Descriptor - Advanced */
5184
+union e1000_adv_rx_desc {
5185
+ struct {
5186
+ uint64_t pkt_addr; /* Packet Buffer Address */
5187
+ uint64_t hdr_addr; /* Header Buffer Address */
5188
+ } read;
5189
+ struct {
5190
+ struct {
5191
+ struct {
5192
+ uint16_t pkt_info; /* RSS Type, Packet Type */
5193
+ uint16_t hdr_info; /* Split Head, Buffer Length */
5194
+ } lo_dword;
5195
+ union {
5196
+ uint32_t rss; /* RSS Hash */
5197
+ struct {
5198
+ uint16_t ip_id; /* IP Id */
5199
+ uint16_t csum; /* Packet Checksum */
5200
+ } csum_ip;
5201
+ } hi_dword;
5202
+ } lower;
5203
+ struct {
5204
+ uint32_t status_error; /* Ext Status/Error */
5205
+ uint16_t length; /* Packet Length */
5206
+ uint16_t vlan; /* VLAN tag */
5207
+ } upper;
5208
+ } wb; /* writeback */
5209
+};
5210
+
5211
+/* from igb/e1000_phy.h */
5212
+
5213
+/* IGP01E1000 Specific Registers */
5214
+#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
5215
+#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */
5216
+#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
5217
+#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
5218
+#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
5219
+#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
5220
+#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
5221
+#define IGP01E1000_PHY_POLARITY_MASK 0x0078
5222
+#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
5223
+#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */
5224
+#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
5225
+
5226
+/* Enable flexible speed on link-up */
5227
+#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
5228
+#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
5229
+#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
5230
+#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
5231
+#define IGP01E1000_PSSR_MDIX 0x0800
5232
+#define IGP01E1000_PSSR_SPEED_MASK 0xC000
5233
+#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
5234
+#define IGP02E1000_PHY_CHANNEL_NUM 4
5235
+#define IGP02E1000_PHY_AGC_A 0x11B1
5236
+#define IGP02E1000_PHY_AGC_B 0x12B1
5237
+#define IGP02E1000_PHY_AGC_C 0x14B1
5238
+#define IGP02E1000_PHY_AGC_D 0x18B1
5239
+#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */
5240
+#define IGP02E1000_AGC_LENGTH_MASK 0x7F
5241
+#define IGP02E1000_AGC_RANGE 15
5242
+
5243
+/* from igb/igb.h */
5244
+
5245
+#define E1000_PCS_CFG_IGN_SD 1
5246
+
5247
+/* Interrupt defines */
5248
+#define IGB_START_ITR 648 /* ~6000 ints/sec */
5249
+#define IGB_4K_ITR 980
5250
+#define IGB_20K_ITR 196
5251
+#define IGB_70K_ITR 56
5252
+
5253
+/* TX/RX descriptor defines */
5254
+#define IGB_DEFAULT_TXD 256
5255
+#define IGB_DEFAULT_TX_WORK 128
5256
+#define IGB_MIN_TXD 80
5257
+#define IGB_MAX_TXD 4096
5258
+
5259
+#define IGB_DEFAULT_RXD 256
5260
+#define IGB_MIN_RXD 80
5261
+#define IGB_MAX_RXD 4096
5262
+
5263
+#define IGB_DEFAULT_ITR 3 /* dynamic */
5264
+#define IGB_MAX_ITR_USECS 10000
5265
+#define IGB_MIN_ITR_USECS 10
5266
+#define NON_Q_VECTORS 1
5267
+#define MAX_Q_VECTORS 8
5268
+#define MAX_MSIX_ENTRIES 10
5269
+
5270
+/* Transmit and receive queues */
5271
+#define IGB_MAX_RX_QUEUES 8
5272
+#define IGB_MAX_RX_QUEUES_82575 4
5273
+#define IGB_MAX_RX_QUEUES_I211 2
5274
+#define IGB_MAX_TX_QUEUES 8
5275
+#define IGB_MAX_VF_MC_ENTRIES 30
5276
+#define IGB_MAX_VF_FUNCTIONS 8
5277
+#define IGB_MAX_VFTA_ENTRIES 128
5278
+#define IGB_82576_VF_DEV_ID 0x10CA
5279
+#define IGB_I350_VF_DEV_ID 0x1520
5280
+
5281
+/* from igb/e1000_82575.h */
5282
+
5283
+#define E1000_MRQC_ENABLE_RSS_MQ 0x00000002
5284
+#define E1000_MRQC_ENABLE_VMDQ 0x00000003
5285
+#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
5286
+#define E1000_MRQC_ENABLE_VMDQ_RSS_MQ 0x00000005
5287
+#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
5288
+#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
5289
+
5290
+/* Additional Receive Descriptor Control definitions */
5291
+#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
5292
+
5293
+/* Direct Cache Access (DCA) definitions */
5294
+#define E1000_DCA_CTRL_DCA_MODE_DISABLE 0x01 /* DCA Disable */
5295
+#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
5296
+
5297
+#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
5298
+#define E1000_DCA_RXCTRL_DESC_DCA_EN BIT(5) /* DCA Rx Desc enable */
5299
+#define E1000_DCA_RXCTRL_HEAD_DCA_EN BIT(6) /* DCA Rx Desc header enable */
5300
+#define E1000_DCA_RXCTRL_DATA_DCA_EN BIT(7) /* DCA Rx Desc payload enable */
5301
+#define E1000_DCA_RXCTRL_DESC_RRO_EN BIT(9) /* DCA Rx rd Desc Relax Order */
5302
+
5303
+#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
5304
+#define E1000_DCA_TXCTRL_DESC_DCA_EN BIT(5) /* DCA Tx Desc enable */
5305
+#define E1000_DCA_TXCTRL_DESC_RRO_EN BIT(9) /* Tx rd Desc Relax Order */
5306
+#define E1000_DCA_TXCTRL_TX_WB_RO_EN BIT(11) /* Tx Desc writeback RO bit */
5307
+#define E1000_DCA_TXCTRL_DATA_RRO_EN BIT(13) /* Tx rd data Relax Order */
5308
+
5309
+/* Additional DCA related definitions, note change in position of CPUID */
5310
+#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */
5311
+#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */
5312
+#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
5313
+#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
5314
+
5315
+#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof control */
5316
+#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof control */
5317
+#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */
5318
+#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8
5319
+#define E1000_DTXSWC_VMDQ_LOOPBACK_EN BIT(31) /* global VF LB enable */
5320
+
5321
+/* Easy defines for setting default pool, would normally be left a zero */
5322
+#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7
5323
+#define E1000_VT_CTL_DEFAULT_POOL_MASK (0x7 << E1000_VT_CTL_DEFAULT_POOL_SHIFT)
5324
+
5325
+/* Other useful VMD_CTL register defines */
5326
+#define E1000_VT_CTL_IGNORE_MAC BIT(28)
5327
+#define E1000_VT_CTL_DISABLE_DEF_POOL BIT(29)
5328
+#define E1000_VT_CTL_VM_REPL_EN BIT(30)
5329
+
5330
+/* Per VM Offload register setup */
5331
+#define E1000_VMOLR_RLPML_MASK 0x00003FFF /* Long Packet Maximum Length mask */
5332
+#define E1000_VMOLR_LPE 0x00010000 /* Accept Long packet */
5333
+#define E1000_VMOLR_RSSE 0x00020000 /* Enable RSS */
5334
+#define E1000_VMOLR_AUPE 0x01000000 /* Accept untagged packets */
5335
+#define E1000_VMOLR_ROMPE 0x02000000 /* Accept overflow multicast */
5336
+#define E1000_VMOLR_ROPE 0x04000000 /* Accept overflow unicast */
5337
+#define E1000_VMOLR_BAM 0x08000000 /* Accept Broadcast packets */
5338
+#define E1000_VMOLR_MPME 0x10000000 /* Multicast promiscuous mode */
5339
+#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
5340
+#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */
5341
+
5342
+#define E1000_DVMOLR_HIDEVLAN 0x20000000 /* Hide vlan enable */
5343
+#define E1000_DVMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
5344
+#define E1000_DVMOLR_STRCRC 0x80000000 /* CRC stripping enable */
5345
+
5346
+#define E1000_VLVF_ARRAY_SIZE 32
5347
+#define E1000_VLVF_VLANID_MASK 0x00000FFF
5348
+#define E1000_VLVF_POOLSEL_SHIFT 12
5349
+#define E1000_VLVF_POOLSEL_MASK (0xFF << E1000_VLVF_POOLSEL_SHIFT)
5350
+#define E1000_VLVF_LVLAN 0x00100000
5351
+#define E1000_VLVF_VLANID_ENABLE 0x80000000
5352
+
5353
+#define E1000_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */
5354
+#define E1000_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */
5355
+
5356
+#define E1000_IOVCTL 0x05BBC
5357
+#define E1000_IOVCTL_REUSE_VFQ 0x00000001
5358
+
5359
+#define E1000_RPLOLR_STRVLAN 0x40000000
5360
+#define E1000_RPLOLR_STRCRC 0x80000000
5361
+
5362
+#define E1000_DTXCTL_8023LL 0x0004
5363
+#define E1000_DTXCTL_VLAN_ADDED 0x0008
5364
+#define E1000_DTXCTL_OOS_ENABLE 0x0010
5365
+#define E1000_DTXCTL_MDP_EN 0x0020
5366
+#define E1000_DTXCTL_SPOOF_INT 0x0040
5367
+
5368
+/* from igb/e1000_defines.h */
5369
+
5370
+#define E1000_IVAR_VALID 0x80
5371
+#define E1000_GPIE_NSICR 0x00000001
5372
+#define E1000_GPIE_MSIX_MODE 0x00000010
5373
+#define E1000_GPIE_EIAME 0x40000000
5374
+#define E1000_GPIE_PBA 0x80000000
5375
+
5376
+/* Transmit Control */
5377
+#define E1000_TCTL_EN 0x00000002 /* enable tx */
5378
+#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
5379
+#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
5380
+#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
5381
+#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
5382
+
5383
+/* Collision related configuration parameters */
5384
+#define E1000_COLLISION_THRESHOLD 15
5385
+#define E1000_CT_SHIFT 4
5386
+#define E1000_COLLISION_DISTANCE 63
5387
+#define E1000_COLD_SHIFT 12
5388
+
5389
+#define E1000_RAH_POOL_MASK 0x03FC0000
5390
+#define E1000_RAH_POOL_1 0x00040000
5391
+
5392
+#define E1000_ICR_VMMB 0x00000100 /* VM MB event */
5393
+#define E1000_ICR_TS 0x00080000 /* Time Sync Interrupt */
5394
+#define E1000_ICR_DRSTA 0x40000000 /* Device Reset Asserted */
5395
+/* If this bit asserted, the driver should claim the interrupt */
5396
+#define E1000_ICR_INT_ASSERTED 0x80000000
5397
+/* LAN connected device generates an interrupt */
5398
+#define E1000_ICR_DOUTSYNC 0x10000000 /* NIC DMA out of sync */
5399
+
5400
+/* Extended Interrupt Cause Read */
5401
+#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */
5402
+#define E1000_EICR_RX_QUEUE1 0x00000002 /* Rx Queue 1 Interrupt */
5403
+#define E1000_EICR_RX_QUEUE2 0x00000004 /* Rx Queue 2 Interrupt */
5404
+#define E1000_EICR_RX_QUEUE3 0x00000008 /* Rx Queue 3 Interrupt */
5405
+#define E1000_EICR_TX_QUEUE0 0x00000100 /* Tx Queue 0 Interrupt */
5406
+#define E1000_EICR_TX_QUEUE1 0x00000200 /* Tx Queue 1 Interrupt */
5407
+#define E1000_EICR_TX_QUEUE2 0x00000400 /* Tx Queue 2 Interrupt */
5408
+#define E1000_EICR_TX_QUEUE3 0x00000800 /* Tx Queue 3 Interrupt */
5409
+#define E1000_EICR_OTHER 0x80000000 /* Interrupt Cause Active */
5410
+
5411
+/* Extended Interrupt Cause Set */
5412
+/* E1000_EITR_CNT_IGNR is only for 82576 and newer */
5413
+#define E1000_EITR_CNT_IGNR 0x80000000 /* Don't reset counters on write */
5414
+
5415
+/* PCI Express Control */
5416
+#define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000
5417
+#define E1000_GCR_CMPL_TMOUT_10ms 0x00001000
5418
+#define E1000_GCR_CMPL_TMOUT_RESEND 0x00010000
5419
+#define E1000_GCR_CAP_VER2 0x00040000
5420
+
5421
+#define PHY_REVISION_MASK 0xFFFFFFF0
5422
+#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
5423
+#define MAX_PHY_MULTI_PAGE_REG 0xF
5424
+
5425
+#define IGP03E1000_E_PHY_ID 0x02A80390
5426
+
5427
+/* from igb/e1000_mbox.h */
5428
+
5429
+#define E1000_P2VMAILBOX_STS 0x00000001 /* Initiate message send to VF */
5430
+#define E1000_P2VMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */
5431
+#define E1000_P2VMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
5432
+#define E1000_P2VMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
5433
+#define E1000_P2VMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */
5434
+
5435
+#define E1000_MBVFICR_VFREQ_MASK 0x000000FF /* bits for VF messages */
5436
+#define E1000_MBVFICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */
5437
+#define E1000_MBVFICR_VFACK_MASK 0x00FF0000 /* bits for VF acks */
5438
+#define E1000_MBVFICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */
5439
+
5440
+#define E1000_V2PMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
5441
+
5442
+/*
5443
+ * If it's a E1000_VF_* msg then it originates in the VF and is sent to the
5444
+ * PF. The reverse is true if it is E1000_PF_*.
5445
+ * Message ACK's are the value or'd with 0xF0000000
5446
+ */
5447
+/* Messages below or'd with this are the ACK */
5448
+#define E1000_VT_MSGTYPE_ACK 0x80000000
5449
+/* Messages below or'd with this are the NACK */
5450
+#define E1000_VT_MSGTYPE_NACK 0x40000000
5451
+/* Indicates that VF is still clear to send requests */
5452
+#define E1000_VT_MSGTYPE_CTS 0x20000000
5453
+#define E1000_VT_MSGINFO_SHIFT 16
5454
+/* bits 23:16 are used for exra info for certain messages */
5455
+#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT)
5456
+
5457
+#define E1000_VF_RESET 0x01 /* VF requests reset */
5458
+#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests to set MAC addr */
5459
+/* VF requests to clear all unicast MAC filters */
5460
+#define E1000_VF_MAC_FILTER_CLR (0x01 << E1000_VT_MSGINFO_SHIFT)
5461
+/* VF requests to add unicast MAC filter */
5462
+#define E1000_VF_MAC_FILTER_ADD (0x02 << E1000_VT_MSGINFO_SHIFT)
5463
+#define E1000_VF_SET_MULTICAST 0x03 /* VF requests to set MC addr */
5464
+#define E1000_VF_SET_VLAN 0x04 /* VF requests to set VLAN */
5465
+#define E1000_VF_SET_LPE 0x05 /* VF requests to set VMOLR.LPE */
5466
+#define E1000_VF_SET_PROMISC 0x06 /*VF requests to clear VMOLR.ROPE/MPME*/
5467
+#define E1000_VF_SET_PROMISC_MULTICAST (0x02 << E1000_VT_MSGINFO_SHIFT)
5468
+
5469
+#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */
5470
+
5471
+/* from igb/e1000_regs.h */
5472
+
5473
+#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */
5474
+#define E1000_EITR(_n) (0x01680 + (0x4 * (_n)))
5475
+#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
5476
+#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
5477
+#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
5478
+#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
5479
+#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
5480
+#define E1000_GPIE 0x01514 /* General Purpose Interrupt Enable; RW */
5481
+#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation Register - RW */
5482
+#define E1000_IVAR_MISC 0x01740 /* Interrupt Vector Allocation Register (last) - RW */
5483
+#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
5484
+#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
5485
+
5486
+#define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40))
5487
+
5488
+#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
5489
+#define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */
5490
+
5491
+#define E1000_DTXCTL 0x03590 /* DMA TX Control - RW */
5492
+
5493
+#define E1000_HTCBDPC 0x04124 /* Host TX Circuit Breaker Dropped Count */
5494
+#define E1000_RLPML 0x05004 /* RX Long Packet Max Length */
5495
+#define E1000_RA2 0x054E0 /* 2nd half of Rx address array - RW Array */
5496
+#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4))
5497
+#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */
5498
+
5499
+/* VT Registers */
5500
+#define E1000_MBVFICR 0x00C80 /* Mailbox VF Cause - RWC */
5501
+#define E1000_MBVFIMR 0x00C84 /* Mailbox VF int Mask - RW */
5502
+#define E1000_VFLRE 0x00C88 /* VF Register Events - RWC */
5503
+#define E1000_VFRE 0x00C8C /* VF Receive Enables */
5504
+#define E1000_VFTE 0x00C90 /* VF Transmit Enables */
5505
+#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */
5506
+#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */
5507
+#define E1000_WVBR 0x03554 /* VM Wrong Behavior - RWS */
5508
+#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */
5509
+#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */
5510
+#define E1000_IOVTCL 0x05BBC /* IOV Control Register */
5511
+#define E1000_TXSWC 0x05ACC /* Tx Switch Control */
5512
+#define E1000_LVMMC 0x03548 /* Last VM Misbehavior cause */
5513
+/* These act per VF so an array friendly macro is used */
5514
+#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n)))
5515
+#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
5516
+#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n)))
5517
+#define E1000_DVMOLR(_n) (0x0C038 + (64 * (_n)))
5518
+#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN VM Filter */
5519
+#define E1000_VMVIR(_n) (0x03700 + (4 * (_n)))
5520
+
5521
+/* from igbvf/defines.h */
5522
+
5523
+/* SRRCTL bit definitions */
5524
+#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
5525
+#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00
5526
+#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
5527
+#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
5528
+#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
5529
+#define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000
5530
+#define E1000_SRRCTL_DROP_EN 0x80000000
5531
+
5532
+#define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F
5533
+#define E1000_SRRCTL_BSIZEHDR_MASK 0x00003F00
5534
+
5535
+/* from igbvf/mbox.h */
5536
+
5537
+#define E1000_V2PMAILBOX_REQ 0x00000001 /* Request for PF Ready bit */
5538
+#define E1000_V2PMAILBOX_ACK 0x00000002 /* Ack PF message received */
5539
+#define E1000_V2PMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */
5540
+#define E1000_V2PMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */
5541
+#define E1000_V2PMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */
5542
+#define E1000_V2PMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */
5543
+#define E1000_V2PMAILBOX_RSTI 0x00000040 /* PF has reset indication */
5544
+#define E1000_V2PMAILBOX_RSTD 0x00000080 /* PF has indicated reset done */
5545
+#define E1000_V2PMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */
5546
+
5547
+#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */
5548
+
5549
+/*
5550
+ * If it's a E1000_VF_* msg then it originates in the VF and is sent to the
5551
+ * PF. The reverse is true if it is E1000_PF_*.
5552
+ * Message ACK's are the value or'd with 0xF0000000
5553
+ */
5554
+/* Messages below or'd with this are the ACK */
5555
+#define E1000_VT_MSGTYPE_ACK 0x80000000
5556
+/* Messages below or'd with this are the NACK */
5557
+#define E1000_VT_MSGTYPE_NACK 0x40000000
5558
+/* Indicates that VF is still clear to send requests */
5559
+#define E1000_VT_MSGTYPE_CTS 0x20000000
5560
+
5561
+/* We have a total wait time of 1s for vf mailbox posted messages */
5562
+#define E1000_VF_MBX_INIT_TIMEOUT 2000 /* retry count for mbx timeout */
5563
+#define E1000_VF_MBX_INIT_DELAY 500 /* usec delay between retries */
5564
+
5565
+#define E1000_VT_MSGINFO_SHIFT 16
5566
+/* bits 23:16 are used for exra info for certain messages */
5567
+#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT)
5568
+
5569
+#define E1000_VF_RESET 0x01 /* VF requests reset */
5570
+#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */
5571
+/* VF requests PF to clear all unicast MAC filters */
5572
+#define E1000_VF_MAC_FILTER_CLR (0x01 << E1000_VT_MSGINFO_SHIFT)
5573
+/* VF requests PF to add unicast MAC filter */
5574
+#define E1000_VF_MAC_FILTER_ADD (0x02 << E1000_VT_MSGINFO_SHIFT)
5575
+#define E1000_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
5576
+#define E1000_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
5577
+#define E1000_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
5578
+
5579
+#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */
5580
+
5581
+/* from igbvf/regs.h */
5582
+
5583
+/* Statistics registers */
5584
+#define E1000_VFGPRC 0x00F10
5585
+#define E1000_VFGORC 0x00F18
5586
+#define E1000_VFMPRC 0x00F3C
5587
+#define E1000_VFGPTC 0x00F14
5588
+#define E1000_VFGOTC 0x00F34
5589
+#define E1000_VFGOTLBC 0x00F50
5590
+#define E1000_VFGPTLBC 0x00F44
5591
+#define E1000_VFGORLBC 0x00F48
5592
+#define E1000_VFGPRLBC 0x00F40
5593
+
5594
+/* These act per VF so an array friendly macro is used */
5595
+#define E1000_V2PMAILBOX(_n) (0x00C40 + (4 * (_n)))
5596
+#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
5597
+
5598
+/* from igbvf/vf.h */
5599
+
5600
+#define E1000_DEV_ID_82576_VF 0x10CA
5601
+
5602
+/* new */
5603
+
5604
+/* Receive Registers */
5605
+
5606
+/* RX Descriptor Base Low; RW */
5607
+#define E1000_RDBAL(_n) (0x0C000 + (0x40 * (_n)))
5608
+#define E1000_RDBAL_A(_n) (0x02800 + (0x100 * (_n)))
5609
+
5610
+/* RX Descriptor Base High; RW */
5611
+#define E1000_RDBAH(_n) (0x0C004 + (0x40 * (_n)))
5612
+#define E1000_RDBAH_A(_n) (0x02804 + (0x100 * (_n)))
5613
+
5614
+/* RX Descriptor Ring Length; RW */
5615
+#define E1000_RDLEN(_n) (0x0C008 + (0x40 * (_n)))
5616
+#define E1000_RDLEN_A(_n) (0x02808 + (0x100 * (_n)))
5617
+
5618
+/* Split and Replication Receive Control; RW */
5619
+#define E1000_SRRCTL(_n) (0x0C00C + (0x40 * (_n)))
5620
+#define E1000_SRRCTL_A(_n) (0x0280C + (0x100 * (_n)))
5621
+
5622
+/* RX Descriptor Head; RW */
5623
+#define E1000_RDH(_n) (0x0C010 + (0x40 * (_n)))
5624
+#define E1000_RDH_A(_n) (0x02810 + (0x100 * (_n)))
5625
+
5626
+/* RX DCA Control; RW */
5627
+#define E1000_RXCTL(_n) (0x0C014 + (0x40 * (_n)))
5628
+#define E1000_RXCTL_A(_n) (0x02814 + (0x100 * (_n)))
5629
+
5630
+/* RX Descriptor Tail; RW */
5631
+#define E1000_RDT(_n) (0x0C018 + (0x40 * (_n)))
5632
+#define E1000_RDT_A(_n) (0x02818 + (0x100 * (_n)))
5633
+
5634
+/* RX Descriptor Control; RW */
5635
+#define E1000_RXDCTL(_n) (0x0C028 + (0x40 * (_n)))
5636
+#define E1000_RXDCTL_A(_n) (0x02828 + (0x100 * (_n)))
5637
+
5638
+/* RX Queue Drop Packet Count; RC */
5639
+#define E1000_RQDPC_A(_n) (0x02830 + (0x100 * (_n)))
5640
+
5641
+/* Transmit Registers */
5642
+
5643
+/* TX Descriptor Base Low; RW */
5644
+#define E1000_TDBAL(_n) (0x0E000 + (0x40 * (_n)))
5645
+#define E1000_TDBAL_A(_n) (0x03800 + (0x100 * (_n)))
5646
+
5647
+/* TX Descriptor Base High; RW */
5648
+#define E1000_TDBAH(_n) (0x0E004 + (0x40 * (_n)))
5649
+#define E1000_TDBAH_A(_n) (0x03804 + (0x100 * (_n)))
5650
+
5651
+/* TX Descriptor Ring Length; RW */
5652
+#define E1000_TDLEN(_n) (0x0E008 + (0x40 * (_n)))
5653
+#define E1000_TDLEN_A(_n) (0x03808 + (0x100 * (_n)))
5654
+
5655
+/* TX Descriptor Head; RW */
5656
+#define E1000_TDH(_n) (0x0E010 + (0x40 * (_n)))
5657
+#define E1000_TDH_A(_n) (0x03810 + (0x100 * (_n)))
5658
+
5659
+/* TX DCA Control; RW */
5660
+#define E1000_TXCTL(_n) (0x0E014 + (0x40 * (_n)))
5661
+#define E1000_TXCTL_A(_n) (0x03814 + (0x100 * (_n)))
5662
+
5663
+/* TX Descriptor Tail; RW */
5664
+#define E1000_TDT(_n) (0x0E018 + (0x40 * (_n)))
5665
+#define E1000_TDT_A(_n) (0x03818 + (0x100 * (_n)))
5666
+
5667
+/* TX Descriptor Control; RW */
5668
+#define E1000_TXDCTL(_n) (0x0E028 + (0x40 * (_n)))
5669
+#define E1000_TXDCTL_A(_n) (0x03828 + (0x100 * (_n)))
5670
+
5671
+/* TX Descriptor Completion Write\ufffd\ufffd\ufffdBack Address Low; RW */
5672
+#define E1000_TDWBAL(_n) (0x0E038 + (0x40 * (_n)))
5673
+#define E1000_TDWBAL_A(_n) (0x03838 + (0x100 * (_n)))
5674
+
5675
+/* TX Descriptor Completion Write\ufffd\ufffd\ufffdBack Address High; RW */
5676
+#define E1000_TDWBAH(_n) (0x0E03C + (0x40 * (_n)))
5677
+#define E1000_TDWBAH_A(_n) (0x0383C + (0x100 * (_n)))
5678
+
5679
+#define E1000_MTA_A 0x0200
5680
+
5681
+#define E1000_XDBAL_MASK (~(BIT(5) - 1)) /* TDBAL and RDBAL Registers Mask */
5682
+
5683
+#define E1000_ICR_MACSEC 0x00000020 /* MACSec */
5684
+#define E1000_ICR_RX0 0x00000040 /* Receiver Overrun */
5685
+#define E1000_ICR_GPI_SDP0 0x00000800 /* General Purpose, SDP0 pin */
5686
+#define E1000_ICR_GPI_SDP1 0x00001000 /* General Purpose, SDP1 pin */
5687
+#define E1000_ICR_GPI_SDP2 0x00002000 /* General Purpose, SDP2 pin */
5688
+#define E1000_ICR_GPI_SDP3 0x00004000 /* General Purpose, SDP3 pin */
5689
+#define E1000_ICR_PTRAP 0x00008000 /* Probe Trap */
5690
+#define E1000_ICR_MNG 0x00040000 /* Management Event */
5691
+#define E1000_ICR_OMED 0x00100000 /* Other Media Energy Detected */
5692
+#define E1000_ICR_FER 0x00400000 /* Fatal Error */
5693
+#define E1000_ICR_NFER 0x00800000 /* Non Fatal Error */
5694
+#define E1000_ICR_CSRTO 0x01000000 /* CSR access Time Out Indication */
5695
+#define E1000_ICR_SCE 0x02000000 /* Storm Control Event */
5696
+#define E1000_ICR_SW_WD 0x04000000 /* Software Watchdog */
5697
+
5698
+/* Extended Interrupts */
5699
+
5700
+#define E1000_EICR_MSIX_MASK 0x01FFFFFF /* Bits used in MSI-X mode */
5701
+#define E1000_EICR_LEGACY_MASK 0x4000FFFF /* Bits used in non MSI-X mode */
5702
+
5703
+/* Mirror VF Control (only RST bit); RW */
5704
+#define E1000_PVTCTRL(_n) (0x10000 + (_n) * 0x100)
5705
+
5706
+/* Mirror Good Packets Received Count; RO */
5707
+#define E1000_PVFGPRC(_n) (0x10010 + (_n) * 0x100)
5708
+
5709
+/* Mirror Good Packets Transmitted Count; RO */
5710
+#define E1000_PVFGPTC(_n) (0x10014 + (_n) * 0x100)
5711
+
5712
+/* Mirror Good Octets Received Count; RO */
5713
+#define E1000_PVFGORC(_n) (0x10018 + (_n) * 0x100)
5714
+
5715
+/* Mirror Extended Interrupt Cause Set; WO */
5716
+#define E1000_PVTEICS(_n) (0x10020 + (_n) * 0x100)
5717
+
5718
+/* Mirror Extended Interrupt Mask Set/Read; RW */
5719
+#define E1000_PVTEIMS(_n) (0x10024 + (_n) * 0x100)
5720
+
5721
+/* Mirror Extended Interrupt Mask Clear; WO */
5722
+#define E1000_PVTEIMC(_n) (0x10028 + (_n) * 0x100)
5723
+
5724
+/* Mirror Extended Interrupt Auto Clear; RW */
5725
+#define E1000_PVTEIAC(_n) (0x1002C + (_n) * 0x100)
5726
+
5727
+/* Mirror Extended Interrupt Auto Mask Enable; RW */
5728
+#define E1000_PVTEIAM(_n) (0x10030 + (_n) * 0x100)
5729
+
5730
+/* Mirror Good Octets Transmitted Count; RO */
5731
+#define E1000_PVFGOTC(_n) (0x10034 + (_n) * 0x100)
5732
+
5733
+/* Mirror Multicast Packets Received Count; RO */
5734
+#define E1000_PVFMPRC(_n) (0x1003C + (_n) * 0x100)
5735
+
5736
+/* Mirror Good RX Packets loopback Count; RO */
5737
+#define E1000_PVFGPRLBC(_n) (0x10040 + (_n) * 0x100)
5738
+
5739
+/* Mirror Good TX packets loopback Count; RO */
5740
+#define E1000_PVFGPTLBC(_n) (0x10044 + (_n) * 0x100)
5741
+
5742
+/* Mirror Good RX Octets loopback Count; RO */
5743
+#define E1000_PVFGORLBC(_n) (0x10048 + (_n) * 0x100)
5744
+
5745
+/* Mirror Good TX Octets loopback Count; RO */
5746
+#define E1000_PVFGOTLBC(_n) (0x10050 + (_n) * 0x100)
5747
+
5748
+/* Mirror Extended Interrupt Cause Set; RC/W1C */
5749
+#define E1000_PVTEICR(_n) (0x10080 + (_n) * 0x100)
5750
+
5751
+/*
5752
+ * These are fake addresses that, according to the specification, the device
5753
+ * is not using. They are used to distinguish between the PF and the VFs
5754
+ * accessing their VTIVAR register (which is the same address, 0x1700)
5755
+ */
5756
+#define E1000_VTIVAR 0x11700
5757
+#define E1000_VTIVAR_MISC 0x11720
5758
+
5759
+#define E1000_RSS_QUEUE(reta, hash) (E1000_RETA_VAL(reta, hash) & 0x0F)
5760
+
5761
+#define E1000_STATUS_IOV_MODE 0x00040000
5762
+
5763
+#define E1000_STATUS_NUM_VFS_SHIFT 14
5764
+
5765
+static inline uint8_t igb_ivar_entry_rx(uint8_t i)
5766
+{
5767
+ return i < 8 ? i * 4 : (i - 8) * 4 + 2;
5768
+}
5769
+
5770
+static inline uint8_t igb_ivar_entry_tx(uint8_t i)
5771
+{
5772
+ return i < 8 ? i * 4 + 1 : (i - 8) * 4 + 3;
5773
+}
5774
+
5775
+#endif
5776
diff --git a/hw/net/igbvf.c b/hw/net/igbvf.c
5777
new file mode 100644
5778
index XXXXXXX..XXXXXXX
5779
--- /dev/null
5780
+++ b/hw/net/igbvf.c
5781
@@ -XXX,XX +XXX,XX @@
5782
+/*
5783
+ * QEMU Intel 82576 SR/IOV Ethernet Controller Emulation
5784
+ *
5785
+ * Datasheet:
5786
+ * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82576eg-gbe-datasheet.pdf
5787
+ *
5788
+ * Copyright (c) 2020-2023 Red Hat, Inc.
5789
+ * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
5790
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
5791
+ *
5792
+ * Authors:
5793
+ * Akihiko Odaki <akihiko.odaki@daynix.com>
5794
+ * Gal Hammmer <gal.hammer@sap.com>
5795
+ * Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
5796
+ * Dmitry Fleytman <dmitry@daynix.com>
5797
+ * Leonid Bloch <leonid@daynix.com>
5798
+ * Yan Vugenfirer <yan@daynix.com>
5799
+ *
5800
+ * Based on work done by:
5801
+ * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
5802
+ * Copyright (c) 2008 Qumranet
5803
+ * Based on work done by:
5804
+ * Copyright (c) 2007 Dan Aloni
5805
+ * Copyright (c) 2004 Antony T Curtis
5806
+ *
5807
+ * This library is free software; you can redistribute it and/or
5808
+ * modify it under the terms of the GNU Lesser General Public
5809
+ * License as published by the Free Software Foundation; either
5810
+ * version 2.1 of the License, or (at your option) any later version.
5811
+ *
5812
+ * This library is distributed in the hope that it will be useful,
5813
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5814
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5815
+ * Lesser General Public License for more details.
5816
+ *
5817
+ * You should have received a copy of the GNU Lesser General Public
5818
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
5819
+ */
5820
+
5821
+#include "qemu/osdep.h"
5822
+#include "hw/hw.h"
5823
+#include "hw/net/mii.h"
5824
+#include "hw/pci/pci_device.h"
5825
+#include "hw/pci/pcie.h"
5826
+#include "hw/pci/msix.h"
5827
+#include "net/eth.h"
5828
+#include "net/net.h"
5829
+#include "igb_common.h"
5830
+#include "igb_core.h"
5831
+#include "trace.h"
5832
+#include "qapi/error.h"
5833
+
5834
+#define TYPE_IGBVF "igbvf"
5835
+OBJECT_DECLARE_SIMPLE_TYPE(IgbVfState, IGBVF)
5836
+
5837
+#define IGBVF_MMIO_BAR_IDX (0)
5838
+#define IGBVF_MSIX_BAR_IDX (3)
5839
+
5840
+#define IGBVF_MMIO_SIZE (16 * 1024)
5841
+#define IGBVF_MSIX_SIZE (16 * 1024)
5842
+
5843
+struct IgbVfState {
5844
+ PCIDevice parent_obj;
5845
+
5846
+ MemoryRegion mmio;
5847
+ MemoryRegion msix;
5848
+};
5849
+
5850
+static hwaddr vf_to_pf_addr(hwaddr addr, uint16_t vfn, bool write)
5851
+{
5852
+ switch (addr) {
5853
+ case E1000_CTRL:
5854
+ case E1000_CTRL_DUP:
5855
+ return E1000_PVTCTRL(vfn);
5856
+ case E1000_EICS:
5857
+ return E1000_PVTEICS(vfn);
5858
+ case E1000_EIMS:
5859
+ return E1000_PVTEIMS(vfn);
5860
+ case E1000_EIMC:
5861
+ return E1000_PVTEIMC(vfn);
5862
+ case E1000_EIAC:
5863
+ return E1000_PVTEIAC(vfn);
5864
+ case E1000_EIAM:
5865
+ return E1000_PVTEIAM(vfn);
5866
+ case E1000_EICR:
5867
+ return E1000_PVTEICR(vfn);
5868
+ case E1000_EITR(0):
5869
+ case E1000_EITR(1):
5870
+ case E1000_EITR(2):
5871
+ return E1000_EITR(22) + (addr - E1000_EITR(0)) - vfn * 0xC;
5872
+ case E1000_IVAR0:
5873
+ return E1000_VTIVAR + vfn * 4;
5874
+ case E1000_IVAR_MISC:
5875
+ return E1000_VTIVAR_MISC + vfn * 4;
5876
+ case 0x0F04: /* PBACL */
5877
+ return E1000_PBACLR;
5878
+ case 0x0F0C: /* PSRTYPE */
5879
+ return E1000_PSRTYPE(vfn);
5880
+ case E1000_V2PMAILBOX(0):
5881
+ return E1000_V2PMAILBOX(vfn);
5882
+ case E1000_VMBMEM(0) ... E1000_VMBMEM(0) + 0x3F:
5883
+ return addr + vfn * 0x40;
5884
+ case E1000_RDBAL_A(0):
5885
+ return E1000_RDBAL(vfn);
5886
+ case E1000_RDBAL_A(1):
5887
+ return E1000_RDBAL(vfn + IGB_MAX_VF_FUNCTIONS);
5888
+ case E1000_RDBAH_A(0):
5889
+ return E1000_RDBAH(vfn);
5890
+ case E1000_RDBAH_A(1):
5891
+ return E1000_RDBAH(vfn + IGB_MAX_VF_FUNCTIONS);
5892
+ case E1000_RDLEN_A(0):
5893
+ return E1000_RDLEN(vfn);
5894
+ case E1000_RDLEN_A(1):
5895
+ return E1000_RDLEN(vfn + IGB_MAX_VF_FUNCTIONS);
5896
+ case E1000_SRRCTL_A(0):
5897
+ return E1000_SRRCTL(vfn);
5898
+ case E1000_SRRCTL_A(1):
5899
+ return E1000_SRRCTL(vfn + IGB_MAX_VF_FUNCTIONS);
5900
+ case E1000_RDH_A(0):
5901
+ return E1000_RDH(vfn);
5902
+ case E1000_RDH_A(1):
5903
+ return E1000_RDH(vfn + IGB_MAX_VF_FUNCTIONS);
5904
+ case E1000_RXCTL_A(0):
5905
+ return E1000_RXCTL(vfn);
5906
+ case E1000_RXCTL_A(1):
5907
+ return E1000_RXCTL(vfn + IGB_MAX_VF_FUNCTIONS);
5908
+ case E1000_RDT_A(0):
5909
+ return E1000_RDT(vfn);
5910
+ case E1000_RDT_A(1):
5911
+ return E1000_RDT(vfn + IGB_MAX_VF_FUNCTIONS);
5912
+ case E1000_RXDCTL_A(0):
5913
+ return E1000_RXDCTL(vfn);
5914
+ case E1000_RXDCTL_A(1):
5915
+ return E1000_RXDCTL(vfn + IGB_MAX_VF_FUNCTIONS);
5916
+ case E1000_RQDPC_A(0):
5917
+ return E1000_RQDPC(vfn);
5918
+ case E1000_RQDPC_A(1):
5919
+ return E1000_RQDPC(vfn + IGB_MAX_VF_FUNCTIONS);
5920
+ case E1000_TDBAL_A(0):
5921
+ return E1000_TDBAL(vfn);
5922
+ case E1000_TDBAL_A(1):
5923
+ return E1000_TDBAL(vfn + IGB_MAX_VF_FUNCTIONS);
5924
+ case E1000_TDBAH_A(0):
5925
+ return E1000_TDBAH(vfn);
5926
+ case E1000_TDBAH_A(1):
5927
+ return E1000_TDBAH(vfn + IGB_MAX_VF_FUNCTIONS);
5928
+ case E1000_TDLEN_A(0):
5929
+ return E1000_TDLEN(vfn);
5930
+ case E1000_TDLEN_A(1):
5931
+ return E1000_TDLEN(vfn + IGB_MAX_VF_FUNCTIONS);
5932
+ case E1000_TDH_A(0):
5933
+ return E1000_TDH(vfn);
5934
+ case E1000_TDH_A(1):
5935
+ return E1000_TDH(vfn + IGB_MAX_VF_FUNCTIONS);
5936
+ case E1000_TXCTL_A(0):
5937
+ return E1000_TXCTL(vfn);
5938
+ case E1000_TXCTL_A(1):
5939
+ return E1000_TXCTL(vfn + IGB_MAX_VF_FUNCTIONS);
5940
+ case E1000_TDT_A(0):
5941
+ return E1000_TDT(vfn);
5942
+ case E1000_TDT_A(1):
5943
+ return E1000_TDT(vfn + IGB_MAX_VF_FUNCTIONS);
5944
+ case E1000_TXDCTL_A(0):
5945
+ return E1000_TXDCTL(vfn);
5946
+ case E1000_TXDCTL_A(1):
5947
+ return E1000_TXDCTL(vfn + IGB_MAX_VF_FUNCTIONS);
5948
+ case E1000_TDWBAL_A(0):
5949
+ return E1000_TDWBAL(vfn);
5950
+ case E1000_TDWBAL_A(1):
5951
+ return E1000_TDWBAL(vfn + IGB_MAX_VF_FUNCTIONS);
5952
+ case E1000_TDWBAH_A(0):
5953
+ return E1000_TDWBAH(vfn);
5954
+ case E1000_TDWBAH_A(1):
5955
+ return E1000_TDWBAH(vfn + IGB_MAX_VF_FUNCTIONS);
5956
+ case E1000_VFGPRC:
5957
+ return E1000_PVFGPRC(vfn);
5958
+ case E1000_VFGPTC:
5959
+ return E1000_PVFGPTC(vfn);
5960
+ case E1000_VFGORC:
5961
+ return E1000_PVFGORC(vfn);
5962
+ case E1000_VFGOTC:
5963
+ return E1000_PVFGOTC(vfn);
5964
+ case E1000_VFMPRC:
5965
+ return E1000_PVFMPRC(vfn);
5966
+ case E1000_VFGPRLBC:
5967
+ return E1000_PVFGPRLBC(vfn);
5968
+ case E1000_VFGPTLBC:
5969
+ return E1000_PVFGPTLBC(vfn);
5970
+ case E1000_VFGORLBC:
5971
+ return E1000_PVFGORLBC(vfn);
5972
+ case E1000_VFGOTLBC:
5973
+ return E1000_PVFGOTLBC(vfn);
5974
+ case E1000_STATUS:
5975
+ case E1000_FRTIMER:
5976
+ if (write) {
5977
+ return HWADDR_MAX;
5978
+ }
5979
+ /* fallthrough */
5980
+ case 0x34E8: /* PBTWAC */
5981
+ case 0x24E8: /* PBRWAC */
5982
+ return addr;
5983
+ }
5984
+
5985
+ trace_igbvf_wrn_io_addr_unknown(addr);
5986
+
5987
+ return HWADDR_MAX;
5988
+}
5989
+
5990
+static void igbvf_write_config(PCIDevice *dev, uint32_t addr, uint32_t val,
5991
+ int len)
5992
+{
5993
+ trace_igbvf_write_config(addr, val, len);
5994
+ pci_default_write_config(dev, addr, val, len);
5995
+}
5996
+
5997
+static uint64_t igbvf_mmio_read(void *opaque, hwaddr addr, unsigned size)
5998
+{
5999
+ PCIDevice *vf = PCI_DEVICE(opaque);
6000
+ PCIDevice *pf = pcie_sriov_get_pf(vf);
6001
+
6002
+ addr = vf_to_pf_addr(addr, pcie_sriov_vf_number(vf), false);
6003
+ return addr == HWADDR_MAX ? 0 : igb_mmio_read(pf, addr, size);
6004
+}
6005
+
6006
+static void igbvf_mmio_write(void *opaque, hwaddr addr, uint64_t val,
6007
+ unsigned size)
6008
+{
6009
+ PCIDevice *vf = PCI_DEVICE(opaque);
6010
+ PCIDevice *pf = pcie_sriov_get_pf(vf);
6011
+
6012
+ addr = vf_to_pf_addr(addr, pcie_sriov_vf_number(vf), true);
6013
+ if (addr != HWADDR_MAX) {
6014
+ igb_mmio_write(pf, addr, val, size);
6015
+ }
6016
+}
6017
+
6018
+static const MemoryRegionOps mmio_ops = {
6019
+ .read = igbvf_mmio_read,
6020
+ .write = igbvf_mmio_write,
6021
+ .endianness = DEVICE_LITTLE_ENDIAN,
6022
+ .impl = {
6023
+ .min_access_size = 4,
6024
+ .max_access_size = 4,
6025
+ },
6026
+};
6027
+
6028
+static void igbvf_pci_realize(PCIDevice *dev, Error **errp)
6029
+{
6030
+ IgbVfState *s = IGBVF(dev);
6031
+ int ret;
6032
+ int i;
6033
+
6034
+ dev->config_write = igbvf_write_config;
6035
+
6036
+ memory_region_init_io(&s->mmio, OBJECT(dev), &mmio_ops, s, "igbvf-mmio",
6037
+ IGBVF_MMIO_SIZE);
6038
+ pcie_sriov_vf_register_bar(dev, IGBVF_MMIO_BAR_IDX, &s->mmio);
6039
+
6040
+ memory_region_init(&s->msix, OBJECT(dev), "igbvf-msix", IGBVF_MSIX_SIZE);
6041
+ pcie_sriov_vf_register_bar(dev, IGBVF_MSIX_BAR_IDX, &s->msix);
6042
+
6043
+ ret = msix_init(dev, IGBVF_MSIX_VEC_NUM, &s->msix, IGBVF_MSIX_BAR_IDX, 0,
6044
+ &s->msix, IGBVF_MSIX_BAR_IDX, 0x2000, 0x70, errp);
6045
+ if (ret) {
6046
+ return;
6047
+ }
6048
+
6049
+ for (i = 0; i < IGBVF_MSIX_VEC_NUM; i++) {
6050
+ msix_vector_use(dev, i);
6051
+ }
6052
+
6053
+ if (pcie_endpoint_cap_init(dev, 0xa0) < 0) {
6054
+ hw_error("Failed to initialize PCIe capability");
6055
+ }
6056
+
6057
+ if (pcie_aer_init(dev, 1, 0x100, 0x40, errp) < 0) {
6058
+ hw_error("Failed to initialize AER capability");
6059
+ }
6060
+
6061
+ pcie_ari_init(dev, 0x150, 1);
6062
+}
6063
+
6064
+static void igbvf_pci_uninit(PCIDevice *dev)
6065
+{
6066
+ IgbVfState *s = IGBVF(dev);
6067
+
6068
+ pcie_aer_exit(dev);
6069
+ pcie_cap_exit(dev);
6070
+ msix_unuse_all_vectors(dev);
6071
+ msix_uninit(dev, &s->msix, &s->msix);
6072
+}
6073
+
6074
+static void igbvf_class_init(ObjectClass *class, void *data)
6075
+{
6076
+ DeviceClass *dc = DEVICE_CLASS(class);
6077
+ PCIDeviceClass *c = PCI_DEVICE_CLASS(class);
6078
+
6079
+ c->realize = igbvf_pci_realize;
6080
+ c->exit = igbvf_pci_uninit;
6081
+ c->vendor_id = PCI_VENDOR_ID_INTEL;
6082
+ c->device_id = E1000_DEV_ID_82576_VF;
6083
+ c->revision = 1;
6084
+ c->class_id = PCI_CLASS_NETWORK_ETHERNET;
6085
+
6086
+ dc->desc = "Intel 82576 Virtual Function";
6087
+ dc->user_creatable = false;
6088
+
6089
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
6090
+}
6091
+
6092
+static const TypeInfo igbvf_info = {
6093
+ .name = TYPE_IGBVF,
6094
+ .parent = TYPE_PCI_DEVICE,
6095
+ .instance_size = sizeof(IgbVfState),
6096
+ .class_init = igbvf_class_init,
6097
+ .interfaces = (InterfaceInfo[]) {
6098
+ { INTERFACE_PCIE_DEVICE },
6099
+ { }
6100
+ },
6101
+};
6102
+
6103
+static void igb_register_types(void)
6104
+{
6105
+ type_register_static(&igbvf_info);
6106
+}
6107
+
6108
+type_init(igb_register_types)
6109
diff --git a/hw/net/meson.build b/hw/net/meson.build
6110
index XXXXXXX..XXXXXXX 100644
6111
--- a/hw/net/meson.build
6112
+++ b/hw/net/meson.build
6113
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_PCNET_COMMON', if_true: files('pcnet.c'))
6114
softmmu_ss.add(when: 'CONFIG_E1000_PCI', if_true: files('e1000.c', 'e1000x_common.c'))
6115
softmmu_ss.add(when: 'CONFIG_E1000E_PCI_EXPRESS', if_true: files('net_tx_pkt.c', 'net_rx_pkt.c'))
6116
softmmu_ss.add(when: 'CONFIG_E1000E_PCI_EXPRESS', if_true: files('e1000e.c', 'e1000e_core.c', 'e1000x_common.c'))
6117
+softmmu_ss.add(when: 'CONFIG_IGB_PCI_EXPRESS', if_true: files('net_tx_pkt.c', 'net_rx_pkt.c'))
6118
+softmmu_ss.add(when: 'CONFIG_IGB_PCI_EXPRESS', if_true: files('igb.c', 'igbvf.c', 'igb_core.c'))
6119
softmmu_ss.add(when: 'CONFIG_RTL8139_PCI', if_true: files('rtl8139.c'))
6120
softmmu_ss.add(when: 'CONFIG_TULIP', if_true: files('tulip.c'))
6121
softmmu_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('net_tx_pkt.c', 'net_rx_pkt.c'))
6122
diff --git a/hw/net/trace-events b/hw/net/trace-events
6123
index XXXXXXX..XXXXXXX 100644
6124
--- a/hw/net/trace-events
6125
+++ b/hw/net/trace-events
6126
@@ -XXX,XX +XXX,XX @@ e1000e_msix_use_vector_fail(uint32_t vec, int32_t res) "Failed to use MSI-X vect
6127
e1000e_mac_set_permanent(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5) "Set permanent MAC: %02x:%02x:%02x:%02x:%02x:%02x"
6128
e1000e_cfg_support_virtio(bool support) "Virtio header supported: %d"
6129
6130
+# igb.c
6131
+igb_write_config(uint32_t address, uint32_t val, int len) "CONFIG write 0x%"PRIx32", value: 0x%"PRIx32", len: %"PRId32
6132
+igbvf_write_config(uint32_t address, uint32_t val, int len) "CONFIG write 0x%"PRIx32", value: 0x%"PRIx32", len: %"PRId32
6133
+
6134
+# igb_core.c
6135
+igb_core_mdic_read(uint32_t addr, uint32_t data) "MDIC READ: PHY[%u] = 0x%x"
6136
+igb_core_mdic_read_unhandled(uint32_t addr) "MDIC READ: PHY[%u] UNHANDLED"
6137
+igb_core_mdic_write(uint32_t addr, uint32_t data) "MDIC WRITE: PHY[%u] = 0x%x"
6138
+igb_core_mdic_write_unhandled(uint32_t addr) "MDIC WRITE: PHY[%u] UNHANDLED"
6139
+
6140
+igb_rx_desc_buff_size(uint32_t b) "buffer size: %u"
6141
+igb_rx_desc_buff_write(uint64_t addr, uint16_t offset, const void* source, uint32_t len) "addr: 0x%"PRIx64", offset: %u, from: %p, length: %u"
6142
+
6143
+igb_rx_metadata_rss(uint32_t rss) "RSS data: 0x%X"
6144
+
6145
+igb_irq_icr_clear_gpie_nsicr(void) "Clearing ICR on read due to GPIE.NSICR enabled"
6146
+igb_irq_icr_write(uint32_t bits, uint32_t old_icr, uint32_t new_icr) "Clearing ICR bits 0x%x: 0x%x --> 0x%x"
6147
+igb_irq_set_iam(uint32_t icr) "Update IAM: 0x%x"
6148
+igb_irq_read_iam(uint32_t icr) "Current IAM: 0x%x"
6149
+igb_irq_write_eics(uint32_t val, bool msix) "Update EICS: 0x%x MSI-X: %d"
6150
+igb_irq_write_eims(uint32_t val, bool msix) "Update EIMS: 0x%x MSI-X: %d"
6151
+igb_irq_write_eimc(uint32_t val, uint32_t eims, bool msix) "Update EIMC: 0x%x EIMS: 0x%x MSI-X: %d"
6152
+igb_irq_write_eiac(uint32_t val) "Update EIAC: 0x%x"
6153
+igb_irq_write_eiam(uint32_t val, bool msix) "Update EIAM: 0x%x MSI-X: %d"
6154
+igb_irq_write_eicr(uint32_t val, bool msix) "Update EICR: 0x%x MSI-X: %d"
6155
+igb_irq_eitr_set(uint32_t eitr_num, uint32_t val) "EITR[%u] = 0x%x"
6156
+igb_set_pfmailbox(uint32_t vf_num, uint32_t val) "PFMailbox[%d]: 0x%x"
6157
+igb_set_vfmailbox(uint32_t vf_num, uint32_t val) "VFMailbox[%d]: 0x%x"
6158
+
6159
+# igbvf.c
6160
+igbvf_wrn_io_addr_unknown(uint64_t addr) "IO unknown register 0x%"PRIx64
6161
+
6162
# spapr_llan.c
6163
spapr_vlan_get_rx_bd_from_pool_found(int pool, int32_t count, uint32_t rx_bufs) "pool=%d count=%"PRId32" rxbufs=%"PRIu32
6164
spapr_vlan_get_rx_bd_from_page(int buf_ptr, uint64_t bd) "use_buf_ptr=%d bd=0x%016"PRIx64
6165
--
406
--
6166
2.7.4
407
2.7.4
408
409
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
This automates ethtool tests for igb registers, interrupts, etc.
3
This is needed to achieve migration, so the destination can restore its
4
index.
4
5
5
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Setting base as last used idx, so destination will see as available all
6
Reviewed-by: Cédric Le Goater <clg@redhat.com>
7
the entries that the device did not use, including the in-flight
8
processing ones.
9
10
This is ok for networking, but other kinds of devices might have
11
problems with these retransmissions.
12
13
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
14
Acked-by: Michael S. Tsirkin <mst@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
16
---
9
MAINTAINERS | 1 +
17
hw/virtio/vhost-vdpa.c | 17 +++++++++++++++++
10
scripts/ci/org.centos/stream/8/x86_64/test-avocado | 1 +
18
1 file changed, 17 insertions(+)
11
tests/avocado/igb.py | 38 ++++++++++++++++++++++
12
3 files changed, 40 insertions(+)
13
create mode 100644 tests/avocado/igb.py
14
19
15
diff --git a/MAINTAINERS b/MAINTAINERS
20
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/MAINTAINERS
22
--- a/hw/virtio/vhost-vdpa.c
18
+++ b/MAINTAINERS
23
+++ b/hw/virtio/vhost-vdpa.c
19
@@ -XXX,XX +XXX,XX @@ igb
24
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_set_vring_base(struct vhost_dev *dev,
20
M: Akihiko Odaki <akihiko.odaki@daynix.com>
25
static int vhost_vdpa_get_vring_base(struct vhost_dev *dev,
21
S: Maintained
26
struct vhost_vring_state *ring)
22
F: hw/net/igb*
27
{
23
+F: tests/avocado/igb.py
28
+ struct vhost_vdpa *v = dev->opaque;
24
F: tests/qtest/igb-test.c
29
int ret;
25
F: tests/qtest/libqos/igb.c
30
26
31
+ if (v->shadow_vqs_enabled) {
27
diff --git a/scripts/ci/org.centos/stream/8/x86_64/test-avocado b/scripts/ci/org.centos/stream/8/x86_64/test-avocado
32
+ VhostShadowVirtqueue *svq = g_ptr_array_index(v->shadow_vqs,
28
index XXXXXXX..XXXXXXX 100755
33
+ ring->index);
29
--- a/scripts/ci/org.centos/stream/8/x86_64/test-avocado
30
+++ b/scripts/ci/org.centos/stream/8/x86_64/test-avocado
31
@@ -XXX,XX +XXX,XX @@ make get-vm-images
32
tests/avocado/cpu_queries.py:QueryCPUModelExpansion.test \
33
tests/avocado/empty_cpu_model.py:EmptyCPUModel.test \
34
tests/avocado/hotplug_cpu.py:HotPlugCPU.test \
35
+ tests/avocado/igb.py:IGB.test \
36
tests/avocado/info_usernet.py:InfoUsernet.test_hostfwd \
37
tests/avocado/intel_iommu.py:IntelIOMMU.test_intel_iommu \
38
tests/avocado/intel_iommu.py:IntelIOMMU.test_intel_iommu_pt \
39
diff --git a/tests/avocado/igb.py b/tests/avocado/igb.py
40
new file mode 100644
41
index XXXXXXX..XXXXXXX
42
--- /dev/null
43
+++ b/tests/avocado/igb.py
44
@@ -XXX,XX +XXX,XX @@
45
+# SPDX-License-Identifier: GPL-2.0-or-later
46
+# ethtool tests for igb registers, interrupts, etc
47
+
34
+
48
+from avocado_qemu import LinuxTest
35
+ /*
36
+ * Setting base as last used idx, so destination will see as available
37
+ * all the entries that the device did not use, including the in-flight
38
+ * processing ones.
39
+ *
40
+ * TODO: This is ok for networking, but other kinds of devices might
41
+ * have problems with these retransmissions.
42
+ */
43
+ ring->num = svq->last_used_idx;
44
+ return 0;
45
+ }
49
+
46
+
50
+class IGB(LinuxTest):
47
ret = vhost_vdpa_call(dev, VHOST_GET_VRING_BASE, ring);
51
+ """
48
trace_vhost_vdpa_get_vring_base(dev, ring->index, ring->num);
52
+ :avocado: tags=accel:kvm
49
return ret;
53
+ :avocado: tags=arch:x86_64
54
+ :avocado: tags=distro:fedora
55
+ :avocado: tags=distro_version:31
56
+ :avocado: tags=machine:q35
57
+ """
58
+
59
+ timeout = 180
60
+
61
+ def test(self):
62
+ self.require_accelerator('kvm')
63
+ kernel_url = self.distro.pxeboot_url + 'vmlinuz'
64
+ kernel_hash = '5b6f6876e1b5bda314f93893271da0d5777b1f3c'
65
+ kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
66
+ initrd_url = self.distro.pxeboot_url + 'initrd.img'
67
+ initrd_hash = 'dd0340a1b39bd28f88532babd4581c67649ec5b1'
68
+ initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
69
+
70
+ # Ideally we want to test MSI as well, but it is blocked by a bug
71
+ # fixed with:
72
+ # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=28e96556baca7056d11d9fb3cdd0aba4483e00d8
73
+ kernel_params = self.distro.default_kernel_params + ' pci=nomsi'
74
+
75
+ self.vm.add_args('-kernel', kernel_path,
76
+ '-initrd', initrd_path,
77
+ '-append', kernel_params,
78
+ '-accel', 'kvm',
79
+ '-device', 'igb')
80
+ self.launch_and_wait()
81
+ self.ssh_command('dnf -y install ethtool')
82
+ self.ssh_command('ethtool -t eth1 offline')
83
--
50
--
84
2.7.4
51
2.7.4
85
52
86
53
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
igb implementation first starts off by copying e1000e code. Correct the
3
Setting the log address would make the device start reporting invalid
4
code style before that.
4
dirty memory because the SVQ vrings are located in qemu's memory.
5
5
6
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Acked-by: Michael S. Tsirkin <mst@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
9
---
10
hw/net/e1000.c | 41 ++++++++++----------
10
hw/virtio/vhost-vdpa.c | 3 ++-
11
hw/net/e1000e.c | 72 +++++++++++++++++-----------------
11
1 file changed, 2 insertions(+), 1 deletion(-)
12
hw/net/e1000e_core.c | 103 +++++++++++++++++++++++++++----------------------
13
hw/net/e1000e_core.h | 66 +++++++++++++++----------------
14
hw/net/e1000x_common.h | 44 ++++++++++-----------
15
5 files changed, 168 insertions(+), 158 deletions(-)
16
12
17
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
13
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/net/e1000.c
15
--- a/hw/virtio/vhost-vdpa.c
20
+++ b/hw/net/e1000.c
16
+++ b/hw/virtio/vhost-vdpa.c
21
@@ -XXX,XX +XXX,XX @@ receive_filter(E1000State *s, const uint8_t *buf, int size)
17
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
22
if (e1000x_is_vlan_packet(buf, le16_to_cpu(s->mac_reg[VET])) &&
18
static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base,
23
e1000x_vlan_rx_filter_enabled(s->mac_reg)) {
19
struct vhost_log *log)
24
uint16_t vid = lduw_be_p(buf + 14);
20
{
25
- uint32_t vfta = ldl_le_p((uint32_t*)(s->mac_reg + VFTA) +
21
- if (vhost_vdpa_one_time_request(dev)) {
26
+ uint32_t vfta = ldl_le_p((uint32_t *)(s->mac_reg + VFTA) +
22
+ struct vhost_vdpa *v = dev->opaque;
27
((vid >> 5) & 0x7f));
23
+ if (v->shadow_vqs_enabled || vhost_vdpa_one_time_request(dev)) {
28
- if ((vfta & (1 << (vid & 0x1f))) == 0)
24
return 0;
29
+ if ((vfta & (1 << (vid & 0x1f))) == 0) {
30
return 0;
31
+ }
32
}
25
}
33
26
34
if (!isbcast && !ismcast && (rctl & E1000_RCTL_UPE)) { /* promiscuous ucast */
35
@@ -XXX,XX +XXX,XX @@ static const readops macreg_readops[] = {
36
[TDFPC] = mac_low13_read,
37
[AIT] = mac_low16_read,
38
39
- [CRCERRS ... MPC] = &mac_readreg,
40
- [IP6AT ... IP6AT+3] = &mac_readreg, [IP4AT ... IP4AT+6] = &mac_readreg,
41
- [FFLT ... FFLT+6] = &mac_low11_read,
42
- [RA ... RA+31] = &mac_readreg,
43
- [WUPM ... WUPM+31] = &mac_readreg,
44
- [MTA ... MTA+127] = &mac_readreg,
45
- [VFTA ... VFTA+127] = &mac_readreg,
46
- [FFMT ... FFMT+254] = &mac_low4_read,
47
- [FFVT ... FFVT+254] = &mac_readreg,
48
- [PBM ... PBM+16383] = &mac_readreg,
49
+ [CRCERRS ... MPC] = &mac_readreg,
50
+ [IP6AT ... IP6AT + 3] = &mac_readreg, [IP4AT ... IP4AT + 6] = &mac_readreg,
51
+ [FFLT ... FFLT + 6] = &mac_low11_read,
52
+ [RA ... RA + 31] = &mac_readreg,
53
+ [WUPM ... WUPM + 31] = &mac_readreg,
54
+ [MTA ... MTA + 127] = &mac_readreg,
55
+ [VFTA ... VFTA + 127] = &mac_readreg,
56
+ [FFMT ... FFMT + 254] = &mac_low4_read,
57
+ [FFVT ... FFVT + 254] = &mac_readreg,
58
+ [PBM ... PBM + 16383] = &mac_readreg,
59
};
60
enum { NREADOPS = ARRAY_SIZE(macreg_readops) };
61
62
@@ -XXX,XX +XXX,XX @@ static const writeops macreg_writeops[] = {
63
[RDTR] = set_16bit, [RADV] = set_16bit, [TADV] = set_16bit,
64
[ITR] = set_16bit,
65
66
- [IP6AT ... IP6AT+3] = &mac_writereg, [IP4AT ... IP4AT+6] = &mac_writereg,
67
- [FFLT ... FFLT+6] = &mac_writereg,
68
- [RA ... RA+31] = &mac_writereg,
69
- [WUPM ... WUPM+31] = &mac_writereg,
70
- [MTA ... MTA+127] = &mac_writereg,
71
- [VFTA ... VFTA+127] = &mac_writereg,
72
- [FFMT ... FFMT+254] = &mac_writereg, [FFVT ... FFVT+254] = &mac_writereg,
73
- [PBM ... PBM+16383] = &mac_writereg,
74
+ [IP6AT ... IP6AT + 3] = &mac_writereg, [IP4AT ... IP4AT + 6] = &mac_writereg,
75
+ [FFLT ... FFLT + 6] = &mac_writereg,
76
+ [RA ... RA + 31] = &mac_writereg,
77
+ [WUPM ... WUPM + 31] = &mac_writereg,
78
+ [MTA ... MTA + 127] = &mac_writereg,
79
+ [VFTA ... VFTA + 127] = &mac_writereg,
80
+ [FFMT ... FFMT + 254] = &mac_writereg, [FFVT ... FFVT + 254] = &mac_writereg,
81
+ [PBM ... PBM + 16383] = &mac_writereg,
82
};
83
84
enum { NWRITEOPS = ARRAY_SIZE(macreg_writeops) };
85
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/net/e1000e.c
88
+++ b/hw/net/e1000e.c
89
@@ -XXX,XX +XXX,XX @@
90
/*
91
-* QEMU INTEL 82574 GbE NIC emulation
92
-*
93
-* Software developer's manuals:
94
-* http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
95
-*
96
-* Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
97
-* Developed by Daynix Computing LTD (http://www.daynix.com)
98
-*
99
-* Authors:
100
-* Dmitry Fleytman <dmitry@daynix.com>
101
-* Leonid Bloch <leonid@daynix.com>
102
-* Yan Vugenfirer <yan@daynix.com>
103
-*
104
-* Based on work done by:
105
-* Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
106
-* Copyright (c) 2008 Qumranet
107
-* Based on work done by:
108
-* Copyright (c) 2007 Dan Aloni
109
-* Copyright (c) 2004 Antony T Curtis
110
-*
111
-* This library is free software; you can redistribute it and/or
112
-* modify it under the terms of the GNU Lesser General Public
113
-* License as published by the Free Software Foundation; either
114
-* version 2.1 of the License, or (at your option) any later version.
115
-*
116
-* This library is distributed in the hope that it will be useful,
117
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
118
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
119
-* Lesser General Public License for more details.
120
-*
121
-* You should have received a copy of the GNU Lesser General Public
122
-* License along with this library; if not, see <http://www.gnu.org/licenses/>.
123
-*/
124
+ * QEMU INTEL 82574 GbE NIC emulation
125
+ *
126
+ * Software developer's manuals:
127
+ * http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
128
+ *
129
+ * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
130
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
131
+ *
132
+ * Authors:
133
+ * Dmitry Fleytman <dmitry@daynix.com>
134
+ * Leonid Bloch <leonid@daynix.com>
135
+ * Yan Vugenfirer <yan@daynix.com>
136
+ *
137
+ * Based on work done by:
138
+ * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
139
+ * Copyright (c) 2008 Qumranet
140
+ * Based on work done by:
141
+ * Copyright (c) 2007 Dan Aloni
142
+ * Copyright (c) 2004 Antony T Curtis
143
+ *
144
+ * This library is free software; you can redistribute it and/or
145
+ * modify it under the terms of the GNU Lesser General Public
146
+ * License as published by the Free Software Foundation; either
147
+ * version 2.1 of the License, or (at your option) any later version.
148
+ *
149
+ * This library is distributed in the hope that it will be useful,
150
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
151
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
152
+ * Lesser General Public License for more details.
153
+ *
154
+ * You should have received a copy of the GNU Lesser General Public
155
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
156
+ */
157
158
#include "qemu/osdep.h"
159
#include "qemu/units.h"
160
@@ -XXX,XX +XXX,XX @@ static NetClientInfo net_e1000e_info = {
161
};
162
163
/*
164
-* EEPROM (NVM) contents documented in Table 36, section 6.1
165
-* and generally 6.1.2 Software accessed words.
166
-*/
167
+ * EEPROM (NVM) contents documented in Table 36, section 6.1
168
+ * and generally 6.1.2 Software accessed words.
169
+ */
170
static const uint16_t e1000e_eeprom_template[64] = {
171
/* Address | Compat. | ImVer | Compat. */
172
0x0000, 0x0000, 0x0000, 0x0420, 0xf746, 0x2010, 0xffff, 0xffff,
173
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
174
index XXXXXXX..XXXXXXX 100644
175
--- a/hw/net/e1000e_core.c
176
+++ b/hw/net/e1000e_core.c
177
@@ -XXX,XX +XXX,XX @@
178
/*
179
-* Core code for QEMU e1000e emulation
180
-*
181
-* Software developer's manuals:
182
-* http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
183
-*
184
-* Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
185
-* Developed by Daynix Computing LTD (http://www.daynix.com)
186
-*
187
-* Authors:
188
-* Dmitry Fleytman <dmitry@daynix.com>
189
-* Leonid Bloch <leonid@daynix.com>
190
-* Yan Vugenfirer <yan@daynix.com>
191
-*
192
-* Based on work done by:
193
-* Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
194
-* Copyright (c) 2008 Qumranet
195
-* Based on work done by:
196
-* Copyright (c) 2007 Dan Aloni
197
-* Copyright (c) 2004 Antony T Curtis
198
-*
199
-* This library is free software; you can redistribute it and/or
200
-* modify it under the terms of the GNU Lesser General Public
201
-* License as published by the Free Software Foundation; either
202
-* version 2.1 of the License, or (at your option) any later version.
203
-*
204
-* This library is distributed in the hope that it will be useful,
205
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
206
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
207
-* Lesser General Public License for more details.
208
-*
209
-* You should have received a copy of the GNU Lesser General Public
210
-* License along with this library; if not, see <http://www.gnu.org/licenses/>.
211
-*/
212
+ * Core code for QEMU e1000e emulation
213
+ *
214
+ * Software developer's manuals:
215
+ * http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
216
+ *
217
+ * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
218
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
219
+ *
220
+ * Authors:
221
+ * Dmitry Fleytman <dmitry@daynix.com>
222
+ * Leonid Bloch <leonid@daynix.com>
223
+ * Yan Vugenfirer <yan@daynix.com>
224
+ *
225
+ * Based on work done by:
226
+ * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
227
+ * Copyright (c) 2008 Qumranet
228
+ * Based on work done by:
229
+ * Copyright (c) 2007 Dan Aloni
230
+ * Copyright (c) 2004 Antony T Curtis
231
+ *
232
+ * This library is free software; you can redistribute it and/or
233
+ * modify it under the terms of the GNU Lesser General Public
234
+ * License as published by the Free Software Foundation; either
235
+ * version 2.1 of the License, or (at your option) any later version.
236
+ *
237
+ * This library is distributed in the hope that it will be useful,
238
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
239
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
240
+ * Lesser General Public License for more details.
241
+ *
242
+ * You should have received a copy of the GNU Lesser General Public
243
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
244
+ */
245
246
#include "qemu/osdep.h"
247
#include "qemu/log.h"
248
@@ -XXX,XX +XXX,XX @@
249
250
#include "trace.h"
251
252
-#define E1000E_MIN_XITR (500) /* No more then 7813 interrupts per
253
- second according to spec 10.2.4.2 */
254
+/* No more then 7813 interrupts per second according to spec 10.2.4.2 */
255
+#define E1000E_MIN_XITR (500)
256
+
257
#define E1000E_MAX_TX_FRAGS (64)
258
259
static inline void
260
@@ -XXX,XX +XXX,XX @@ e1000e_intrmgr_delay_rx_causes(E1000ECore *core, uint32_t *causes)
261
core->delayed_causes |= *causes & delayable_causes;
262
*causes &= ~delayable_causes;
263
264
- /* Check if delayed RX interrupts disabled by client
265
- or if there are causes that cannot be delayed */
266
+ /*
267
+ * Check if delayed RX interrupts disabled by client
268
+ * or if there are causes that cannot be delayed
269
+ */
270
if ((rdtr == 0) || (*causes != 0)) {
271
return false;
272
}
273
274
- /* Check if delayed RX ACK interrupts disabled by client
275
- and there is an ACK packet received */
276
+ /*
277
+ * Check if delayed RX ACK interrupts disabled by client
278
+ * and there is an ACK packet received
279
+ */
280
if ((raid == 0) && (core->delayed_causes & E1000_ICR_ACK)) {
281
return false;
282
}
283
@@ -XXX,XX +XXX,XX @@ e1000e_set_icr(E1000ECore *core, int index, uint32_t val)
284
}
285
286
icr = core->mac[ICR] & ~val;
287
- /* Windows driver expects that the "receive overrun" bit and other
288
+ /*
289
+ * Windows driver expects that the "receive overrun" bit and other
290
* ones to be cleared when the "Other" bit (#24) is cleared.
291
*/
292
icr = (val & E1000_ICR_OTHER) ? (icr & ~E1000_ICR_OTHER_CAUSES) : icr;
293
@@ -XXX,XX +XXX,XX @@ enum { E1000E_NWRITEOPS = ARRAY_SIZE(e1000e_macreg_writeops) };
294
295
enum { MAC_ACCESS_PARTIAL = 1 };
296
297
-/* The array below combines alias offsets of the index values for the
298
+/*
299
+ * The array below combines alias offsets of the index values for the
300
* MAC registers that have aliases, with the indication of not fully
301
* implemented registers (lowest bit). This combination is possible
302
- * because all of the offsets are even. */
303
+ * because all of the offsets are even.
304
+ */
305
static const uint16_t mac_reg_access[E1000E_MAC_SIZE] = {
306
/* Alias index offsets */
307
[FCRTL_A] = 0x07fe, [FCRTH_A] = 0x0802,
308
@@ -XXX,XX +XXX,XX @@ void e1000e_core_pre_save(E1000ECore *core)
309
NetClientState *nc = qemu_get_queue(core->owner_nic);
310
311
/*
312
- * If link is down and auto-negotiation is supported and ongoing,
313
- * complete auto-negotiation immediately. This allows us to look
314
- * at MII_SR_AUTONEG_COMPLETE to infer link status on load.
315
- */
316
+ * If link is down and auto-negotiation is supported and ongoing,
317
+ * complete auto-negotiation immediately. This allows us to look
318
+ * at MII_SR_AUTONEG_COMPLETE to infer link status on load.
319
+ */
320
if (nc->link_down && e1000e_have_autoneg(core)) {
321
core->phy[0][PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;
322
e1000e_update_flowctl_status(core);
323
@@ -XXX,XX +XXX,XX @@ e1000e_core_post_load(E1000ECore *core)
324
{
325
NetClientState *nc = qemu_get_queue(core->owner_nic);
326
327
- /* nc.link_down can't be migrated, so infer link_down according
328
+ /*
329
+ * nc.link_down can't be migrated, so infer link_down according
330
* to link status bit in core.mac[STATUS].
331
*/
332
nc->link_down = (core->mac[STATUS] & E1000_STATUS_LU) == 0;
333
diff --git a/hw/net/e1000e_core.h b/hw/net/e1000e_core.h
334
index XXXXXXX..XXXXXXX 100644
335
--- a/hw/net/e1000e_core.h
336
+++ b/hw/net/e1000e_core.h
337
@@ -XXX,XX +XXX,XX @@
338
/*
339
-* Core code for QEMU e1000e emulation
340
-*
341
-* Software developer's manuals:
342
-* http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
343
-*
344
-* Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
345
-* Developed by Daynix Computing LTD (http://www.daynix.com)
346
-*
347
-* Authors:
348
-* Dmitry Fleytman <dmitry@daynix.com>
349
-* Leonid Bloch <leonid@daynix.com>
350
-* Yan Vugenfirer <yan@daynix.com>
351
-*
352
-* Based on work done by:
353
-* Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
354
-* Copyright (c) 2008 Qumranet
355
-* Based on work done by:
356
-* Copyright (c) 2007 Dan Aloni
357
-* Copyright (c) 2004 Antony T Curtis
358
-*
359
-* This library is free software; you can redistribute it and/or
360
-* modify it under the terms of the GNU Lesser General Public
361
-* License as published by the Free Software Foundation; either
362
-* version 2.1 of the License, or (at your option) any later version.
363
-*
364
-* This library is distributed in the hope that it will be useful,
365
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
366
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
367
-* Lesser General Public License for more details.
368
-*
369
-* You should have received a copy of the GNU Lesser General Public
370
-* License along with this library; if not, see <http://www.gnu.org/licenses/>.
371
-*/
372
+ * Core code for QEMU e1000e emulation
373
+ *
374
+ * Software developer's manuals:
375
+ * http://www.intel.com/content/dam/doc/datasheet/82574l-gbe-controller-datasheet.pdf
376
+ *
377
+ * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
378
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
379
+ *
380
+ * Authors:
381
+ * Dmitry Fleytman <dmitry@daynix.com>
382
+ * Leonid Bloch <leonid@daynix.com>
383
+ * Yan Vugenfirer <yan@daynix.com>
384
+ *
385
+ * Based on work done by:
386
+ * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
387
+ * Copyright (c) 2008 Qumranet
388
+ * Based on work done by:
389
+ * Copyright (c) 2007 Dan Aloni
390
+ * Copyright (c) 2004 Antony T Curtis
391
+ *
392
+ * This library is free software; you can redistribute it and/or
393
+ * modify it under the terms of the GNU Lesser General Public
394
+ * License as published by the Free Software Foundation; either
395
+ * version 2.1 of the License, or (at your option) any later version.
396
+ *
397
+ * This library is distributed in the hope that it will be useful,
398
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
399
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
400
+ * Lesser General Public License for more details.
401
+ *
402
+ * You should have received a copy of the GNU Lesser General Public
403
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
404
+ */
405
406
#ifndef HW_NET_E1000E_CORE_H
407
#define HW_NET_E1000E_CORE_H
408
diff --git a/hw/net/e1000x_common.h b/hw/net/e1000x_common.h
409
index XXXXXXX..XXXXXXX 100644
410
--- a/hw/net/e1000x_common.h
411
+++ b/hw/net/e1000x_common.h
412
@@ -XXX,XX +XXX,XX @@
413
/*
414
-* QEMU e1000(e) emulation - shared code
415
-*
416
-* Copyright (c) 2008 Qumranet
417
-*
418
-* Based on work done by:
419
-* Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
420
-* Copyright (c) 2007 Dan Aloni
421
-* Copyright (c) 2004 Antony T Curtis
422
-*
423
-* This library is free software; you can redistribute it and/or
424
-* modify it under the terms of the GNU Lesser General Public
425
-* License as published by the Free Software Foundation; either
426
-* version 2.1 of the License, or (at your option) any later version.
427
-*
428
-* This library is distributed in the hope that it will be useful,
429
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
430
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
431
-* Lesser General Public License for more details.
432
-*
433
-* You should have received a copy of the GNU Lesser General Public
434
-* License along with this library; if not, see <http://www.gnu.org/licenses/>.
435
-*/
436
+ * QEMU e1000(e) emulation - shared code
437
+ *
438
+ * Copyright (c) 2008 Qumranet
439
+ *
440
+ * Based on work done by:
441
+ * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc.
442
+ * Copyright (c) 2007 Dan Aloni
443
+ * Copyright (c) 2004 Antony T Curtis
444
+ *
445
+ * This library is free software; you can redistribute it and/or
446
+ * modify it under the terms of the GNU Lesser General Public
447
+ * License as published by the Free Software Foundation; either
448
+ * version 2.1 of the License, or (at your option) any later version.
449
+ *
450
+ * This library is distributed in the hope that it will be useful,
451
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
452
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
453
+ * Lesser General Public License for more details.
454
+ *
455
+ * You should have received a copy of the GNU Lesser General Public
456
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
457
+ */
458
459
#ifndef HW_NET_E1000X_COMMON_H
460
#define HW_NET_E1000X_COMMON_H
461
--
27
--
462
2.7.4
28
2.7.4
463
29
464
30
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
The definitions will be used by igb.
4
5
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
include/hw/net/mii.h | 13 ++++++++++++-
9
1 file changed, 12 insertions(+), 1 deletion(-)
10
11
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/include/hw/net/mii.h
14
+++ b/include/hw/net/mii.h
15
@@ -XXX,XX +XXX,XX @@
16
#define MII_ANLPAR_ACK (1 << 14)
17
#define MII_ANLPAR_PAUSEASY (1 << 11) /* can pause asymmetrically */
18
#define MII_ANLPAR_PAUSE (1 << 10) /* can pause */
19
+#define MII_ANLPAR_T4 (1 << 9)
20
#define MII_ANLPAR_TXFD (1 << 8)
21
#define MII_ANLPAR_TX (1 << 7)
22
#define MII_ANLPAR_10FD (1 << 6)
23
#define MII_ANLPAR_10 (1 << 5)
24
#define MII_ANLPAR_CSMACD (1 << 0)
25
26
-#define MII_ANER_NWAY (1 << 0) /* Can do N-way auto-nego */
27
+#define MII_ANER_NP (1 << 2) /* Next Page Able */
28
+#define MII_ANER_NWAY (1 << 0) /* Can do N-way auto-nego */
29
30
+#define MII_ANNP_MP (1 << 13) /* Message Page */
31
+
32
+#define MII_CTRL1000_MASTER (1 << 11) /* MASTER-SLAVE Manual Configuration Value */
33
+#define MII_CTRL1000_PORT (1 << 10) /* T2_Repeater/DTE bit */
34
#define MII_CTRL1000_FULL (1 << 9) /* 1000BASE-T full duplex */
35
#define MII_CTRL1000_HALF (1 << 8) /* 1000BASE-T half duplex */
36
37
+#define MII_STAT1000_LOK (1 << 13) /* Local Receiver Status */
38
+#define MII_STAT1000_ROK (1 << 12) /* Remote Receiver Status */
39
#define MII_STAT1000_FULL (1 << 11) /* 1000BASE-T full duplex */
40
#define MII_STAT1000_HALF (1 << 10) /* 1000BASE-T half duplex */
41
42
+#define MII_EXTSTAT_1000T_FD (1 << 13) /* 1000BASE-T Full Duplex */
43
+#define MII_EXTSTAT_1000T_HD (1 << 12) /* 1000BASE-T Half Duplex */
44
+
45
/* List of vendor identifiers */
46
/* RealTek 8201 */
47
#define RTL8201CP_PHYID1 0x0000
48
--
49
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
hw/net/mii.h provides common definitions for MII.
4
5
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
hw/net/fsl_etsec/etsec.c | 11 ++++++-----
10
hw/net/fsl_etsec/etsec.h | 17 -----------------
11
hw/net/fsl_etsec/miim.c | 5 +++--
12
include/hw/net/mii.h | 1 +
13
4 files changed, 10 insertions(+), 24 deletions(-)
14
15
diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/net/fsl_etsec/etsec.c
18
+++ b/hw/net/fsl_etsec/etsec.c
19
@@ -XXX,XX +XXX,XX @@
20
#include "qemu/osdep.h"
21
#include "hw/sysbus.h"
22
#include "hw/irq.h"
23
+#include "hw/net/mii.h"
24
#include "hw/ptimer.h"
25
#include "hw/qdev-properties.h"
26
#include "etsec.h"
27
@@ -XXX,XX +XXX,XX @@ static void etsec_reset(DeviceState *d)
28
etsec->rx_buffer_len = 0;
29
30
etsec->phy_status =
31
- MII_SR_EXTENDED_CAPS | MII_SR_LINK_STATUS | MII_SR_AUTONEG_CAPS |
32
- MII_SR_AUTONEG_COMPLETE | MII_SR_PREAMBLE_SUPPRESS |
33
- MII_SR_EXTENDED_STATUS | MII_SR_100T2_HD_CAPS | MII_SR_100T2_FD_CAPS |
34
- MII_SR_10T_HD_CAPS | MII_SR_10T_FD_CAPS | MII_SR_100X_HD_CAPS |
35
- MII_SR_100X_FD_CAPS | MII_SR_100T4_CAPS;
36
+ MII_BMSR_EXTCAP | MII_BMSR_LINK_ST | MII_BMSR_AUTONEG |
37
+ MII_BMSR_AN_COMP | MII_BMSR_MFPS | MII_BMSR_EXTSTAT |
38
+ MII_BMSR_100T2_HD | MII_BMSR_100T2_FD |
39
+ MII_BMSR_10T_HD | MII_BMSR_10T_FD |
40
+ MII_BMSR_100TX_HD | MII_BMSR_100TX_FD | MII_BMSR_100T4;
41
42
etsec_update_irq(etsec);
43
}
44
diff --git a/hw/net/fsl_etsec/etsec.h b/hw/net/fsl_etsec/etsec.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/net/fsl_etsec/etsec.h
47
+++ b/hw/net/fsl_etsec/etsec.h
48
@@ -XXX,XX +XXX,XX @@ typedef struct eTSEC_rxtx_bd {
49
#define FCB_TX_CTU (1 << 1)
50
#define FCB_TX_NPH (1 << 0)
51
52
-/* PHY Status Register */
53
-#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
54
-#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
55
-#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
56
-#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
57
-#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
58
-#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
59
-#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
60
-#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
61
-#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
62
-#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
63
-#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
64
-#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
65
-#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
66
-#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
67
-#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
68
-
69
/* eTSEC */
70
71
/* Number of register in the device */
72
diff --git a/hw/net/fsl_etsec/miim.c b/hw/net/fsl_etsec/miim.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/net/fsl_etsec/miim.c
75
+++ b/hw/net/fsl_etsec/miim.c
76
@@ -XXX,XX +XXX,XX @@
77
*/
78
79
#include "qemu/osdep.h"
80
+#include "hw/net/mii.h"
81
#include "etsec.h"
82
#include "registers.h"
83
84
@@ -XXX,XX +XXX,XX @@ void etsec_miim_link_status(eTSEC *etsec, NetClientState *nc)
85
{
86
/* Set link status */
87
if (nc->link_down) {
88
- etsec->phy_status &= ~MII_SR_LINK_STATUS;
89
+ etsec->phy_status &= ~MII_BMSR_LINK_ST;
90
} else {
91
- etsec->phy_status |= MII_SR_LINK_STATUS;
92
+ etsec->phy_status |= MII_BMSR_LINK_ST;
93
}
94
}
95
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
96
index XXXXXXX..XXXXXXX 100644
97
--- a/include/hw/net/mii.h
98
+++ b/include/hw/net/mii.h
99
@@ -XXX,XX +XXX,XX @@
100
#define MII_BMCR_CTST (1 << 7) /* Collision test */
101
#define MII_BMCR_SPEED1000 (1 << 6) /* MSB of Speed (1000) */
102
103
+#define MII_BMSR_100T4 (1 << 15) /* Can do 100mbps T4 */
104
#define MII_BMSR_100TX_FD (1 << 14) /* Can do 100mbps, full-duplex */
105
#define MII_BMSR_100TX_HD (1 << 13) /* Can do 100mbps, half-duplex */
106
#define MII_BMSR_10T_FD (1 << 12) /* Can do 10mbps, full-duplex */
107
--
108
2.7.4
109
110
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
When a register has effective bits fewer than their width, the old code
4
inconsistently masked when writing or reading. Make the code consistent
5
by always masking when writing, and remove some code duplication.
6
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
hw/net/e1000.c | 84 ++++++++++++++++++++++------------------------------------
11
1 file changed, 31 insertions(+), 53 deletions(-)
12
13
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/e1000.c
16
+++ b/hw/net/e1000.c
17
@@ -XXX,XX +XXX,XX @@ mac_readreg(E1000State *s, int index)
18
}
19
20
static uint32_t
21
-mac_low4_read(E1000State *s, int index)
22
-{
23
- return s->mac_reg[index] & 0xf;
24
-}
25
-
26
-static uint32_t
27
-mac_low11_read(E1000State *s, int index)
28
-{
29
- return s->mac_reg[index] & 0x7ff;
30
-}
31
-
32
-static uint32_t
33
-mac_low13_read(E1000State *s, int index)
34
-{
35
- return s->mac_reg[index] & 0x1fff;
36
-}
37
-
38
-static uint32_t
39
-mac_low16_read(E1000State *s, int index)
40
-{
41
- return s->mac_reg[index] & 0xffff;
42
-}
43
-
44
-static uint32_t
45
mac_icr_read(E1000State *s, int index)
46
{
47
uint32_t ret = s->mac_reg[ICR];
48
@@ -XXX,XX +XXX,XX @@ set_rdt(E1000State *s, int index, uint32_t val)
49
}
50
}
51
52
-static void
53
-set_16bit(E1000State *s, int index, uint32_t val)
54
-{
55
- s->mac_reg[index] = val & 0xffff;
56
-}
57
+#define LOW_BITS_SET_FUNC(num) \
58
+ static void \
59
+ set_##num##bit(E1000State *s, int index, uint32_t val) \
60
+ { \
61
+ s->mac_reg[index] = val & (BIT(num) - 1); \
62
+ }
63
+
64
+LOW_BITS_SET_FUNC(4)
65
+LOW_BITS_SET_FUNC(11)
66
+LOW_BITS_SET_FUNC(13)
67
+LOW_BITS_SET_FUNC(16)
68
69
static void
70
set_dlen(E1000State *s, int index, uint32_t val)
71
@@ -XXX,XX +XXX,XX @@ static const readops macreg_readops[] = {
72
getreg(XONRXC), getreg(XONTXC), getreg(XOFFRXC), getreg(XOFFTXC),
73
getreg(RFC), getreg(RJC), getreg(RNBC), getreg(TSCTFC),
74
getreg(MGTPRC), getreg(MGTPDC), getreg(MGTPTC), getreg(GORCL),
75
- getreg(GOTCL),
76
+ getreg(GOTCL), getreg(RDFH), getreg(RDFT), getreg(RDFHS),
77
+ getreg(RDFTS), getreg(RDFPC), getreg(TDFH), getreg(TDFT),
78
+ getreg(TDFHS), getreg(TDFTS), getreg(TDFPC), getreg(AIT),
79
80
[TOTH] = mac_read_clr8, [TORH] = mac_read_clr8,
81
[GOTCH] = mac_read_clr8, [GORCH] = mac_read_clr8,
82
@@ -XXX,XX +XXX,XX @@ static const readops macreg_readops[] = {
83
[MPTC] = mac_read_clr4,
84
[ICR] = mac_icr_read, [EECD] = get_eecd,
85
[EERD] = flash_eerd_read,
86
- [RDFH] = mac_low13_read, [RDFT] = mac_low13_read,
87
- [RDFHS] = mac_low13_read, [RDFTS] = mac_low13_read,
88
- [RDFPC] = mac_low13_read,
89
- [TDFH] = mac_low11_read, [TDFT] = mac_low11_read,
90
- [TDFHS] = mac_low13_read, [TDFTS] = mac_low13_read,
91
- [TDFPC] = mac_low13_read,
92
- [AIT] = mac_low16_read,
93
94
[CRCERRS ... MPC] = &mac_readreg,
95
[IP6AT ... IP6AT + 3] = &mac_readreg, [IP4AT ... IP4AT + 6] = &mac_readreg,
96
- [FFLT ... FFLT + 6] = &mac_low11_read,
97
+ [FFLT ... FFLT + 6] = &mac_readreg,
98
[RA ... RA + 31] = &mac_readreg,
99
[WUPM ... WUPM + 31] = &mac_readreg,
100
[MTA ... MTA + 127] = &mac_readreg,
101
[VFTA ... VFTA + 127] = &mac_readreg,
102
- [FFMT ... FFMT + 254] = &mac_low4_read,
103
+ [FFMT ... FFMT + 254] = &mac_readreg,
104
[FFVT ... FFVT + 254] = &mac_readreg,
105
[PBM ... PBM + 16383] = &mac_readreg,
106
};
107
@@ -XXX,XX +XXX,XX @@ static const writeops macreg_writeops[] = {
108
putreg(PBA), putreg(EERD), putreg(SWSM), putreg(WUFC),
109
putreg(TDBAL), putreg(TDBAH), putreg(TXDCTL), putreg(RDBAH),
110
putreg(RDBAL), putreg(LEDCTL), putreg(VET), putreg(FCRUC),
111
- putreg(TDFH), putreg(TDFT), putreg(TDFHS), putreg(TDFTS),
112
- putreg(TDFPC), putreg(RDFH), putreg(RDFT), putreg(RDFHS),
113
- putreg(RDFTS), putreg(RDFPC), putreg(IPAV), putreg(WUC),
114
- putreg(WUS), putreg(AIT),
115
-
116
- [TDLEN] = set_dlen, [RDLEN] = set_dlen, [TCTL] = set_tctl,
117
- [TDT] = set_tctl, [MDIC] = set_mdic, [ICS] = set_ics,
118
- [TDH] = set_16bit, [RDH] = set_16bit, [RDT] = set_rdt,
119
- [IMC] = set_imc, [IMS] = set_ims, [ICR] = set_icr,
120
- [EECD] = set_eecd, [RCTL] = set_rx_control, [CTRL] = set_ctrl,
121
- [RDTR] = set_16bit, [RADV] = set_16bit, [TADV] = set_16bit,
122
- [ITR] = set_16bit,
123
+ putreg(IPAV), putreg(WUC),
124
+ putreg(WUS),
125
+
126
+ [TDLEN] = set_dlen, [RDLEN] = set_dlen, [TCTL] = set_tctl,
127
+ [TDT] = set_tctl, [MDIC] = set_mdic, [ICS] = set_ics,
128
+ [TDH] = set_16bit, [RDH] = set_16bit, [RDT] = set_rdt,
129
+ [IMC] = set_imc, [IMS] = set_ims, [ICR] = set_icr,
130
+ [EECD] = set_eecd, [RCTL] = set_rx_control, [CTRL] = set_ctrl,
131
+ [RDTR] = set_16bit, [RADV] = set_16bit, [TADV] = set_16bit,
132
+ [ITR] = set_16bit, [TDFH] = set_11bit, [TDFT] = set_11bit,
133
+ [TDFHS] = set_13bit, [TDFTS] = set_13bit, [TDFPC] = set_13bit,
134
+ [RDFH] = set_13bit, [RDFT] = set_13bit, [RDFHS] = set_13bit,
135
+ [RDFTS] = set_13bit, [RDFPC] = set_13bit, [AIT] = set_16bit,
136
137
[IP6AT ... IP6AT + 3] = &mac_writereg, [IP4AT ... IP4AT + 6] = &mac_writereg,
138
- [FFLT ... FFLT + 6] = &mac_writereg,
139
+ [FFLT ... FFLT + 6] = &set_11bit,
140
[RA ... RA + 31] = &mac_writereg,
141
[WUPM ... WUPM + 31] = &mac_writereg,
142
[MTA ... MTA + 127] = &mac_writereg,
143
[VFTA ... VFTA + 127] = &mac_writereg,
144
- [FFMT ... FFMT + 254] = &mac_writereg, [FFVT ... FFVT + 254] = &mac_writereg,
145
+ [FFMT ... FFMT + 254] = &set_4bit, [FFVT ... FFVT + 254] = &mac_writereg,
146
[PBM ... PBM + 16383] = &mac_writereg,
147
};
148
149
--
150
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
e1000e_set_16bit and e1000e_set_12bit look so similar so define a
4
generic macro.
5
6
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
hw/net/e1000e_core.c | 18 ++++++++----------
10
1 file changed, 8 insertions(+), 10 deletions(-)
11
12
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/e1000e_core.c
15
+++ b/hw/net/e1000e_core.c
16
@@ -XXX,XX +XXX,XX @@ e1000e_set_fcrtl(E1000ECore *core, int index, uint32_t val)
17
core->mac[FCRTL] = val & 0x8000FFF8;
18
}
19
20
-static inline void
21
-e1000e_set_16bit(E1000ECore *core, int index, uint32_t val)
22
-{
23
- core->mac[index] = val & 0xffff;
24
-}
25
+#define E1000E_LOW_BITS_SET_FUNC(num) \
26
+ static void \
27
+ e1000e_set_##num##bit(E1000ECore *core, int index, uint32_t val) \
28
+ { \
29
+ core->mac[index] = val & (BIT(num) - 1); \
30
+ }
31
32
-static void
33
-e1000e_set_12bit(E1000ECore *core, int index, uint32_t val)
34
-{
35
- core->mac[index] = val & 0xfff;
36
-}
37
+E1000E_LOW_BITS_SET_FUNC(12)
38
+E1000E_LOW_BITS_SET_FUNC(16)
39
40
static void
41
e1000e_set_vet(E1000ECore *core, int index, uint32_t val)
42
--
43
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
When a register has effective bits fewer than their width, the old code
4
inconsistently masked when writing or reading. Make the code consistent
5
by always masking when writing, and remove some code duplication.
6
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
hw/net/e1000e_core.c | 76 ++++++++++++++++++++++------------------------------
11
1 file changed, 32 insertions(+), 44 deletions(-)
12
13
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/e1000e_core.c
16
+++ b/hw/net/e1000e_core.c
17
@@ -XXX,XX +XXX,XX @@ e1000e_set_fcrtl(E1000ECore *core, int index, uint32_t val)
18
core->mac[index] = val & (BIT(num) - 1); \
19
}
20
21
+E1000E_LOW_BITS_SET_FUNC(4)
22
+E1000E_LOW_BITS_SET_FUNC(6)
23
+E1000E_LOW_BITS_SET_FUNC(11)
24
E1000E_LOW_BITS_SET_FUNC(12)
25
+E1000E_LOW_BITS_SET_FUNC(13)
26
E1000E_LOW_BITS_SET_FUNC(16)
27
28
static void
29
@@ -XXX,XX +XXX,XX @@ e1000e_mac_ims_read(E1000ECore *core, int index)
30
return core->mac[IMS];
31
}
32
33
-#define E1000E_LOW_BITS_READ_FUNC(num) \
34
- static uint32_t \
35
- e1000e_mac_low##num##_read(E1000ECore *core, int index) \
36
- { \
37
- return core->mac[index] & (BIT(num) - 1); \
38
- } \
39
-
40
-#define E1000E_LOW_BITS_READ(num) \
41
- e1000e_mac_low##num##_read
42
-
43
-E1000E_LOW_BITS_READ_FUNC(4);
44
-E1000E_LOW_BITS_READ_FUNC(6);
45
-E1000E_LOW_BITS_READ_FUNC(11);
46
-E1000E_LOW_BITS_READ_FUNC(13);
47
-E1000E_LOW_BITS_READ_FUNC(16);
48
-
49
static uint32_t
50
e1000e_mac_swsm_read(E1000ECore *core, int index)
51
{
52
@@ -XXX,XX +XXX,XX @@ static const readops e1000e_macreg_readops[] = {
53
e1000e_getreg(LATECOL),
54
e1000e_getreg(SEQEC),
55
e1000e_getreg(XONTXC),
56
+ e1000e_getreg(AIT),
57
+ e1000e_getreg(TDFH),
58
+ e1000e_getreg(TDFT),
59
+ e1000e_getreg(TDFHS),
60
+ e1000e_getreg(TDFTS),
61
+ e1000e_getreg(TDFPC),
62
e1000e_getreg(WUS),
63
+ e1000e_getreg(PBS),
64
+ e1000e_getreg(RDFH),
65
+ e1000e_getreg(RDFT),
66
+ e1000e_getreg(RDFHS),
67
+ e1000e_getreg(RDFTS),
68
+ e1000e_getreg(RDFPC),
69
e1000e_getreg(GORCL),
70
e1000e_getreg(MGTPRC),
71
e1000e_getreg(EERD),
72
@@ -XXX,XX +XXX,XX @@ static const readops e1000e_macreg_readops[] = {
73
[MPTC] = e1000e_mac_read_clr4,
74
[IAC] = e1000e_mac_read_clr4,
75
[ICR] = e1000e_mac_icr_read,
76
- [RDFH] = E1000E_LOW_BITS_READ(13),
77
- [RDFHS] = E1000E_LOW_BITS_READ(13),
78
- [RDFPC] = E1000E_LOW_BITS_READ(13),
79
- [TDFH] = E1000E_LOW_BITS_READ(13),
80
- [TDFHS] = E1000E_LOW_BITS_READ(13),
81
[STATUS] = e1000e_get_status,
82
[TARC0] = e1000e_get_tarc,
83
- [PBS] = E1000E_LOW_BITS_READ(6),
84
[ICS] = e1000e_mac_ics_read,
85
- [AIT] = E1000E_LOW_BITS_READ(16),
86
[TORH] = e1000e_mac_read_clr8,
87
[GORCH] = e1000e_mac_read_clr8,
88
[PRC127] = e1000e_mac_read_clr4,
89
@@ -XXX,XX +XXX,XX @@ static const readops e1000e_macreg_readops[] = {
90
[BPTC] = e1000e_mac_read_clr4,
91
[TSCTC] = e1000e_mac_read_clr4,
92
[ITR] = e1000e_mac_itr_read,
93
- [RDFT] = E1000E_LOW_BITS_READ(13),
94
- [RDFTS] = E1000E_LOW_BITS_READ(13),
95
- [TDFPC] = E1000E_LOW_BITS_READ(13),
96
- [TDFT] = E1000E_LOW_BITS_READ(13),
97
- [TDFTS] = E1000E_LOW_BITS_READ(13),
98
[CTRL] = e1000e_get_ctrl,
99
[TARC1] = e1000e_get_tarc,
100
[SWSM] = e1000e_mac_swsm_read,
101
@@ -XXX,XX +XXX,XX @@ static const readops e1000e_macreg_readops[] = {
102
[WUPM ... WUPM + 31] = e1000e_mac_readreg,
103
[MTA ... MTA + 127] = e1000e_mac_readreg,
104
[VFTA ... VFTA + 127] = e1000e_mac_readreg,
105
- [FFMT ... FFMT + 254] = E1000E_LOW_BITS_READ(4),
106
+ [FFMT ... FFMT + 254] = e1000e_mac_readreg,
107
[FFVT ... FFVT + 254] = e1000e_mac_readreg,
108
[MDEF ... MDEF + 7] = e1000e_mac_readreg,
109
- [FFLT ... FFLT + 10] = E1000E_LOW_BITS_READ(11),
110
+ [FFLT ... FFLT + 10] = e1000e_mac_readreg,
111
[FTFT ... FTFT + 254] = e1000e_mac_readreg,
112
[PBM ... PBM + 10239] = e1000e_mac_readreg,
113
[RETA ... RETA + 31] = e1000e_mac_readreg,
114
@@ -XXX,XX +XXX,XX @@ static const writeops e1000e_macreg_writeops[] = {
115
e1000e_putreg(LEDCTL),
116
e1000e_putreg(FCAL),
117
e1000e_putreg(FCRUC),
118
- e1000e_putreg(AIT),
119
- e1000e_putreg(TDFH),
120
- e1000e_putreg(TDFT),
121
- e1000e_putreg(TDFHS),
122
- e1000e_putreg(TDFTS),
123
- e1000e_putreg(TDFPC),
124
e1000e_putreg(WUC),
125
e1000e_putreg(WUS),
126
- e1000e_putreg(RDFH),
127
- e1000e_putreg(RDFT),
128
- e1000e_putreg(RDFHS),
129
- e1000e_putreg(RDFTS),
130
- e1000e_putreg(RDFPC),
131
e1000e_putreg(IPAV),
132
e1000e_putreg(TDBAH1),
133
e1000e_putreg(TIMINCA),
134
@@ -XXX,XX +XXX,XX @@ static const writeops e1000e_macreg_writeops[] = {
135
e1000e_putreg(TARC1),
136
e1000e_putreg(FLSWDATA),
137
e1000e_putreg(POEMB),
138
- e1000e_putreg(PBS),
139
e1000e_putreg(MFUTP01),
140
e1000e_putreg(MFUTP23),
141
e1000e_putreg(MANC),
142
@@ -XXX,XX +XXX,XX @@ static const writeops e1000e_macreg_writeops[] = {
143
[TADV] = e1000e_set_16bit,
144
[ITR] = e1000e_set_itr,
145
[EERD] = e1000e_set_eerd,
146
+ [AIT] = e1000e_set_16bit,
147
+ [TDFH] = e1000e_set_13bit,
148
+ [TDFT] = e1000e_set_13bit,
149
+ [TDFHS] = e1000e_set_13bit,
150
+ [TDFTS] = e1000e_set_13bit,
151
+ [TDFPC] = e1000e_set_13bit,
152
+ [RDFH] = e1000e_set_13bit,
153
+ [RDFHS] = e1000e_set_13bit,
154
+ [RDFT] = e1000e_set_13bit,
155
+ [RDFTS] = e1000e_set_13bit,
156
+ [RDFPC] = e1000e_set_13bit,
157
+ [PBS] = e1000e_set_6bit,
158
[GCR] = e1000e_set_gcr,
159
[PSRCTL] = e1000e_set_psrctl,
160
[RXCSUM] = e1000e_set_rxcsum,
161
@@ -XXX,XX +XXX,XX @@ static const writeops e1000e_macreg_writeops[] = {
162
[WUPM ... WUPM + 31] = e1000e_mac_writereg,
163
[MTA ... MTA + 127] = e1000e_mac_writereg,
164
[VFTA ... VFTA + 127] = e1000e_mac_writereg,
165
- [FFMT ... FFMT + 254] = e1000e_mac_writereg,
166
+ [FFMT ... FFMT + 254] = e1000e_set_4bit,
167
[FFVT ... FFVT + 254] = e1000e_mac_writereg,
168
[PBM ... PBM + 10239] = e1000e_mac_writereg,
169
[MDEF ... MDEF + 7] = e1000e_mac_writereg,
170
- [FFLT ... FFLT + 10] = e1000e_mac_writereg,
171
+ [FFLT ... FFLT + 10] = e1000e_set_11bit,
172
[FTFT ... FTFT + 254] = e1000e_mac_writereg,
173
[RETA ... RETA + 31] = e1000e_mac_writereg,
174
[RSSRK ... RSSRK + 31] = e1000e_mac_writereg,
175
--
176
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
The definitions for E1000_VFTA_ENTRY_SHIFT, E1000_VFTA_ENTRY_MASK, and
4
E1000_VFTA_ENTRY_BIT_SHIFT_MASK were copied from:
5
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/net/ethernet/intel/e1000/e1000_hw.h?h=v6.0.9#n306
6
7
The definitions for E1000_NUM_UNICAST, E1000_MC_TBL_SIZE, and
8
E1000_VLAN_FILTER_TBL_SIZE were copied from:
9
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/net/ethernet/intel/e1000/e1000_hw.h?h=v6.0.9#n707
10
11
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
15
hw/net/e1000.c | 50 ++++++++++++++++++++++++++++----------------------
16
hw/net/e1000_regs.h | 9 +++++++++
17
hw/net/e1000x_common.c | 5 +++--
18
hw/net/e1000x_common.h | 2 +-
19
4 files changed, 41 insertions(+), 25 deletions(-)
20
21
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/net/e1000.c
24
+++ b/hw/net/e1000.c
25
@@ -XXX,XX +XXX,XX @@
26
#include "trace.h"
27
#include "qom/object.h"
28
29
-static const uint8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
30
-
31
/* #define E1000_DEBUG */
32
33
#ifdef E1000_DEBUG
34
@@ -XXX,XX +XXX,XX @@ static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL);
35
36
#define IOPORT_SIZE 0x40
37
#define PNPMMIO_SIZE 0x20000
38
-#define MIN_BUF_SIZE 60 /* Min. octets in an ethernet frame sans FCS */
39
40
-#define MAXIMUM_ETHERNET_HDR_LEN (14+4)
41
+#define MAXIMUM_ETHERNET_HDR_LEN (ETH_HLEN + 4)
42
43
/*
44
* HW models:
45
@@ -XXX,XX +XXX,XX @@ static const uint16_t phy_reg_init[] = {
46
47
[MII_PHYID1] = 0x141,
48
/* [MII_PHYID2] configured per DevId, from e1000_reset() */
49
- [MII_ANAR] = 0xde1,
50
- [MII_ANLPAR] = 0x1e0,
51
- [MII_CTRL1000] = 0x0e00,
52
- [MII_STAT1000] = 0x3c00,
53
+ [MII_ANAR] = MII_ANAR_CSMACD | MII_ANAR_10 |
54
+ MII_ANAR_10FD | MII_ANAR_TX |
55
+ MII_ANAR_TXFD | MII_ANAR_PAUSE |
56
+ MII_ANAR_PAUSE_ASYM,
57
+ [MII_ANLPAR] = MII_ANLPAR_10 | MII_ANLPAR_10FD |
58
+ MII_ANLPAR_TX | MII_ANLPAR_TXFD,
59
+ [MII_CTRL1000] = MII_CTRL1000_FULL | MII_CTRL1000_PORT |
60
+ MII_CTRL1000_MASTER,
61
+ [MII_STAT1000] = MII_STAT1000_HALF | MII_STAT1000_FULL |
62
+ MII_STAT1000_ROK | MII_STAT1000_LOK,
63
[M88E1000_PHY_SPEC_CTRL] = 0x360,
64
[M88E1000_PHY_SPEC_STATUS] = 0xac00,
65
[M88E1000_EXT_PHY_SPEC_CTRL] = 0x0d60,
66
@@ -XXX,XX +XXX,XX @@ putsum(uint8_t *data, uint32_t n, uint32_t sloc, uint32_t css, uint32_t cse)
67
static inline void
68
inc_tx_bcast_or_mcast_count(E1000State *s, const unsigned char *arr)
69
{
70
- if (!memcmp(arr, bcast, sizeof bcast)) {
71
+ if (is_broadcast_ether_addr(arr)) {
72
e1000x_inc_reg_if_not_full(s->mac_reg, BPTC);
73
- } else if (arr[0] & 1) {
74
+ } else if (is_multicast_ether_addr(arr)) {
75
e1000x_inc_reg_if_not_full(s->mac_reg, MPTC);
76
}
77
}
78
@@ -XXX,XX +XXX,XX @@ static int
79
receive_filter(E1000State *s, const uint8_t *buf, int size)
80
{
81
uint32_t rctl = s->mac_reg[RCTL];
82
- int isbcast = !memcmp(buf, bcast, sizeof bcast), ismcast = (buf[0] & 1);
83
+ int isbcast = is_broadcast_ether_addr(buf);
84
+ int ismcast = is_multicast_ether_addr(buf);
85
86
if (e1000x_is_vlan_packet(buf, le16_to_cpu(s->mac_reg[VET])) &&
87
e1000x_vlan_rx_filter_enabled(s->mac_reg)) {
88
- uint16_t vid = lduw_be_p(buf + 14);
89
- uint32_t vfta = ldl_le_p((uint32_t *)(s->mac_reg + VFTA) +
90
- ((vid >> 5) & 0x7f));
91
- if ((vfta & (1 << (vid & 0x1f))) == 0) {
92
+ uint16_t vid = lduw_be_p(&PKT_GET_VLAN_HDR(buf)->h_tci);
93
+ uint32_t vfta =
94
+ ldl_le_p((uint32_t *)(s->mac_reg + VFTA) +
95
+ ((vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK));
96
+ if ((vfta & (1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK))) == 0) {
97
return 0;
98
}
99
}
100
@@ -XXX,XX +XXX,XX @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
101
uint32_t rdh_start;
102
uint16_t vlan_special = 0;
103
uint8_t vlan_status = 0;
104
- uint8_t min_buf[MIN_BUF_SIZE];
105
+ uint8_t min_buf[ETH_ZLEN];
106
struct iovec min_iov;
107
uint8_t *filter_buf = iov->iov_base;
108
size_t size = iov_size(iov, iovcnt);
109
@@ -XXX,XX +XXX,XX @@ static const readops macreg_readops[] = {
110
[FFLT ... FFLT + 6] = &mac_readreg,
111
[RA ... RA + 31] = &mac_readreg,
112
[WUPM ... WUPM + 31] = &mac_readreg,
113
- [MTA ... MTA + 127] = &mac_readreg,
114
- [VFTA ... VFTA + 127] = &mac_readreg,
115
+ [MTA ... MTA + E1000_MC_TBL_SIZE - 1] = &mac_readreg,
116
+ [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] = &mac_readreg,
117
[FFMT ... FFMT + 254] = &mac_readreg,
118
[FFVT ... FFVT + 254] = &mac_readreg,
119
[PBM ... PBM + 16383] = &mac_readreg,
120
@@ -XXX,XX +XXX,XX @@ static const writeops macreg_writeops[] = {
121
[FFLT ... FFLT + 6] = &set_11bit,
122
[RA ... RA + 31] = &mac_writereg,
123
[WUPM ... WUPM + 31] = &mac_writereg,
124
- [MTA ... MTA + 127] = &mac_writereg,
125
- [VFTA ... VFTA + 127] = &mac_writereg,
126
+ [MTA ... MTA + E1000_MC_TBL_SIZE - 1] = &mac_writereg,
127
+ [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] = &mac_writereg,
128
[FFMT ... FFMT + 254] = &set_4bit, [FFVT ... FFVT + 254] = &mac_writereg,
129
[PBM ... PBM + 16383] = &mac_writereg,
130
};
131
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_e1000 = {
132
VMSTATE_UINT32(mac_reg[WUFC], E1000State),
133
VMSTATE_UINT32(mac_reg[VET], E1000State),
134
VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, RA, 32),
135
- VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, MTA, 128),
136
- VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, VFTA, 128),
137
+ VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, MTA, E1000_MC_TBL_SIZE),
138
+ VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, VFTA,
139
+ E1000_VLAN_FILTER_TBL_SIZE),
140
VMSTATE_END_OF_LIST()
141
},
142
.subsections = (const VMStateDescription*[]) {
143
diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h
144
index XXXXXXX..XXXXXXX 100644
145
--- a/hw/net/e1000_regs.h
146
+++ b/hw/net/e1000_regs.h
147
@@ -XXX,XX +XXX,XX @@ struct e1000_data_desc {
148
} upper;
149
};
150
151
+/* Filters */
152
+#define E1000_NUM_UNICAST 16 /* Unicast filter entries */
153
+#define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
154
+#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
155
+
156
/* Management Control */
157
#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
158
#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
159
@@ -XXX,XX +XXX,XX @@ struct e1000_data_desc {
160
#define E1000_IOADDR 0x00
161
#define E1000_IODATA 0x04
162
163
+#define E1000_VFTA_ENTRY_SHIFT 5
164
+#define E1000_VFTA_ENTRY_MASK 0x7F
165
+#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
166
+
167
#endif /* HW_E1000_REGS_H */
168
diff --git a/hw/net/e1000x_common.c b/hw/net/e1000x_common.c
169
index XXXXXXX..XXXXXXX 100644
170
--- a/hw/net/e1000x_common.c
171
+++ b/hw/net/e1000x_common.c
172
@@ -XXX,XX +XXX,XX @@
173
#include "qemu/units.h"
174
#include "hw/net/mii.h"
175
#include "hw/pci/pci_device.h"
176
+#include "net/eth.h"
177
#include "net/net.h"
178
179
#include "e1000x_common.h"
180
@@ -XXX,XX +XXX,XX @@ bool e1000x_rx_ready(PCIDevice *d, uint32_t *mac)
181
182
bool e1000x_is_vlan_packet(const uint8_t *buf, uint16_t vet)
183
{
184
- uint16_t eth_proto = lduw_be_p(buf + 12);
185
+ uint16_t eth_proto = lduw_be_p(&PKT_GET_ETH_HDR(buf)->h_proto);
186
bool res = (eth_proto == vet);
187
188
trace_e1000x_vlan_is_vlan_pkt(res, eth_proto, vet);
189
@@ -XXX,XX +XXX,XX @@ bool e1000x_rx_group_filter(uint32_t *mac, const uint8_t *buf)
190
}
191
ra[0] = cpu_to_le32(rp[0]);
192
ra[1] = cpu_to_le32(rp[1]);
193
- if (!memcmp(buf, (uint8_t *)ra, 6)) {
194
+ if (!memcmp(buf, (uint8_t *)ra, ETH_ALEN)) {
195
trace_e1000x_rx_flt_ucast_match((int)(rp - mac - RA) / 2,
196
MAC_ARG(buf));
197
return true;
198
diff --git a/hw/net/e1000x_common.h b/hw/net/e1000x_common.h
199
index XXXXXXX..XXXXXXX 100644
200
--- a/hw/net/e1000x_common.h
201
+++ b/hw/net/e1000x_common.h
202
@@ -XXX,XX +XXX,XX @@ enum {
203
static inline void
204
e1000x_inc_reg_if_not_full(uint32_t *mac, int index)
205
{
206
- if (mac[index] != 0xffffffff) {
207
+ if (mac[index] != UINT32_MAX) {
208
mac[index]++;
209
}
210
}
211
--
212
2.7.4
213
214
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
The definitions of SW Semaphore Register were copied from:
4
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/net/ethernet/intel/e1000e/defines.h?h=v6.0.9#n374
5
6
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
hw/net/e1000_regs.h | 7 +++++++
10
hw/net/e1000e_core.c | 49 +++++++++++++++++++++++++++----------------------
11
2 files changed, 34 insertions(+), 22 deletions(-)
12
13
diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/e1000_regs.h
16
+++ b/hw/net/e1000_regs.h
17
@@ -XXX,XX +XXX,XX @@
18
#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */
19
#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */
20
21
+/* SW Semaphore Register */
22
+#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
23
+#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
24
+#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
25
+
26
+#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */
27
+
28
/* Interrupt Cause Read */
29
#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
30
#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
31
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/net/e1000e_core.c
34
+++ b/hw/net/e1000e_core.c
35
@@ -XXX,XX +XXX,XX @@ e1000e_receive_filter(E1000ECore *core, const uint8_t *buf, int size)
36
37
if (e1000x_is_vlan_packet(buf, core->mac[VET]) &&
38
e1000x_vlan_rx_filter_enabled(core->mac)) {
39
- uint16_t vid = lduw_be_p(buf + 14);
40
- uint32_t vfta = ldl_le_p((uint32_t *)(core->mac + VFTA) +
41
- ((vid >> 5) & 0x7f));
42
- if ((vfta & (1 << (vid & 0x1f))) == 0) {
43
+ uint16_t vid = lduw_be_p(&PKT_GET_VLAN_HDR(buf)->h_tci);
44
+ uint32_t vfta =
45
+ ldl_le_p((uint32_t *)(core->mac + VFTA) +
46
+ ((vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK));
47
+ if ((vfta & (1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK))) == 0) {
48
trace_e1000e_rx_flt_vlan_mismatch(vid);
49
return false;
50
} else {
51
@@ -XXX,XX +XXX,XX @@ e1000e_rx_fix_l4_csum(E1000ECore *core, struct NetRxPkt *pkt)
52
}
53
}
54
55
-/* Min. octets in an ethernet frame sans FCS */
56
-#define MIN_BUF_SIZE 60
57
-
58
ssize_t
59
e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt)
60
{
61
- static const int maximum_ethernet_hdr_len = (14 + 4);
62
+ static const int maximum_ethernet_hdr_len = (ETH_HLEN + 4);
63
64
uint32_t n = 0;
65
- uint8_t min_buf[MIN_BUF_SIZE];
66
+ uint8_t min_buf[ETH_ZLEN];
67
struct iovec min_iov;
68
uint8_t *filter_buf;
69
size_t size, orig_size;
70
@@ -XXX,XX +XXX,XX @@ static uint32_t
71
e1000e_mac_swsm_read(E1000ECore *core, int index)
72
{
73
uint32_t val = core->mac[SWSM];
74
- core->mac[SWSM] = val | 1;
75
+ core->mac[SWSM] = val | E1000_SWSM_SMBI;
76
return val;
77
}
78
79
@@ -XXX,XX +XXX,XX @@ static const readops e1000e_macreg_readops[] = {
80
[IP4AT ... IP4AT + 6] = e1000e_mac_readreg,
81
[RA ... RA + 31] = e1000e_mac_readreg,
82
[WUPM ... WUPM + 31] = e1000e_mac_readreg,
83
- [MTA ... MTA + 127] = e1000e_mac_readreg,
84
- [VFTA ... VFTA + 127] = e1000e_mac_readreg,
85
+ [MTA ... MTA + E1000_MC_TBL_SIZE - 1] = e1000e_mac_readreg,
86
+ [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] = e1000e_mac_readreg,
87
[FFMT ... FFMT + 254] = e1000e_mac_readreg,
88
[FFVT ... FFVT + 254] = e1000e_mac_readreg,
89
[MDEF ... MDEF + 7] = e1000e_mac_readreg,
90
@@ -XXX,XX +XXX,XX @@ static const writeops e1000e_macreg_writeops[] = {
91
[IP4AT ... IP4AT + 6] = e1000e_mac_writereg,
92
[RA + 2 ... RA + 31] = e1000e_mac_writereg,
93
[WUPM ... WUPM + 31] = e1000e_mac_writereg,
94
- [MTA ... MTA + 127] = e1000e_mac_writereg,
95
- [VFTA ... VFTA + 127] = e1000e_mac_writereg,
96
+ [MTA ... MTA + E1000_MC_TBL_SIZE - 1] = e1000e_mac_writereg,
97
+ [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] = e1000e_mac_writereg,
98
[FFMT ... FFMT + 254] = e1000e_set_4bit,
99
[FFVT ... FFVT + 254] = e1000e_mac_writereg,
100
[PBM ... PBM + 10239] = e1000e_mac_writereg,
101
@@ -XXX,XX +XXX,XX @@ static const uint16_t mac_reg_access[E1000E_MAC_SIZE] = {
102
[TDH_A] = 0x0cf8, [TDT_A] = 0x0cf8, [TIDV_A] = 0x0cf8,
103
[TDFH_A] = 0xed00, [TDFT_A] = 0xed00,
104
[RA_A ... RA_A + 31] = 0x14f0,
105
- [VFTA_A ... VFTA_A + 127] = 0x1400,
106
+ [VFTA_A ... VFTA_A + E1000_VLAN_FILTER_TBL_SIZE - 1] = 0x1400,
107
[RDBAL0_A ... RDLEN0_A] = 0x09bc,
108
[TDBAL_A ... TDLEN_A] = 0x0cf8,
109
/* Access options */
110
@@ -XXX,XX +XXX,XX @@ e1000e_phy_reg_init[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE] = {
111
112
[MII_PHYID1] = 0x141,
113
[MII_PHYID2] = E1000_PHY_ID2_82574x,
114
- [MII_ANAR] = 0xde1,
115
- [MII_ANLPAR] = 0x7e0,
116
- [MII_ANER] = BIT(2),
117
- [MII_ANNP] = BIT(0) | BIT(13),
118
- [MII_CTRL1000] = BIT(8) | BIT(9) | BIT(10) | BIT(11),
119
- [MII_STAT1000] = 0x3c00,
120
- [MII_EXTSTAT] = BIT(12) | BIT(13),
121
+ [MII_ANAR] = MII_ANAR_CSMACD | MII_ANAR_10 |
122
+ MII_ANAR_10FD | MII_ANAR_TX |
123
+ MII_ANAR_TXFD | MII_ANAR_PAUSE |
124
+ MII_ANAR_PAUSE_ASYM,
125
+ [MII_ANLPAR] = MII_ANLPAR_10 | MII_ANLPAR_10FD |
126
+ MII_ANLPAR_TX | MII_ANLPAR_TXFD |
127
+ MII_ANLPAR_T4 | MII_ANLPAR_PAUSE,
128
+ [MII_ANER] = MII_ANER_NP,
129
+ [MII_ANNP] = 1 | MII_ANNP_MP,
130
+ [MII_CTRL1000] = MII_CTRL1000_HALF | MII_CTRL1000_FULL |
131
+ MII_CTRL1000_PORT | MII_CTRL1000_MASTER,
132
+ [MII_STAT1000] = MII_STAT1000_HALF | MII_STAT1000_FULL |
133
+ MII_STAT1000_ROK | MII_STAT1000_LOK,
134
+ [MII_EXTSTAT] = MII_EXTSTAT_1000T_HD | MII_EXTSTAT_1000T_FD,
135
136
[PHY_COPPER_CTRL1] = BIT(5) | BIT(6) | BIT(8) | BIT(9) |
137
BIT(12) | BIT(13),
138
--
139
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
Use memcpy instead of memmove to initialize registers. The initial
4
register templates and register table instances will never overlap.
5
6
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
hw/net/e1000.c | 4 ++--
10
1 file changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/e1000.c
15
+++ b/hw/net/e1000.c
16
@@ -XXX,XX +XXX,XX @@ static void e1000_reset(void *opaque)
17
d->mit_irq_level = 0;
18
d->mit_ide = 0;
19
memset(d->phy_reg, 0, sizeof d->phy_reg);
20
- memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init);
21
+ memcpy(d->phy_reg, phy_reg_init, sizeof phy_reg_init);
22
d->phy_reg[MII_PHYID2] = edc->phy_id2;
23
memset(d->mac_reg, 0, sizeof d->mac_reg);
24
- memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init);
25
+ memcpy(d->mac_reg, mac_reg_init, sizeof mac_reg_init);
26
d->rxbuf_min_shift = 1;
27
memset(&d->tx, 0, sizeof d->tx);
28
29
--
30
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
Use memcpy instead of memmove to initialize registers. The initial
4
register templates and register table instances will never overlap.
5
6
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
hw/net/e1000e_core.c | 4 ++--
10
1 file changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/e1000e_core.c
15
+++ b/hw/net/e1000e_core.c
16
@@ -XXX,XX +XXX,XX @@ e1000e_core_reset(E1000ECore *core)
17
e1000e_intrmgr_reset(core);
18
19
memset(core->phy, 0, sizeof core->phy);
20
- memmove(core->phy, e1000e_phy_reg_init, sizeof e1000e_phy_reg_init);
21
+ memcpy(core->phy, e1000e_phy_reg_init, sizeof e1000e_phy_reg_init);
22
memset(core->mac, 0, sizeof core->mac);
23
- memmove(core->mac, e1000e_mac_reg_init, sizeof e1000e_mac_reg_init);
24
+ memcpy(core->mac, e1000e_mac_reg_init, sizeof e1000e_mac_reg_init);
25
26
core->rxbuf_min_shift = 1 + E1000_RING_DESC_LEN_SHIFT;
27
28
--
29
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
They are duplicate of running throttling timer flags and incomplete as
4
the flags are not cleared when the interrupts are fired or the device is
5
reset.
6
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
hw/net/e1000e.c | 5 ++---
11
hw/net/e1000e_core.c | 19 +++----------------
12
hw/net/e1000e_core.h | 2 --
13
hw/net/trace-events | 2 --
14
4 files changed, 5 insertions(+), 23 deletions(-)
15
16
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/e1000e.c
19
+++ b/hw/net/e1000e.c
20
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription e1000e_vmstate = {
21
VMSTATE_E1000E_INTR_DELAY_TIMER(core.tidv, E1000EState),
22
23
VMSTATE_E1000E_INTR_DELAY_TIMER(core.itr, E1000EState),
24
- VMSTATE_BOOL(core.itr_intr_pending, E1000EState),
25
+ VMSTATE_UNUSED(1),
26
27
VMSTATE_E1000E_INTR_DELAY_TIMER_ARRAY(core.eitr, E1000EState,
28
E1000E_MSIX_VEC_NUM),
29
- VMSTATE_BOOL_ARRAY(core.eitr_intr_pending, E1000EState,
30
- E1000E_MSIX_VEC_NUM),
31
+ VMSTATE_UNUSED(E1000E_MSIX_VEC_NUM),
32
33
VMSTATE_UINT32(core.itr_guest_value, E1000EState),
34
VMSTATE_UINT32_ARRAY(core.eitr_guest_value, E1000EState,
35
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/net/e1000e_core.c
38
+++ b/hw/net/e1000e_core.c
39
@@ -XXX,XX +XXX,XX @@ e1000e_intrmgr_on_throttling_timer(void *opaque)
40
41
timer->running = false;
42
43
- if (!timer->core->itr_intr_pending) {
44
- trace_e1000e_irq_throttling_no_pending_interrupts();
45
- return;
46
- }
47
-
48
if (msi_enabled(timer->core->owner)) {
49
trace_e1000e_irq_msi_notify_postponed();
50
/* Clear msi_causes_pending to fire MSI eventually */
51
@@ -XXX,XX +XXX,XX @@ e1000e_intrmgr_on_msix_throttling_timer(void *opaque)
52
53
timer->running = false;
54
55
- if (!timer->core->eitr_intr_pending[idx]) {
56
- trace_e1000e_irq_throttling_no_pending_vec(idx);
57
- return;
58
- }
59
-
60
trace_e1000e_irq_msix_notify_postponed_vec(idx);
61
msix_notify(timer->core->owner, idx);
62
}
63
@@ -XXX,XX +XXX,XX @@ e1000e_clear_ims_bits(E1000ECore *core, uint32_t bits)
64
}
65
66
static inline bool
67
-e1000e_postpone_interrupt(bool *interrupt_pending,
68
- E1000IntrDelayTimer *timer)
69
+e1000e_postpone_interrupt(E1000IntrDelayTimer *timer)
70
{
71
if (timer->running) {
72
trace_e1000e_irq_postponed_by_xitr(timer->delay_reg << 2);
73
74
- *interrupt_pending = true;
75
return true;
76
}
77
78
@@ -XXX,XX +XXX,XX @@ e1000e_postpone_interrupt(bool *interrupt_pending,
79
static inline bool
80
e1000e_itr_should_postpone(E1000ECore *core)
81
{
82
- return e1000e_postpone_interrupt(&core->itr_intr_pending, &core->itr);
83
+ return e1000e_postpone_interrupt(&core->itr);
84
}
85
86
static inline bool
87
e1000e_eitr_should_postpone(E1000ECore *core, int idx)
88
{
89
- return e1000e_postpone_interrupt(&core->eitr_intr_pending[idx],
90
- &core->eitr[idx]);
91
+ return e1000e_postpone_interrupt(&core->eitr[idx]);
92
}
93
94
static void
95
diff --git a/hw/net/e1000e_core.h b/hw/net/e1000e_core.h
96
index XXXXXXX..XXXXXXX 100644
97
--- a/hw/net/e1000e_core.h
98
+++ b/hw/net/e1000e_core.h
99
@@ -XXX,XX +XXX,XX @@ struct E1000Core {
100
E1000IntrDelayTimer tidv;
101
102
E1000IntrDelayTimer itr;
103
- bool itr_intr_pending;
104
105
E1000IntrDelayTimer eitr[E1000E_MSIX_VEC_NUM];
106
- bool eitr_intr_pending[E1000E_MSIX_VEC_NUM];
107
108
VMChangeStateEntry *vmstate;
109
110
diff --git a/hw/net/trace-events b/hw/net/trace-events
111
index XXXXXXX..XXXXXXX 100644
112
--- a/hw/net/trace-events
113
+++ b/hw/net/trace-events
114
@@ -XXX,XX +XXX,XX @@ e1000e_rx_metadata_ipv6_filtering_disabled(void) "IPv6 RX filtering disabled by
115
e1000e_vlan_vet(uint16_t vet) "Setting VLAN ethernet type 0x%X"
116
117
e1000e_irq_msi_notify(uint32_t cause) "MSI notify 0x%x"
118
-e1000e_irq_throttling_no_pending_interrupts(void) "No pending interrupts to notify"
119
e1000e_irq_msi_notify_postponed(void) "Sending MSI postponed by ITR"
120
e1000e_irq_legacy_notify_postponed(void) "Raising legacy IRQ postponed by ITR"
121
-e1000e_irq_throttling_no_pending_vec(int idx) "No pending interrupts for vector %d"
122
e1000e_irq_msix_notify_postponed_vec(int idx) "Sending MSI-X postponed by EITR[%d]"
123
e1000e_irq_legacy_notify(bool level) "IRQ line state: %d"
124
e1000e_irq_msix_notify_vec(uint32_t vector) "MSI-X notify vector 0x%x"
125
--
126
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
This change makes e1000e reset more things when software reset was
4
triggered. Some registers are exempted from software reset in the
5
datasheet and this change also implements the behavior accordingly.
6
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
hw/net/e1000e_core.c | 24 +++++++++++++++++++-----
11
1 file changed, 19 insertions(+), 5 deletions(-)
12
13
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/e1000e_core.c
16
+++ b/hw/net/e1000e_core.c
17
@@ -XXX,XX +XXX,XX @@
18
static inline void
19
e1000e_set_interrupt_cause(E1000ECore *core, uint32_t val);
20
21
+static void e1000e_reset(E1000ECore *core, bool sw);
22
+
23
static inline void
24
e1000e_process_ts_option(E1000ECore *core, struct e1000_tx_desc *dp)
25
{
26
@@ -XXX,XX +XXX,XX @@ e1000e_set_ctrl(E1000ECore *core, int index, uint32_t val)
27
28
if (val & E1000_CTRL_RST) {
29
trace_e1000e_core_ctrl_sw_reset();
30
- e1000x_reset_mac_addr(core->owner_nic, core->mac, core->permanent_mac);
31
+ e1000e_reset(core, true);
32
}
33
34
if (val & E1000_CTRL_PHY_RST) {
35
@@ -XXX,XX +XXX,XX @@ static const uint32_t e1000e_mac_reg_init[] = {
36
[EITR...EITR + E1000E_MSIX_VEC_NUM - 1] = E1000E_MIN_XITR,
37
};
38
39
-void
40
-e1000e_core_reset(E1000ECore *core)
41
+static void e1000e_reset(E1000ECore *core, bool sw)
42
{
43
int i;
44
45
@@ -XXX,XX +XXX,XX @@ e1000e_core_reset(E1000ECore *core)
46
47
memset(core->phy, 0, sizeof core->phy);
48
memcpy(core->phy, e1000e_phy_reg_init, sizeof e1000e_phy_reg_init);
49
- memset(core->mac, 0, sizeof core->mac);
50
- memcpy(core->mac, e1000e_mac_reg_init, sizeof e1000e_mac_reg_init);
51
+
52
+ for (i = 0; i < E1000E_MAC_SIZE; i++) {
53
+ if (sw && (i == PBA || i == PBS || i == FLA)) {
54
+ continue;
55
+ }
56
+
57
+ core->mac[i] = i < ARRAY_SIZE(e1000e_mac_reg_init) ?
58
+ e1000e_mac_reg_init[i] : 0;
59
+ }
60
61
core->rxbuf_min_shift = 1 + E1000_RING_DESC_LEN_SHIFT;
62
63
@@ -XXX,XX +XXX,XX @@ e1000e_core_reset(E1000ECore *core)
64
}
65
}
66
67
+void
68
+e1000e_core_reset(E1000ECore *core)
69
+{
70
+ e1000e_reset(core, false);
71
+}
72
+
73
void e1000e_core_pre_save(E1000ECore *core)
74
{
75
int i;
76
--
77
2.7.4
diff view generated by jsdifflib
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
1
From: Eugenio Pérez <eperezma@redhat.com>
2
2
3
This is part of recent efforts of refactoring e1000 and e1000e.
3
SVQ is able to log the dirty bits by itself, so let's use it to not
4
block migration.
4
5
5
DeviceClass's reset member is deprecated so migrate to ResettableClass.
6
Also, ignore set and clear of VHOST_F_LOG_ALL on set_features if SVQ is
6
There is no behavioral difference.
7
enabled. Even if the device supports it, the reports would be nonsense
8
because SVQ memory is in the qemu region.
7
9
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
The log region is still allocated. Future changes might skip that, but
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
this series is already long enough.
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
13
Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
14
Acked-by: Michael S. Tsirkin <mst@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
16
---
13
hw/net/e1000.c | 13 ++++---------
17
hw/virtio/vhost-vdpa.c | 39 +++++++++++++++++++++++++++++++++++----
14
1 file changed, 4 insertions(+), 9 deletions(-)
18
include/hw/virtio/vhost-vdpa.h | 1 +
19
2 files changed, 36 insertions(+), 4 deletions(-)
15
20
16
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
21
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/e1000.c
23
--- a/hw/virtio/vhost-vdpa.c
19
+++ b/hw/net/e1000.c
24
+++ b/hw/virtio/vhost-vdpa.c
20
@@ -XXX,XX +XXX,XX @@ static bool e1000_vet_init_need(void *opaque)
25
@@ -XXX,XX +XXX,XX @@ static bool vhost_vdpa_one_time_request(struct vhost_dev *dev)
21
return chkflag(VET);
26
return v->index != 0;
22
}
27
}
23
28
24
-static void e1000_reset(void *opaque)
29
+static int vhost_vdpa_get_dev_features(struct vhost_dev *dev,
25
+static void e1000_reset_hold(Object *obj)
30
+ uint64_t *features)
31
+{
32
+ int ret;
33
+
34
+ ret = vhost_vdpa_call(dev, VHOST_GET_FEATURES, features);
35
+ trace_vhost_vdpa_get_features(dev, *features);
36
+ return ret;
37
+}
38
+
39
static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v,
40
Error **errp)
26
{
41
{
27
- E1000State *d = opaque;
42
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v,
28
+ E1000State *d = E1000(obj);
43
return 0;
29
E1000BaseClass *edc = E1000_GET_CLASS(d);
44
}
30
uint8_t *macaddr = d->conf.macaddr.a;
45
31
46
- r = hdev->vhost_ops->vhost_get_features(hdev, &dev_features);
32
@@ -XXX,XX +XXX,XX @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp)
47
+ r = vhost_vdpa_get_dev_features(hdev, &dev_features);
33
e1000_flush_queue_timer, d);
48
if (r != 0) {
49
error_setg_errno(errp, -r, "Can't get vdpa device features");
50
return r;
51
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_set_mem_table(struct vhost_dev *dev,
52
static int vhost_vdpa_set_features(struct vhost_dev *dev,
53
uint64_t features)
54
{
55
+ struct vhost_vdpa *v = dev->opaque;
56
int ret;
57
58
if (vhost_vdpa_one_time_request(dev)) {
59
return 0;
60
}
61
62
+ if (v->shadow_vqs_enabled) {
63
+ if ((v->acked_features ^ features) == BIT_ULL(VHOST_F_LOG_ALL)) {
64
+ /*
65
+ * QEMU is just trying to enable or disable logging. SVQ handles
66
+ * this sepparately, so no need to forward this.
67
+ */
68
+ v->acked_features = features;
69
+ return 0;
70
+ }
71
+
72
+ v->acked_features = features;
73
+
74
+ /* We must not ack _F_LOG if SVQ is enabled */
75
+ features &= ~BIT_ULL(VHOST_F_LOG_ALL);
76
+ }
77
+
78
trace_vhost_vdpa_set_features(dev, features);
79
ret = vhost_vdpa_call(dev, VHOST_SET_FEATURES, &features);
80
if (ret) {
81
@@ -XXX,XX +XXX,XX @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
82
static int vhost_vdpa_get_features(struct vhost_dev *dev,
83
uint64_t *features)
84
{
85
- int ret;
86
+ struct vhost_vdpa *v = dev->opaque;
87
+ int ret = vhost_vdpa_get_dev_features(dev, features);
88
+
89
+ if (ret == 0 && v->shadow_vqs_enabled) {
90
+ /* Add SVQ logging capabilities */
91
+ *features |= BIT_ULL(VHOST_F_LOG_ALL);
92
+ }
93
94
- ret = vhost_vdpa_call(dev, VHOST_GET_FEATURES, features);
95
- trace_vhost_vdpa_get_features(dev, *features);
96
return ret;
34
}
97
}
35
98
36
-static void qdev_e1000_reset(DeviceState *dev)
99
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
37
-{
100
index XXXXXXX..XXXXXXX 100644
38
- E1000State *d = E1000(dev);
101
--- a/include/hw/virtio/vhost-vdpa.h
39
- e1000_reset(d);
102
+++ b/include/hw/virtio/vhost-vdpa.h
40
-}
103
@@ -XXX,XX +XXX,XX @@ typedef struct vhost_vdpa {
41
-
104
bool iotlb_batch_begin_sent;
42
static Property e1000_properties[] = {
105
MemoryListener listener;
43
DEFINE_NIC_PROPERTIES(E1000State, conf),
106
struct vhost_vdpa_iova_range iova_range;
44
DEFINE_PROP_BIT("autonegotiation", E1000State,
107
+ uint64_t acked_features;
45
@@ -XXX,XX +XXX,XX @@ typedef struct E1000Info {
108
bool shadow_vqs_enabled;
46
static void e1000_class_init(ObjectClass *klass, void *data)
109
/* IOVA mapping used by the Shadow Virtqueue */
47
{
110
VhostIOVATree *iova_tree;
48
DeviceClass *dc = DEVICE_CLASS(klass);
49
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
50
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
51
E1000BaseClass *e = E1000_CLASS(klass);
52
const E1000Info *info = data;
53
@@ -XXX,XX +XXX,XX @@ static void e1000_class_init(ObjectClass *klass, void *data)
54
k->revision = info->revision;
55
e->phy_id2 = info->phy_id2;
56
k->class_id = PCI_CLASS_NETWORK_ETHERNET;
57
+ rc->phases.hold = e1000_reset_hold;
58
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
59
dc->desc = "Intel Gigabit Ethernet";
60
- dc->reset = qdev_e1000_reset;
61
dc->vmsd = &vmstate_e1000;
62
device_class_set_props(dc, e1000_properties);
63
}
64
--
111
--
65
2.7.4
112
2.7.4
66
113
67
114
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
Before this change, e1000e_write_packet_to_guest() allocated the
4
receive descriptor buffer as an array of uint8_t. This does not ensure
5
the buffer is sufficiently aligned.
6
7
Introduce e1000_rx_desc_union type, a union type of all receive
8
descriptor types to correct this.
9
10
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
13
hw/net/e1000_regs.h | 1 -
14
hw/net/e1000e_core.c | 115 +++++++++++++++++++++++++--------------------------
15
2 files changed, 57 insertions(+), 59 deletions(-)
16
17
diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/net/e1000_regs.h
20
+++ b/hw/net/e1000_regs.h
21
@@ -XXX,XX +XXX,XX @@ union e1000_rx_desc_packet_split {
22
#define E1000_RING_DESC_LEN_SHIFT (4)
23
24
#define E1000_MIN_RX_DESC_LEN E1000_RING_DESC_LEN
25
-#define E1000_MAX_RX_DESC_LEN (sizeof(union e1000_rx_desc_packet_split))
26
27
/* Receive Descriptor bit definitions */
28
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
29
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/net/e1000e_core.c
32
+++ b/hw/net/e1000e_core.c
33
@@ -XXX,XX +XXX,XX @@
34
35
#define E1000E_MAX_TX_FRAGS (64)
36
37
+union e1000_rx_desc_union {
38
+ struct e1000_rx_desc legacy;
39
+ union e1000_rx_desc_extended extended;
40
+ union e1000_rx_desc_packet_split packet_split;
41
+};
42
+
43
static inline void
44
e1000e_set_interrupt_cause(E1000ECore *core, uint32_t val);
45
46
@@ -XXX,XX +XXX,XX @@ e1000e_receive_filter(E1000ECore *core, const uint8_t *buf, int size)
47
}
48
49
static inline void
50
-e1000e_read_lgcy_rx_descr(E1000ECore *core, uint8_t *desc, hwaddr *buff_addr)
51
+e1000e_read_lgcy_rx_descr(E1000ECore *core, struct e1000_rx_desc *desc,
52
+ hwaddr *buff_addr)
53
{
54
- struct e1000_rx_desc *d = (struct e1000_rx_desc *) desc;
55
- *buff_addr = le64_to_cpu(d->buffer_addr);
56
+ *buff_addr = le64_to_cpu(desc->buffer_addr);
57
}
58
59
static inline void
60
-e1000e_read_ext_rx_descr(E1000ECore *core, uint8_t *desc, hwaddr *buff_addr)
61
+e1000e_read_ext_rx_descr(E1000ECore *core, union e1000_rx_desc_extended *desc,
62
+ hwaddr *buff_addr)
63
{
64
- union e1000_rx_desc_extended *d = (union e1000_rx_desc_extended *) desc;
65
- *buff_addr = le64_to_cpu(d->read.buffer_addr);
66
+ *buff_addr = le64_to_cpu(desc->read.buffer_addr);
67
}
68
69
static inline void
70
-e1000e_read_ps_rx_descr(E1000ECore *core, uint8_t *desc,
71
+e1000e_read_ps_rx_descr(E1000ECore *core,
72
+ union e1000_rx_desc_packet_split *desc,
73
hwaddr (*buff_addr)[MAX_PS_BUFFERS])
74
{
75
int i;
76
- union e1000_rx_desc_packet_split *d =
77
- (union e1000_rx_desc_packet_split *) desc;
78
79
for (i = 0; i < MAX_PS_BUFFERS; i++) {
80
- (*buff_addr)[i] = le64_to_cpu(d->read.buffer_addr[i]);
81
+ (*buff_addr)[i] = le64_to_cpu(desc->read.buffer_addr[i]);
82
}
83
84
trace_e1000e_rx_desc_ps_read((*buff_addr)[0], (*buff_addr)[1],
85
@@ -XXX,XX +XXX,XX @@ e1000e_read_ps_rx_descr(E1000ECore *core, uint8_t *desc,
86
}
87
88
static inline void
89
-e1000e_read_rx_descr(E1000ECore *core, uint8_t *desc,
90
+e1000e_read_rx_descr(E1000ECore *core, union e1000_rx_desc_union *desc,
91
hwaddr (*buff_addr)[MAX_PS_BUFFERS])
92
{
93
if (e1000e_rx_use_legacy_descriptor(core)) {
94
- e1000e_read_lgcy_rx_descr(core, desc, &(*buff_addr)[0]);
95
+ e1000e_read_lgcy_rx_descr(core, &desc->legacy, &(*buff_addr)[0]);
96
(*buff_addr)[1] = (*buff_addr)[2] = (*buff_addr)[3] = 0;
97
} else {
98
if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) {
99
- e1000e_read_ps_rx_descr(core, desc, buff_addr);
100
+ e1000e_read_ps_rx_descr(core, &desc->packet_split, buff_addr);
101
} else {
102
- e1000e_read_ext_rx_descr(core, desc, &(*buff_addr)[0]);
103
+ e1000e_read_ext_rx_descr(core, &desc->extended, &(*buff_addr)[0]);
104
(*buff_addr)[1] = (*buff_addr)[2] = (*buff_addr)[3] = 0;
105
}
106
}
107
@@ -XXX,XX +XXX,XX @@ func_exit:
108
}
109
110
static inline void
111
-e1000e_write_lgcy_rx_descr(E1000ECore *core, uint8_t *desc,
112
+e1000e_write_lgcy_rx_descr(E1000ECore *core, struct e1000_rx_desc *desc,
113
struct NetRxPkt *pkt,
114
const E1000E_RSSInfo *rss_info,
115
uint16_t length)
116
@@ -XXX,XX +XXX,XX @@ e1000e_write_lgcy_rx_descr(E1000ECore *core, uint8_t *desc,
117
uint32_t status_flags, rss, mrq;
118
uint16_t ip_id;
119
120
- struct e1000_rx_desc *d = (struct e1000_rx_desc *) desc;
121
-
122
assert(!rss_info->enabled);
123
124
- d->length = cpu_to_le16(length);
125
- d->csum = 0;
126
+ desc->length = cpu_to_le16(length);
127
+ desc->csum = 0;
128
129
e1000e_build_rx_metadata(core, pkt, pkt != NULL,
130
rss_info,
131
&rss, &mrq,
132
&status_flags, &ip_id,
133
- &d->special);
134
- d->errors = (uint8_t) (le32_to_cpu(status_flags) >> 24);
135
- d->status = (uint8_t) le32_to_cpu(status_flags);
136
+ &desc->special);
137
+ desc->errors = (uint8_t) (le32_to_cpu(status_flags) >> 24);
138
+ desc->status = (uint8_t) le32_to_cpu(status_flags);
139
}
140
141
static inline void
142
-e1000e_write_ext_rx_descr(E1000ECore *core, uint8_t *desc,
143
+e1000e_write_ext_rx_descr(E1000ECore *core, union e1000_rx_desc_extended *desc,
144
struct NetRxPkt *pkt,
145
const E1000E_RSSInfo *rss_info,
146
uint16_t length)
147
{
148
- union e1000_rx_desc_extended *d = (union e1000_rx_desc_extended *) desc;
149
-
150
- memset(&d->wb, 0, sizeof(d->wb));
151
+ memset(&desc->wb, 0, sizeof(desc->wb));
152
153
- d->wb.upper.length = cpu_to_le16(length);
154
+ desc->wb.upper.length = cpu_to_le16(length);
155
156
e1000e_build_rx_metadata(core, pkt, pkt != NULL,
157
rss_info,
158
- &d->wb.lower.hi_dword.rss,
159
- &d->wb.lower.mrq,
160
- &d->wb.upper.status_error,
161
- &d->wb.lower.hi_dword.csum_ip.ip_id,
162
- &d->wb.upper.vlan);
163
+ &desc->wb.lower.hi_dword.rss,
164
+ &desc->wb.lower.mrq,
165
+ &desc->wb.upper.status_error,
166
+ &desc->wb.lower.hi_dword.csum_ip.ip_id,
167
+ &desc->wb.upper.vlan);
168
}
169
170
static inline void
171
-e1000e_write_ps_rx_descr(E1000ECore *core, uint8_t *desc,
172
+e1000e_write_ps_rx_descr(E1000ECore *core,
173
+ union e1000_rx_desc_packet_split *desc,
174
struct NetRxPkt *pkt,
175
const E1000E_RSSInfo *rss_info,
176
size_t ps_hdr_len,
177
uint16_t(*written)[MAX_PS_BUFFERS])
178
{
179
int i;
180
- union e1000_rx_desc_packet_split *d =
181
- (union e1000_rx_desc_packet_split *) desc;
182
183
- memset(&d->wb, 0, sizeof(d->wb));
184
+ memset(&desc->wb, 0, sizeof(desc->wb));
185
186
- d->wb.middle.length0 = cpu_to_le16((*written)[0]);
187
+ desc->wb.middle.length0 = cpu_to_le16((*written)[0]);
188
189
for (i = 0; i < PS_PAGE_BUFFERS; i++) {
190
- d->wb.upper.length[i] = cpu_to_le16((*written)[i + 1]);
191
+ desc->wb.upper.length[i] = cpu_to_le16((*written)[i + 1]);
192
}
193
194
e1000e_build_rx_metadata(core, pkt, pkt != NULL,
195
rss_info,
196
- &d->wb.lower.hi_dword.rss,
197
- &d->wb.lower.mrq,
198
- &d->wb.middle.status_error,
199
- &d->wb.lower.hi_dword.csum_ip.ip_id,
200
- &d->wb.middle.vlan);
201
+ &desc->wb.lower.hi_dword.rss,
202
+ &desc->wb.lower.mrq,
203
+ &desc->wb.middle.status_error,
204
+ &desc->wb.lower.hi_dword.csum_ip.ip_id,
205
+ &desc->wb.middle.vlan);
206
207
- d->wb.upper.header_status =
208
+ desc->wb.upper.header_status =
209
cpu_to_le16(ps_hdr_len | (ps_hdr_len ? E1000_RXDPS_HDRSTAT_HDRSP : 0));
210
211
trace_e1000e_rx_desc_ps_write((*written)[0], (*written)[1],
212
@@ -XXX,XX +XXX,XX @@ e1000e_write_ps_rx_descr(E1000ECore *core, uint8_t *desc,
213
}
214
215
static inline void
216
-e1000e_write_rx_descr(E1000ECore *core, uint8_t *desc,
217
+e1000e_write_rx_descr(E1000ECore *core, union e1000_rx_desc_union *desc,
218
struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info,
219
size_t ps_hdr_len, uint16_t(*written)[MAX_PS_BUFFERS])
220
{
221
if (e1000e_rx_use_legacy_descriptor(core)) {
222
assert(ps_hdr_len == 0);
223
- e1000e_write_lgcy_rx_descr(core, desc, pkt, rss_info, (*written)[0]);
224
+ e1000e_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info,
225
+ (*written)[0]);
226
} else {
227
if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) {
228
- e1000e_write_ps_rx_descr(core, desc, pkt, rss_info,
229
+ e1000e_write_ps_rx_descr(core, &desc->packet_split, pkt, rss_info,
230
ps_hdr_len, written);
231
} else {
232
assert(ps_hdr_len == 0);
233
- e1000e_write_ext_rx_descr(core, desc, pkt, rss_info,
234
+ e1000e_write_ext_rx_descr(core, &desc->extended, pkt, rss_info,
235
(*written)[0]);
236
}
237
}
238
@@ -XXX,XX +XXX,XX @@ struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info,
239
240
static inline void
241
e1000e_pci_dma_write_rx_desc(E1000ECore *core, dma_addr_t addr,
242
- uint8_t *desc, dma_addr_t len)
243
+ union e1000_rx_desc_union *desc, dma_addr_t len)
244
{
245
PCIDevice *dev = core->owner;
246
247
if (e1000e_rx_use_legacy_descriptor(core)) {
248
- struct e1000_rx_desc *d = (struct e1000_rx_desc *) desc;
249
+ struct e1000_rx_desc *d = &desc->legacy;
250
size_t offset = offsetof(struct e1000_rx_desc, status);
251
uint8_t status = d->status;
252
253
@@ -XXX,XX +XXX,XX @@ e1000e_pci_dma_write_rx_desc(E1000ECore *core, dma_addr_t addr,
254
}
255
} else {
256
if (core->mac[RCTL] & E1000_RCTL_DTYP_PS) {
257
- union e1000_rx_desc_packet_split *d =
258
- (union e1000_rx_desc_packet_split *) desc;
259
+ union e1000_rx_desc_packet_split *d = &desc->packet_split;
260
size_t offset = offsetof(union e1000_rx_desc_packet_split,
261
wb.middle.status_error);
262
uint32_t status = d->wb.middle.status_error;
263
@@ -XXX,XX +XXX,XX @@ e1000e_pci_dma_write_rx_desc(E1000ECore *core, dma_addr_t addr,
264
pci_dma_write(dev, addr + offset, &status, sizeof(status));
265
}
266
} else {
267
- union e1000_rx_desc_extended *d =
268
- (union e1000_rx_desc_extended *) desc;
269
+ union e1000_rx_desc_extended *d = &desc->extended;
270
size_t offset = offsetof(union e1000_rx_desc_extended,
271
wb.upper.status_error);
272
uint32_t status = d->wb.upper.status_error;
273
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
274
{
275
PCIDevice *d = core->owner;
276
dma_addr_t base;
277
- uint8_t desc[E1000_MAX_RX_DESC_LEN];
278
+ union e1000_rx_desc_union desc;
279
size_t desc_size;
280
size_t desc_offset = 0;
281
size_t iov_ofs = 0;
282
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
283
284
trace_e1000e_rx_descr(rxi->idx, base, core->rx_desc_len);
285
286
- e1000e_read_rx_descr(core, desc, &ba);
287
+ e1000e_read_rx_descr(core, &desc, &ba);
288
289
if (ba[0]) {
290
if (desc_offset < size) {
291
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
292
is_last = true;
293
}
294
295
- e1000e_write_rx_descr(core, desc, is_last ? core->rx_pkt : NULL,
296
+ e1000e_write_rx_descr(core, &desc, is_last ? core->rx_pkt : NULL,
297
rss_info, do_ps ? ps_hdr_len : 0, &bastate.written);
298
- e1000e_pci_dma_write_rx_desc(core, base, desc, core->rx_desc_len);
299
+ e1000e_pci_dma_write_rx_desc(core, base, &desc, core->rx_desc_len);
300
301
e1000e_ring_advance(core, rxi,
302
core->rx_desc_len / E1000_MIN_RX_DESC_LEN);
303
--
304
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
This keeps Windows driver 12.18.9.23 from generating an event with ID
4
30. The description of the event is as follows:
5
> Intel(R) 82574L Gigabit Network Connection
6
> PROBLEM: The network adapter is configured for auto-negotiation but
7
> the link partner is not. This may result in a duplex mismatch.
8
> ACTION: Configure the link partner for auto-negotiation.
9
10
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
14
hw/net/e1000e_core.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
16
17
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/net/e1000e_core.c
20
+++ b/hw/net/e1000e_core.c
21
@@ -XXX,XX +XXX,XX @@ e1000e_phy_reg_init[E1000E_PHY_PAGES][E1000E_PHY_PAGE_SIZE] = {
22
[MII_ANLPAR] = MII_ANLPAR_10 | MII_ANLPAR_10FD |
23
MII_ANLPAR_TX | MII_ANLPAR_TXFD |
24
MII_ANLPAR_T4 | MII_ANLPAR_PAUSE,
25
- [MII_ANER] = MII_ANER_NP,
26
+ [MII_ANER] = MII_ANER_NP | MII_ANER_NWAY,
27
[MII_ANNP] = 1 | MII_ANNP_MP,
28
[MII_CTRL1000] = MII_CTRL1000_HALF | MII_CTRL1000_FULL |
29
MII_CTRL1000_PORT | MII_CTRL1000_MASTER,
30
--
31
2.7.4
32
33
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
e1000x_is_vlan_packet() had a pointer to uint8_t as a parameter, but
4
it does not have to be uint8_t. Change the type to void *.
5
6
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
hw/net/e1000x_common.c | 2 +-
10
hw/net/e1000x_common.h | 2 +-
11
2 files changed, 2 insertions(+), 2 deletions(-)
12
13
diff --git a/hw/net/e1000x_common.c b/hw/net/e1000x_common.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/e1000x_common.c
16
+++ b/hw/net/e1000x_common.c
17
@@ -XXX,XX +XXX,XX @@ bool e1000x_rx_ready(PCIDevice *d, uint32_t *mac)
18
return true;
19
}
20
21
-bool e1000x_is_vlan_packet(const uint8_t *buf, uint16_t vet)
22
+bool e1000x_is_vlan_packet(const void *buf, uint16_t vet)
23
{
24
uint16_t eth_proto = lduw_be_p(&PKT_GET_ETH_HDR(buf)->h_proto);
25
bool res = (eth_proto == vet);
26
diff --git a/hw/net/e1000x_common.h b/hw/net/e1000x_common.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/net/e1000x_common.h
29
+++ b/hw/net/e1000x_common.h
30
@@ -XXX,XX +XXX,XX @@ uint32_t e1000x_rxbufsize(uint32_t rctl);
31
32
bool e1000x_rx_ready(PCIDevice *d, uint32_t *mac);
33
34
-bool e1000x_is_vlan_packet(const uint8_t *buf, uint16_t vet);
35
+bool e1000x_is_vlan_packet(const void *buf, uint16_t vet);
36
37
bool e1000x_rx_group_filter(uint32_t *mac, const uint8_t *buf);
38
39
--
40
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
The new function qemu_get_using_vnet_hdr() allows to automatically
4
determine if virtio-net header is used.
5
6
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
hw/net/e1000e_core.c | 3 +--
10
hw/net/net_tx_pkt.c | 19 ++++++++++---------
11
hw/net/net_tx_pkt.h | 3 +--
12
hw/net/vmxnet3.c | 6 ++----
13
4 files changed, 14 insertions(+), 17 deletions(-)
14
15
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/net/e1000e_core.c
18
+++ b/hw/net/e1000e_core.c
19
@@ -XXX,XX +XXX,XX @@ e1000e_core_pci_realize(E1000ECore *core,
20
qemu_add_vm_change_state_handler(e1000e_vm_state_change, core);
21
22
for (i = 0; i < E1000E_NUM_QUEUES; i++) {
23
- net_tx_pkt_init(&core->tx[i].tx_pkt, core->owner,
24
- E1000E_MAX_TX_FRAGS, core->has_vnet);
25
+ net_tx_pkt_init(&core->tx[i].tx_pkt, core->owner, E1000E_MAX_TX_FRAGS);
26
}
27
28
net_rx_pkt_init(&core->rx_pkt, core->has_vnet);
29
diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/net/net_tx_pkt.c
32
+++ b/hw/net/net_tx_pkt.c
33
@@ -XXX,XX +XXX,XX @@ struct NetTxPkt {
34
PCIDevice *pci_dev;
35
36
struct virtio_net_hdr virt_hdr;
37
- bool has_virt_hdr;
38
39
struct iovec *raw;
40
uint32_t raw_frags;
41
@@ -XXX,XX +XXX,XX @@ struct NetTxPkt {
42
};
43
44
void net_tx_pkt_init(struct NetTxPkt **pkt, PCIDevice *pci_dev,
45
- uint32_t max_frags, bool has_virt_hdr)
46
+ uint32_t max_frags)
47
{
48
struct NetTxPkt *p = g_malloc0(sizeof *p);
49
50
@@ -XXX,XX +XXX,XX @@ void net_tx_pkt_init(struct NetTxPkt **pkt, PCIDevice *pci_dev,
51
52
p->max_payload_frags = max_frags;
53
p->max_raw_frags = max_frags;
54
- p->has_virt_hdr = has_virt_hdr;
55
p->vec[NET_TX_PKT_VHDR_FRAG].iov_base = &p->virt_hdr;
56
- p->vec[NET_TX_PKT_VHDR_FRAG].iov_len =
57
- p->has_virt_hdr ? sizeof p->virt_hdr : 0;
58
+ p->vec[NET_TX_PKT_VHDR_FRAG].iov_len = sizeof p->virt_hdr;
59
p->vec[NET_TX_PKT_L2HDR_FRAG].iov_base = &p->l2_hdr;
60
p->vec[NET_TX_PKT_L3HDR_FRAG].iov_base = &p->l3_hdr;
61
62
@@ -XXX,XX +XXX,XX @@ static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt,
63
64
bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc)
65
{
66
+ bool using_vnet_hdr = qemu_get_using_vnet_hdr(nc->peer);
67
+
68
assert(pkt);
69
70
- if (!pkt->has_virt_hdr &&
71
+ if (!using_vnet_hdr &&
72
pkt->virt_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
73
net_tx_pkt_do_sw_csum(pkt);
74
}
75
@@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc)
76
}
77
}
78
79
- if (pkt->has_virt_hdr ||
80
+ if (using_vnet_hdr ||
81
pkt->virt_hdr.gso_type == VIRTIO_NET_HDR_GSO_NONE) {
82
+ int index = using_vnet_hdr ?
83
+ NET_TX_PKT_VHDR_FRAG : NET_TX_PKT_L2HDR_FRAG;
84
net_tx_pkt_fix_ip6_payload_len(pkt);
85
- net_tx_pkt_sendv(pkt, nc, pkt->vec,
86
- pkt->payload_frags + NET_TX_PKT_PL_START_FRAG);
87
+ net_tx_pkt_sendv(pkt, nc, pkt->vec + index,
88
+ pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - index);
89
return true;
90
}
91
92
diff --git a/hw/net/net_tx_pkt.h b/hw/net/net_tx_pkt.h
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/net/net_tx_pkt.h
95
+++ b/hw/net/net_tx_pkt.h
96
@@ -XXX,XX +XXX,XX @@ struct NetTxPkt;
97
* @pkt: packet pointer
98
* @pci_dev: PCI device processing this packet
99
* @max_frags: max tx ip fragments
100
- * @has_virt_hdr: device uses virtio header.
101
*/
102
void net_tx_pkt_init(struct NetTxPkt **pkt, PCIDevice *pci_dev,
103
- uint32_t max_frags, bool has_virt_hdr);
104
+ uint32_t max_frags);
105
106
/**
107
* Clean all tx packet resources.
108
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/net/vmxnet3.c
111
+++ b/hw/net/vmxnet3.c
112
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_activate_device(VMXNET3State *s)
113
114
/* Preallocate TX packet wrapper */
115
VMW_CFPRN("Max TX fragments is %u", s->max_tx_frags);
116
- net_tx_pkt_init(&s->tx_pkt, PCI_DEVICE(s),
117
- s->max_tx_frags, s->peer_has_vhdr);
118
+ net_tx_pkt_init(&s->tx_pkt, PCI_DEVICE(s), s->max_tx_frags);
119
net_rx_pkt_init(&s->rx_pkt, s->peer_has_vhdr);
120
121
/* Read rings memory locations for RX queues */
122
@@ -XXX,XX +XXX,XX @@ static int vmxnet3_post_load(void *opaque, int version_id)
123
{
124
VMXNET3State *s = opaque;
125
126
- net_tx_pkt_init(&s->tx_pkt, PCI_DEVICE(s),
127
- s->max_tx_frags, s->peer_has_vhdr);
128
+ net_tx_pkt_init(&s->tx_pkt, PCI_DEVICE(s), s->max_tx_frags);
129
net_rx_pkt_init(&s->rx_pkt, s->peer_has_vhdr);
130
131
if (s->msix_used) {
132
--
133
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
When virtio-net header is not set, net_rx_pkt_get_vhdr() returns
4
zero-filled virtio_net_hdr, which is actually valid. In fact, tap device
5
uses zero-filled virtio_net_hdr when virtio-net header is not provided
6
by the peer. Therefore, we can just remove net_rx_pkt_has_virt_hdr() and
7
always assume NetTxPkt has a valid virtio-net header.
8
9
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
hw/net/e1000e_core.c | 16 ++++------------
13
hw/net/net_rx_pkt.c | 11 +----------
14
hw/net/net_rx_pkt.h | 12 +-----------
15
hw/net/trace-events | 1 -
16
hw/net/virtio-net.c | 2 +-
17
hw/net/vmxnet3.c | 12 ++----------
18
6 files changed, 9 insertions(+), 45 deletions(-)
19
20
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/net/e1000e_core.c
23
+++ b/hw/net/e1000e_core.c
24
@@ -XXX,XX +XXX,XX @@ e1000e_build_rx_metadata(E1000ECore *core,
25
goto func_exit;
26
}
27
28
- if (!net_rx_pkt_has_virt_hdr(pkt)) {
29
- trace_e1000e_rx_metadata_no_virthdr();
30
- e1000e_verify_csum_in_sw(core, pkt, status_flags, istcp, isudp);
31
- goto func_exit;
32
- }
33
-
34
vhdr = net_rx_pkt_get_vhdr(pkt);
35
36
if (!(vhdr->flags & VIRTIO_NET_HDR_F_DATA_VALID) &&
37
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
38
static inline void
39
e1000e_rx_fix_l4_csum(E1000ECore *core, struct NetRxPkt *pkt)
40
{
41
- if (net_rx_pkt_has_virt_hdr(pkt)) {
42
- struct virtio_net_hdr *vhdr = net_rx_pkt_get_vhdr(pkt);
43
+ struct virtio_net_hdr *vhdr = net_rx_pkt_get_vhdr(pkt);
44
45
- if (vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
46
- net_rx_pkt_fix_l4_csum(pkt);
47
- }
48
+ if (vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
49
+ net_rx_pkt_fix_l4_csum(pkt);
50
}
51
}
52
53
@@ -XXX,XX +XXX,XX @@ e1000e_core_pci_realize(E1000ECore *core,
54
net_tx_pkt_init(&core->tx[i].tx_pkt, core->owner, E1000E_MAX_TX_FRAGS);
55
}
56
57
- net_rx_pkt_init(&core->rx_pkt, core->has_vnet);
58
+ net_rx_pkt_init(&core->rx_pkt);
59
60
e1000x_core_prepare_eeprom(core->eeprom,
61
eeprom_templ,
62
diff --git a/hw/net/net_rx_pkt.c b/hw/net/net_rx_pkt.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/net/net_rx_pkt.c
65
+++ b/hw/net/net_rx_pkt.c
66
@@ -XXX,XX +XXX,XX @@ struct NetRxPkt {
67
uint32_t tot_len;
68
uint16_t tci;
69
size_t ehdr_buf_len;
70
- bool has_virt_hdr;
71
eth_pkt_types_e packet_type;
72
73
/* Analysis results */
74
@@ -XXX,XX +XXX,XX @@ struct NetRxPkt {
75
eth_l4_hdr_info l4hdr_info;
76
};
77
78
-void net_rx_pkt_init(struct NetRxPkt **pkt, bool has_virt_hdr)
79
+void net_rx_pkt_init(struct NetRxPkt **pkt)
80
{
81
struct NetRxPkt *p = g_malloc0(sizeof *p);
82
- p->has_virt_hdr = has_virt_hdr;
83
p->vec = NULL;
84
p->vec_len_total = 0;
85
*pkt = p;
86
@@ -XXX,XX +XXX,XX @@ bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt)
87
return pkt->ehdr_buf_len ? true : false;
88
}
89
90
-bool net_rx_pkt_has_virt_hdr(struct NetRxPkt *pkt)
91
-{
92
- assert(pkt);
93
-
94
- return pkt->has_virt_hdr;
95
-}
96
-
97
uint16_t net_rx_pkt_get_vlan_tag(struct NetRxPkt *pkt)
98
{
99
assert(pkt);
100
diff --git a/hw/net/net_rx_pkt.h b/hw/net/net_rx_pkt.h
101
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/net/net_rx_pkt.h
103
+++ b/hw/net/net_rx_pkt.h
104
@@ -XXX,XX +XXX,XX @@ void net_rx_pkt_uninit(struct NetRxPkt *pkt);
105
* Init function for rx packet functionality
106
*
107
* @pkt: packet pointer
108
- * @has_virt_hdr: device uses virtio header
109
*
110
*/
111
-void net_rx_pkt_init(struct NetRxPkt **pkt, bool has_virt_hdr);
112
+void net_rx_pkt_init(struct NetRxPkt **pkt);
113
114
/**
115
* returns total length of data attached to rx context
116
@@ -XXX,XX +XXX,XX @@ uint16_t net_rx_pkt_get_vlan_tag(struct NetRxPkt *pkt);
117
bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt);
118
119
/**
120
- * notifies caller if the packet has virtio header
121
- *
122
- * @pkt: packet
123
- * @ret: true if packet has virtio header, false otherwize
124
- *
125
- */
126
-bool net_rx_pkt_has_virt_hdr(struct NetRxPkt *pkt);
127
-
128
-/**
129
* attach scatter-gather data to rx packet
130
*
131
* @pkt: packet
132
diff --git a/hw/net/trace-events b/hw/net/trace-events
133
index XXXXXXX..XXXXXXX 100644
134
--- a/hw/net/trace-events
135
+++ b/hw/net/trace-events
136
@@ -XXX,XX +XXX,XX @@ e1000e_rx_metadata_rss(uint32_t rss, uint32_t mrq) "RSS data: rss: 0x%X, mrq: 0x
137
e1000e_rx_metadata_ip_id(uint16_t ip_id) "the IPv4 ID is 0x%X"
138
e1000e_rx_metadata_ack(void) "the packet is TCP ACK"
139
e1000e_rx_metadata_pkt_type(uint32_t pkt_type) "the packet type is %u"
140
-e1000e_rx_metadata_no_virthdr(void) "the packet has no virt-header"
141
e1000e_rx_metadata_virthdr_no_csum_info(void) "virt-header does not contain checksum info"
142
e1000e_rx_metadata_l3_cso_disabled(void) "IP4 CSO is disabled"
143
e1000e_rx_metadata_l4_cso_disabled(void) "TCP/UDP CSO is disabled"
144
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/hw/net/virtio-net.c
147
+++ b/hw/net/virtio-net.c
148
@@ -XXX,XX +XXX,XX @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
149
QTAILQ_INIT(&n->rsc_chains);
150
n->qdev = dev;
151
152
- net_rx_pkt_init(&n->rx_pkt, false);
153
+ net_rx_pkt_init(&n->rx_pkt);
154
155
if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
156
virtio_net_load_ebpf(n);
157
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/hw/net/vmxnet3.c
160
+++ b/hw/net/vmxnet3.c
161
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_rx_need_csum_calculate(struct NetRxPkt *pkt,
162
uint8_t *data;
163
int len;
164
165
- if (!net_rx_pkt_has_virt_hdr(pkt)) {
166
- return;
167
- }
168
-
169
vhdr = net_rx_pkt_get_vhdr(pkt);
170
if (!VMXNET_FLAG_IS_SET(vhdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM)) {
171
return;
172
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_rx_update_descr(struct NetRxPkt *pkt,
173
rxcd->tci = net_rx_pkt_get_vlan_tag(pkt);
174
}
175
176
- if (!net_rx_pkt_has_virt_hdr(pkt)) {
177
- goto nocsum;
178
- }
179
-
180
vhdr = net_rx_pkt_get_vhdr(pkt);
181
/*
182
* Checksum is valid when lower level tell so or when lower level
183
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_activate_device(VMXNET3State *s)
184
/* Preallocate TX packet wrapper */
185
VMW_CFPRN("Max TX fragments is %u", s->max_tx_frags);
186
net_tx_pkt_init(&s->tx_pkt, PCI_DEVICE(s), s->max_tx_frags);
187
- net_rx_pkt_init(&s->rx_pkt, s->peer_has_vhdr);
188
+ net_rx_pkt_init(&s->rx_pkt);
189
190
/* Read rings memory locations for RX queues */
191
for (i = 0; i < s->rxq_num; i++) {
192
@@ -XXX,XX +XXX,XX @@ static int vmxnet3_post_load(void *opaque, int version_id)
193
VMXNET3State *s = opaque;
194
195
net_tx_pkt_init(&s->tx_pkt, PCI_DEVICE(s), s->max_tx_frags);
196
- net_rx_pkt_init(&s->rx_pkt, s->peer_has_vhdr);
197
+ net_rx_pkt_init(&s->rx_pkt);
198
199
if (s->msix_used) {
200
vmxnet3_use_msix_vectors(s, VMXNET3_MAX_INTRS);
201
--
202
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
Check the payload length if checksumming to ensure the payload contains
4
the space for the resulting value.
5
6
This bug was found by Alexander Bulekov with the fuzzer:
7
https://patchew.org/QEMU/20230129053316.1071513-1-alxndr@bu.edu/
8
9
The fixed test case is:
10
fuzz/crash_6aeaa33e7211ecd603726c53e834df4c6d1e08bc
11
12
Fixes: e263cd49c7 ("Packet abstraction for VMWARE network devices")
13
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
---
16
hw/net/net_tx_pkt.c | 6 ++++++
17
1 file changed, 6 insertions(+)
18
19
diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/net/net_tx_pkt.c
22
+++ b/hw/net/net_tx_pkt.c
23
@@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable,
24
if (csum_enable) {
25
switch (pkt->l4proto) {
26
case IP_PROTO_TCP:
27
+ if (pkt->payload_len < sizeof(struct tcp_hdr)) {
28
+ return false;
29
+ }
30
pkt->virt_hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
31
pkt->virt_hdr.csum_start = pkt->hdr_len;
32
pkt->virt_hdr.csum_offset = offsetof(struct tcp_hdr, th_sum);
33
break;
34
case IP_PROTO_UDP:
35
+ if (pkt->payload_len < sizeof(struct udp_hdr)) {
36
+ return false;
37
+ }
38
pkt->virt_hdr.flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
39
pkt->virt_hdr.csum_start = pkt->hdr_len;
40
pkt->virt_hdr.csum_offset = offsetof(struct udp_hdr, uh_sum);
41
--
42
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
Assertions will fail if MSI-X gets disabled while a timer for MSI-X
4
interrupts is running so remove them to avoid abortions. Fortunately,
5
nothing bad happens even if the assertions won't trigger as
6
msix_notify(), called by timer handlers, does nothing when MSI-X is
7
disabled.
8
9
This bug was found by Alexander Bulekov when fuzzing igb, a new
10
device implementation derived from e1000e:
11
https://patchew.org/QEMU/20230129053316.1071513-1-alxndr@bu.edu/
12
13
The fixed test case is:
14
fuzz/crash_aea040166819193cf9fedb810c6d100221da721a
15
16
Fixes: 6f3fbe4ed0 ("net: Introduce e1000e device emulation")
17
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
18
Signed-off-by: Jason Wang <jasowang@redhat.com>
19
---
20
hw/net/e1000e_core.c | 4 ----
21
1 file changed, 4 deletions(-)
22
23
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/net/e1000e_core.c
26
+++ b/hw/net/e1000e_core.c
27
@@ -XXX,XX +XXX,XX @@ e1000e_intrmgr_on_throttling_timer(void *opaque)
28
{
29
E1000IntrDelayTimer *timer = opaque;
30
31
- assert(!msix_enabled(timer->core->owner));
32
-
33
timer->running = false;
34
35
if (msi_enabled(timer->core->owner)) {
36
@@ -XXX,XX +XXX,XX @@ e1000e_intrmgr_on_msix_throttling_timer(void *opaque)
37
E1000IntrDelayTimer *timer = opaque;
38
int idx = timer - &timer->core->eitr[0];
39
40
- assert(msix_enabled(timer->core->owner));
41
-
42
timer->running = false;
43
44
trace_e1000e_irq_msix_notify_postponed_vec(idx);
45
--
46
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
I want to know to be notified when there is a new change for e1000e
4
as e1000e is similar to igb and such a change may also be applicable for
5
igb.
6
7
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
MAINTAINERS | 2 ++
12
1 file changed, 2 insertions(+)
13
14
diff --git a/MAINTAINERS b/MAINTAINERS
15
index XXXXXXX..XXXXXXX 100644
16
--- a/MAINTAINERS
17
+++ b/MAINTAINERS
18
@@ -XXX,XX +XXX,XX @@ F: docs/specs/rocker.txt
19
20
e1000x
21
M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
22
+R: Akihiko Odaki <akihiko.odaki@daynix.com>
23
S: Maintained
24
F: hw/net/e1000x*
25
26
e1000e
27
M: Dmitry Fleytman <dmitry.fleytman@gmail.com>
28
+R: Akihiko Odaki <akihiko.odaki@daynix.com>
29
S: Maintained
30
F: hw/net/e1000e*
31
F: tests/qtest/fuzz-e1000e-test.c
32
--
33
2.7.4
34
35
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
Acked-by: Thomas Huth <thuth@redhat.com>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
MAINTAINERS | 2 ++
9
1 file changed, 2 insertions(+)
10
11
diff --git a/MAINTAINERS b/MAINTAINERS
12
index XXXXXXX..XXXXXXX 100644
13
--- a/MAINTAINERS
14
+++ b/MAINTAINERS
15
@@ -XXX,XX +XXX,XX @@ R: Akihiko Odaki <akihiko.odaki@daynix.com>
16
S: Maintained
17
F: hw/net/e1000e*
18
F: tests/qtest/fuzz-e1000e-test.c
19
+F: tests/qtest/e1000e-test.c
20
+F: tests/qtest/libqos/e1000e.*
21
22
eepro100
23
M: Stefan Weil <sw@weilnetz.de>
24
--
25
2.7.4
26
27
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
Whether a packet will be written back to the guest depends on the
4
remaining space of the queue. Therefore, e1000e_rx_written_to_guest and
5
e1000e_rx_not_written_to_guest should log the index of the queue instead
6
of generated interrupts. This also removes the need of
7
e1000e_rx_rss_dispatched_to_queue, which logs the queue index.
8
9
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
hw/net/e1000e_core.c | 6 ++----
13
hw/net/trace-events | 5 ++---
14
2 files changed, 4 insertions(+), 7 deletions(-)
15
16
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/e1000e_core.c
19
+++ b/hw/net/e1000e_core.c
20
@@ -XXX,XX +XXX,XX @@ e1000e_receive_internal(E1000ECore *core, const struct iovec *iov, int iovcnt,
21
e1000e_rss_parse_packet(core, core->rx_pkt, &rss_info);
22
e1000e_rx_ring_init(core, &rxr, rss_info.queue);
23
24
- trace_e1000e_rx_rss_dispatched_to_queue(rxr.i->idx);
25
-
26
total_size = net_rx_pkt_get_total_len(core->rx_pkt) +
27
e1000x_fcs_len(core->mac);
28
29
@@ -XXX,XX +XXX,XX @@ e1000e_receive_internal(E1000ECore *core, const struct iovec *iov, int iovcnt,
30
rdmts_hit = e1000e_rx_descr_threshold_hit(core, rxr.i);
31
n |= e1000e_rx_wb_interrupt_cause(core, rxr.i->idx, rdmts_hit);
32
33
- trace_e1000e_rx_written_to_guest(n);
34
+ trace_e1000e_rx_written_to_guest(rxr.i->idx);
35
} else {
36
n |= E1000_ICS_RXO;
37
retval = 0;
38
39
- trace_e1000e_rx_not_written_to_guest(n);
40
+ trace_e1000e_rx_not_written_to_guest(rxr.i->idx);
41
}
42
43
if (!e1000e_intrmgr_delay_rx_causes(core, &n)) {
44
diff --git a/hw/net/trace-events b/hw/net/trace-events
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/net/trace-events
47
+++ b/hw/net/trace-events
48
@@ -XXX,XX +XXX,XX @@ e1000e_rx_descr(int ridx, uint64_t base, uint8_t len) "Next RX descriptor: ring
49
e1000e_rx_set_rctl(uint32_t rctl) "RCTL = 0x%x"
50
e1000e_rx_receive_iov(int iovcnt) "Received vector of %d fragments"
51
e1000e_rx_flt_dropped(void) "Received packet dropped by RX filter"
52
-e1000e_rx_written_to_guest(uint32_t causes) "Received packet written to guest (ICR causes %u)"
53
-e1000e_rx_not_written_to_guest(uint32_t causes) "Received packet NOT written to guest (ICR causes %u)"
54
+e1000e_rx_written_to_guest(int queue_idx) "Received packet written to guest (queue %d)"
55
+e1000e_rx_not_written_to_guest(int queue_idx) "Received packet NOT written to guest (queue %d)"
56
e1000e_rx_interrupt_set(uint32_t causes) "Receive interrupt set (ICR causes %u)"
57
e1000e_rx_interrupt_delayed(uint32_t causes) "Receive interrupt delayed (ICR causes %u)"
58
e1000e_rx_set_cso(int cso_state) "RX CSO state set to %d"
59
@@ -XXX,XX +XXX,XX @@ e1000e_rx_rss_type(uint32_t type) "RSS type is %u"
60
e1000e_rx_rss_ip4(bool isfragment, bool istcp, uint32_t mrqc, bool tcpipv4_enabled, bool ipv4_enabled) "RSS IPv4: fragment %d, tcp %d, mrqc 0x%X, tcpipv4 enabled %d, ipv4 enabled %d"
61
e1000e_rx_rss_ip6_rfctl(uint32_t rfctl) "RSS IPv6: rfctl 0x%X"
62
e1000e_rx_rss_ip6(bool ex_dis, bool new_ex_dis, bool istcp, bool has_ext_headers, bool ex_dst_valid, bool ex_src_valid, uint32_t mrqc, bool tcpipv6_enabled, bool ipv6ex_enabled, bool ipv6_enabled) "RSS IPv6: ex_dis: %d, new_ex_dis: %d, tcp %d, has_ext_headers %d, ex_dst_valid %d, ex_src_valid %d, mrqc 0x%X, tcpipv6 enabled %d, ipv6ex enabled %d, ipv6 enabled %d"
63
-e1000e_rx_rss_dispatched_to_queue(int queue_idx) "Packet being dispatched to queue %d"
64
65
e1000e_rx_metadata_protocols(bool isip4, bool isip6, bool isudp, bool istcp) "protocols: ip4: %d, ip6: %d, udp: %d, tcp: %d"
66
e1000e_rx_metadata_vlan(uint16_t vlan_tag) "VLAN tag is 0x%X"
67
--
68
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
The Software Developer's Manual 13.7.4.5 "Packets Transmitted (64 Bytes)
4
Count" says:
5
> This register counts the number of packets transmitted that are
6
> exactly 64 bytes (from <Destination Address> through <CRC>,
7
> inclusively) in length.
8
9
It also says similar for the other Tx statistics registers. Add the
10
number of bytes for CRC to those registers.
11
12
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
15
hw/net/e1000.c | 4 ++--
16
1 file changed, 2 insertions(+), 2 deletions(-)
17
18
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/net/e1000.c
21
+++ b/hw/net/e1000.c
22
@@ -XXX,XX +XXX,XX @@ e1000_send_packet(E1000State *s, const uint8_t *buf, int size)
23
qemu_send_packet(nc, buf, size);
24
}
25
inc_tx_bcast_or_mcast_count(s, buf);
26
- e1000x_increase_size_stats(s->mac_reg, PTCregs, size);
27
+ e1000x_increase_size_stats(s->mac_reg, PTCregs, size + 4);
28
}
29
30
static void
31
@@ -XXX,XX +XXX,XX @@ xmit_seg(E1000State *s)
32
}
33
34
e1000x_inc_reg_if_not_full(s->mac_reg, TPT);
35
- e1000x_grow_8reg_if_not_full(s->mac_reg, TOTL, s->tx.size);
36
+ e1000x_grow_8reg_if_not_full(s->mac_reg, TOTL, s->tx.size + 4);
37
s->mac_reg[GPTC] = s->mac_reg[TPT];
38
s->mac_reg[GOTCL] = s->mac_reg[TOTL];
39
s->mac_reg[GOTCH] = s->mac_reg[TOTH];
40
--
41
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
The datasheet 8.19.29 "Good Packets Transmitted Count - GPTC (0x04080;
4
RC)" says:
5
> This register counts the number of good (no errors) packets
6
> transmitted. A good transmit packet is considered one that is 64 or
7
> more bytes in length (from <Destination Address> through <CRC>,
8
> inclusively) in length.
9
10
It also says similar for the other Tx statistics registers. Add the
11
number of bytes for CRC to those registers.
12
13
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
---
16
hw/net/e1000e_core.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
18
19
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/net/e1000e_core.c
22
+++ b/hw/net/e1000e_core.c
23
@@ -XXX,XX +XXX,XX @@ e1000e_on_tx_done_update_stats(E1000ECore *core, struct NetTxPkt *tx_pkt)
24
static const int PTCregs[6] = { PTC64, PTC127, PTC255, PTC511,
25
PTC1023, PTC1522 };
26
27
- size_t tot_len = net_tx_pkt_get_total_len(tx_pkt);
28
+ size_t tot_len = net_tx_pkt_get_total_len(tx_pkt) + 4;
29
30
e1000x_increase_size_stats(core->mac, PTCregs, tot_len);
31
e1000x_inc_reg_if_not_full(core->mac, TPT);
32
--
33
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
The system clock is necessary to implement PTP features. While we are
4
not implementing PTP features for e1000e yet, we do have a plan to
5
implement them for igb, a new network device derived from e1000e,
6
so add system clock to the common base first.
7
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
hw/core/machine.c | 1 +
12
hw/net/e1000_regs.h | 27 +++++++++++++++++++++++++++
13
hw/net/e1000e.c | 11 +++++++++++
14
hw/net/e1000e_core.c | 39 ++++++++++++++++++++++++++++++++++-----
15
hw/net/e1000e_core.h | 2 ++
16
hw/net/e1000x_common.c | 25 +++++++++++++++++++++++++
17
hw/net/e1000x_common.h | 3 +++
18
7 files changed, 103 insertions(+), 5 deletions(-)
19
20
diff --git a/hw/core/machine.c b/hw/core/machine.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/core/machine.c
23
+++ b/hw/core/machine.c
24
@@ -XXX,XX +XXX,XX @@
25
#include "hw/virtio/virtio-pci.h"
26
27
GlobalProperty hw_compat_7_2[] = {
28
+ { "e1000e", "migrate-timadj", "off" },
29
{ "virtio-mem", "x-early-migration", "false" },
30
};
31
const size_t hw_compat_7_2_len = G_N_ELEMENTS(hw_compat_7_2);
32
diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/net/e1000_regs.h
35
+++ b/hw/net/e1000_regs.h
36
@@ -XXX,XX +XXX,XX @@
37
#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */
38
#define E1000_EEPROM_CFG_DONE_PORT_1 0x00080000 /* ...for second port */
39
40
+/* HH Time Sync */
41
+#define E1000_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK 0x0000F000 /* max delay */
42
+#define E1000_TSYNCTXCTL_SYNC_COMP 0x40000000 /* sync complete */
43
+#define E1000_TSYNCTXCTL_START_SYNC 0x80000000 /* initiate sync */
44
+
45
+#define E1000_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */
46
+#define E1000_TSYNCTXCTL_ENABLED 0x00000010 /* enable Tx timestamping */
47
+
48
+#define E1000_TSYNCRXCTL_VALID 0x00000001 /* Rx timestamp valid */
49
+#define E1000_TSYNCRXCTL_TYPE_MASK 0x0000000E /* Rx type mask */
50
+#define E1000_TSYNCRXCTL_TYPE_L2_V2 0x00
51
+#define E1000_TSYNCRXCTL_TYPE_L4_V1 0x02
52
+#define E1000_TSYNCRXCTL_TYPE_L2_L4_V2 0x04
53
+#define E1000_TSYNCRXCTL_TYPE_ALL 0x08
54
+#define E1000_TSYNCRXCTL_TYPE_EVENT_V2 0x0A
55
+#define E1000_TSYNCRXCTL_ENABLED 0x00000010 /* enable Rx timestamping */
56
+#define E1000_TSYNCRXCTL_SYSCFI 0x00000020 /* Sys clock frequency */
57
+
58
+#define E1000_RXMTRL_PTP_V1_SYNC_MESSAGE 0x00000000
59
+#define E1000_RXMTRL_PTP_V1_DELAY_REQ_MESSAGE 0x00010000
60
+
61
+#define E1000_RXMTRL_PTP_V2_SYNC_MESSAGE 0x00000000
62
+#define E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE 0x01000000
63
+
64
+#define E1000_TIMINCA_INCPERIOD_SHIFT 24
65
+#define E1000_TIMINCA_INCVALUE_MASK 0x00FFFFFF
66
+
67
/* PCI Express Control */
68
/* 3GIO Control Register - GCR (0x05B00; RW) */
69
#define E1000_L0S_ADJUST (1 << 9)
70
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/net/e1000e.c
73
+++ b/hw/net/e1000e.c
74
@@ -XXX,XX +XXX,XX @@ struct E1000EState {
75
76
E1000ECore core;
77
bool init_vet;
78
+ bool timadj;
79
};
80
81
#define E1000E_MMIO_IDX 0
82
@@ -XXX,XX +XXX,XX @@ static int e1000e_post_load(void *opaque, int version_id)
83
return e1000e_core_post_load(&s->core);
84
}
85
86
+static bool e1000e_migrate_timadj(void *opaque, int version_id)
87
+{
88
+ E1000EState *s = opaque;
89
+ return s->timadj;
90
+}
91
+
92
static const VMStateDescription e1000e_vmstate_tx = {
93
.name = "e1000e-tx",
94
.version_id = 1,
95
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription e1000e_vmstate = {
96
97
VMSTATE_STRUCT_ARRAY(core.tx, E1000EState, E1000E_NUM_QUEUES, 0,
98
e1000e_vmstate_tx, struct e1000e_tx),
99
+
100
+ VMSTATE_INT64_TEST(core.timadj, E1000EState, e1000e_migrate_timadj),
101
+
102
VMSTATE_END_OF_LIST()
103
}
104
};
105
@@ -XXX,XX +XXX,XX @@ static Property e1000e_properties[] = {
106
DEFINE_PROP_SIGNED("subsys", E1000EState, subsys, 0,
107
e1000e_prop_subsys, uint16_t),
108
DEFINE_PROP_BOOL("init-vet", E1000EState, init_vet, true),
109
+ DEFINE_PROP_BOOL("migrate-timadj", E1000EState, timadj, true),
110
DEFINE_PROP_END_OF_LIST(),
111
};
112
113
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/hw/net/e1000e_core.c
116
+++ b/hw/net/e1000e_core.c
117
@@ -XXX,XX +XXX,XX @@ e1000e_set_gcr(E1000ECore *core, int index, uint32_t val)
118
core->mac[GCR] = (val & ~E1000_GCR_RO_BITS) | ro_bits;
119
}
120
121
+static uint32_t e1000e_get_systiml(E1000ECore *core, int index)
122
+{
123
+ e1000x_timestamp(core->mac, core->timadj, SYSTIML, SYSTIMH);
124
+ return core->mac[SYSTIML];
125
+}
126
+
127
+static uint32_t e1000e_get_rxsatrh(E1000ECore *core, int index)
128
+{
129
+ core->mac[TSYNCRXCTL] &= ~E1000_TSYNCRXCTL_VALID;
130
+ return core->mac[RXSATRH];
131
+}
132
+
133
+static uint32_t e1000e_get_txstmph(E1000ECore *core, int index)
134
+{
135
+ core->mac[TSYNCTXCTL] &= ~E1000_TSYNCTXCTL_VALID;
136
+ return core->mac[TXSTMPH];
137
+}
138
+
139
+static void e1000e_set_timinca(E1000ECore *core, int index, uint32_t val)
140
+{
141
+ e1000x_set_timinca(core->mac, &core->timadj, val);
142
+}
143
+
144
+static void e1000e_set_timadjh(E1000ECore *core, int index, uint32_t val)
145
+{
146
+ core->mac[TIMADJH] = val;
147
+ core->timadj += core->mac[TIMADJL] | ((int64_t)core->mac[TIMADJH] << 32);
148
+}
149
+
150
#define e1000e_getreg(x) [x] = e1000e_mac_readreg
151
typedef uint32_t (*readops)(E1000ECore *, int);
152
static const readops e1000e_macreg_readops[] = {
153
@@ -XXX,XX +XXX,XX @@ static const readops e1000e_macreg_readops[] = {
154
e1000e_getreg(GSCL_2),
155
e1000e_getreg(RDBAH1),
156
e1000e_getreg(FLSWDATA),
157
- e1000e_getreg(RXSATRH),
158
e1000e_getreg(TIPG),
159
e1000e_getreg(FLMNGCTL),
160
e1000e_getreg(FLMNGCNT),
161
@@ -XXX,XX +XXX,XX @@ static const readops e1000e_macreg_readops[] = {
162
e1000e_getreg(FLSWCTL),
163
e1000e_getreg(RXDCTL1),
164
e1000e_getreg(RXSATRL),
165
- e1000e_getreg(SYSTIML),
166
e1000e_getreg(RXUDP),
167
e1000e_getreg(TORL),
168
e1000e_getreg(TDLEN1),
169
@@ -XXX,XX +XXX,XX @@ static const readops e1000e_macreg_readops[] = {
170
e1000e_getreg(FLOL),
171
e1000e_getreg(RXDCTL),
172
e1000e_getreg(RXSTMPL),
173
- e1000e_getreg(TXSTMPH),
174
e1000e_getreg(TIMADJH),
175
e1000e_getreg(FCRTL),
176
e1000e_getreg(TDBAH),
177
@@ -XXX,XX +XXX,XX @@ static const readops e1000e_macreg_readops[] = {
178
[TARC1] = e1000e_get_tarc,
179
[SWSM] = e1000e_mac_swsm_read,
180
[IMS] = e1000e_mac_ims_read,
181
+ [SYSTIML] = e1000e_get_systiml,
182
+ [RXSATRH] = e1000e_get_rxsatrh,
183
+ [TXSTMPH] = e1000e_get_txstmph,
184
185
[CRCERRS ... MPC] = e1000e_mac_readreg,
186
[IP6AT ... IP6AT + 3] = e1000e_mac_readreg,
187
@@ -XXX,XX +XXX,XX @@ static const writeops e1000e_macreg_writeops[] = {
188
e1000e_putreg(WUS),
189
e1000e_putreg(IPAV),
190
e1000e_putreg(TDBAH1),
191
- e1000e_putreg(TIMINCA),
192
e1000e_putreg(IAM),
193
e1000e_putreg(EIAC),
194
e1000e_putreg(IVAR),
195
@@ -XXX,XX +XXX,XX @@ static const writeops e1000e_macreg_writeops[] = {
196
e1000e_putreg(SYSTIML),
197
e1000e_putreg(SYSTIMH),
198
e1000e_putreg(TIMADJL),
199
- e1000e_putreg(TIMADJH),
200
e1000e_putreg(RXUDP),
201
e1000e_putreg(RXCFGL),
202
e1000e_putreg(TSYNCRXCTL),
203
@@ -XXX,XX +XXX,XX @@ static const writeops e1000e_macreg_writeops[] = {
204
[CTRL_DUP] = e1000e_set_ctrl,
205
[RFCTL] = e1000e_set_rfctl,
206
[RA + 1] = e1000e_mac_setmacaddr,
207
+ [TIMINCA] = e1000e_set_timinca,
208
+ [TIMADJH] = e1000e_set_timadjh,
209
210
[IP6AT ... IP6AT + 3] = e1000e_mac_writereg,
211
[IP4AT ... IP4AT + 6] = e1000e_mac_writereg,
212
diff --git a/hw/net/e1000e_core.h b/hw/net/e1000e_core.h
213
index XXXXXXX..XXXXXXX 100644
214
--- a/hw/net/e1000e_core.h
215
+++ b/hw/net/e1000e_core.h
216
@@ -XXX,XX +XXX,XX @@ struct E1000Core {
217
void (*owner_start_recv)(PCIDevice *d);
218
219
uint32_t msi_causes_pending;
220
+
221
+ int64_t timadj;
222
};
223
224
void
225
diff --git a/hw/net/e1000x_common.c b/hw/net/e1000x_common.c
226
index XXXXXXX..XXXXXXX 100644
227
--- a/hw/net/e1000x_common.c
228
+++ b/hw/net/e1000x_common.c
229
@@ -XXX,XX +XXX,XX @@ e1000x_read_tx_ctx_descr(struct e1000_context_desc *d,
230
props->tcp = (op & E1000_TXD_CMD_TCP) ? 1 : 0;
231
props->tse = (op & E1000_TXD_CMD_TSE) ? 1 : 0;
232
}
233
+
234
+void e1000x_timestamp(uint32_t *mac, int64_t timadj, size_t lo, size_t hi)
235
+{
236
+ int64_t ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
237
+ uint32_t timinca = mac[TIMINCA];
238
+ uint32_t incvalue = timinca & E1000_TIMINCA_INCVALUE_MASK;
239
+ uint32_t incperiod = MAX(timinca >> E1000_TIMINCA_INCPERIOD_SHIFT, 1);
240
+ int64_t timestamp = timadj + muldiv64(ns, incvalue, incperiod * 16);
241
+
242
+ mac[lo] = timestamp & 0xffffffff;
243
+ mac[hi] = timestamp >> 32;
244
+}
245
+
246
+void e1000x_set_timinca(uint32_t *mac, int64_t *timadj, uint32_t val)
247
+{
248
+ int64_t ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
249
+ uint32_t old_val = mac[TIMINCA];
250
+ uint32_t old_incvalue = old_val & E1000_TIMINCA_INCVALUE_MASK;
251
+ uint32_t old_incperiod = MAX(old_val >> E1000_TIMINCA_INCPERIOD_SHIFT, 1);
252
+ uint32_t incvalue = val & E1000_TIMINCA_INCVALUE_MASK;
253
+ uint32_t incperiod = MAX(val >> E1000_TIMINCA_INCPERIOD_SHIFT, 1);
254
+
255
+ mac[TIMINCA] = val;
256
+ *timadj += (muldiv64(ns, incvalue, incperiod) - muldiv64(ns, old_incvalue, old_incperiod)) / 16;
257
+}
258
diff --git a/hw/net/e1000x_common.h b/hw/net/e1000x_common.h
259
index XXXXXXX..XXXXXXX 100644
260
--- a/hw/net/e1000x_common.h
261
+++ b/hw/net/e1000x_common.h
262
@@ -XXX,XX +XXX,XX @@ typedef struct e1000x_txd_props {
263
void e1000x_read_tx_ctx_descr(struct e1000_context_desc *d,
264
e1000x_txd_props *props);
265
266
+void e1000x_timestamp(uint32_t *mac, int64_t timadj, size_t lo, size_t hi);
267
+void e1000x_set_timinca(uint32_t *mac, int64_t *timadj, uint32_t val);
268
+
269
#endif
270
--
271
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
igb, a new network device emulation, will need SCTP checksum offloading.
4
Currently eth_get_protocols() has a bool parameter for each protocol
5
currently it supports, but there will be a bit too many parameters if
6
we add yet another protocol.
7
8
Introduce an enum type, EthL4HdrProto to represent all L4 protocols
9
eth_get_protocols() support with one parameter.
10
11
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
14
hw/net/e1000e_core.c | 60 ++++++++++++++++++++++++++-------------------
15
hw/net/net_rx_pkt.c | 48 ++++++++++++++++++------------------
16
hw/net/net_rx_pkt.h | 5 ++--
17
hw/net/trace-events | 8 +++---
18
hw/net/virtio-net.c | 69 ++++++++++++++++++++++++++++++++++------------------
19
hw/net/vmxnet3.c | 22 +++++++++++------
20
include/net/eth.h | 8 +++++-
21
net/eth.c | 26 +++++++++++---------
22
8 files changed, 147 insertions(+), 99 deletions(-)
23
24
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/net/e1000e_core.c
27
+++ b/hw/net/e1000e_core.c
28
@@ -XXX,XX +XXX,XX @@ typedef struct E1000E_RSSInfo_st {
29
static uint32_t
30
e1000e_rss_get_hash_type(E1000ECore *core, struct NetRxPkt *pkt)
31
{
32
- bool hasip4, hasip6, hasudp, hastcp;
33
+ bool hasip4, hasip6;
34
+ EthL4HdrProto l4hdr_proto;
35
36
assert(e1000e_rss_enabled(core));
37
38
- net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
39
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
40
41
if (hasip4) {
42
- trace_e1000e_rx_rss_ip4(hastcp, core->mac[MRQC],
43
+ trace_e1000e_rx_rss_ip4(l4hdr_proto, core->mac[MRQC],
44
E1000_MRQC_EN_TCPIPV4(core->mac[MRQC]),
45
E1000_MRQC_EN_IPV4(core->mac[MRQC]));
46
47
- if (hastcp && E1000_MRQC_EN_TCPIPV4(core->mac[MRQC])) {
48
+ if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP &&
49
+ E1000_MRQC_EN_TCPIPV4(core->mac[MRQC])) {
50
return E1000_MRQ_RSS_TYPE_IPV4TCP;
51
}
52
53
@@ -XXX,XX +XXX,XX @@ e1000e_rss_get_hash_type(E1000ECore *core, struct NetRxPkt *pkt)
54
* backends like these.
55
*/
56
trace_e1000e_rx_rss_ip6_rfctl(core->mac[RFCTL]);
57
- trace_e1000e_rx_rss_ip6(ex_dis, new_ex_dis, hastcp,
58
+ trace_e1000e_rx_rss_ip6(ex_dis, new_ex_dis, l4hdr_proto,
59
ip6info->has_ext_hdrs,
60
ip6info->rss_ex_dst_valid,
61
ip6info->rss_ex_src_valid,
62
@@ -XXX,XX +XXX,XX @@ e1000e_rss_get_hash_type(E1000ECore *core, struct NetRxPkt *pkt)
63
(!new_ex_dis || !(ip6info->rss_ex_dst_valid ||
64
ip6info->rss_ex_src_valid))) {
65
66
- if (hastcp && E1000_MRQC_EN_TCPIPV6(core->mac[MRQC])) {
67
+ if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP &&
68
+ E1000_MRQC_EN_TCPIPV6(core->mac[MRQC])) {
69
return E1000_MRQ_RSS_TYPE_IPV6TCP;
70
}
71
72
@@ -XXX,XX +XXX,XX @@ static void
73
e1000e_verify_csum_in_sw(E1000ECore *core,
74
struct NetRxPkt *pkt,
75
uint32_t *status_flags,
76
- bool hastcp, bool hasudp)
77
+ EthL4HdrProto l4hdr_proto)
78
{
79
bool csum_valid;
80
uint32_t csum_error;
81
@@ -XXX,XX +XXX,XX @@ e1000e_verify_csum_in_sw(E1000ECore *core,
82
}
83
84
csum_error = csum_valid ? 0 : E1000_RXDEXT_STATERR_TCPE;
85
+ *status_flags |= E1000_RXD_STAT_TCPCS | csum_error;
86
87
- if (hastcp) {
88
- *status_flags |= E1000_RXD_STAT_TCPCS |
89
- csum_error;
90
- } else if (hasudp) {
91
- *status_flags |= E1000_RXD_STAT_TCPCS |
92
- E1000_RXD_STAT_UDPCS |
93
- csum_error;
94
+ if (l4hdr_proto == ETH_L4_HDR_PROTO_UDP) {
95
+ *status_flags |= E1000_RXD_STAT_UDPCS;
96
}
97
}
98
99
@@ -XXX,XX +XXX,XX @@ e1000e_build_rx_metadata(E1000ECore *core,
100
uint16_t *vlan_tag)
101
{
102
struct virtio_net_hdr *vhdr;
103
- bool hasip4, hasip6, hastcp, hasudp;
104
+ bool hasip4, hasip6;
105
+ EthL4HdrProto l4hdr_proto;
106
uint32_t pkt_type;
107
108
*status_flags = E1000_RXD_STAT_DD;
109
@@ -XXX,XX +XXX,XX @@ e1000e_build_rx_metadata(E1000ECore *core,
110
111
*status_flags |= E1000_RXD_STAT_EOP;
112
113
- net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
114
- trace_e1000e_rx_metadata_protocols(hasip4, hasip6, hasudp, hastcp);
115
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
116
+ trace_e1000e_rx_metadata_protocols(hasip4, hasip6, l4hdr_proto);
117
118
/* VLAN state */
119
if (net_rx_pkt_is_vlan_stripped(pkt)) {
120
@@ -XXX,XX +XXX,XX @@ e1000e_build_rx_metadata(E1000ECore *core,
121
trace_e1000e_rx_metadata_ip_id(*ip_id);
122
}
123
124
- if (hastcp && e1000e_is_tcp_ack(core, pkt)) {
125
+ if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP && e1000e_is_tcp_ack(core, pkt)) {
126
*status_flags |= E1000_RXD_STAT_ACK;
127
trace_e1000e_rx_metadata_ack();
128
}
129
@@ -XXX,XX +XXX,XX @@ e1000e_build_rx_metadata(E1000ECore *core,
130
if (hasip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_DIS)) {
131
trace_e1000e_rx_metadata_ipv6_filtering_disabled();
132
pkt_type = E1000_RXD_PKT_MAC;
133
- } else if (hastcp || hasudp) {
134
+ } else if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP ||
135
+ l4hdr_proto == ETH_L4_HDR_PROTO_UDP) {
136
pkt_type = hasip4 ? E1000_RXD_PKT_IP4_XDP : E1000_RXD_PKT_IP6_XDP;
137
} else if (hasip4 || hasip6) {
138
pkt_type = hasip4 ? E1000_RXD_PKT_IP4 : E1000_RXD_PKT_IP6;
139
@@ -XXX,XX +XXX,XX @@ e1000e_build_rx_metadata(E1000ECore *core,
140
if (!(vhdr->flags & VIRTIO_NET_HDR_F_DATA_VALID) &&
141
!(vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM)) {
142
trace_e1000e_rx_metadata_virthdr_no_csum_info();
143
- e1000e_verify_csum_in_sw(core, pkt, status_flags, hastcp, hasudp);
144
+ e1000e_verify_csum_in_sw(core, pkt, status_flags, l4hdr_proto);
145
goto func_exit;
146
}
147
148
@@ -XXX,XX +XXX,XX @@ e1000e_build_rx_metadata(E1000ECore *core,
149
}
150
151
if (e1000e_rx_l4_cso_enabled(core)) {
152
- if (hastcp) {
153
+ switch (l4hdr_proto) {
154
+ case ETH_L4_HDR_PROTO_TCP:
155
*status_flags |= E1000_RXD_STAT_TCPCS;
156
- } else if (hasudp) {
157
+ break;
158
+
159
+ case ETH_L4_HDR_PROTO_UDP:
160
*status_flags |= E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS;
161
+ break;
162
+
163
+ default:
164
+ break;
165
}
166
} else {
167
trace_e1000e_rx_metadata_l4_cso_disabled();
168
@@ -XXX,XX +XXX,XX @@ e1000e_rx_descr_threshold_hit(E1000ECore *core, const E1000E_RingInfo *rxi)
169
static bool
170
e1000e_do_ps(E1000ECore *core, struct NetRxPkt *pkt, size_t *hdr_len)
171
{
172
- bool hasip4, hasip6, hasudp, hastcp;
173
+ bool hasip4, hasip6;
174
+ EthL4HdrProto l4hdr_proto;
175
bool fragment;
176
177
if (!e1000e_rx_use_ps_descriptor(core)) {
178
return false;
179
}
180
181
- net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
182
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
183
184
if (hasip4) {
185
fragment = net_rx_pkt_get_ip4_info(pkt)->fragment;
186
@@ -XXX,XX +XXX,XX @@ e1000e_do_ps(E1000ECore *core, struct NetRxPkt *pkt, size_t *hdr_len)
187
return false;
188
}
189
190
- if (hasudp || hastcp) {
191
+ if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP ||
192
+ l4hdr_proto == ETH_L4_HDR_PROTO_UDP) {
193
*hdr_len = net_rx_pkt_get_l5_hdr_offset(pkt);
194
} else {
195
*hdr_len = net_rx_pkt_get_l4_hdr_offset(pkt);
196
diff --git a/hw/net/net_rx_pkt.c b/hw/net/net_rx_pkt.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/hw/net/net_rx_pkt.c
199
+++ b/hw/net/net_rx_pkt.c
200
@@ -XXX,XX +XXX,XX @@ struct NetRxPkt {
201
/* Analysis results */
202
bool hasip4;
203
bool hasip6;
204
- bool hasudp;
205
- bool hastcp;
206
207
size_t l3hdr_off;
208
size_t l4hdr_off;
209
@@ -XXX,XX +XXX,XX @@ net_rx_pkt_pull_data(struct NetRxPkt *pkt,
210
}
211
212
eth_get_protocols(pkt->vec, pkt->vec_len, &pkt->hasip4, &pkt->hasip6,
213
- &pkt->hasudp, &pkt->hastcp,
214
&pkt->l3hdr_off, &pkt->l4hdr_off, &pkt->l5hdr_off,
215
&pkt->ip6hdr_info, &pkt->ip4hdr_info, &pkt->l4hdr_info);
216
217
- trace_net_rx_pkt_parsed(pkt->hasip4, pkt->hasip6, pkt->hasudp, pkt->hastcp,
218
+ trace_net_rx_pkt_parsed(pkt->hasip4, pkt->hasip6, pkt->l4hdr_info.proto,
219
pkt->l3hdr_off, pkt->l4hdr_off, pkt->l5hdr_off);
220
}
221
222
@@ -XXX,XX +XXX,XX @@ void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data,
223
assert(pkt);
224
225
eth_get_protocols(&iov, 1, &pkt->hasip4, &pkt->hasip6,
226
- &pkt->hasudp, &pkt->hastcp,
227
&pkt->l3hdr_off, &pkt->l4hdr_off, &pkt->l5hdr_off,
228
&pkt->ip6hdr_info, &pkt->ip4hdr_info, &pkt->l4hdr_info);
229
}
230
231
void net_rx_pkt_get_protocols(struct NetRxPkt *pkt,
232
bool *hasip4, bool *hasip6,
233
- bool *hasudp, bool *hastcp)
234
+ EthL4HdrProto *l4hdr_proto)
235
{
236
assert(pkt);
237
238
*hasip4 = pkt->hasip4;
239
*hasip6 = pkt->hasip6;
240
- *hasudp = pkt->hasudp;
241
- *hastcp = pkt->hastcp;
242
+ *l4hdr_proto = pkt->l4hdr_info.proto;
243
}
244
245
size_t net_rx_pkt_get_l3_hdr_offset(struct NetRxPkt *pkt)
246
@@ -XXX,XX +XXX,XX @@ net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt,
247
break;
248
case NetPktRssIpV4Tcp:
249
assert(pkt->hasip4);
250
- assert(pkt->hastcp);
251
+ assert(pkt->l4hdr_info.proto == ETH_L4_HDR_PROTO_TCP);
252
trace_net_rx_pkt_rss_ip4_tcp();
253
_net_rx_rss_prepare_ip4(&rss_input[0], pkt, &rss_length);
254
_net_rx_rss_prepare_tcp(&rss_input[0], pkt, &rss_length);
255
break;
256
case NetPktRssIpV6Tcp:
257
assert(pkt->hasip6);
258
- assert(pkt->hastcp);
259
+ assert(pkt->l4hdr_info.proto == ETH_L4_HDR_PROTO_TCP);
260
trace_net_rx_pkt_rss_ip6_tcp();
261
_net_rx_rss_prepare_ip6(&rss_input[0], pkt, false, &rss_length);
262
_net_rx_rss_prepare_tcp(&rss_input[0], pkt, &rss_length);
263
@@ -XXX,XX +XXX,XX @@ net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt,
264
break;
265
case NetPktRssIpV6TcpEx:
266
assert(pkt->hasip6);
267
- assert(pkt->hastcp);
268
+ assert(pkt->l4hdr_info.proto == ETH_L4_HDR_PROTO_TCP);
269
trace_net_rx_pkt_rss_ip6_ex_tcp();
270
_net_rx_rss_prepare_ip6(&rss_input[0], pkt, true, &rss_length);
271
_net_rx_rss_prepare_tcp(&rss_input[0], pkt, &rss_length);
272
break;
273
case NetPktRssIpV4Udp:
274
assert(pkt->hasip4);
275
- assert(pkt->hasudp);
276
+ assert(pkt->l4hdr_info.proto == ETH_L4_HDR_PROTO_UDP);
277
trace_net_rx_pkt_rss_ip4_udp();
278
_net_rx_rss_prepare_ip4(&rss_input[0], pkt, &rss_length);
279
_net_rx_rss_prepare_udp(&rss_input[0], pkt, &rss_length);
280
break;
281
case NetPktRssIpV6Udp:
282
assert(pkt->hasip6);
283
- assert(pkt->hasudp);
284
+ assert(pkt->l4hdr_info.proto == ETH_L4_HDR_PROTO_UDP);
285
trace_net_rx_pkt_rss_ip6_udp();
286
_net_rx_rss_prepare_ip6(&rss_input[0], pkt, false, &rss_length);
287
_net_rx_rss_prepare_udp(&rss_input[0], pkt, &rss_length);
288
break;
289
case NetPktRssIpV6UdpEx:
290
assert(pkt->hasip6);
291
- assert(pkt->hasudp);
292
+ assert(pkt->l4hdr_info.proto == ETH_L4_HDR_PROTO_UDP);
293
trace_net_rx_pkt_rss_ip6_ex_udp();
294
_net_rx_rss_prepare_ip6(&rss_input[0], pkt, true, &rss_length);
295
_net_rx_rss_prepare_udp(&rss_input[0], pkt, &rss_length);
296
@@ -XXX,XX +XXX,XX @@ bool net_rx_pkt_is_tcp_ack(struct NetRxPkt *pkt)
297
{
298
assert(pkt);
299
300
- if (pkt->hastcp) {
301
+ if (pkt->l4hdr_info.proto == ETH_L4_HDR_PROTO_TCP) {
302
return TCP_HEADER_FLAGS(&pkt->l4hdr_info.hdr.tcp) & TCP_FLAG_ACK;
303
}
304
305
@@ -XXX,XX +XXX,XX @@ bool net_rx_pkt_has_tcp_data(struct NetRxPkt *pkt)
306
{
307
assert(pkt);
308
309
- if (pkt->hastcp) {
310
+ if (pkt->l4hdr_info.proto == ETH_L4_HDR_PROTO_TCP) {
311
return pkt->l4hdr_info.has_tcp_data;
312
}
313
314
@@ -XXX,XX +XXX,XX @@ _net_rx_pkt_calc_l4_csum(struct NetRxPkt *pkt)
315
trace_net_rx_pkt_l4_csum_calc_entry();
316
317
if (pkt->hasip4) {
318
- if (pkt->hasudp) {
319
+ if (pkt->l4hdr_info.proto == ETH_L4_HDR_PROTO_UDP) {
320
csl = be16_to_cpu(pkt->l4hdr_info.hdr.udp.uh_ulen);
321
trace_net_rx_pkt_l4_csum_calc_ip4_udp();
322
} else {
323
@@ -XXX,XX +XXX,XX @@ _net_rx_pkt_calc_l4_csum(struct NetRxPkt *pkt)
324
csl, &cso);
325
trace_net_rx_pkt_l4_csum_calc_ph_csum(cntr, csl);
326
} else {
327
- if (pkt->hasudp) {
328
+ if (pkt->l4hdr_info.proto == ETH_L4_HDR_PROTO_UDP) {
329
csl = be16_to_cpu(pkt->l4hdr_info.hdr.udp.uh_ulen);
330
trace_net_rx_pkt_l4_csum_calc_ip6_udp();
331
} else {
332
@@ -XXX,XX +XXX,XX @@ bool net_rx_pkt_validate_l4_csum(struct NetRxPkt *pkt, bool *csum_valid)
333
334
trace_net_rx_pkt_l4_csum_validate_entry();
335
336
- if (!pkt->hastcp && !pkt->hasudp) {
337
+ if (pkt->l4hdr_info.proto != ETH_L4_HDR_PROTO_TCP &&
338
+ pkt->l4hdr_info.proto != ETH_L4_HDR_PROTO_UDP) {
339
trace_net_rx_pkt_l4_csum_validate_not_xxp();
340
return false;
341
}
342
343
- if (pkt->hasudp && (pkt->l4hdr_info.hdr.udp.uh_sum == 0)) {
344
+ if (pkt->l4hdr_info.proto == ETH_L4_HDR_PROTO_UDP &&
345
+ pkt->l4hdr_info.hdr.udp.uh_sum == 0) {
346
trace_net_rx_pkt_l4_csum_validate_udp_with_no_checksum();
347
return false;
348
}
349
@@ -XXX,XX +XXX,XX @@ bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt)
350
351
trace_net_rx_pkt_l4_csum_fix_entry();
352
353
- if (pkt->hastcp) {
354
+ switch (pkt->l4hdr_info.proto) {
355
+ case ETH_L4_HDR_PROTO_TCP:
356
l4_cso = offsetof(struct tcp_header, th_sum);
357
trace_net_rx_pkt_l4_csum_fix_tcp(l4_cso);
358
- } else if (pkt->hasudp) {
359
+ break;
360
+
361
+ case ETH_L4_HDR_PROTO_UDP:
362
if (pkt->l4hdr_info.hdr.udp.uh_sum == 0) {
363
trace_net_rx_pkt_l4_csum_fix_udp_with_no_checksum();
364
return false;
365
}
366
l4_cso = offsetof(struct udp_header, uh_sum);
367
trace_net_rx_pkt_l4_csum_fix_udp(l4_cso);
368
- } else {
369
+ break;
370
+
371
+ default:
372
trace_net_rx_pkt_l4_csum_fix_not_xxp();
373
return false;
374
}
375
diff --git a/hw/net/net_rx_pkt.h b/hw/net/net_rx_pkt.h
376
index XXXXXXX..XXXXXXX 100644
377
--- a/hw/net/net_rx_pkt.h
378
+++ b/hw/net/net_rx_pkt.h
379
@@ -XXX,XX +XXX,XX @@ void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data,
380
* @pkt: packet
381
* @hasip4: whether the packet has an IPv4 header
382
* @hasip6: whether the packet has an IPv6 header
383
- * @hasudp: whether the packet has a UDP header
384
- * @hastcp: whether the packet has a TCP header
385
+ * @l4hdr_proto: protocol of L4 header
386
*
387
*/
388
void net_rx_pkt_get_protocols(struct NetRxPkt *pkt,
389
bool *hasip4, bool *hasip6,
390
- bool *hasudp, bool *hastcp);
391
+ EthL4HdrProto *l4hdr_proto);
392
393
/**
394
* fetches L3 header offset
395
diff --git a/hw/net/trace-events b/hw/net/trace-events
396
index XXXXXXX..XXXXXXX 100644
397
--- a/hw/net/trace-events
398
+++ b/hw/net/trace-events
399
@@ -XXX,XX +XXX,XX @@ pcnet_ioport_read(void *opaque, uint64_t addr, unsigned size) "opaque=%p addr=0x
400
pcnet_ioport_write(void *opaque, uint64_t addr, uint64_t data, unsigned size) "opaque=%p addr=0x%"PRIx64" data=0x%"PRIx64" size=%d"
401
402
# net_rx_pkt.c
403
-net_rx_pkt_parsed(bool ip4, bool ip6, bool udp, bool tcp, size_t l3o, size_t l4o, size_t l5o) "RX packet parsed: ip4: %d, ip6: %d, udp: %d, tcp: %d, l3 offset: %zu, l4 offset: %zu, l5 offset: %zu"
404
+net_rx_pkt_parsed(bool ip4, bool ip6, int l4proto, size_t l3o, size_t l4o, size_t l5o) "RX packet parsed: ip4: %d, ip6: %d, l4 protocol: %d, l3 offset: %zu, l4 offset: %zu, l5 offset: %zu"
405
net_rx_pkt_l4_csum_validate_entry(void) "Starting L4 checksum validation"
406
net_rx_pkt_l4_csum_validate_not_xxp(void) "Not a TCP/UDP packet"
407
net_rx_pkt_l4_csum_validate_udp_with_no_checksum(void) "UDP packet without checksum"
408
@@ -XXX,XX +XXX,XX @@ e1000e_rx_start_recv(void)
409
e1000e_rx_rss_started(void) "Starting RSS processing"
410
e1000e_rx_rss_disabled(void) "RSS is disabled"
411
e1000e_rx_rss_type(uint32_t type) "RSS type is %u"
412
-e1000e_rx_rss_ip4(bool hastcp, uint32_t mrqc, bool tcpipv4_enabled, bool ipv4_enabled) "RSS IPv4: tcp %d, mrqc 0x%X, tcpipv4 enabled %d, ipv4 enabled %d"
413
+e1000e_rx_rss_ip4(int l4hdr_proto, uint32_t mrqc, bool tcpipv4_enabled, bool ipv4_enabled) "RSS IPv4: L4 header protocol %d, mrqc 0x%X, tcpipv4 enabled %d, ipv4 enabled %d"
414
e1000e_rx_rss_ip6_rfctl(uint32_t rfctl) "RSS IPv6: rfctl 0x%X"
415
-e1000e_rx_rss_ip6(bool ex_dis, bool new_ex_dis, bool hastcp, bool has_ext_headers, bool ex_dst_valid, bool ex_src_valid, uint32_t mrqc, bool tcpipv6_enabled, bool ipv6ex_enabled, bool ipv6_enabled) "RSS IPv6: ex_dis: %d, new_ex_dis: %d, tcp %d, has_ext_headers %d, ex_dst_valid %d, ex_src_valid %d, mrqc 0x%X, tcpipv6 enabled %d, ipv6ex enabled %d, ipv6 enabled %d"
416
+e1000e_rx_rss_ip6(bool ex_dis, bool new_ex_dis, int l4hdr_proto, bool has_ext_headers, bool ex_dst_valid, bool ex_src_valid, uint32_t mrqc, bool tcpipv6_enabled, bool ipv6ex_enabled, bool ipv6_enabled) "RSS IPv6: ex_dis: %d, new_ex_dis: %d, L4 header protocol %d, has_ext_headers %d, ex_dst_valid %d, ex_src_valid %d, mrqc 0x%X, tcpipv6 enabled %d, ipv6ex enabled %d, ipv6 enabled %d"
417
418
-e1000e_rx_metadata_protocols(bool hasip4, bool hasip6, bool hasudp, bool hastcp) "protocols: ip4: %d, ip6: %d, udp: %d, tcp: %d"
419
+e1000e_rx_metadata_protocols(bool hasip4, bool hasip6, int l4hdr_protocol) "protocols: ip4: %d, ip6: %d, l4hdr: %d"
420
e1000e_rx_metadata_vlan(uint16_t vlan_tag) "VLAN tag is 0x%X"
421
e1000e_rx_metadata_rss(uint32_t rss, uint32_t mrq) "RSS data: rss: 0x%X, mrq: 0x%X"
422
e1000e_rx_metadata_ip_id(uint16_t ip_id) "the IPv4 ID is 0x%X"
423
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
424
index XXXXXXX..XXXXXXX 100644
425
--- a/hw/net/virtio-net.c
426
+++ b/hw/net/virtio-net.c
427
@@ -XXX,XX +XXX,XX @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
428
429
static uint8_t virtio_net_get_hash_type(bool hasip4,
430
bool hasip6,
431
- bool hasudp,
432
- bool hastcp,
433
+ EthL4HdrProto l4hdr_proto,
434
uint32_t types)
435
{
436
if (hasip4) {
437
- if (hastcp && (types & VIRTIO_NET_RSS_HASH_TYPE_TCPv4)) {
438
- return NetPktRssIpV4Tcp;
439
- }
440
- if (hasudp && (types & VIRTIO_NET_RSS_HASH_TYPE_UDPv4)) {
441
- return NetPktRssIpV4Udp;
442
+ switch (l4hdr_proto) {
443
+ case ETH_L4_HDR_PROTO_TCP:
444
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_TCPv4) {
445
+ return NetPktRssIpV4Tcp;
446
+ }
447
+ break;
448
+
449
+ case ETH_L4_HDR_PROTO_UDP:
450
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_UDPv4) {
451
+ return NetPktRssIpV4Udp;
452
+ }
453
+ break;
454
+
455
+ default:
456
+ break;
457
}
458
+
459
if (types & VIRTIO_NET_RSS_HASH_TYPE_IPv4) {
460
return NetPktRssIpV4;
461
}
462
} else if (hasip6) {
463
- uint32_t mask = VIRTIO_NET_RSS_HASH_TYPE_TCP_EX |
464
- VIRTIO_NET_RSS_HASH_TYPE_TCPv6;
465
+ switch (l4hdr_proto) {
466
+ case ETH_L4_HDR_PROTO_TCP:
467
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_TCP_EX) {
468
+ return NetPktRssIpV6TcpEx;
469
+ }
470
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_TCPv6) {
471
+ return NetPktRssIpV6Tcp;
472
+ }
473
+ break;
474
475
- if (hastcp && (types & mask)) {
476
- return (types & VIRTIO_NET_RSS_HASH_TYPE_TCP_EX) ?
477
- NetPktRssIpV6TcpEx : NetPktRssIpV6Tcp;
478
+ case ETH_L4_HDR_PROTO_UDP:
479
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_UDP_EX) {
480
+ return NetPktRssIpV6UdpEx;
481
+ }
482
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_UDPv6) {
483
+ return NetPktRssIpV6Udp;
484
+ }
485
+ break;
486
+
487
+ default:
488
+ break;
489
}
490
- mask = VIRTIO_NET_RSS_HASH_TYPE_UDP_EX | VIRTIO_NET_RSS_HASH_TYPE_UDPv6;
491
- if (hasudp && (types & mask)) {
492
- return (types & VIRTIO_NET_RSS_HASH_TYPE_UDP_EX) ?
493
- NetPktRssIpV6UdpEx : NetPktRssIpV6Udp;
494
+
495
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_IP_EX) {
496
+ return NetPktRssIpV6Ex;
497
}
498
- mask = VIRTIO_NET_RSS_HASH_TYPE_IP_EX | VIRTIO_NET_RSS_HASH_TYPE_IPv6;
499
- if (types & mask) {
500
- return (types & VIRTIO_NET_RSS_HASH_TYPE_IP_EX) ?
501
- NetPktRssIpV6Ex : NetPktRssIpV6;
502
+ if (types & VIRTIO_NET_RSS_HASH_TYPE_IPv6) {
503
+ return NetPktRssIpV6;
504
}
505
}
506
return 0xff;
507
@@ -XXX,XX +XXX,XX @@ static int virtio_net_process_rss(NetClientState *nc, const uint8_t *buf,
508
struct NetRxPkt *pkt = n->rx_pkt;
509
uint8_t net_hash_type;
510
uint32_t hash;
511
- bool hasip4, hasip6, hasudp, hastcp;
512
+ bool hasip4, hasip6;
513
+ EthL4HdrProto l4hdr_proto;
514
static const uint8_t reports[NetPktRssIpV6UdpEx + 1] = {
515
VIRTIO_NET_HASH_REPORT_IPv4,
516
VIRTIO_NET_HASH_REPORT_TCPv4,
517
@@ -XXX,XX +XXX,XX @@ static int virtio_net_process_rss(NetClientState *nc, const uint8_t *buf,
518
519
net_rx_pkt_set_protocols(pkt, buf + n->host_hdr_len,
520
size - n->host_hdr_len);
521
- net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
522
- net_hash_type = virtio_net_get_hash_type(hasip4, hasip6, hasudp, hastcp,
523
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
524
+ net_hash_type = virtio_net_get_hash_type(hasip4, hasip6, l4hdr_proto,
525
n->rss_data.hash_types);
526
if (net_hash_type > NetPktRssIpV6UdpEx) {
527
if (n->rss_data.populate_hash) {
528
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
529
index XXXXXXX..XXXXXXX 100644
530
--- a/hw/net/vmxnet3.c
531
+++ b/hw/net/vmxnet3.c
532
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_rx_need_csum_calculate(struct NetRxPkt *pkt,
533
size_t pkt_len)
534
{
535
struct virtio_net_hdr *vhdr;
536
- bool hasip4, hasip6, hastcp, hasudp;
537
+ bool hasip4, hasip6;
538
+ EthL4HdrProto l4hdr_proto;
539
uint8_t *data;
540
int len;
541
542
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_rx_need_csum_calculate(struct NetRxPkt *pkt,
543
return;
544
}
545
546
- net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
547
- if (!(hasip4 || hasip6) || !(hastcp || hasudp)) {
548
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
549
+ if (!(hasip4 || hasip6) ||
550
+ (l4hdr_proto != ETH_L4_HDR_PROTO_TCP &&
551
+ l4hdr_proto != ETH_L4_HDR_PROTO_UDP)) {
552
return;
553
}
554
555
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_rx_update_descr(struct NetRxPkt *pkt,
556
struct Vmxnet3_RxCompDesc *rxcd)
557
{
558
int csum_ok, is_gso;
559
- bool hasip4, hasip6, hastcp, hasudp;
560
+ bool hasip4, hasip6;
561
+ EthL4HdrProto l4hdr_proto;
562
struct virtio_net_hdr *vhdr;
563
uint8_t offload_type;
564
565
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_rx_update_descr(struct NetRxPkt *pkt,
566
goto nocsum;
567
}
568
569
- net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &hasudp, &hastcp);
570
- if ((!hastcp && !hasudp) || (!hasip4 && !hasip6)) {
571
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
572
+ if ((l4hdr_proto != ETH_L4_HDR_PROTO_TCP &&
573
+ l4hdr_proto != ETH_L4_HDR_PROTO_UDP) ||
574
+ (!hasip4 && !hasip6)) {
575
goto nocsum;
576
}
577
578
rxcd->cnc = 0;
579
rxcd->v4 = hasip4 ? 1 : 0;
580
rxcd->v6 = hasip6 ? 1 : 0;
581
- rxcd->tcp = hastcp ? 1 : 0;
582
- rxcd->udp = hasudp ? 1 : 0;
583
+ rxcd->tcp = l4hdr_proto == ETH_L4_HDR_PROTO_TCP;
584
+ rxcd->udp = l4hdr_proto == ETH_L4_HDR_PROTO_UDP;
585
rxcd->fcs = rxcd->tuc = rxcd->ipc = 1;
586
return;
587
588
diff --git a/include/net/eth.h b/include/net/eth.h
589
index XXXXXXX..XXXXXXX 100644
590
--- a/include/net/eth.h
591
+++ b/include/net/eth.h
592
@@ -XXX,XX +XXX,XX @@ typedef struct eth_ip4_hdr_info_st {
593
bool fragment;
594
} eth_ip4_hdr_info;
595
596
+typedef enum EthL4HdrProto {
597
+ ETH_L4_HDR_PROTO_INVALID,
598
+ ETH_L4_HDR_PROTO_TCP,
599
+ ETH_L4_HDR_PROTO_UDP
600
+} EthL4HdrProto;
601
+
602
typedef struct eth_l4_hdr_info_st {
603
union {
604
struct tcp_header tcp;
605
struct udp_header udp;
606
} hdr;
607
608
+ EthL4HdrProto proto;
609
bool has_tcp_data;
610
} eth_l4_hdr_info;
611
612
void eth_get_protocols(const struct iovec *iov, int iovcnt,
613
bool *hasip4, bool *hasip6,
614
- bool *hasudp, bool *hastcp,
615
size_t *l3hdr_off,
616
size_t *l4hdr_off,
617
size_t *l5hdr_off,
618
diff --git a/net/eth.c b/net/eth.c
619
index XXXXXXX..XXXXXXX 100644
620
--- a/net/eth.c
621
+++ b/net/eth.c
622
@@ -XXX,XX +XXX,XX @@ _eth_tcp_has_data(bool is_ip4,
623
624
void eth_get_protocols(const struct iovec *iov, int iovcnt,
625
bool *hasip4, bool *hasip6,
626
- bool *hasudp, bool *hastcp,
627
size_t *l3hdr_off,
628
size_t *l4hdr_off,
629
size_t *l5hdr_off,
630
@@ -XXX,XX +XXX,XX @@ void eth_get_protocols(const struct iovec *iov, int iovcnt,
631
size_t copied;
632
uint8_t ip_p;
633
634
- *hasip4 = *hasip6 = *hasudp = *hastcp = false;
635
+ *hasip4 = *hasip6 = false;
636
+ l4hdr_info->proto = ETH_L4_HDR_PROTO_INVALID;
637
638
proto = eth_get_l3_proto(iov, iovcnt, l2hdr_len);
639
640
@@ -XXX,XX +XXX,XX @@ void eth_get_protocols(const struct iovec *iov, int iovcnt,
641
642
switch (ip_p) {
643
case IP_PROTO_TCP:
644
- *hastcp = _eth_copy_chunk(input_size,
645
- iov, iovcnt,
646
- *l4hdr_off, sizeof(l4hdr_info->hdr.tcp),
647
- &l4hdr_info->hdr.tcp);
648
- if (*hastcp) {
649
+ if (_eth_copy_chunk(input_size,
650
+ iov, iovcnt,
651
+ *l4hdr_off, sizeof(l4hdr_info->hdr.tcp),
652
+ &l4hdr_info->hdr.tcp)) {
653
+ l4hdr_info->proto = ETH_L4_HDR_PROTO_TCP;
654
*l5hdr_off = *l4hdr_off +
655
TCP_HEADER_DATA_OFFSET(&l4hdr_info->hdr.tcp);
656
657
@@ -XXX,XX +XXX,XX @@ void eth_get_protocols(const struct iovec *iov, int iovcnt,
658
break;
659
660
case IP_PROTO_UDP:
661
- *hasudp = _eth_copy_chunk(input_size,
662
- iov, iovcnt,
663
- *l4hdr_off, sizeof(l4hdr_info->hdr.udp),
664
- &l4hdr_info->hdr.udp);
665
- *l5hdr_off = *l4hdr_off + sizeof(l4hdr_info->hdr.udp);
666
+ if (_eth_copy_chunk(input_size,
667
+ iov, iovcnt,
668
+ *l4hdr_off, sizeof(l4hdr_info->hdr.udp),
669
+ &l4hdr_info->hdr.udp)) {
670
+ l4hdr_info->proto = ETH_L4_HDR_PROTO_UDP;
671
+ *l5hdr_off = *l4hdr_off + sizeof(l4hdr_info->hdr.udp);
672
+ }
673
break;
674
}
675
}
676
--
677
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
igb can use this function to change its behavior depending on the
4
number of virtual functions currently enabled.
5
6
Signed-off-by: Gal Hammer <gal.hammer@sap.com>
7
Signed-off-by: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
hw/pci/pcie_sriov.c | 5 +++++
13
include/hw/pci/pcie_sriov.h | 3 +++
14
2 files changed, 8 insertions(+)
15
16
diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/pci/pcie_sriov.c
19
+++ b/hw/pci/pcie_sriov.c
20
@@ -XXX,XX +XXX,XX @@ PCIDevice *pcie_sriov_get_vf_at_index(PCIDevice *dev, int n)
21
}
22
return NULL;
23
}
24
+
25
+uint16_t pcie_sriov_num_vfs(PCIDevice *dev)
26
+{
27
+ return dev->exp.sriov_pf.num_vfs;
28
+}
29
diff --git a/include/hw/pci/pcie_sriov.h b/include/hw/pci/pcie_sriov.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/pci/pcie_sriov.h
32
+++ b/include/hw/pci/pcie_sriov.h
33
@@ -XXX,XX +XXX,XX @@ PCIDevice *pcie_sriov_get_pf(PCIDevice *dev);
34
*/
35
PCIDevice *pcie_sriov_get_vf_at_index(PCIDevice *dev, int n);
36
37
+/* Returns the current number of virtual functions. */
38
+uint16_t pcie_sriov_num_vfs(PCIDevice *dev);
39
+
40
#endif /* QEMU_PCIE_SRIOV_H */
41
--
42
2.7.4
43
44
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
e1000e understands ethernet header so fabricate something convincing.
4
5
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
tests/qtest/e1000e-test.c | 25 +++++++++++++++----------
10
tests/qtest/libqos/e1000e.h | 2 ++
11
2 files changed, 17 insertions(+), 10 deletions(-)
12
13
diff --git a/tests/qtest/e1000e-test.c b/tests/qtest/e1000e-test.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/qtest/e1000e-test.c
16
+++ b/tests/qtest/e1000e-test.c
17
@@ -XXX,XX +XXX,XX @@
18
#include "qemu/osdep.h"
19
#include "libqtest-single.h"
20
#include "libqos/pci-pc.h"
21
+#include "net/eth.h"
22
#include "qemu/sockets.h"
23
#include "qemu/iov.h"
24
#include "qemu/module.h"
25
@@ -XXX,XX +XXX,XX @@
26
#include "libqos/e1000e.h"
27
#include "hw/net/e1000_regs.h"
28
29
+static const struct eth_header packet = {
30
+ .h_dest = E1000E_ADDRESS,
31
+ .h_source = E1000E_ADDRESS,
32
+};
33
+
34
static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
35
{
36
- static const char test[] = "TEST";
37
struct e1000_tx_desc descr;
38
char buffer[64];
39
int ret;
40
@@ -XXX,XX +XXX,XX @@ static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a
41
42
/* Prepare test data buffer */
43
uint64_t data = guest_alloc(alloc, sizeof(buffer));
44
- memwrite(data, test, sizeof(test));
45
+ memwrite(data, &packet, sizeof(packet));
46
47
/* Prepare TX descriptor */
48
memset(&descr, 0, sizeof(descr));
49
@@ -XXX,XX +XXX,XX @@ static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a
50
g_assert_cmpint(ret, == , sizeof(recv_len));
51
ret = recv(test_sockets[0], buffer, sizeof(buffer), 0);
52
g_assert_cmpint(ret, ==, sizeof(buffer));
53
- g_assert_cmpstr(buffer, == , test);
54
+ g_assert_false(memcmp(buffer, &packet, sizeof(packet)));
55
56
/* Free test data buffer */
57
guest_free(alloc, data);
58
@@ -XXX,XX +XXX,XX @@ static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator
59
{
60
union e1000_rx_desc_extended descr;
61
62
- char test[] = "TEST";
63
- int len = htonl(sizeof(test));
64
+ struct eth_header test_iov = packet;
65
+ int len = htonl(sizeof(packet));
66
struct iovec iov[] = {
67
{
68
.iov_base = &len,
69
.iov_len = sizeof(len),
70
},{
71
- .iov_base = test,
72
- .iov_len = sizeof(test),
73
+ .iov_base = &test_iov,
74
+ .iov_len = sizeof(packet),
75
},
76
};
77
78
@@ -XXX,XX +XXX,XX @@ static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator
79
int ret;
80
81
/* Send a dummy packet to device's socket*/
82
- ret = iov_send(test_sockets[0], iov, 2, 0, sizeof(len) + sizeof(test));
83
- g_assert_cmpint(ret, == , sizeof(test) + sizeof(len));
84
+ ret = iov_send(test_sockets[0], iov, 2, 0, sizeof(len) + sizeof(packet));
85
+ g_assert_cmpint(ret, == , sizeof(packet) + sizeof(len));
86
87
/* Prepare test data buffer */
88
uint64_t data = guest_alloc(alloc, sizeof(buffer));
89
@@ -XXX,XX +XXX,XX @@ static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator
90
91
/* Check data sent to the backend */
92
memread(data, buffer, sizeof(buffer));
93
- g_assert_cmpstr(buffer, == , test);
94
+ g_assert_false(memcmp(buffer, &packet, sizeof(packet)));
95
96
/* Free test data buffer */
97
guest_free(alloc, data);
98
diff --git a/tests/qtest/libqos/e1000e.h b/tests/qtest/libqos/e1000e.h
99
index XXXXXXX..XXXXXXX 100644
100
--- a/tests/qtest/libqos/e1000e.h
101
+++ b/tests/qtest/libqos/e1000e.h
102
@@ -XXX,XX +XXX,XX @@
103
#define E1000E_RX0_MSG_ID (0)
104
#define E1000E_TX0_MSG_ID (1)
105
106
+#define E1000E_ADDRESS { 0x52, 0x54, 0x00, 0x12, 0x34, 0x56 }
107
+
108
typedef struct QE1000E QE1000E;
109
typedef struct QE1000E_PCI QE1000E_PCI;
110
111
--
112
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
1
3
They will be useful for igb testing.
4
5
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
tests/qtest/libqos/e1000e.c | 12 ------------
10
tests/qtest/libqos/e1000e.h | 12 ++++++++++++
11
2 files changed, 12 insertions(+), 12 deletions(-)
12
13
diff --git a/tests/qtest/libqos/e1000e.c b/tests/qtest/libqos/e1000e.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/qtest/libqos/e1000e.c
16
+++ b/tests/qtest/libqos/e1000e.c
17
@@ -XXX,XX +XXX,XX @@
18
19
#define E1000E_RING_LEN (0x1000)
20
21
-static void e1000e_macreg_write(QE1000E *d, uint32_t reg, uint32_t val)
22
-{
23
- QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e);
24
- qpci_io_writel(&d_pci->pci_dev, d_pci->mac_regs, reg, val);
25
-}
26
-
27
-static uint32_t e1000e_macreg_read(QE1000E *d, uint32_t reg)
28
-{
29
- QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e);
30
- return qpci_io_readl(&d_pci->pci_dev, d_pci->mac_regs, reg);
31
-}
32
-
33
void e1000e_tx_ring_push(QE1000E *d, void *descr)
34
{
35
QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e);
36
diff --git a/tests/qtest/libqos/e1000e.h b/tests/qtest/libqos/e1000e.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/qtest/libqos/e1000e.h
39
+++ b/tests/qtest/libqos/e1000e.h
40
@@ -XXX,XX +XXX,XX @@ struct QE1000E_PCI {
41
QE1000E e1000e;
42
};
43
44
+static inline void e1000e_macreg_write(QE1000E *d, uint32_t reg, uint32_t val)
45
+{
46
+ QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e);
47
+ qpci_io_writel(&d_pci->pci_dev, d_pci->mac_regs, reg, val);
48
+}
49
+
50
+static inline uint32_t e1000e_macreg_read(QE1000E *d, uint32_t reg)
51
+{
52
+ QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e);
53
+ return qpci_io_readl(&d_pci->pci_dev, d_pci->mac_regs, reg);
54
+}
55
+
56
void e1000e_wait_isr(QE1000E *d, uint16_t msg_id);
57
void e1000e_tx_ring_push(QE1000E *d, void *descr);
58
void e1000e_rx_ring_push(QE1000E *d, void *descr);
59
--
60
2.7.4
diff view generated by jsdifflib
Deleted patch
1
From: Shreesh Adiga <16567adigashreesh@gmail.com>
2
1
3
The current implementation fails to load on a system with
4
libbpf 1.0 and reports that legacy map definitions in 'maps'
5
section are not supported by libbpf v1.0+. This commit updates
6
the Makefile to add BTF (-g flag) and appropriately updates
7
the maps in rss.bpf.c and update the skeleton file in repo.
8
9
Signed-off-by: Shreesh Adiga <16567adigashreesh@gmail.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
---
12
ebpf/rss.bpf.skeleton.h | 1171 ++++++++++++++++++++++++++++++++++------------
13
tools/ebpf/Makefile.ebpf | 8 +-
14
tools/ebpf/rss.bpf.c | 43 +-
15
3 files changed, 891 insertions(+), 331 deletions(-)
16
17
diff --git a/ebpf/rss.bpf.skeleton.h b/ebpf/rss.bpf.skeleton.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/ebpf/rss.bpf.skeleton.h
20
+++ b/ebpf/rss.bpf.skeleton.h
21
@@ -XXX,XX +XXX,XX @@
22
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
23
24
-/* THIS FILE IS AUTOGENERATED! */
25
+/* THIS FILE IS AUTOGENERATED BY BPFTOOL! */
26
#ifndef __RSS_BPF_SKEL_H__
27
#define __RSS_BPF_SKEL_H__
28
29
+#include <errno.h>
30
#include <stdlib.h>
31
#include <bpf/libbpf.h>
32
33
@@ -XXX,XX +XXX,XX @@ struct rss_bpf {
34
    struct bpf_object *obj;
35
    struct {
36
        struct bpf_map *tap_rss_map_configurations;
37
-        struct bpf_map *tap_rss_map_indirection_table;
38
        struct bpf_map *tap_rss_map_toeplitz_key;
39
+        struct bpf_map *tap_rss_map_indirection_table;
40
    } maps;
41
    struct {
42
        struct bpf_program *tun_rss_steering_prog;
43
@@ -XXX,XX +XXX,XX @@ struct rss_bpf {
44
    struct {
45
        struct bpf_link *tun_rss_steering_prog;
46
    } links;
47
+
48
+#ifdef __cplusplus
49
+    static inline struct rss_bpf *open(const struct bpf_object_open_opts *opts = nullptr);
50
+    static inline struct rss_bpf *open_and_load();
51
+    static inline int load(struct rss_bpf *skel);
52
+    static inline int attach(struct rss_bpf *skel);
53
+    static inline void detach(struct rss_bpf *skel);
54
+    static inline void destroy(struct rss_bpf *skel);
55
+    static inline const void *elf_bytes(size_t *sz);
56
+#endif /* __cplusplus */
57
};
58
59
static void
60
@@ -XXX,XX +XXX,XX @@ static inline struct rss_bpf *
61
rss_bpf__open_opts(const struct bpf_object_open_opts *opts)
62
{
63
    struct rss_bpf *obj;
64
+    int err;
65
66
    obj = (struct rss_bpf *)calloc(1, sizeof(*obj));
67
-    if (!obj)
68
+    if (!obj) {
69
+        errno = ENOMEM;
70
        return NULL;
71
-    if (rss_bpf__create_skeleton(obj))
72
-        goto err;
73
-    if (bpf_object__open_skeleton(obj->skeleton, opts))
74
-        goto err;
75
+    }
76
+
77
+    err = rss_bpf__create_skeleton(obj);
78
+    if (err)
79
+        goto err_out;
80
+
81
+    err = bpf_object__open_skeleton(obj->skeleton, opts);
82
+    if (err)
83
+        goto err_out;
84
85
    return obj;
86
-err:
87
+err_out:
88
    rss_bpf__destroy(obj);
89
+    errno = -err;
90
    return NULL;
91
}
92
93
@@ -XXX,XX +XXX,XX @@ static inline struct rss_bpf *
94
rss_bpf__open_and_load(void)
95
{
96
    struct rss_bpf *obj;
97
+    int err;
98
99
    obj = rss_bpf__open();
100
    if (!obj)
101
        return NULL;
102
-    if (rss_bpf__load(obj)) {
103
+    err = rss_bpf__load(obj);
104
+    if (err) {
105
        rss_bpf__destroy(obj);
106
+        errno = -err;
107
        return NULL;
108
    }
109
    return obj;
110
@@ -XXX,XX +XXX,XX @@ rss_bpf__attach(struct rss_bpf *obj)
111
static inline void
112
rss_bpf__detach(struct rss_bpf *obj)
113
{
114
-    return bpf_object__detach_skeleton(obj->skeleton);
115
+    bpf_object__detach_skeleton(obj->skeleton);
116
}
117
118
+static inline const void *rss_bpf__elf_bytes(size_t *sz);
119
+
120
static inline int
121
rss_bpf__create_skeleton(struct rss_bpf *obj)
122
{
123
    struct bpf_object_skeleton *s;
124
+    int err;
125
126
    s = (struct bpf_object_skeleton *)calloc(1, sizeof(*s));
127
-    if (!s)
128
-        return -1;
129
-    obj->skeleton = s;
130
+    if (!s)    {
131
+        err = -ENOMEM;
132
+        goto err;
133
+    }
134
135
    s->sz = sizeof(*s);
136
    s->name = "rss_bpf";
137
@@ -XXX,XX +XXX,XX @@ rss_bpf__create_skeleton(struct rss_bpf *obj)
138
    s->map_cnt = 3;
139
    s->map_skel_sz = sizeof(*s->maps);
140
    s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt, s->map_skel_sz);
141
-    if (!s->maps)
142
+    if (!s->maps) {
143
+        err = -ENOMEM;
144
        goto err;
145
+    }
146
147
    s->maps[0].name = "tap_rss_map_configurations";
148
    s->maps[0].map = &obj->maps.tap_rss_map_configurations;
149
150
-    s->maps[1].name = "tap_rss_map_indirection_table";
151
-    s->maps[1].map = &obj->maps.tap_rss_map_indirection_table;
152
+    s->maps[1].name = "tap_rss_map_toeplitz_key";
153
+    s->maps[1].map = &obj->maps.tap_rss_map_toeplitz_key;
154
155
-    s->maps[2].name = "tap_rss_map_toeplitz_key";
156
-    s->maps[2].map = &obj->maps.tap_rss_map_toeplitz_key;
157
+    s->maps[2].name = "tap_rss_map_indirection_table";
158
+    s->maps[2].map = &obj->maps.tap_rss_map_indirection_table;
159
160
    /* programs */
161
    s->prog_cnt = 1;
162
    s->prog_skel_sz = sizeof(*s->progs);
163
    s->progs = (struct bpf_prog_skeleton *)calloc(s->prog_cnt, s->prog_skel_sz);
164
-    if (!s->progs)
165
+    if (!s->progs) {
166
+        err = -ENOMEM;
167
        goto err;
168
+    }
169
170
    s->progs[0].name = "tun_rss_steering_prog";
171
    s->progs[0].prog = &obj->progs.tun_rss_steering_prog;
172
    s->progs[0].link = &obj->links.tun_rss_steering_prog;
173
174
-    s->data_sz = 8088;
175
-    s->data = (void *)"\
176
+    s->data = (void *)rss_bpf__elf_bytes(&s->data_sz);
177
+
178
+    obj->skeleton = s;
179
+    return 0;
180
+err:
181
+    bpf_object__destroy_skeleton(s);
182
+    return err;
183
+}
184
+
185
+static inline const void *rss_bpf__elf_bytes(size_t *sz)
186
+{
187
+    *sz = 20440;
188
+    return (const void *)"\
189
\x7f\x45\x4c\x46\x02\x01\x01\0\0\0\0\0\0\0\0\0\x01\0\xf7\0\x01\0\0\0\0\0\0\0\0\
190
-\0\0\0\0\0\0\0\0\0\0\0\x18\x1d\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\x40\0\x0a\0\
191
-\x01\0\xbf\x18\0\0\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\x4c\xff\0\0\0\0\xbf\xa7\
192
-\0\0\0\0\0\0\x07\x07\0\0\x4c\xff\xff\xff\x18\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
193
+\0\0\0\0\0\0\0\0\0\0\0\x98\x4c\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\x40\0\x0d\0\
194
+\x01\0\xbf\x19\0\0\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\x54\xff\0\0\0\0\xbf\xa7\
195
+\0\0\0\0\0\0\x07\x07\0\0\x54\xff\xff\xff\x18\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
196
\xbf\x72\0\0\0\0\0\0\x85\0\0\0\x01\0\0\0\xbf\x06\0\0\0\0\0\0\x18\x01\0\0\0\0\0\
197
-\0\0\0\0\0\0\0\0\0\xbf\x72\0\0\0\0\0\0\x85\0\0\0\x01\0\0\0\xbf\x07\0\0\0\0\0\0\
198
-\x18\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\x15\x06\x66\x02\0\0\0\0\xbf\x79\0\0\
199
-\0\0\0\0\x15\x09\x64\x02\0\0\0\0\x71\x61\0\0\0\0\0\0\x55\x01\x01\0\0\0\0\0\x05\
200
-\0\x5d\x02\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xc0\xff\0\0\0\0\x7b\x1a\xb8\xff\
201
-\0\0\0\0\x7b\x1a\xb0\xff\0\0\0\0\x7b\x1a\xa8\xff\0\0\0\0\x7b\x1a\xa0\xff\0\0\0\
202
-\0\x63\x1a\x98\xff\0\0\0\0\x7b\x1a\x90\xff\0\0\0\0\x7b\x1a\x88\xff\0\0\0\0\x7b\
203
-\x1a\x80\xff\0\0\0\0\x7b\x1a\x78\xff\0\0\0\0\x7b\x1a\x70\xff\0\0\0\0\x7b\x1a\
204
-\x68\xff\0\0\0\0\x7b\x1a\x60\xff\0\0\0\0\x7b\x1a\x58\xff\0\0\0\0\x7b\x1a\x50\
205
-\xff\0\0\0\0\x15\x08\x4c\x02\0\0\0\0\x6b\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\
206
-\0\x07\x03\0\0\xd0\xff\xff\xff\xbf\x81\0\0\0\0\0\0\xb7\x02\0\0\x0c\0\0\0\xb7\
207
+\0\0\0\0\0\0\0\0\0\xbf\x72\0\0\0\0\0\0\x85\0\0\0\x01\0\0\0\xbf\x08\0\0\0\0\0\0\
208
+\x18\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\x15\x06\x67\x02\0\0\0\0\xbf\x87\0\0\
209
+\0\0\0\0\x15\x07\x65\x02\0\0\0\0\x71\x61\0\0\0\0\0\0\x55\x01\x01\0\0\0\0\0\x05\
210
+\0\x5e\x02\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xc8\xff\0\0\0\0\x7b\x1a\xc0\xff\
211
+\0\0\0\0\x7b\x1a\xb8\xff\0\0\0\0\x7b\x1a\xb0\xff\0\0\0\0\x7b\x1a\xa8\xff\0\0\0\
212
+\0\x63\x1a\xa0\xff\0\0\0\0\x7b\x1a\x98\xff\0\0\0\0\x7b\x1a\x90\xff\0\0\0\0\x7b\
213
+\x1a\x88\xff\0\0\0\0\x7b\x1a\x80\xff\0\0\0\0\x7b\x1a\x78\xff\0\0\0\0\x7b\x1a\
214
+\x70\xff\0\0\0\0\x7b\x1a\x68\xff\0\0\0\0\x7b\x1a\x60\xff\0\0\0\0\x7b\x1a\x58\
215
+\xff\0\0\0\0\x15\x09\x4d\x02\0\0\0\0\x6b\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\
216
+\0\x07\x03\0\0\xd0\xff\xff\xff\xbf\x91\0\0\0\0\0\0\xb7\x02\0\0\x0c\0\0\0\xb7\
217
\x04\0\0\x02\0\0\0\xb7\x05\0\0\0\0\0\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\
218
-\x77\0\0\0\x20\0\0\0\x55\0\x11\0\0\0\0\0\xb7\x02\0\0\x10\0\0\0\x69\xa1\xd0\xff\
219
-\0\0\0\0\xbf\x13\0\0\0\0\0\0\xdc\x03\0\0\x10\0\0\0\x15\x03\x02\0\0\x81\0\0\x55\
220
-\x03\x0c\0\xa8\x88\0\0\xb7\x02\0\0\x14\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\
221
-\xd0\xff\xff\xff\xbf\x81\0\0\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\0\0\0\0\
222
-\x85\0\0\0\x44\0\0\0\x69\xa1\xd0\xff\0\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\
223
-\0\0\0\x15\0\x01\0\0\0\0\0\x05\0\x2f\x02\0\0\0\0\x15\x01\x2e\x02\0\0\0\0\x7b\
224
-\x9a\x30\xff\0\0\0\0\x15\x01\x57\0\x86\xdd\0\0\x55\x01\x3b\0\x08\0\0\0\x7b\x7a\
225
-\x20\xff\0\0\0\0\xb7\x07\0\0\x01\0\0\0\x73\x7a\x50\xff\0\0\0\0\xb7\x01\0\0\0\0\
226
-\0\0\x63\x1a\xe0\xff\0\0\0\0\x7b\x1a\xd8\xff\0\0\0\0\x7b\x1a\xd0\xff\0\0\0\0\
227
-\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xd0\xff\xff\xff\xbf\x81\0\0\0\0\0\0\xb7\x02\0\
228
-\0\0\0\0\0\xb7\x04\0\0\x14\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x67\
229
-\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x55\0\x1a\x02\0\0\0\0\x69\xa1\xd6\xff\0\0\
230
-\0\0\x55\x01\x01\0\0\0\0\0\xb7\x07\0\0\0\0\0\0\x61\xa1\xdc\xff\0\0\0\0\x63\x1a\
231
-\x5c\xff\0\0\0\0\x61\xa1\xe0\xff\0\0\0\0\x63\x1a\x60\xff\0\0\0\0\x73\x7a\x56\
232
-\xff\0\0\0\0\x71\xa9\xd9\xff\0\0\0\0\x71\xa1\xd0\xff\0\0\0\0\x67\x01\0\0\x02\0\
233
-\0\0\x57\x01\0\0\x3c\0\0\0\x7b\x1a\x40\xff\0\0\0\0\x79\xa7\x20\xff\0\0\0\0\xbf\
234
-\x91\0\0\0\0\0\0\x57\x01\0\0\xff\0\0\0\x15\x01\x19\0\0\0\0\0\x71\xa1\x56\xff\0\
235
-\0\0\0\x55\x01\x17\0\0\0\0\0\x57\x09\0\0\xff\0\0\0\x15\x09\x7a\x01\x11\0\0\0\
236
-\x55\x09\x14\0\x06\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x53\xff\0\0\0\0\xb7\x01\
237
-\0\0\0\0\0\0\x63\x1a\xe0\xff\0\0\0\0\x7b\x1a\xd8\xff\0\0\0\0\x7b\x1a\xd0\xff\0\
238
-\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xd0\xff\xff\xff\xbf\x81\0\0\0\0\0\0\x79\
239
-\xa2\x40\xff\0\0\0\0\xb7\x04\0\0\x14\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\
240
-\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x55\0\xf4\x01\0\0\0\0\x69\xa1\
241
-\xd0\xff\0\0\0\0\x6b\x1a\x58\xff\0\0\0\0\x69\xa1\xd2\xff\0\0\0\0\x6b\x1a\x5a\
242
-\xff\0\0\0\0\x71\xa1\x50\xff\0\0\0\0\x15\x01\xd4\0\0\0\0\0\x71\x62\x03\0\0\0\0\
243
-\0\x67\x02\0\0\x08\0\0\0\x71\x61\x02\0\0\0\0\0\x4f\x12\0\0\0\0\0\0\x71\x63\x04\
244
-\0\0\0\0\0\x71\x61\x05\0\0\0\0\0\x67\x01\0\0\x08\0\0\0\x4f\x31\0\0\0\0\0\0\x67\
245
-\x01\0\0\x10\0\0\0\x4f\x21\0\0\0\0\0\0\x71\xa2\x53\xff\0\0\0\0\x79\xa0\x30\xff\
246
-\0\0\0\0\x15\x02\x06\x01\0\0\0\0\xbf\x12\0\0\0\0\0\0\x57\x02\0\0\x02\0\0\0\x15\
247
-\x02\x03\x01\0\0\0\0\x61\xa1\x5c\xff\0\0\0\0\x63\x1a\xa0\xff\0\0\0\0\x61\xa1\
248
-\x60\xff\0\0\0\0\x63\x1a\xa4\xff\0\0\0\0\x69\xa1\x58\xff\0\0\0\0\x6b\x1a\xa8\
249
-\xff\0\0\0\0\x69\xa1\x5a\xff\0\0\0\0\x6b\x1a\xaa\xff\0\0\0\0\x05\0\x65\x01\0\0\
250
-\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x51\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x7b\x1a\
251
-\xf0\xff\0\0\0\0\x7b\x1a\xe8\xff\0\0\0\0\x7b\x1a\xe0\xff\0\0\0\0\x7b\x1a\xd8\
252
-\xff\0\0\0\0\x7b\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xd0\xff\
253
-\xff\xff\xb7\x01\0\0\x28\0\0\0\x7b\x1a\x40\xff\0\0\0\0\xbf\x81\0\0\0\0\0\0\xb7\
254
-\x02\0\0\0\0\0\0\xb7\x04\0\0\x28\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\
255
-\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x55\0\x10\x01\0\0\0\0\x79\xa1\xe0\
256
-\xff\0\0\0\0\x63\x1a\x64\xff\0\0\0\0\x77\x01\0\0\x20\0\0\0\x63\x1a\x68\xff\0\0\
257
-\0\0\x79\xa1\xd8\xff\0\0\0\0\x63\x1a\x5c\xff\0\0\0\0\x77\x01\0\0\x20\0\0\0\x63\
258
-\x1a\x60\xff\0\0\0\0\x79\xa1\xe8\xff\0\0\0\0\x63\x1a\x6c\xff\0\0\0\0\x77\x01\0\
259
-\0\x20\0\0\0\x63\x1a\x70\xff\0\0\0\0\x79\xa1\xf0\xff\0\0\0\0\x63\x1a\x74\xff\0\
260
-\0\0\0\x77\x01\0\0\x20\0\0\0\x63\x1a\x78\xff\0\0\0\0\x71\xa9\xd6\xff\0\0\0\0\
261
-\x25\x09\xff\0\x3c\0\0\0\xb7\x01\0\0\x01\0\0\0\x6f\x91\0\0\0\0\0\0\x18\x02\0\0\
262
-\x01\0\0\0\0\0\0\0\0\x18\0\x1c\x5f\x21\0\0\0\0\0\0\x55\x01\x01\0\0\0\0\0\x05\0\
263
-\xf8\0\0\0\0\0\xb7\x01\0\0\0\0\0\0\x6b\x1a\xfe\xff\0\0\0\0\xb7\x01\0\0\x28\0\0\
264
-\0\x7b\x1a\x40\xff\0\0\0\0\xbf\xa1\0\0\0\0\0\0\x07\x01\0\0\x8c\xff\xff\xff\x7b\
265
-\x1a\x18\xff\0\0\0\0\xbf\xa1\0\0\0\0\0\0\x07\x01\0\0\x7c\xff\xff\xff\x7b\x1a\
266
-\x10\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x7b\x1a\x28\xff\0\0\0\0\x7b\x7a\x20\xff\0\
267
-\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xfe\xff\xff\xff\xbf\x81\0\0\0\0\0\0\x79\
268
-\xa2\x40\xff\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\
269
-\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x15\0\x01\0\0\0\0\0\x05\0\x90\
270
-\x01\0\0\0\0\xbf\x91\0\0\0\0\0\0\x15\x01\x23\0\x3c\0\0\0\x15\x01\x59\0\x2c\0\0\
271
-\0\x55\x01\x5a\0\x2b\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xf8\xff\0\0\0\0\xbf\xa3\
272
-\0\0\0\0\0\0\x07\x03\0\0\xf8\xff\xff\xff\xbf\x81\0\0\0\0\0\0\x79\xa2\x40\xff\0\
273
-\0\0\0\xb7\x04\0\0\x04\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\xbf\x01\
274
-\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\x03\x01\0\0\0\
275
-\0\x71\xa1\xfa\xff\0\0\0\0\x55\x01\x4b\0\x02\0\0\0\x71\xa1\xf9\xff\0\0\0\0\x55\
276
-\x01\x49\0\x02\0\0\0\x71\xa1\xfb\xff\0\0\0\0\x55\x01\x47\0\x01\0\0\0\x79\xa2\
277
-\x40\xff\0\0\0\0\x07\x02\0\0\x08\0\0\0\xbf\x81\0\0\0\0\0\0\x79\xa3\x18\xff\0\0\
278
-\0\0\xb7\x04\0\0\x10\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\xbf\x01\0\
279
-\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\xf2\0\0\0\0\0\
280
-\xb7\x01\0\0\x01\0\0\0\x73\x1a\x55\xff\0\0\0\0\x05\0\x39\0\0\0\0\0\xb7\x01\0\0\
281
-\0\0\0\0\x6b\x1a\xf8\xff\0\0\0\0\xb7\x09\0\0\x02\0\0\0\xb7\x07\0\0\x1e\0\0\0\
282
-\x05\0\x0e\0\0\0\0\0\x79\xa2\x38\xff\0\0\0\0\x0f\x29\0\0\0\0\0\0\xbf\x92\0\0\0\
283
-\0\0\0\x07\x02\0\0\x01\0\0\0\x71\xa3\xff\xff\0\0\0\0\x67\x03\0\0\x03\0\0\0\x2d\
284
-\x23\x02\0\0\0\0\0\x79\xa7\x20\xff\0\0\0\0\x05\0\x2b\0\0\0\0\0\x07\x07\0\0\xff\
285
-\xff\xff\xff\xbf\x72\0\0\0\0\0\0\x67\x02\0\0\x20\0\0\0\x77\x02\0\0\x20\0\0\0\
286
-\x15\x02\xf9\xff\0\0\0\0\x7b\x9a\x38\xff\0\0\0\0\x79\xa1\x40\xff\0\0\0\0\x0f\
287
-\x19\0\0\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xf8\xff\xff\xff\xbf\x81\0\0\0\
288
-\0\0\0\xbf\x92\0\0\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\
289
-\0\x44\0\0\0\xbf\x01\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\
290
-\x55\x01\x94\0\0\0\0\0\x71\xa2\xf8\xff\0\0\0\0\x55\x02\x0f\0\xc9\0\0\0\x07\x09\
291
-\0\0\x02\0\0\0\xbf\x81\0\0\0\0\0\0\xbf\x92\0\0\0\0\0\0\x79\xa3\x10\xff\0\0\0\0\
292
-\xb7\x04\0\0\x10\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\xbf\x01\0\0\0\
293
-\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\x87\0\0\0\0\0\xb7\
294
-\x01\0\0\x01\0\0\0\x73\x1a\x54\xff\0\0\0\0\x79\xa7\x20\xff\0\0\0\0\x05\0\x07\0\
295
-\0\0\0\0\xb7\x09\0\0\x01\0\0\0\x15\x02\xd1\xff\0\0\0\0\x71\xa9\xf9\xff\0\0\0\0\
296
-\x07\x09\0\0\x02\0\0\0\x05\0\xce\xff\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x56\
297
-\xff\0\0\0\0\x71\xa1\xff\xff\0\0\0\0\x67\x01\0\0\x03\0\0\0\x79\xa2\x40\xff\0\0\
298
-\0\0\x0f\x12\0\0\0\0\0\0\x07\x02\0\0\x08\0\0\0\x7b\x2a\x40\xff\0\0\0\0\x71\xa9\
299
-\xfe\xff\0\0\0\0\x25\x09\x0e\0\x3c\0\0\0\xb7\x01\0\0\x01\0\0\0\x6f\x91\0\0\0\0\
300
-\0\0\x18\x02\0\0\x01\0\0\0\0\0\0\0\0\x18\0\x1c\x5f\x21\0\0\0\0\0\0\x55\x01\x01\
301
-\0\0\0\0\0\x05\0\x07\0\0\0\0\0\x79\xa1\x28\xff\0\0\0\0\x07\x01\0\0\x01\0\0\0\
302
-\x7b\x1a\x28\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\
303
-\x82\xff\x0b\0\0\0\x05\0\x10\xff\0\0\0\0\x15\x09\xf8\xff\x87\0\0\0\x05\0\xfd\
304
-\xff\0\0\0\0\x71\xa1\x51\xff\0\0\0\0\x79\xa0\x30\xff\0\0\0\0\x15\x01\x17\x01\0\
305
-\0\0\0\x71\x62\x03\0\0\0\0\0\x67\x02\0\0\x08\0\0\0\x71\x61\x02\0\0\0\0\0\x4f\
306
-\x12\0\0\0\0\0\0\x71\x63\x04\0\0\0\0\0\x71\x61\x05\0\0\0\0\0\x67\x01\0\0\x08\0\
307
-\0\0\x4f\x31\0\0\0\0\0\0\x67\x01\0\0\x10\0\0\0\x4f\x21\0\0\0\0\0\0\x71\xa2\x53\
308
-\xff\0\0\0\0\x15\x02\x3d\0\0\0\0\0\xbf\x12\0\0\0\0\0\0\x57\x02\0\0\x10\0\0\0\
309
-\x15\x02\x3a\0\0\0\0\0\xbf\xa2\0\0\0\0\0\0\x07\x02\0\0\x5c\xff\xff\xff\x71\xa4\
310
-\x54\xff\0\0\0\0\xbf\x23\0\0\0\0\0\0\x15\x04\x02\0\0\0\0\0\xbf\xa3\0\0\0\0\0\0\
311
-\x07\x03\0\0\x7c\xff\xff\xff\x67\x01\0\0\x38\0\0\0\xc7\x01\0\0\x38\0\0\0\x65\
312
-\x01\x01\0\xff\xff\xff\xff\xbf\x32\0\0\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\
313
-\x6c\xff\xff\xff\x71\xa5\x55\xff\0\0\0\0\xbf\x34\0\0\0\0\0\0\x15\x05\x02\0\0\0\
314
-\0\0\xbf\xa4\0\0\0\0\0\0\x07\x04\0\0\x8c\xff\xff\xff\x65\x01\x01\0\xff\xff\xff\
315
-\xff\xbf\x43\0\0\0\0\0\0\x61\x21\x04\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\x24\0\
316
-\0\0\0\0\0\x4f\x41\0\0\0\0\0\0\x7b\x1a\xa0\xff\0\0\0\0\x61\x21\x08\0\0\0\0\0\
317
-\x61\x22\x0c\0\0\0\0\0\x67\x02\0\0\x20\0\0\0\x4f\x12\0\0\0\0\0\0\x7b\x2a\xa8\
318
-\xff\0\0\0\0\x61\x31\0\0\0\0\0\0\x61\x32\x04\0\0\0\0\0\x61\x34\x08\0\0\0\0\0\
319
-\x61\x33\x0c\0\0\0\0\0\x69\xa5\x5a\xff\0\0\0\0\x6b\x5a\xc2\xff\0\0\0\0\x69\xa5\
320
-\x58\xff\0\0\0\0\x6b\x5a\xc0\xff\0\0\0\0\x67\x03\0\0\x20\0\0\0\x4f\x43\0\0\0\0\
321
-\0\0\x7b\x3a\xb8\xff\0\0\0\0\x67\x02\0\0\x20\0\0\0\x4f\x12\0\0\0\0\0\0\x7b\x2a\
322
-\xb0\xff\0\0\0\0\x05\0\x6b\0\0\0\0\0\x71\xa2\x52\xff\0\0\0\0\x15\x02\x04\0\0\0\
323
-\0\0\xbf\x12\0\0\0\0\0\0\x57\x02\0\0\x04\0\0\0\x15\x02\x01\0\0\0\0\0\x05\0\xf7\
324
-\xfe\0\0\0\0\x57\x01\0\0\x01\0\0\0\x15\x01\xd3\0\0\0\0\0\x61\xa1\x5c\xff\0\0\0\
325
-\0\x63\x1a\xa0\xff\0\0\0\0\x61\xa1\x60\xff\0\0\0\0\x63\x1a\xa4\xff\0\0\0\0\x05\
326
-\0\x5e\0\0\0\0\0\x71\xa2\x52\xff\0\0\0\0\x15\x02\x1e\0\0\0\0\0\xbf\x12\0\0\0\0\
327
-\0\0\x57\x02\0\0\x20\0\0\0\x15\x02\x1b\0\0\0\0\0\xbf\xa2\0\0\0\0\0\0\x07\x02\0\
328
-\0\x5c\xff\xff\xff\x71\xa4\x54\xff\0\0\0\0\xbf\x23\0\0\0\0\0\0\x15\x04\x02\0\0\
329
-\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\x7c\xff\xff\xff\x57\x01\0\0\0\x01\0\0\
330
-\x15\x01\x01\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\x6c\
331
-\xff\xff\xff\x71\xa5\x55\xff\0\0\0\0\xbf\x34\0\0\0\0\0\0\x15\x05\x02\0\0\0\0\0\
332
-\xbf\xa4\0\0\0\0\0\0\x07\x04\0\0\x8c\xff\xff\xff\x15\x01\xc3\xff\0\0\0\0\x05\0\
333
-\xc1\xff\0\0\0\0\xb7\x09\0\0\x3c\0\0\0\x79\xa7\x20\xff\0\0\0\0\x67\0\0\0\x20\0\
334
-\0\0\x77\0\0\0\x20\0\0\0\x15\0\xa5\xfe\0\0\0\0\x05\0\xb0\0\0\0\0\0\x15\x09\x07\
335
-\xff\x87\0\0\0\x05\0\xa2\xfe\0\0\0\0\xbf\x12\0\0\0\0\0\0\x57\x02\0\0\x08\0\0\0\
336
-\x15\x02\xab\0\0\0\0\0\xbf\xa2\0\0\0\0\0\0\x07\x02\0\0\x5c\xff\xff\xff\x71\xa4\
337
-\x54\xff\0\0\0\0\xbf\x23\0\0\0\0\0\0\x15\x04\x02\0\0\0\0\0\xbf\xa3\0\0\0\0\0\0\
338
-\x07\x03\0\0\x7c\xff\xff\xff\x57\x01\0\0\x40\0\0\0\x15\x01\x01\0\0\0\0\0\xbf\
339
-\x32\0\0\0\0\0\0\x61\x23\x04\0\0\0\0\0\x67\x03\0\0\x20\0\0\0\x61\x24\0\0\0\0\0\
340
-\0\x4f\x43\0\0\0\0\0\0\x7b\x3a\xa0\xff\0\0\0\0\x61\x23\x08\0\0\0\0\0\x61\x22\
341
-\x0c\0\0\0\0\0\x67\x02\0\0\x20\0\0\0\x4f\x32\0\0\0\0\0\0\x7b\x2a\xa8\xff\0\0\0\
342
-\0\x15\x01\x1c\0\0\0\0\0\x71\xa1\x55\xff\0\0\0\0\x15\x01\x1a\0\0\0\0\0\x61\xa1\
343
-\x98\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\xa2\x94\xff\0\0\0\0\x4f\x21\0\0\0\0\
344
-\0\0\x7b\x1a\xb8\xff\0\0\0\0\x61\xa1\x90\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\
345
-\xa2\x8c\xff\0\0\0\0\x05\0\x19\0\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x52\xff\
346
-\0\0\0\0\xb7\x01\0\0\0\0\0\0\x7b\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\
347
-\x03\0\0\xd0\xff\xff\xff\xbf\x81\0\0\0\0\0\0\x79\xa2\x40\xff\0\0\0\0\xb7\x04\0\
348
-\0\x08\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\
349
-\0\0\0\x20\0\0\0\x55\0\x7d\0\0\0\0\0\x05\0\x88\xfe\0\0\0\0\xb7\x09\0\0\x2b\0\0\
350
-\0\x05\0\xc6\xff\0\0\0\0\x61\xa1\x78\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\xa2\
351
-\x74\xff\0\0\0\0\x4f\x21\0\0\0\0\0\0\x7b\x1a\xb8\xff\0\0\0\0\x61\xa1\x70\xff\0\
352
-\0\0\0\x67\x01\0\0\x20\0\0\0\x61\xa2\x6c\xff\0\0\0\0\x4f\x21\0\0\0\0\0\0\x7b\
353
-\x1a\xb0\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x07\x07\0\0\x04\0\0\0\x61\x03\0\0\0\0\
354
-\0\0\xb7\x05\0\0\0\0\0\0\x05\0\x4e\0\0\0\0\0\xaf\x52\0\0\0\0\0\0\xbf\x75\0\0\0\
355
-\0\0\0\x0f\x15\0\0\0\0\0\0\x71\x55\0\0\0\0\0\0\x67\x03\0\0\x01\0\0\0\xbf\x50\0\
356
-\0\0\0\0\0\x77\0\0\0\x07\0\0\0\x4f\x03\0\0\0\0\0\0\xbf\x40\0\0\0\0\0\0\x67\0\0\
357
-\0\x39\0\0\0\xc7\0\0\0\x3f\0\0\0\x5f\x30\0\0\0\0\0\0\xaf\x02\0\0\0\0\0\0\xbf\
358
-\x50\0\0\0\0\0\0\x77\0\0\0\x06\0\0\0\x57\0\0\0\x01\0\0\0\x67\x03\0\0\x01\0\0\0\
359
-\x4f\x03\0\0\0\0\0\0\xbf\x40\0\0\0\0\0\0\x67\0\0\0\x3a\0\0\0\xc7\0\0\0\x3f\0\0\
360
-\0\x5f\x30\0\0\0\0\0\0\xaf\x02\0\0\0\0\0\0\x67\x03\0\0\x01\0\0\0\xbf\x50\0\0\0\
361
-\0\0\0\x77\0\0\0\x05\0\0\0\x57\0\0\0\x01\0\0\0\x4f\x03\0\0\0\0\0\0\xbf\x40\0\0\
362
-\0\0\0\0\x67\0\0\0\x3b\0\0\0\xc7\0\0\0\x3f\0\0\0\x5f\x30\0\0\0\0\0\0\xaf\x02\0\
363
-\0\0\0\0\0\x67\x03\0\0\x01\0\0\0\xbf\x50\0\0\0\0\0\0\x77\0\0\0\x04\0\0\0\x57\0\
364
-\0\0\x01\0\0\0\x4f\x03\0\0\0\0\0\0\xbf\x40\0\0\0\0\0\0\x67\0\0\0\x3c\0\0\0\xc7\
365
-\0\0\0\x3f\0\0\0\x5f\x30\0\0\0\0\0\0\xaf\x02\0\0\0\0\0\0\xbf\x50\0\0\0\0\0\0\
366
-\x77\0\0\0\x03\0\0\0\x57\0\0\0\x01\0\0\0\x67\x03\0\0\x01\0\0\0\x4f\x03\0\0\0\0\
367
-\0\0\xbf\x40\0\0\0\0\0\0\x67\0\0\0\x3d\0\0\0\xc7\0\0\0\x3f\0\0\0\x5f\x30\0\0\0\
368
-\0\0\0\xaf\x02\0\0\0\0\0\0\xbf\x50\0\0\0\0\0\0\x77\0\0\0\x02\0\0\0\x57\0\0\0\
369
-\x01\0\0\0\x67\x03\0\0\x01\0\0\0\x4f\x03\0\0\0\0\0\0\xbf\x40\0\0\0\0\0\0\x67\0\
370
-\0\0\x3e\0\0\0\xc7\0\0\0\x3f\0\0\0\x5f\x30\0\0\0\0\0\0\xaf\x02\0\0\0\0\0\0\xbf\
371
-\x50\0\0\0\0\0\0\x77\0\0\0\x01\0\0\0\x57\0\0\0\x01\0\0\0\x67\x03\0\0\x01\0\0\0\
372
-\x4f\x03\0\0\0\0\0\0\x57\x04\0\0\x01\0\0\0\x87\x04\0\0\0\0\0\0\x5f\x34\0\0\0\0\
373
-\0\0\xaf\x42\0\0\0\0\0\0\x57\x05\0\0\x01\0\0\0\x67\x03\0\0\x01\0\0\0\x4f\x53\0\
374
-\0\0\0\0\0\x07\x01\0\0\x01\0\0\0\xbf\x25\0\0\0\0\0\0\x15\x01\x0b\0\x24\0\0\0\
375
-\xbf\xa2\0\0\0\0\0\0\x07\x02\0\0\xa0\xff\xff\xff\x0f\x12\0\0\0\0\0\0\x71\x24\0\
376
-\0\0\0\0\0\xbf\x40\0\0\0\0\0\0\x67\0\0\0\x38\0\0\0\xc7\0\0\0\x38\0\0\0\xb7\x02\
377
-\0\0\0\0\0\0\x65\0\xa9\xff\xff\xff\xff\xff\xbf\x32\0\0\0\0\0\0\x05\0\xa7\xff\0\
378
-\0\0\0\xbf\x21\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x15\x01\
379
-\x0e\0\0\0\0\0\x71\x63\x06\0\0\0\0\0\x71\x64\x07\0\0\0\0\0\x67\x04\0\0\x08\0\0\
380
-\0\x4f\x34\0\0\0\0\0\0\x3f\x41\0\0\0\0\0\0\x2f\x41\0\0\0\0\0\0\x1f\x12\0\0\0\0\
381
-\0\0\x63\x2a\x50\xff\0\0\0\0\xbf\xa2\0\0\0\0\0\0\x07\x02\0\0\x50\xff\xff\xff\
382
-\x18\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x85\0\0\0\x01\0\0\0\x55\0\x05\0\0\0\0\0\
383
-\x71\x61\x08\0\0\0\0\0\x71\x60\x09\0\0\0\0\0\x67\0\0\0\x08\0\0\0\x4f\x10\0\0\0\
384
-\0\0\0\x95\0\0\0\0\0\0\0\x69\0\0\0\0\0\0\0\x05\0\xfd\xff\0\0\0\0\x02\0\0\0\x04\
385
-\0\0\0\x0a\0\0\0\x01\0\0\0\0\0\0\0\x02\0\0\0\x04\0\0\0\x28\0\0\0\x01\0\0\0\0\0\
386
-\0\0\x02\0\0\0\x04\0\0\0\x02\0\0\0\x80\0\0\0\0\0\0\0\x47\x50\x4c\x20\x76\x32\0\
387
-\0\0\0\0\0\x10\0\0\0\0\0\0\0\x01\x7a\x52\0\x08\x7c\x0b\x01\x0c\0\0\0\x18\0\0\0\
388
-\x18\0\0\0\0\0\0\0\0\0\0\0\xd8\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
389
-\0\0\0\0\0\0\0\0\0\0\0\0\xa0\0\0\0\x04\0\xf1\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
390
-\0\x60\x02\0\0\0\0\x03\0\x20\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3f\x02\0\0\0\0\
391
-\x03\0\xd0\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xed\x01\0\0\0\0\x03\0\x10\x10\0\0\0\
392
-\0\0\0\0\0\0\0\0\0\0\0\xd4\x01\0\0\0\0\x03\0\x20\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\
393
-\0\xa3\x01\0\0\0\0\x03\0\xb8\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x63\x01\0\0\0\0\
394
-\x03\0\x48\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2a\x01\0\0\0\0\x03\0\x10\x13\0\0\0\
395
-\0\0\0\0\0\0\0\0\0\0\0\xe1\0\0\0\0\0\x03\0\xa0\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
396
-\x2e\x02\0\0\0\0\x03\0\x28\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x68\x02\0\0\0\0\x03\
397
-\0\xc0\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x36\x02\0\0\0\0\x03\0\xc8\x13\0\0\0\0\0\
398
-\0\0\0\0\0\0\0\0\0\x22\x01\0\0\0\0\x03\0\xe8\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
399
-\x02\x01\0\0\0\0\x03\0\x40\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd9\0\0\0\0\0\x03\0\
400
-\xf8\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x26\x02\0\0\0\0\x03\0\x20\x0e\0\0\0\0\0\0\
401
-\0\0\0\0\0\0\0\0\xcc\x01\0\0\0\0\x03\0\x60\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x9b\
402
-\x01\0\0\0\0\x03\0\xc8\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5b\x01\0\0\0\0\x03\0\
403
-\x20\x07\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7c\x01\0\0\0\0\x03\0\x48\x08\0\0\0\0\0\0\
404
-\0\0\0\0\0\0\0\0\x53\x01\0\0\0\0\x03\0\xb8\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1a\
405
-\x01\0\0\0\0\x03\0\xe0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x84\x01\0\0\0\0\x03\0\
406
-\xb8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x02\0\0\0\0\x03\0\xd8\x09\0\0\0\0\0\0\0\
407
-\0\0\0\0\0\0\0\xc4\x01\0\0\0\0\x03\0\x70\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x93\
408
-\x01\0\0\0\0\x03\0\xa8\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x74\x01\0\0\0\0\x03\0\
409
-\xf0\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4b\x01\0\0\0\0\x03\0\0\x0a\0\0\0\0\0\0\0\
410
-\0\0\0\0\0\0\0\x12\x01\0\0\0\0\x03\0\x10\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xfa\0\
411
-\0\0\0\0\x03\0\xc0\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x58\x02\0\0\0\0\x03\0\x88\
412
-\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x02\0\0\0\0\x03\0\xb8\x0a\0\0\0\0\0\0\0\0\
413
-\0\0\0\0\0\0\xe5\x01\0\0\0\0\x03\0\xc0\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbc\x01\
414
-\0\0\0\0\x03\0\0\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x8b\x01\0\0\0\0\x03\0\x18\x0e\
415
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd1\0\0\0\0\0\x03\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\
416
-\0\0\x50\x02\0\0\0\0\x03\0\x20\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0e\x02\0\0\0\0\
417
-\x03\0\x48\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6c\x01\0\0\0\0\x03\0\xb0\x04\0\0\0\
418
-\0\0\0\0\0\0\0\0\0\0\0\x43\x01\0\0\0\0\x03\0\xc8\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\
419
-\0\xc9\0\0\0\0\0\x03\0\xf8\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x06\x02\0\0\0\0\x03\
420
-\0\xd0\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3b\x01\0\0\0\0\x03\0\x98\x0b\0\0\0\0\0\
421
-\0\0\0\0\0\0\0\0\0\xf2\0\0\0\0\0\x03\0\xb8\x0b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x48\
422
-\x02\0\0\0\0\x03\0\xf0\x0b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xfe\x01\0\0\0\0\x03\0\
423
-\xf8\x0b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xdd\x01\0\0\0\0\x03\0\0\x0c\0\0\0\0\0\0\0\
424
-\0\0\0\0\0\0\0\xb4\x01\0\0\0\0\x03\0\x30\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0a\
425
-\x01\0\0\0\0\x03\0\x90\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc1\0\0\0\0\0\x03\0\xa8\
426
-\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xba\0\0\0\0\0\x03\0\xd0\x01\0\0\0\0\0\0\0\0\0\
427
-\0\0\0\0\0\xf6\x01\0\0\0\0\x03\0\xe0\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xac\x01\0\
428
-\0\0\0\x03\0\x30\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x33\x01\0\0\0\0\x03\0\x80\x0e\
429
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xea\0\0\0\0\0\x03\0\x98\x0e\0\0\0\0\0\0\0\0\0\0\0\
430
-\0\0\0\0\0\0\0\x03\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6b\0\0\0\x11\0\x06\
431
-\0\0\0\0\0\0\0\0\0\x07\0\0\0\0\0\0\0\x25\0\0\0\x11\0\x05\0\0\0\0\0\0\0\0\0\x14\
432
-\0\0\0\0\0\0\0\x82\0\0\0\x11\0\x05\0\x28\0\0\0\0\0\0\0\x14\0\0\0\0\0\0\0\x01\0\
433
-\0\0\x11\0\x05\0\x14\0\0\0\0\0\0\0\x14\0\0\0\0\0\0\0\x40\0\0\0\x12\0\x03\0\0\0\
434
-\0\0\0\0\0\0\xd8\x13\0\0\0\0\0\0\x28\0\0\0\0\0\0\0\x01\0\0\0\x3a\0\0\0\x50\0\0\
435
-\0\0\0\0\0\x01\0\0\0\x3c\0\0\0\x80\x13\0\0\0\0\0\0\x01\0\0\0\x3b\0\0\0\x1c\0\0\
436
-\0\0\0\0\0\x01\0\0\0\x38\0\0\0\0\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\
437
+\x77\0\0\0\x20\0\0\0\x55\0\x42\x02\0\0\0\0\xb7\x02\0\0\x10\0\0\0\x69\xa1\xd0\
438
+\xff\0\0\0\0\xbf\x13\0\0\0\0\0\0\xdc\x03\0\0\x10\0\0\0\x15\x03\x02\0\0\x81\0\0\
439
+\x55\x03\x0b\0\xa8\x88\0\0\xb7\x02\0\0\x14\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\
440
+\0\xd0\xff\xff\xff\xbf\x91\0\0\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\0\0\0\
441
+\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x55\0\x32\x02\0\
442
+\0\0\0\x69\xa1\xd0\xff\0\0\0\0\x15\x01\x30\x02\0\0\0\0\x7b\x7a\x38\xff\0\0\0\0\
443
+\x7b\x9a\x40\xff\0\0\0\0\x15\x01\x55\0\x86\xdd\0\0\x55\x01\x39\0\x08\0\0\0\xb7\
444
+\x07\0\0\x01\0\0\0\x73\x7a\x58\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xe0\xff\
445
+\0\0\0\0\x7b\x1a\xd8\xff\0\0\0\0\x7b\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\0\
446
+\x07\x03\0\0\xd0\xff\xff\xff\x79\xa1\x40\xff\0\0\0\0\xb7\x02\0\0\0\0\0\0\xb7\
447
+\x04\0\0\x14\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\
448
+\0\x77\0\0\0\x20\0\0\0\x55\0\x1c\x02\0\0\0\0\x69\xa1\xd6\xff\0\0\0\0\x55\x01\
449
+\x01\0\0\0\0\0\xb7\x07\0\0\0\0\0\0\x61\xa1\xdc\xff\0\0\0\0\x63\x1a\x64\xff\0\0\
450
+\0\0\x61\xa1\xe0\xff\0\0\0\0\x63\x1a\x68\xff\0\0\0\0\x71\xa9\xd9\xff\0\0\0\0\
451
+\x73\x7a\x5e\xff\0\0\0\0\x71\xa1\xd0\xff\0\0\0\0\x67\x01\0\0\x02\0\0\0\x57\x01\
452
+\0\0\x3c\0\0\0\x7b\x1a\x48\xff\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\xff\0\0\
453
+\0\x15\x01\x19\0\0\0\0\0\x57\x07\0\0\xff\0\0\0\x55\x07\x17\0\0\0\0\0\x57\x09\0\
454
+\0\xff\0\0\0\x15\x09\x5a\x01\x11\0\0\0\x55\x09\x14\0\x06\0\0\0\xb7\x01\0\0\x01\
455
+\0\0\0\x73\x1a\x5b\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xe0\xff\0\0\0\0\x7b\
456
+\x1a\xd8\xff\0\0\0\0\x7b\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\
457
+\xd0\xff\xff\xff\x79\xa1\x40\xff\0\0\0\0\x79\xa2\x48\xff\0\0\0\0\xb7\x04\0\0\
458
+\x14\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\
459
+\0\0\x20\0\0\0\x55\0\xf7\x01\0\0\0\0\x69\xa1\xd0\xff\0\0\0\0\x6b\x1a\x60\xff\0\
460
+\0\0\0\x69\xa1\xd2\xff\0\0\0\0\x6b\x1a\x62\xff\0\0\0\0\x71\xa1\x58\xff\0\0\0\0\
461
+\x15\x01\xdb\0\0\0\0\0\x71\x62\x03\0\0\0\0\0\x67\x02\0\0\x08\0\0\0\x71\x61\x02\
462
+\0\0\0\0\0\x4f\x12\0\0\0\0\0\0\x71\x63\x04\0\0\0\0\0\x71\x61\x05\0\0\0\0\0\x67\
463
+\x01\0\0\x08\0\0\0\x4f\x31\0\0\0\0\0\0\x67\x01\0\0\x10\0\0\0\x4f\x21\0\0\0\0\0\
464
+\0\x71\xa2\x5b\xff\0\0\0\0\x79\xa0\x38\xff\0\0\0\0\x15\x02\x0c\x01\0\0\0\0\xbf\
465
+\x12\0\0\0\0\0\0\x57\x02\0\0\x02\0\0\0\x15\x02\x09\x01\0\0\0\0\x61\xa1\x64\xff\
466
+\0\0\0\0\x63\x1a\xa8\xff\0\0\0\0\x61\xa1\x68\xff\0\0\0\0\x63\x1a\xac\xff\0\0\0\
467
+\0\x69\xa1\x60\xff\0\0\0\0\x6b\x1a\xb0\xff\0\0\0\0\x69\xa1\x62\xff\0\0\0\0\x6b\
468
+\x1a\xb2\xff\0\0\0\0\x05\0\x6b\x01\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x59\
469
+\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x7b\x1a\xf0\xff\0\0\0\0\x7b\x1a\xe8\xff\0\0\0\
470
+\0\x7b\x1a\xe0\xff\0\0\0\0\x7b\x1a\xd8\xff\0\0\0\0\x7b\x1a\xd0\xff\0\0\0\0\xbf\
471
+\xa3\0\0\0\0\0\0\x07\x03\0\0\xd0\xff\xff\xff\xb7\x01\0\0\x28\0\0\0\x7b\x1a\x48\
472
+\xff\0\0\0\0\xbf\x91\0\0\0\0\0\0\xb7\x02\0\0\0\0\0\0\xb7\x04\0\0\x28\0\0\0\xb7\
473
+\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\
474
+\x55\0\xfe\0\0\0\0\0\x79\xa1\xe0\xff\0\0\0\0\x63\x1a\x6c\xff\0\0\0\0\x77\x01\0\
475
+\0\x20\0\0\0\x63\x1a\x70\xff\0\0\0\0\x79\xa1\xd8\xff\0\0\0\0\x63\x1a\x64\xff\0\
476
+\0\0\0\x77\x01\0\0\x20\0\0\0\x63\x1a\x68\xff\0\0\0\0\x79\xa1\xe8\xff\0\0\0\0\
477
+\x63\x1a\x74\xff\0\0\0\0\x77\x01\0\0\x20\0\0\0\x63\x1a\x78\xff\0\0\0\0\x79\xa1\
478
+\xf0\xff\0\0\0\0\x63\x1a\x7c\xff\0\0\0\0\x77\x01\0\0\x20\0\0\0\x63\x1a\x80\xff\
479
+\0\0\0\0\x71\xa9\xd6\xff\0\0\0\0\x25\x09\x13\x01\x3c\0\0\0\xb7\x01\0\0\x01\0\0\
480
+\0\x6f\x91\0\0\0\0\0\0\x18\x02\0\0\x01\0\0\0\0\0\0\0\0\x18\0\x1c\x5f\x21\0\0\0\
481
+\0\0\0\x55\x01\x01\0\0\0\0\0\x05\0\x0c\x01\0\0\0\0\xb7\x01\0\0\0\0\0\0\x6b\x1a\
482
+\xfe\xff\0\0\0\0\xb7\x01\0\0\x28\0\0\0\x7b\x1a\x48\xff\0\0\0\0\xbf\xa1\0\0\0\0\
483
+\0\0\x07\x01\0\0\x94\xff\xff\xff\x7b\x1a\x20\xff\0\0\0\0\xbf\xa1\0\0\0\0\0\0\
484
+\x07\x01\0\0\x84\xff\xff\xff\x7b\x1a\x18\xff\0\0\0\0\x18\x07\0\0\x01\0\0\0\0\0\
485
+\0\0\0\x18\0\x1c\xb7\x02\0\0\0\0\0\0\x7b\x8a\x28\xff\0\0\0\0\x7b\x2a\x30\xff\0\
486
+\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xfe\xff\xff\xff\x79\xa1\x40\xff\0\0\0\0\
487
+\x79\xa2\x48\xff\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\
488
+\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x15\0\x01\0\0\0\0\0\x05\0\
489
+\x91\x01\0\0\0\0\xbf\x91\0\0\0\0\0\0\x15\x01\x26\0\x3c\0\0\0\x15\x01\x5f\0\x2c\
490
+\0\0\0\x55\x01\x60\0\x2b\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xf8\xff\0\0\0\0\xbf\
491
+\xa3\0\0\0\0\0\0\x07\x03\0\0\xf8\xff\xff\xff\x79\xa7\x40\xff\0\0\0\0\xbf\x71\0\
492
+\0\0\0\0\0\x79\xa2\x48\xff\0\0\0\0\xb7\x04\0\0\x04\0\0\0\xb7\x05\0\0\x01\0\0\0\
493
+\x85\0\0\0\x44\0\0\0\xbf\x01\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\
494
+\0\0\0\x55\x01\x06\x01\0\0\0\0\x71\xa1\xfa\xff\0\0\0\0\x55\x01\x11\0\x02\0\0\0\
495
+\x71\xa1\xf9\xff\0\0\0\0\x55\x01\x0f\0\x02\0\0\0\x71\xa1\xfb\xff\0\0\0\0\x55\
496
+\x01\x0d\0\x01\0\0\0\x79\xa2\x48\xff\0\0\0\0\x07\x02\0\0\x08\0\0\0\xbf\x71\0\0\
497
+\0\0\0\0\x79\xa3\x20\xff\0\0\0\0\xb7\x04\0\0\x10\0\0\0\xb7\x05\0\0\x01\0\0\0\
498
+\x85\0\0\0\x44\0\0\0\xbf\x01\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\
499
+\0\0\0\x55\x01\xf5\0\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x5d\xff\0\0\0\0\x18\
500
+\x07\0\0\x01\0\0\0\0\0\0\0\0\x18\0\x1c\x05\0\x3c\0\0\0\0\0\xb7\x08\0\0\x02\0\0\
501
+\0\xb7\x07\0\0\0\0\0\0\x6b\x7a\xf8\xff\0\0\0\0\x05\0\x13\0\0\0\0\0\x0f\x81\0\0\
502
+\0\0\0\0\xbf\x12\0\0\0\0\0\0\x07\x02\0\0\x01\0\0\0\x71\xa3\xff\xff\0\0\0\0\x67\
503
+\x03\0\0\x03\0\0\0\x3d\x32\x09\0\0\0\0\0\xbf\x72\0\0\0\0\0\0\x07\x02\0\0\x01\0\
504
+\0\0\x67\x07\0\0\x20\0\0\0\xbf\x73\0\0\0\0\0\0\x77\x03\0\0\x20\0\0\0\xbf\x27\0\
505
+\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xb7\x01\0\0\x1d\0\0\0\x2d\x31\x04\0\0\0\0\0\x79\
506
+\xa8\x28\xff\0\0\0\0\x18\x07\0\0\x01\0\0\0\0\0\0\0\0\x18\0\x1c\x05\0\x25\0\0\0\
507
+\0\0\xbf\x89\0\0\0\0\0\0\x79\xa1\x48\xff\0\0\0\0\x0f\x19\0\0\0\0\0\0\xbf\xa3\0\
508
+\0\0\0\0\0\x07\x03\0\0\xf8\xff\xff\xff\x79\xa1\x40\xff\0\0\0\0\xbf\x92\0\0\0\0\
509
+\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\xbf\x01\0\
510
+\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\x79\0\0\0\0\0\
511
+\x71\xa2\xf8\xff\0\0\0\0\x55\x02\x0e\0\xc9\0\0\0\x07\x09\0\0\x02\0\0\0\x79\xa1\
512
+\x40\xff\0\0\0\0\xbf\x92\0\0\0\0\0\0\x79\xa3\x18\xff\0\0\0\0\xb7\x04\0\0\x10\0\
513
+\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\xbf\x01\0\0\0\0\0\0\x67\x01\0\0\
514
+\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\x6c\0\0\0\0\0\xb7\x01\0\0\x01\0\0\0\
515
+\x73\x1a\x5c\xff\0\0\0\0\x05\0\xde\xff\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x15\x02\
516
+\xcd\xff\0\0\0\0\x71\xa1\xf9\xff\0\0\0\0\x07\x01\0\0\x02\0\0\0\x05\0\xca\xff\0\
517
+\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x5e\xff\0\0\0\0\x71\xa1\xff\xff\0\0\0\0\
518
+\x67\x01\0\0\x03\0\0\0\x79\xa2\x48\xff\0\0\0\0\x0f\x12\0\0\0\0\0\0\x07\x02\0\0\
519
+\x08\0\0\0\x7b\x2a\x48\xff\0\0\0\0\x71\xa9\xfe\xff\0\0\0\0\x79\xa2\x30\xff\0\0\
520
+\0\0\x25\x09\x0c\0\x3c\0\0\0\xb7\x01\0\0\x01\0\0\0\x6f\x91\0\0\0\0\0\0\x5f\x71\
521
+\0\0\0\0\0\0\x55\x01\x01\0\0\0\0\0\x05\0\x07\0\0\0\0\0\x07\x02\0\0\x01\0\0\0\
522
+\xbf\x21\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\x7d\
523
+\xff\x0b\0\0\0\x71\xa7\x5e\xff\0\0\0\0\x05\0\x09\xff\0\0\0\0\x15\x09\xf8\xff\
524
+\x87\0\0\0\x05\0\xfc\xff\0\0\0\0\x71\xa1\x59\xff\0\0\0\0\x79\xa0\x38\xff\0\0\0\
525
+\0\x15\x01\x13\x01\0\0\0\0\x71\x62\x03\0\0\0\0\0\x67\x02\0\0\x08\0\0\0\x71\x61\
526
+\x02\0\0\0\0\0\x4f\x12\0\0\0\0\0\0\x71\x63\x04\0\0\0\0\0\x71\x61\x05\0\0\0\0\0\
527
+\x67\x01\0\0\x08\0\0\0\x4f\x31\0\0\0\0\0\0\x67\x01\0\0\x10\0\0\0\x4f\x21\0\0\0\
528
+\0\0\0\x71\xa2\x5b\xff\0\0\0\0\x15\x02\x42\0\0\0\0\0\xbf\x12\0\0\0\0\0\0\x57\
529
+\x02\0\0\x10\0\0\0\x15\x02\x3f\0\0\0\0\0\x57\x01\0\0\x80\0\0\0\xb7\x02\0\0\x10\
530
+\0\0\0\xb7\x03\0\0\x10\0\0\0\x15\x01\x01\0\0\0\0\0\xb7\x03\0\0\x30\0\0\0\x71\
531
+\xa4\x5d\xff\0\0\0\0\x15\x04\x01\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\xbf\xa3\0\0\0\0\
532
+\0\0\x07\x03\0\0\x64\xff\xff\xff\xbf\x34\0\0\0\0\0\0\x15\x01\x02\0\0\0\0\0\xbf\
533
+\xa4\0\0\0\0\0\0\x07\x04\0\0\x84\xff\xff\xff\x71\xa5\x5c\xff\0\0\0\0\xbf\x31\0\
534
+\0\0\0\0\0\x15\x05\x01\0\0\0\0\0\xbf\x41\0\0\0\0\0\0\x61\x14\x04\0\0\0\0\0\x67\
535
+\x04\0\0\x20\0\0\0\x61\x15\0\0\0\0\0\0\x4f\x54\0\0\0\0\0\0\x7b\x4a\xa8\xff\0\0\
536
+\0\0\x61\x14\x08\0\0\0\0\0\x61\x11\x0c\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x4f\x41\
537
+\0\0\0\0\0\0\x7b\x1a\xb0\xff\0\0\0\0\x0f\x23\0\0\0\0\0\0\x61\x31\0\0\0\0\0\0\
538
+\x61\x32\x04\0\0\0\0\0\x61\x34\x08\0\0\0\0\0\x61\x33\x0c\0\0\0\0\0\x69\xa5\x62\
539
+\xff\0\0\0\0\x6b\x5a\xca\xff\0\0\0\0\x69\xa5\x60\xff\0\0\0\0\x6b\x5a\xc8\xff\0\
540
+\0\0\0\x67\x03\0\0\x20\0\0\0\x4f\x43\0\0\0\0\0\0\x7b\x3a\xc0\xff\0\0\0\0\x67\
541
+\x02\0\0\x20\0\0\0\x4f\x12\0\0\0\0\0\0\x7b\x2a\xb8\xff\0\0\0\0\x05\0\x6b\0\0\0\
542
+\0\0\x71\xa2\x5a\xff\0\0\0\0\x15\x02\x04\0\0\0\0\0\xbf\x12\0\0\0\0\0\0\x57\x02\
543
+\0\0\x04\0\0\0\x15\x02\x01\0\0\0\0\0\x05\0\xf1\xfe\0\0\0\0\x57\x01\0\0\x01\0\0\
544
+\0\x15\x01\xd0\0\0\0\0\0\x61\xa1\x64\xff\0\0\0\0\x63\x1a\xa8\xff\0\0\0\0\x61\
545
+\xa1\x68\xff\0\0\0\0\x63\x1a\xac\xff\0\0\0\0\x05\0\x5e\0\0\0\0\0\xb7\x09\0\0\
546
+\x3c\0\0\0\x79\xa8\x28\xff\0\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x15\
547
+\0\xac\xff\0\0\0\0\x05\0\xc5\0\0\0\0\0\x71\xa2\x5a\xff\0\0\0\0\x15\x02\x26\0\0\
548
+\0\0\0\xbf\x12\0\0\0\0\0\0\x57\x02\0\0\x20\0\0\0\x15\x02\x23\0\0\0\0\0\x57\x01\
549
+\0\0\0\x01\0\0\xb7\x02\0\0\x10\0\0\0\xb7\x03\0\0\x10\0\0\0\x15\x01\x01\0\0\0\0\
550
+\0\xb7\x03\0\0\x30\0\0\0\x71\xa4\x5d\xff\0\0\0\0\x15\x04\x01\0\0\0\0\0\xbf\x32\
551
+\0\0\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\x64\xff\xff\xff\xbf\x34\0\0\0\0\0\
552
+\0\x15\x01\x02\0\0\0\0\0\xbf\xa4\0\0\0\0\0\0\x07\x04\0\0\x84\xff\xff\xff\x71\
553
+\xa5\x5c\xff\0\0\0\0\xbf\x31\0\0\0\0\0\0\x15\x05\xbd\xff\0\0\0\0\x05\0\xbb\xff\
554
+\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x5a\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x7b\
555
+\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xd0\xff\xff\xff\x79\xa1\
556
+\x40\xff\0\0\0\0\x79\xa2\x48\xff\0\0\0\0\xb7\x04\0\0\x08\0\0\0\xb7\x05\0\0\x01\
557
+\0\0\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x55\0\xa0\0\
558
+\0\0\0\0\x05\0\xa8\xfe\0\0\0\0\x15\x09\xf3\xfe\x87\0\0\0\x05\0\x83\xff\0\0\0\0\
559
+\xbf\x12\0\0\0\0\0\0\x57\x02\0\0\x08\0\0\0\x15\x02\x9a\0\0\0\0\0\x57\x01\0\0\
560
+\x40\0\0\0\xb7\x02\0\0\x0c\0\0\0\xb7\x03\0\0\x0c\0\0\0\x15\x01\x01\0\0\0\0\0\
561
+\xb7\x03\0\0\x2c\0\0\0\x71\xa4\x5c\xff\0\0\0\0\x15\x04\x01\0\0\0\0\0\xbf\x32\0\
562
+\0\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\x58\xff\xff\xff\x0f\x23\0\0\0\0\0\0\
563
+\x61\x32\x04\0\0\0\0\0\x67\x02\0\0\x20\0\0\0\x61\x34\0\0\0\0\0\0\x4f\x42\0\0\0\
564
+\0\0\0\x7b\x2a\xa8\xff\0\0\0\0\x61\x32\x08\0\0\0\0\0\x61\x33\x0c\0\0\0\0\0\x67\
565
+\x03\0\0\x20\0\0\0\x4f\x23\0\0\0\0\0\0\x7b\x3a\xb0\xff\0\0\0\0\x71\xa2\x5d\xff\
566
+\0\0\0\0\x15\x02\x0c\0\0\0\0\0\x15\x01\x0b\0\0\0\0\0\x61\xa1\xa0\xff\0\0\0\0\
567
+\x67\x01\0\0\x20\0\0\0\x61\xa2\x9c\xff\0\0\0\0\x4f\x21\0\0\0\0\0\0\x7b\x1a\xc0\
568
+\xff\0\0\0\0\x61\xa1\x98\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\xa2\x94\xff\0\0\
569
+\0\0\x05\0\x0a\0\0\0\0\0\xb7\x09\0\0\x2b\0\0\0\x05\0\xae\xff\0\0\0\0\x61\xa1\
570
+\x80\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\xa2\x7c\xff\0\0\0\0\x4f\x21\0\0\0\0\
571
+\0\0\x7b\x1a\xc0\xff\0\0\0\0\x61\xa1\x78\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\
572
+\xa2\x74\xff\0\0\0\0\x4f\x21\0\0\0\0\0\0\x7b\x1a\xb8\xff\0\0\0\0\xb7\x02\0\0\0\
573
+\0\0\0\x07\x08\0\0\x04\0\0\0\x61\x03\0\0\0\0\0\0\xb7\x05\0\0\0\0\0\0\xbf\xa1\0\
574
+\0\0\0\0\0\x07\x01\0\0\xa8\xff\xff\xff\x0f\x21\0\0\0\0\0\0\x71\x14\0\0\0\0\0\0\
575
+\xbf\x41\0\0\0\0\0\0\x67\x01\0\0\x38\0\0\0\xc7\x01\0\0\x3f\0\0\0\x5f\x31\0\0\0\
576
+\0\0\0\xaf\x51\0\0\0\0\0\0\xbf\x85\0\0\0\0\0\0\x0f\x25\0\0\0\0\0\0\x71\x55\0\0\
577
+\0\0\0\0\x67\x03\0\0\x01\0\0\0\xbf\x50\0\0\0\0\0\0\x77\0\0\0\x07\0\0\0\x4f\x03\
578
+\0\0\0\0\0\0\xbf\x40\0\0\0\0\0\0\x67\0\0\0\x39\0\0\0\xc7\0\0\0\x3f\0\0\0\x5f\
579
+\x30\0\0\0\0\0\0\xaf\x01\0\0\0\0\0\0\xbf\x50\0\0\0\0\0\0\x77\0\0\0\x06\0\0\0\
580
+\x57\0\0\0\x01\0\0\0\x67\x03\0\0\x01\0\0\0\x4f\x03\0\0\0\0\0\0\xbf\x40\0\0\0\0\
581
+\0\0\x67\0\0\0\x3a\0\0\0\xc7\0\0\0\x3f\0\0\0\x5f\x30\0\0\0\0\0\0\xaf\x01\0\0\0\
582
+\0\0\0\x67\x03\0\0\x01\0\0\0\xbf\x50\0\0\0\0\0\0\x77\0\0\0\x05\0\0\0\x57\0\0\0\
583
+\x01\0\0\0\x4f\x03\0\0\0\0\0\0\xbf\x40\0\0\0\0\0\0\x67\0\0\0\x3b\0\0\0\xc7\0\0\
584
+\0\x3f\0\0\0\x5f\x30\0\0\0\0\0\0\xaf\x01\0\0\0\0\0\0\x67\x03\0\0\x01\0\0\0\xbf\
585
+\x50\0\0\0\0\0\0\x77\0\0\0\x04\0\0\0\x57\0\0\0\x01\0\0\0\x4f\x03\0\0\0\0\0\0\
586
+\xbf\x40\0\0\0\0\0\0\x67\0\0\0\x3c\0\0\0\xc7\0\0\0\x3f\0\0\0\x5f\x30\0\0\0\0\0\
587
+\0\xaf\x01\0\0\0\0\0\0\xbf\x50\0\0\0\0\0\0\x77\0\0\0\x03\0\0\0\x57\0\0\0\x01\0\
588
+\0\0\x67\x03\0\0\x01\0\0\0\x4f\x03\0\0\0\0\0\0\xbf\x40\0\0\0\0\0\0\x67\0\0\0\
589
+\x3d\0\0\0\xc7\0\0\0\x3f\0\0\0\x5f\x30\0\0\0\0\0\0\xaf\x01\0\0\0\0\0\0\xbf\x50\
590
+\0\0\0\0\0\0\x77\0\0\0\x02\0\0\0\x57\0\0\0\x01\0\0\0\x67\x03\0\0\x01\0\0\0\x4f\
591
+\x03\0\0\0\0\0\0\xbf\x40\0\0\0\0\0\0\x67\0\0\0\x3e\0\0\0\xc7\0\0\0\x3f\0\0\0\
592
+\x5f\x30\0\0\0\0\0\0\xaf\x01\0\0\0\0\0\0\xbf\x50\0\0\0\0\0\0\x77\0\0\0\x01\0\0\
593
+\0\x57\0\0\0\x01\0\0\0\x67\x03\0\0\x01\0\0\0\x4f\x03\0\0\0\0\0\0\x57\x04\0\0\
594
+\x01\0\0\0\x87\x04\0\0\0\0\0\0\x5f\x34\0\0\0\0\0\0\xaf\x41\0\0\0\0\0\0\x57\x05\
595
+\0\0\x01\0\0\0\x67\x03\0\0\x01\0\0\0\x4f\x53\0\0\0\0\0\0\x07\x02\0\0\x01\0\0\0\
596
+\xbf\x15\0\0\0\0\0\0\x15\x02\x01\0\x24\0\0\0\x05\0\xa9\xff\0\0\0\0\xbf\x12\0\0\
597
+\0\0\0\0\x67\x02\0\0\x20\0\0\0\x77\x02\0\0\x20\0\0\0\x15\x02\x0e\0\0\0\0\0\x71\
598
+\x63\x06\0\0\0\0\0\x71\x64\x07\0\0\0\0\0\x67\x04\0\0\x08\0\0\0\x4f\x34\0\0\0\0\
599
+\0\0\x3f\x42\0\0\0\0\0\0\x2f\x42\0\0\0\0\0\0\x1f\x21\0\0\0\0\0\0\x63\x1a\x58\
600
+\xff\0\0\0\0\xbf\xa2\0\0\0\0\0\0\x07\x02\0\0\x58\xff\xff\xff\x18\x01\0\0\0\0\0\
601
+\0\0\0\0\0\0\0\0\0\x85\0\0\0\x01\0\0\0\x55\0\x05\0\0\0\0\0\x71\x61\x08\0\0\0\0\
602
+\0\x71\x60\x09\0\0\0\0\0\x67\0\0\0\x08\0\0\0\x4f\x10\0\0\0\0\0\0\x95\0\0\0\0\0\
603
+\0\0\x69\0\0\0\0\0\0\0\x05\0\xfd\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
604
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
605
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
606
+\0\x47\x50\x4c\x20\x76\x32\0\0\x9f\xeb\x01\0\x18\0\0\0\0\0\0\0\x10\x05\0\0\x10\
607
+\x05\0\0\x65\x11\0\0\0\0\0\0\0\0\0\x02\x03\0\0\0\x01\0\0\0\0\0\0\x01\x04\0\0\0\
608
+\x20\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x02\0\0\0\x05\0\0\0\
609
+\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\0\0\0\0\0\0\x02\x06\0\0\0\0\0\0\0\0\0\0\x03\0\
610
+\0\0\0\x02\0\0\0\x04\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\x02\x08\0\0\0\0\0\0\0\0\0\0\
611
+\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x0a\0\0\0\0\0\0\0\0\0\0\x02\x0a\0\0\0\0\0\0\0\
612
+\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x01\0\0\0\0\0\0\0\x04\0\0\x04\x20\0\0\0\
613
+\x19\0\0\0\x01\0\0\0\0\0\0\0\x1e\0\0\0\x05\0\0\0\x40\0\0\0\x27\0\0\0\x07\0\0\0\
614
+\x80\0\0\0\x32\0\0\0\x09\0\0\0\xc0\0\0\0\x3e\0\0\0\0\0\0\x0e\x0b\0\0\0\x01\0\0\
615
+\0\0\0\0\0\0\0\0\x02\x0e\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\
616
+\x28\0\0\0\0\0\0\0\x04\0\0\x04\x20\0\0\0\x19\0\0\0\x01\0\0\0\0\0\0\0\x1e\0\0\0\
617
+\x05\0\0\0\x40\0\0\0\x27\0\0\0\x0d\0\0\0\x80\0\0\0\x32\0\0\0\x09\0\0\0\xc0\0\0\
618
+\0\x59\0\0\0\0\0\0\x0e\x0f\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\x02\x12\0\0\0\0\0\0\0\
619
+\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x80\0\0\0\0\0\0\0\x04\0\0\x04\x20\0\0\0\
620
+\x19\0\0\0\x01\0\0\0\0\0\0\0\x1e\0\0\0\x05\0\0\0\x40\0\0\0\x27\0\0\0\x01\0\0\0\
621
+\x80\0\0\0\x32\0\0\0\x11\0\0\0\xc0\0\0\0\x72\0\0\0\0\0\0\x0e\x13\0\0\0\x01\0\0\
622
+\0\0\0\0\0\0\0\0\x02\x16\0\0\0\x90\0\0\0\x22\0\0\x04\xc0\0\0\0\x9a\0\0\0\x17\0\
623
+\0\0\0\0\0\0\x9e\0\0\0\x17\0\0\0\x20\0\0\0\xa7\0\0\0\x17\0\0\0\x40\0\0\0\xac\0\
624
+\0\0\x17\0\0\0\x60\0\0\0\xba\0\0\0\x17\0\0\0\x80\0\0\0\xc3\0\0\0\x17\0\0\0\xa0\
625
+\0\0\0\xd0\0\0\0\x17\0\0\0\xc0\0\0\0\xd9\0\0\0\x17\0\0\0\xe0\0\0\0\xe4\0\0\0\
626
+\x17\0\0\0\0\x01\0\0\xed\0\0\0\x17\0\0\0\x20\x01\0\0\xfd\0\0\0\x17\0\0\0\x40\
627
+\x01\0\0\x05\x01\0\0\x17\0\0\0\x60\x01\0\0\x0e\x01\0\0\x19\0\0\0\x80\x01\0\0\
628
+\x11\x01\0\0\x17\0\0\0\x20\x02\0\0\x16\x01\0\0\x17\0\0\0\x40\x02\0\0\x21\x01\0\
629
+\0\x17\0\0\0\x60\x02\0\0\x26\x01\0\0\x17\0\0\0\x80\x02\0\0\x2f\x01\0\0\x17\0\0\
630
+\0\xa0\x02\0\0\x37\x01\0\0\x17\0\0\0\xc0\x02\0\0\x3e\x01\0\0\x17\0\0\0\xe0\x02\
631
+\0\0\x49\x01\0\0\x17\0\0\0\0\x03\0\0\x53\x01\0\0\x1a\0\0\0\x20\x03\0\0\x5e\x01\
632
+\0\0\x1a\0\0\0\xa0\x03\0\0\x68\x01\0\0\x17\0\0\0\x20\x04\0\0\x74\x01\0\0\x17\0\
633
+\0\0\x40\x04\0\0\x7f\x01\0\0\x17\0\0\0\x60\x04\0\0\0\0\0\0\x1b\0\0\0\x80\x04\0\
634
+\0\x89\x01\0\0\x1d\0\0\0\xc0\x04\0\0\x90\x01\0\0\x17\0\0\0\0\x05\0\0\x99\x01\0\
635
+\0\x17\0\0\0\x20\x05\0\0\0\0\0\0\x1f\0\0\0\x40\x05\0\0\xa2\x01\0\0\x17\0\0\0\
636
+\x80\x05\0\0\xab\x01\0\0\x21\0\0\0\xa0\x05\0\0\xb7\x01\0\0\x1d\0\0\0\xc0\x05\0\
637
+\0\xc0\x01\0\0\0\0\0\x08\x18\0\0\0\xc6\x01\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\
638
+\0\0\0\0\0\0\x03\0\0\0\0\x17\0\0\0\x04\0\0\0\x05\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\
639
+\0\x17\0\0\0\x04\0\0\0\x04\0\0\0\0\0\0\0\x01\0\0\x05\x08\0\0\0\xd3\x01\0\0\x1c\
640
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x2a\0\0\0\xdd\x01\0\0\0\0\0\x08\x1e\0\0\0\xe3\
641
+\x01\0\0\0\0\0\x01\x08\0\0\0\x40\0\0\0\0\0\0\0\x01\0\0\x05\x08\0\0\0\xf6\x01\0\
642
+\0\x20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x2b\0\0\0\xf9\x01\0\0\0\0\0\x08\x22\0\0\
643
+\0\xfe\x01\0\0\0\0\0\x01\x01\0\0\0\x08\0\0\0\0\0\0\0\x01\0\0\x0d\x02\0\0\0\x0c\
644
+\x02\0\0\x15\0\0\0\x10\x02\0\0\x01\0\0\x0c\x23\0\0\0\x32\x11\0\0\0\0\0\x01\x01\
645
+\0\0\0\x08\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x25\0\0\0\x04\0\0\0\x07\0\0\0\x37\
646
+\x11\0\0\0\0\0\x0e\x26\0\0\0\x01\0\0\0\x40\x11\0\0\x03\0\0\x0f\0\0\0\0\x0c\0\0\
647
+\0\0\0\0\0\x20\0\0\0\x10\0\0\0\0\0\0\0\x20\0\0\0\x14\0\0\0\0\0\0\0\x20\0\0\0\
648
+\x46\x11\0\0\x01\0\0\x0f\0\0\0\0\x27\0\0\0\0\0\0\0\x07\0\0\0\x4e\x11\0\0\0\0\0\
649
+\x07\0\0\0\0\x5c\x11\0\0\0\0\0\x07\0\0\0\0\0\x69\x6e\x74\0\x5f\x5f\x41\x52\x52\
650
+\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\0\x74\x79\x70\x65\0\
651
+\x6b\x65\x79\x5f\x73\x69\x7a\x65\0\x76\x61\x6c\x75\x65\x5f\x73\x69\x7a\x65\0\
652
+\x6d\x61\x78\x5f\x65\x6e\x74\x72\x69\x65\x73\0\x74\x61\x70\x5f\x72\x73\x73\x5f\
653
+\x6d\x61\x70\x5f\x63\x6f\x6e\x66\x69\x67\x75\x72\x61\x74\x69\x6f\x6e\x73\0\x74\
654
+\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x74\x6f\x65\x70\x6c\x69\x74\x7a\
655
+\x5f\x6b\x65\x79\0\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x69\x6e\x64\
656
+\x69\x72\x65\x63\x74\x69\x6f\x6e\x5f\x74\x61\x62\x6c\x65\0\x5f\x5f\x73\x6b\x5f\
657
+\x62\x75\x66\x66\0\x6c\x65\x6e\0\x70\x6b\x74\x5f\x74\x79\x70\x65\0\x6d\x61\x72\
658
+\x6b\0\x71\x75\x65\x75\x65\x5f\x6d\x61\x70\x70\x69\x6e\x67\0\x70\x72\x6f\x74\
659
+\x6f\x63\x6f\x6c\0\x76\x6c\x61\x6e\x5f\x70\x72\x65\x73\x65\x6e\x74\0\x76\x6c\
660
+\x61\x6e\x5f\x74\x63\x69\0\x76\x6c\x61\x6e\x5f\x70\x72\x6f\x74\x6f\0\x70\x72\
661
+\x69\x6f\x72\x69\x74\x79\0\x69\x6e\x67\x72\x65\x73\x73\x5f\x69\x66\x69\x6e\x64\
662
+\x65\x78\0\x69\x66\x69\x6e\x64\x65\x78\0\x74\x63\x5f\x69\x6e\x64\x65\x78\0\x63\
663
+\x62\0\x68\x61\x73\x68\0\x74\x63\x5f\x63\x6c\x61\x73\x73\x69\x64\0\x64\x61\x74\
664
+\x61\0\x64\x61\x74\x61\x5f\x65\x6e\x64\0\x6e\x61\x70\x69\x5f\x69\x64\0\x66\x61\
665
+\x6d\x69\x6c\x79\0\x72\x65\x6d\x6f\x74\x65\x5f\x69\x70\x34\0\x6c\x6f\x63\x61\
666
+\x6c\x5f\x69\x70\x34\0\x72\x65\x6d\x6f\x74\x65\x5f\x69\x70\x36\0\x6c\x6f\x63\
667
+\x61\x6c\x5f\x69\x70\x36\0\x72\x65\x6d\x6f\x74\x65\x5f\x70\x6f\x72\x74\0\x6c\
668
+\x6f\x63\x61\x6c\x5f\x70\x6f\x72\x74\0\x64\x61\x74\x61\x5f\x6d\x65\x74\x61\0\
669
+\x74\x73\x74\x61\x6d\x70\0\x77\x69\x72\x65\x5f\x6c\x65\x6e\0\x67\x73\x6f\x5f\
670
+\x73\x65\x67\x73\0\x67\x73\x6f\x5f\x73\x69\x7a\x65\0\x74\x73\x74\x61\x6d\x70\
671
+\x5f\x74\x79\x70\x65\0\x68\x77\x74\x73\x74\x61\x6d\x70\0\x5f\x5f\x75\x33\x32\0\
672
+\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\0\x66\x6c\x6f\x77\x5f\x6b\x65\
673
+\x79\x73\0\x5f\x5f\x75\x36\x34\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x6c\x6f\
674
+\x6e\x67\x20\x6c\x6f\x6e\x67\0\x73\x6b\0\x5f\x5f\x75\x38\0\x75\x6e\x73\x69\x67\
675
+\x6e\x65\x64\x20\x63\x68\x61\x72\0\x73\x6b\x62\0\x74\x75\x6e\x5f\x72\x73\x73\
676
+\x5f\x73\x74\x65\x65\x72\x69\x6e\x67\x5f\x70\x72\x6f\x67\0\x74\x75\x6e\x5f\x72\
677
+\x73\x73\x5f\x73\x74\x65\x65\x72\x69\x6e\x67\0\x2f\x68\x6f\x6d\x65\x2f\x73\x68\
678
+\x72\x65\x65\x73\x68\x2f\x63\x2f\x71\x65\x6d\x75\x2f\x74\x6f\x6f\x6c\x73\x2f\
679
+\x65\x62\x70\x66\x2f\x72\x73\x73\x2e\x62\x70\x66\x2e\x63\0\x69\x6e\x74\x20\x74\
680
+\x75\x6e\x5f\x72\x73\x73\x5f\x73\x74\x65\x65\x72\x69\x6e\x67\x5f\x70\x72\x6f\
681
+\x67\x28\x73\x74\x72\x75\x63\x74\x20\x5f\x5f\x73\x6b\x5f\x62\x75\x66\x66\x20\
682
+\x2a\x73\x6b\x62\x29\0\x20\x20\x20\x20\x5f\x5f\x75\x33\x32\x20\x6b\x65\x79\x20\
683
+\x3d\x20\x30\x3b\0\x20\x20\x20\x20\x63\x6f\x6e\x66\x69\x67\x20\x3d\x20\x62\x70\
684
+\x66\x5f\x6d\x61\x70\x5f\x6c\x6f\x6f\x6b\x75\x70\x5f\x65\x6c\x65\x6d\x28\x26\
685
+\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x63\x6f\x6e\x66\x69\x67\x75\
686
+\x72\x61\x74\x69\x6f\x6e\x73\x2c\x20\x26\x6b\x65\x79\x29\x3b\0\x20\x20\x20\x20\
687
+\x74\x6f\x65\x20\x3d\x20\x62\x70\x66\x5f\x6d\x61\x70\x5f\x6c\x6f\x6f\x6b\x75\
688
+\x70\x5f\x65\x6c\x65\x6d\x28\x26\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\
689
+\x5f\x74\x6f\x65\x70\x6c\x69\x74\x7a\x5f\x6b\x65\x79\x2c\x20\x26\x6b\x65\x79\
690
+\x29\x3b\0\x20\x20\x20\x20\x69\x66\x20\x28\x63\x6f\x6e\x66\x69\x67\x20\x26\x26\
691
+\x20\x74\x6f\x65\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\
692
+\x21\x63\x6f\x6e\x66\x69\x67\x2d\x3e\x72\x65\x64\x69\x72\x65\x63\x74\x29\x20\
693
+\x7b\0\x20\x20\x20\x20\x5f\x5f\x75\x38\x20\x72\x73\x73\x5f\x69\x6e\x70\x75\x74\
694
+\x5b\x48\x41\x53\x48\x5f\x43\x41\x4c\x43\x55\x4c\x41\x54\x49\x4f\x4e\x5f\x42\
695
+\x55\x46\x46\x45\x52\x5f\x53\x49\x5a\x45\x5d\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\
696
+\x20\x20\x73\x74\x72\x75\x63\x74\x20\x70\x61\x63\x6b\x65\x74\x5f\x68\x61\x73\
697
+\x68\x5f\x69\x6e\x66\x6f\x5f\x74\x20\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\
698
+\x6f\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x69\x66\x20\x28\x21\x69\x6e\x66\
699
+\x6f\x20\x7c\x7c\x20\x21\x73\x6b\x62\x29\x20\x7b\0\x20\x20\x20\x20\x5f\x5f\x62\
700
+\x65\x31\x36\x20\x72\x65\x74\x20\x3d\x20\x30\x3b\0\x20\x20\x20\x20\x65\x72\x72\
701
+\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\
702
+\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x6f\x66\
703
+\x66\x73\x65\x74\x2c\x20\x26\x72\x65\x74\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\
704
+\x72\x65\x74\x29\x2c\0\x20\x20\x20\x20\x69\x66\x20\x28\x65\x72\x72\x29\x20\x7b\
705
+\0\x20\x20\x20\x20\x73\x77\x69\x74\x63\x68\x20\x28\x62\x70\x66\x5f\x6e\x74\x6f\
706
+\x68\x73\x28\x72\x65\x74\x29\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x65\
707
+\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\
708
+\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\
709
+\x6f\x66\x66\x73\x65\x74\x2c\x20\x26\x72\x65\x74\x2c\x20\x73\x69\x7a\x65\x6f\
710
+\x66\x28\x72\x65\x74\x29\x2c\0\x20\x20\x20\x20\x72\x65\x74\x75\x72\x6e\x20\x72\
711
+\x65\x74\x3b\0\x20\x20\x20\x20\x69\x66\x20\x28\x6c\x33\x5f\x70\x72\x6f\x74\x6f\
712
+\x63\x6f\x6c\x20\x3d\x3d\x20\x30\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\
713
+\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x69\x70\x76\x34\x20\x3d\x20\x31\x3b\0\x20\
714
+\x20\x20\x20\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\x20\x69\x70\x68\x64\x72\
715
+\x20\x69\x70\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\
716
+\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\
717
+\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x30\
718
+\x2c\x20\x26\x69\x70\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\x69\x70\x29\x2c\0\x20\
719
+\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x65\x72\x72\x29\x20\x7b\0\x20\x20\
720
+\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x66\x72\x61\x67\
721
+\x6d\x65\x6e\x74\x65\x64\x20\x3d\x20\x21\x21\x69\x70\x2e\x66\x72\x61\x67\x5f\
722
+\x6f\x66\x66\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\
723
+\x6e\x5f\x73\x72\x63\x20\x3d\x20\x69\x70\x2e\x73\x61\x64\x64\x72\x3b\0\x20\x20\
724
+\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x6e\x5f\x64\x73\x74\x20\
725
+\x3d\x20\x69\x70\x2e\x64\x61\x64\x64\x72\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\
726
+\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\x20\x69\x70\x2e\x70\x72\
727
+\x6f\x74\x6f\x63\x6f\x6c\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x6c\x34\x5f\x6f\
728
+\x66\x66\x73\x65\x74\x20\x3d\x20\x69\x70\x2e\x69\x68\x6c\x20\x2a\x20\x34\x3b\0\
729
+\x20\x20\x20\x20\x69\x66\x20\x28\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\
730
+\x20\x21\x3d\x20\x30\x20\x26\x26\x20\x21\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\
731
+\x66\x72\x61\x67\x6d\x65\x6e\x74\x65\x64\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\
732
+\x20\x20\x69\x66\x20\x28\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\
733
+\x3d\x20\x49\x50\x50\x52\x4f\x54\x4f\x5f\x54\x43\x50\x29\x20\x7b\0\x20\x20\x20\
734
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x74\
735
+\x63\x70\x20\x3d\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
736
+\x73\x74\x72\x75\x63\x74\x20\x74\x63\x70\x68\x64\x72\x20\x74\x63\x70\x20\x3d\
737
+\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\
738
+\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\
739
+\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x6c\x34\
740
+\x5f\x6f\x66\x66\x73\x65\x74\x2c\x20\x26\x74\x63\x70\x2c\x20\x73\x69\x7a\x65\
741
+\x6f\x66\x28\x74\x63\x70\x29\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
742
+\x20\x69\x66\x20\x28\x65\x72\x72\x29\x20\x7b\0\x20\x20\x20\x20\x69\x66\x20\x28\
743
+\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\x6f\x2e\x69\x73\x5f\x69\x70\x76\x34\
744
+\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x70\x61\x63\x6b\
745
+\x65\x74\x5f\x69\x6e\x66\x6f\x2e\x69\x73\x5f\x74\x63\x70\x20\x26\x26\0\x20\x20\
746
+\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x69\x70\x76\x36\
747
+\x20\x3d\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\
748
+\x20\x69\x70\x76\x36\x68\x64\x72\x20\x69\x70\x36\x20\x3d\x20\x7b\x7d\x3b\0\x20\
749
+\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\
750
+\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\
751
+\x76\x65\x28\x73\x6b\x62\x2c\x20\x30\x2c\x20\x26\x69\x70\x36\x2c\x20\x73\x69\
752
+\x7a\x65\x6f\x66\x28\x69\x70\x36\x29\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\
753
+\x6e\x66\x6f\x2d\x3e\x69\x6e\x36\x5f\x73\x72\x63\x20\x3d\x20\x69\x70\x36\x2e\
754
+\x73\x61\x64\x64\x72\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\
755
+\x3e\x69\x6e\x36\x5f\x64\x73\x74\x20\x3d\x20\x69\x70\x36\x2e\x64\x61\x64\x64\
756
+\x72\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\
757
+\x6f\x6c\x20\x3d\x20\x69\x70\x36\x2e\x6e\x65\x78\x74\x68\x64\x72\x3b\0\x20\x20\
758
+\x20\x20\x73\x77\x69\x74\x63\x68\x20\x28\x68\x64\x72\x5f\x74\x79\x70\x65\x29\
759
+\x20\x7b\0\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\x20\x69\x70\x76\x36\x5f\x6f\
760
+\x70\x74\x5f\x68\x64\x72\x20\x65\x78\x74\x5f\x68\x64\x72\x20\x3d\x20\x7b\x7d\
761
+\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\
762
+\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\
763
+\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x2a\x6c\x34\x5f\x6f\x66\x66\x73\x65\
764
+\x74\x2c\x20\x26\x65\x78\x74\x5f\x68\x64\x72\x2c\0\x20\x20\x20\x20\x20\x20\x20\
765
+\x20\x69\x66\x20\x28\x2a\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\
766
+\x3d\x20\x49\x50\x50\x52\x4f\x54\x4f\x5f\x52\x4f\x55\x54\x49\x4e\x47\x29\x20\
767
+\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\
768
+\x20\x69\x70\x76\x36\x5f\x72\x74\x5f\x68\x64\x72\x20\x65\x78\x74\x5f\x72\x74\
769
+\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\
770
+\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\
771
+\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\
772
+\x2a\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x2c\x20\x26\x65\x78\x74\x5f\x72\x74\
773
+\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x28\x65\
774
+\x78\x74\x5f\x72\x74\x2e\x74\x79\x70\x65\x20\x3d\x3d\x20\x49\x50\x56\x36\x5f\
775
+\x53\x52\x43\x52\x54\x5f\x54\x59\x50\x45\x5f\x32\x29\x20\x26\x26\0\x20\x20\x20\
776
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2a\x6c\
777
+\x34\x5f\x6f\x66\x66\x73\x65\x74\x20\x2b\x20\x6f\x66\x66\x73\x65\x74\x6f\x66\
778
+\x28\x73\x74\x72\x75\x63\x74\x20\x72\x74\x32\x5f\x68\x64\x72\x2c\x20\x61\x64\
779
+\x64\x72\x29\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
780
+\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\
781
+\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\
782
+\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\
783
+\x20\x28\x65\x72\x72\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
784
+\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x69\x70\x76\x36\x5f\
785
+\x65\x78\x74\x5f\x64\x73\x74\x20\x3d\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\
786
+\x20\x20\x20\x20\x20\x7d\x20\x5f\x5f\x61\x74\x74\x72\x69\x62\x75\x74\x65\x5f\
787
+\x5f\x28\x28\x70\x61\x63\x6b\x65\x64\x29\x29\x20\x6f\x70\x74\x20\x3d\x20\x7b\
788
+\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\
789
+\x70\x74\x5f\x6f\x66\x66\x73\x65\x74\x20\x2b\x3d\x20\x28\x6f\x70\x74\x2e\x74\
790
+\x79\x70\x65\x20\x3d\x3d\x20\x49\x50\x56\x36\x5f\x54\x4c\x56\x5f\x50\x41\x44\
791
+\x31\x29\x20\x3f\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
792
+\x20\x69\x66\x20\x28\x6f\x70\x74\x5f\x6f\x66\x66\x73\x65\x74\x20\x2b\x20\x31\
793
+\x20\x3e\x3d\x20\x65\x78\x74\x5f\x68\x64\x72\x2e\x68\x64\x72\x6c\x65\x6e\x20\
794
+\x2a\x20\x38\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
795
+\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\
796
+\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\
797
+\x6b\x62\x2c\x20\x2a\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x20\x2b\x20\x6f\x70\
798
+\x74\x5f\x6f\x66\x66\x73\x65\x74\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
799
+\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x6f\x70\x74\x2e\x74\x79\x70\x65\x20\
800
+\x3d\x3d\x20\x49\x50\x56\x36\x5f\x54\x4c\x56\x5f\x48\x41\x4f\x29\x20\x7b\0\x20\
801
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
802
+\x20\x20\x20\x20\x2a\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x20\x2b\x20\x6f\x70\
803
+\x74\x5f\x6f\x66\x66\x73\x65\x74\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
804
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\
805
+\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\
806
+\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
807
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x65\x72\x72\x29\x20\
808
+\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
809
+\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x69\x70\x76\x36\x5f\x65\x78\x74\
810
+\x5f\x73\x72\x63\x20\x3d\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
811
+\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x66\x72\x61\x67\x6d\x65\x6e\x74\
812
+\x65\x64\x20\x3d\x20\x74\x72\x75\x65\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x2a\
813
+\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x20\x2b\x3d\x20\x28\x65\x78\x74\x5f\x68\
814
+\x64\x72\x2e\x68\x64\x72\x6c\x65\x6e\x20\x2b\x20\x31\x29\x20\x2a\x20\x38\x3b\0\
815
+\x20\x20\x20\x20\x20\x20\x20\x20\x2a\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\
816
+\x6c\x20\x3d\x20\x65\x78\x74\x5f\x68\x64\x72\x2e\x6e\x65\x78\x74\x68\x64\x72\
817
+\x3b\0\x20\x20\x20\x20\x66\x6f\x72\x20\x28\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\
818
+\x69\x6e\x74\x20\x69\x20\x3d\x20\x30\x3b\x20\x69\x20\x3c\x20\x49\x50\x36\x5f\
819
+\x45\x58\x54\x45\x4e\x53\x49\x4f\x4e\x53\x5f\x43\x4f\x55\x4e\x54\x3b\x20\x2b\
820
+\x2b\x69\x29\x20\x7b\0\x20\x20\x20\x20\x7d\x20\x65\x6c\x73\x65\x20\x69\x66\x20\
821
+\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\x6f\x2e\x69\x73\x5f\x69\x70\x76\
822
+\x36\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\
823
+\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\x6f\x2e\x69\x73\x5f\x69\x70\x76\
824
+\x36\x5f\x65\x78\x74\x5f\x64\x73\x74\x20\x26\x26\0\x20\x20\x20\x20\x20\x20\x20\
825
+\x20\x20\x20\x20\x20\x69\x66\x20\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\
826
+\x6f\x2e\x69\x73\x5f\x69\x70\x76\x36\x5f\x65\x78\x74\x5f\x73\x72\x63\x20\x26\
827
+\x26\0\x20\x20\x20\x20\x20\x20\x20\x20\x7d\x20\x65\x6c\x73\x65\x20\x69\x66\x20\
828
+\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\x6f\x2e\x69\x73\x5f\x75\x64\x70\
829
+\x20\x26\x26\0\x20\x20\x20\x20\x20\x20\x20\x20\x7d\x20\x65\x6c\x73\x65\x20\x69\
830
+\x66\x20\x28\x63\x6f\x6e\x66\x69\x67\x2d\x3e\x68\x61\x73\x68\x5f\x74\x79\x70\
831
+\x65\x73\x20\x26\x20\x56\x49\x52\x54\x49\x4f\x5f\x4e\x45\x54\x5f\x52\x53\x53\
832
+\x5f\x48\x41\x53\x48\x5f\x54\x59\x50\x45\x5f\x49\x50\x76\x34\x29\x20\x7b\0\x20\
833
+\x20\x20\x20\x5f\x5f\x62\x75\x69\x6c\x74\x69\x6e\x5f\x6d\x65\x6d\x63\x70\x79\
834
+\x28\x26\x72\x73\x73\x5f\x69\x6e\x70\x75\x74\x5b\x2a\x62\x79\x74\x65\x73\x5f\
835
+\x77\x72\x69\x74\x74\x65\x6e\x5d\x2c\x20\x70\x74\x72\x2c\x20\x73\x69\x7a\x65\
836
+\x29\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\
837
+\x3e\x69\x73\x5f\x75\x64\x70\x20\x3d\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\
838
+\x20\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\x20\x75\x64\x70\x68\x64\x72\x20\
839
+\x75\x64\x70\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
840
+\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\
841
+\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\
842
+\x62\x2c\x20\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x2c\x20\x26\x75\x64\x70\x2c\
843
+\x20\x73\x69\x7a\x65\x6f\x66\x28\x75\x64\x70\x29\x2c\0\x20\x20\x20\x20\x20\x20\
844
+\x20\x20\x7d\x20\x65\x6c\x73\x65\x20\x69\x66\x20\x28\x63\x6f\x6e\x66\x69\x67\
845
+\x2d\x3e\x68\x61\x73\x68\x5f\x74\x79\x70\x65\x73\x20\x26\x20\x56\x49\x52\x54\
846
+\x49\x4f\x5f\x4e\x45\x54\x5f\x52\x53\x53\x5f\x48\x41\x53\x48\x5f\x54\x59\x50\
847
+\x45\x5f\x49\x50\x76\x36\x29\x20\x7b\0\x20\x20\x20\x20\x66\x6f\x72\x20\x28\x62\
848
+\x79\x74\x65\x20\x3d\x20\x30\x3b\x20\x62\x79\x74\x65\x20\x3c\x20\x48\x41\x53\
849
+\x48\x5f\x43\x41\x4c\x43\x55\x4c\x41\x54\x49\x4f\x4e\x5f\x42\x55\x46\x46\x45\
850
+\x52\x5f\x53\x49\x5a\x45\x3b\x20\x62\x79\x74\x65\x2b\x2b\x29\x20\x7b\0\x20\x20\
851
+\x20\x20\x5f\x5f\x75\x33\x32\x20\x6c\x65\x66\x74\x6d\x6f\x73\x74\x5f\x33\x32\
852
+\x5f\x62\x69\x74\x73\x20\x3d\x20\x6b\x65\x79\x2d\x3e\x6c\x65\x66\x74\x6d\x6f\
853
+\x73\x74\x5f\x33\x32\x5f\x62\x69\x74\x73\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\
854
+\x5f\x5f\x75\x38\x20\x69\x6e\x70\x75\x74\x5f\x62\x79\x74\x65\x20\x3d\x20\x69\
855
+\x6e\x70\x75\x74\x5b\x62\x79\x74\x65\x5d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\
856
+\x20\x20\x20\x20\x69\x66\x20\x28\x69\x6e\x70\x75\x74\x5f\x62\x79\x74\x65\x20\
857
+\x26\x20\x28\x31\x20\x3c\x3c\x20\x37\x29\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\
858
+\x20\x20\x5f\x5f\x75\x38\x20\x6b\x65\x79\x5f\x62\x79\x74\x65\x20\x3d\x20\x6b\
859
+\x65\x79\x2d\x3e\x6e\x65\x78\x74\x5f\x62\x79\x74\x65\x5b\x62\x79\x74\x65\x5d\
860
+\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
861
+\x20\x20\x28\x6c\x65\x66\x74\x6d\x6f\x73\x74\x5f\x33\x32\x5f\x62\x69\x74\x73\
862
+\x20\x3c\x3c\x20\x31\x29\x20\x7c\x20\x28\x28\x6b\x65\x79\x5f\x62\x79\x74\x65\
863
+\x20\x26\x20\x28\x31\x20\x3c\x3c\x20\x37\x29\x29\x20\x3e\x3e\x20\x37\x29\x3b\0\
864
+\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x68\x61\x73\x68\x29\x20\x7b\0\
865
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5f\x5f\x75\x33\x32\x20\x74\
866
+\x61\x62\x6c\x65\x5f\x69\x64\x78\x20\x3d\x20\x68\x61\x73\x68\x20\x25\x20\x63\
867
+\x6f\x6e\x66\x69\x67\x2d\x3e\x69\x6e\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x73\
868
+\x5f\x6c\x65\x6e\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x71\x75\
869
+\x65\x75\x65\x20\x3d\x20\x62\x70\x66\x5f\x6d\x61\x70\x5f\x6c\x6f\x6f\x6b\x75\
870
+\x70\x5f\x65\x6c\x65\x6d\x28\x26\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\
871
+\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x5f\x74\x61\x62\x6c\x65\x2c\0\
872
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x71\x75\x65\
873
+\x75\x65\x29\x20\x7b\0\x7d\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
874
+\x20\x20\x20\x20\x72\x65\x74\x75\x72\x6e\x20\x2a\x71\x75\x65\x75\x65\x3b\0\x63\
875
+\x68\x61\x72\0\x5f\x6c\x69\x63\x65\x6e\x73\x65\0\x2e\x6d\x61\x70\x73\0\x6c\x69\
876
+\x63\x65\x6e\x73\x65\0\x62\x70\x66\x5f\x66\x6c\x6f\x77\x5f\x6b\x65\x79\x73\0\
877
+\x62\x70\x66\x5f\x73\x6f\x63\x6b\0\0\0\0\x9f\xeb\x01\0\x20\0\0\0\0\0\0\0\x14\0\
878
+\0\0\x14\0\0\0\x6c\x0c\0\0\x80\x0c\0\0\0\0\0\0\x08\0\0\0\x26\x02\0\0\x01\0\0\0\
879
+\0\0\0\0\x24\0\0\0\x10\0\0\0\x26\x02\0\0\xc6\0\0\0\0\0\0\0\x37\x02\0\0\x61\x02\
880
+\0\0\0\x50\x08\0\x10\0\0\0\x37\x02\0\0\x92\x02\0\0\x0b\x68\x08\0\x20\0\0\0\x37\
881
+\x02\0\0\0\0\0\0\0\0\0\0\x28\0\0\0\x37\x02\0\0\xa5\x02\0\0\x0e\x74\x08\0\x50\0\
882
+\0\0\x37\x02\0\0\xea\x02\0\0\x0b\x78\x08\0\x88\0\0\0\x37\x02\0\0\x2a\x03\0\0\
883
+\x10\x80\x08\0\x90\0\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x98\0\0\0\x37\x02\0\0\x2a\
884
+\x03\0\0\x10\x80\x08\0\xa0\0\0\0\x37\x02\0\0\x43\x03\0\0\x16\x84\x08\0\xa8\0\0\
885
+\0\x37\x02\0\0\x43\x03\0\0\x0d\x84\x08\0\xc0\0\0\0\x37\x02\0\0\x64\x03\0\0\x0a\
886
+\xfc\x05\0\xe8\0\0\0\x37\x02\0\0\x9b\x03\0\0\x1f\x0c\x06\0\x38\x01\0\0\x37\x02\
887
+\0\0\xcb\x03\0\0\x0f\xa0\x04\0\x40\x01\0\0\x37\x02\0\0\xe4\x03\0\0\x0c\x20\x04\
888
+\0\x50\x01\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x58\x01\0\0\x37\x02\0\0\xf8\x03\0\0\
889
+\x0b\x2c\x04\0\x90\x01\0\0\x37\x02\0\0\x3e\x04\0\0\x09\x34\x04\0\xa0\x01\0\0\
890
+\x37\x02\0\0\x4d\x04\0\0\x0d\x44\x04\0\xb8\x01\0\0\x37\x02\0\0\x4d\x04\0\0\x05\
891
+\x44\x04\0\xd8\x01\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\xe0\x01\0\0\x37\x02\0\0\x6b\
892
+\x04\0\0\x0f\x58\x04\0\x10\x02\0\0\x37\x02\0\0\x3e\x04\0\0\x09\x70\x04\0\x18\
893
+\x02\0\0\x37\x02\0\0\xb5\x04\0\0\x0c\x80\x04\0\x20\x02\0\0\x37\x02\0\0\xc5\x04\
894
+\0\0\x09\xbc\x04\0\x50\x02\0\0\x37\x02\0\0\xe1\x04\0\0\x17\xd4\x04\0\x60\x02\0\
895
+\0\x37\x02\0\0\xfc\x04\0\0\x16\xdc\x04\0\x80\x02\0\0\x37\x02\0\0\xe1\x04\0\0\
896
+\x17\xd4\x04\0\x88\x02\0\0\x37\x02\0\0\x1a\x05\0\0\x0f\xe0\x04\0\xc0\x02\0\0\
897
+\x37\x02\0\0\x5d\x05\0\0\x0d\xe8\x04\0\xc8\x02\0\0\x37\x02\0\0\x70\x05\0\0\x24\
898
+\0\x05\0\xd0\x02\0\0\x37\x02\0\0\x70\x05\0\0\x20\0\x05\0\xe0\x02\0\0\x37\x02\0\
899
+\0\x9d\x05\0\0\x1b\xf8\x04\0\xe8\x02\0\0\x37\x02\0\0\x9d\x05\0\0\x16\xf8\x04\0\
900
+\xf0\x02\0\0\x37\x02\0\0\xbe\x05\0\0\x1b\xfc\x04\0\xf8\x02\0\0\x37\x02\0\0\xbe\
901
+\x05\0\0\x16\xfc\x04\0\0\x03\0\0\x37\x02\0\0\xdf\x05\0\0\x1a\x08\x05\0\x08\x03\
902
+\0\0\x37\x02\0\0\x70\x05\0\0\x1d\0\x05\0\x10\x03\0\0\x37\x02\0\0\x02\x06\0\0\
903
+\x18\x0c\x05\0\x18\x03\0\0\x37\x02\0\0\x02\x06\0\0\x1c\x0c\x05\0\x30\x03\0\0\
904
+\x37\x02\0\0\x22\x06\0\0\x15\x68\x05\0\x40\x03\0\0\x37\x02\0\0\x22\x06\0\0\x1a\
905
+\x68\x05\0\x58\x03\0\0\x37\x02\0\0\x56\x06\0\0\x0d\x6c\x05\0\x78\x03\0\0\x37\
906
+\x02\0\0\x80\x06\0\0\x1a\x70\x05\0\x88\x03\0\0\x37\x02\0\0\x9e\x06\0\0\x1b\x78\
907
+\x05\0\xa8\x03\0\0\x37\x02\0\0\x80\x06\0\0\x1a\x70\x05\0\xb0\x03\0\0\x37\x02\0\
908
+\0\xc2\x06\0\0\x13\x7c\x05\0\xe8\x03\0\0\x37\x02\0\0\x13\x07\0\0\x11\x84\x05\0\
909
+\xf0\x03\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x10\x04\0\0\x37\x02\0\0\x2a\x07\0\0\
910
+\x15\x28\x06\0\x18\x04\0\0\x37\x02\0\0\x2a\x07\0\0\x09\x28\x06\0\x20\x04\0\0\
911
+\x37\x02\0\0\0\0\0\0\0\0\0\0\x70\x04\0\0\x37\x02\0\0\x49\x07\0\0\x19\x2c\x06\0\
912
+\x80\x04\0\0\x37\x02\0\0\x49\x07\0\0\x20\x2c\x06\0\xa0\x04\0\0\x37\x02\0\0\0\0\
913
+\0\0\0\0\0\0\xf0\x04\0\0\x37\x02\0\0\x6b\x07\0\0\x17\x14\x05\0\0\x05\0\0\x37\
914
+\x02\0\0\x86\x07\0\0\x18\x1c\x05\0\x30\x05\0\0\x37\x02\0\0\x6b\x07\0\0\x17\x14\
915
+\x05\0\x48\x05\0\0\x37\x02\0\0\xa7\x07\0\0\x0f\x20\x05\0\x80\x05\0\0\x37\x02\0\
916
+\0\x5d\x05\0\0\x0d\x28\x05\0\x88\x05\0\0\x37\x02\0\0\xec\x07\0\0\x1d\x38\x05\0\
917
+\xc8\x05\0\0\x37\x02\0\0\x0f\x08\0\0\x1d\x3c\x05\0\x08\x06\0\0\x37\x02\0\0\x32\
918
+\x08\0\0\x1b\x44\x05\0\x10\x06\0\0\x37\x02\0\0\x55\x08\0\0\x05\x30\x02\0\x58\
919
+\x06\0\0\x37\x02\0\0\x6d\x08\0\0\x19\xb8\x02\0\xd0\x06\0\0\x37\x02\0\0\0\0\0\0\
920
+\0\0\0\0\xd8\x06\0\0\x37\x02\0\0\x93\x08\0\0\x0f\xc8\x02\0\x10\x07\0\0\x37\x02\
921
+\0\0\x5d\x05\0\0\x0d\xd0\x02\0\x20\x07\0\0\x37\x02\0\0\xd8\x08\0\0\x0d\xe0\x02\
922
+\0\x40\x07\0\0\x37\x02\0\0\x07\x09\0\0\x20\xe4\x02\0\x68\x07\0\0\x37\x02\0\0\
923
+\x33\x09\0\0\x13\xec\x02\0\xa8\x07\0\0\x37\x02\0\0\x13\x07\0\0\x11\xf4\x02\0\
924
+\xb0\x07\0\0\x37\x02\0\0\x7b\x09\0\0\x19\x04\x03\0\xb8\x07\0\0\x37\x02\0\0\x7b\
925
+\x09\0\0\x34\x04\x03\0\xe0\x07\0\0\x37\x02\0\0\xb1\x09\0\0\x15\x18\x03\0\xf0\
926
+\x07\0\0\x37\x02\0\0\xf2\x09\0\0\x17\x14\x03\0\x30\x08\0\0\x37\x02\0\0\x29\x0a\
927
+\0\0\x15\x24\x03\0\x38\x08\0\0\x37\x02\0\0\x44\x0a\0\0\x27\x34\x03\0\x70\x08\0\
928
+\0\x37\x02\0\0\x6f\x0a\0\0\x27\x50\x03\0\x80\x08\0\0\x37\x02\0\0\x9f\x0a\0\0\
929
+\x1c\xb4\x03\0\x88\x08\0\0\x37\x02\0\0\xdb\x0a\0\0\x20\xc0\x03\0\x98\x08\0\0\
930
+\x37\x02\0\0\xdb\x0a\0\0\x2f\xc0\x03\0\xa0\x08\0\0\x37\x02\0\0\xdb\x0a\0\0\x36\
931
+\xc0\x03\0\xa8\x08\0\0\x37\x02\0\0\xdb\x0a\0\0\x15\xc0\x03\0\x18\x09\0\0\x37\
932
+\x02\0\0\x17\x0b\0\0\x43\x64\x03\0\x38\x09\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x40\
933
+\x09\0\0\x37\x02\0\0\x17\x0b\0\0\x17\x64\x03\0\x80\x09\0\0\x37\x02\0\0\x29\x0a\
934
+\0\0\x15\x6c\x03\0\x88\x09\0\0\x37\x02\0\0\x67\x0b\0\0\x19\x7c\x03\0\x90\x09\0\
935
+\0\x37\x02\0\0\x67\x0b\0\0\x15\x7c\x03\0\x98\x09\0\0\x37\x02\0\0\x97\x0b\0\0\
936
+\x19\x84\x03\0\xa0\x09\0\0\x37\x02\0\0\xc7\x0b\0\0\x1b\x80\x03\0\xe8\x09\0\0\
937
+\x37\x02\0\0\x02\x0c\0\0\x19\x94\x03\0\xf0\x09\0\0\x37\x02\0\0\x21\x0c\0\0\x2b\
938
+\xa4\x03\0\x10\x0a\0\0\x37\x02\0\0\x9f\x0a\0\0\x1f\xb4\x03\0\x30\x0a\0\0\x37\
939
+\x02\0\0\x50\x0c\0\0\x21\xd4\x03\0\x40\x0a\0\0\x37\x02\0\0\x78\x0c\0\0\x20\xe4\
940
+\x03\0\x48\x0a\0\0\x37\x02\0\0\x78\x0c\0\0\x2c\xe4\x03\0\x60\x0a\0\0\x37\x02\0\
941
+\0\x78\x0c\0\0\x14\xe4\x03\0\x70\x0a\0\0\x37\x02\0\0\xa8\x0c\0\0\x20\xe0\x03\0\
942
+\x80\x0a\0\0\x37\x02\0\0\x55\x08\0\0\x05\x30\x02\0\xb0\x0a\0\0\x37\x02\0\0\xd0\
943
+\x0c\0\0\x38\xc0\x02\0\xd0\x0a\0\0\x37\x02\0\0\xd0\x0c\0\0\x05\xc0\x02\0\xe8\
944
+\x0a\0\0\x37\x02\0\0\x55\x08\0\0\x05\x30\x02\0\xf8\x0a\0\0\x37\x02\0\0\x0e\x0d\
945
+\0\0\x1c\xc4\x06\0\x08\x0b\0\0\x37\x02\0\0\x0e\x0d\0\0\x10\xc4\x06\0\x10\x0b\0\
946
+\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x60\x0b\0\0\x37\x02\0\0\x49\x07\0\0\x19\xc8\x06\
947
+\0\x68\x0b\0\0\x37\x02\0\0\x49\x07\0\0\x20\xc8\x06\0\xa0\x0b\0\0\x37\x02\0\0\
948
+\x34\x0d\0\0\x2d\0\x07\0\xb0\x0b\0\0\x37\x02\0\0\x34\x0d\0\0\x1d\0\x07\0\xb8\
949
+\x0b\0\0\x37\x02\0\0\x34\x0d\0\0\x2d\0\x07\0\xc8\x0b\0\0\x37\x02\0\0\x63\x0d\0\
950
+\0\x2d\xd4\x06\0\xf8\x0b\0\0\x37\x02\0\0\x63\x0d\0\0\x1d\xd4\x06\0\x08\x0c\0\0\
951
+\x37\x02\0\0\x63\x0d\0\0\x2d\xd4\x06\0\x18\x0c\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\
952
+\xe8\x0c\0\0\x37\x02\0\0\x92\x0d\0\0\x20\x68\x06\0\xf0\x0c\0\0\x37\x02\0\0\x92\
953
+\x0d\0\0\x27\x68\x06\0\x18\x0d\0\0\x37\x02\0\0\xbb\x0d\0\0\x27\xa4\x06\0\x20\
954
+\x0d\0\0\x37\x02\0\0\xbb\x0d\0\0\x14\xa4\x06\0\x28\x0d\0\0\x37\x02\0\0\x04\x0e\
955
+\0\0\x05\x98\x01\0\x38\x0d\0\0\x37\x02\0\0\x04\x0e\0\0\x05\x98\x01\0\x60\x0d\0\
956
+\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x70\x0d\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x80\x0d\
957
+\0\0\x37\x02\0\0\x92\x0d\0\0\x20\x44\x07\0\x88\x0d\0\0\x37\x02\0\0\x92\x0d\0\0\
958
+\x27\x44\x07\0\xc0\x0d\0\0\x37\x02\0\0\x34\x0d\0\0\x2d\x7c\x07\0\xd0\x0d\0\0\
959
+\x37\x02\0\0\x34\x0d\0\0\x1d\x7c\x07\0\xd8\x0d\0\0\x37\x02\0\0\x34\x0d\0\0\x2d\
960
+\x7c\x07\0\xe8\x0d\0\0\x37\x02\0\0\x63\x0d\0\0\x2d\x50\x07\0\x18\x0e\0\0\x37\
961
+\x02\0\0\x63\x0d\0\0\x1d\x50\x07\0\x28\x0e\0\0\x37\x02\0\0\x63\x0d\0\0\x2d\x50\
962
+\x07\0\x40\x0e\0\0\x37\x02\0\0\x41\x0e\0\0\x1a\xa0\x05\0\x50\x0e\0\0\x37\x02\0\
963
+\0\x5f\x0e\0\0\x1b\xa8\x05\0\x60\x0e\0\0\x37\x02\0\0\x41\x0e\0\0\x1a\xa0\x05\0\
964
+\x68\x0e\0\0\x37\x02\0\0\x83\x0e\0\0\x13\xac\x05\0\xa0\x0e\0\0\x37\x02\0\0\x13\
965
+\x07\0\0\x11\xb4\x05\0\xb0\x0e\0\0\x37\x02\0\0\x55\x08\0\0\x05\x30\x02\0\xc0\
966
+\x0e\0\0\x37\x02\0\0\xd4\x0e\0\0\x27\xc8\x07\0\xd0\x0e\0\0\x37\x02\0\0\xd4\x0e\
967
+\0\0\x14\xc8\x07\0\xf0\x0e\0\0\x37\x02\0\0\x63\x0d\0\0\x2d\xcc\x07\0\0\x0f\0\0\
968
+\x37\x02\0\0\x63\x0d\0\0\x1d\xcc\x07\0\x08\x0f\0\0\x37\x02\0\0\x63\x0d\0\0\x2d\
969
+\xcc\x07\0\x30\x0f\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x80\x0f\0\0\x37\x02\0\0\x34\
970
+\x0d\0\0\x1d\xf8\x07\0\x88\x0f\0\0\x37\x02\0\0\x34\x0d\0\0\x2d\xf8\x07\0\x98\
971
+\x0f\0\0\x37\x02\0\0\x04\x0e\0\0\x05\x98\x01\0\xf0\x0f\0\0\x37\x02\0\0\x04\x0e\
972
+\0\0\x05\x98\x01\0\x30\x10\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x48\x10\0\0\x37\x02\
973
+\0\0\x1d\x0f\0\0\x05\xd0\x01\0\x50\x10\0\0\x37\x02\0\0\x5f\x0f\0\0\x23\xc4\x01\
974
+\0\x68\x10\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x70\x10\0\0\x37\x02\0\0\x93\x0f\0\0\
975
+\x1b\xd4\x01\0\x90\x10\0\0\x37\x02\0\0\xba\x0f\0\0\x11\xe8\x01\0\xa8\x10\0\0\
976
+\x37\x02\0\0\xe3\x0f\0\0\x19\xd8\x01\0\xc0\x10\0\0\x37\x02\0\0\x11\x10\0\0\x27\
977
+\xfc\x01\0\xc8\x10\0\0\x37\x02\0\0\x11\x10\0\0\x46\xfc\x01\0\xd8\x10\0\0\x37\
978
+\x02\0\0\x11\x10\0\0\x2d\xfc\x01\0\xe0\x10\0\0\x37\x02\0\0\xba\x0f\0\0\x11\xe8\
979
+\x01\0\x08\x11\0\0\x37\x02\0\0\x11\x10\0\0\x46\xfc\x01\0\x20\x11\0\0\x37\x02\0\
980
+\0\x11\x10\0\0\x27\xfc\x01\0\x28\x11\0\0\x37\x02\0\0\x11\x10\0\0\x2d\xfc\x01\0\
981
+\x30\x11\0\0\x37\x02\0\0\xba\x0f\0\0\x11\xe8\x01\0\x58\x11\0\0\x37\x02\0\0\x11\
982
+\x10\0\0\x27\xfc\x01\0\x60\x11\0\0\x37\x02\0\0\x11\x10\0\0\x46\xfc\x01\0\x78\
983
+\x11\0\0\x37\x02\0\0\x11\x10\0\0\x2d\xfc\x01\0\x80\x11\0\0\x37\x02\0\0\xba\x0f\
984
+\0\0\x11\xe8\x01\0\xa8\x11\0\0\x37\x02\0\0\x11\x10\0\0\x27\xfc\x01\0\xb0\x11\0\
985
+\0\x37\x02\0\0\x11\x10\0\0\x46\xfc\x01\0\xc8\x11\0\0\x37\x02\0\0\x11\x10\0\0\
986
+\x2d\xfc\x01\0\xd0\x11\0\0\x37\x02\0\0\xba\x0f\0\0\x11\xe8\x01\0\xf8\x11\0\0\
987
+\x37\x02\0\0\x11\x10\0\0\x46\xfc\x01\0\x10\x12\0\0\x37\x02\0\0\x11\x10\0\0\x27\
988
+\xfc\x01\0\x18\x12\0\0\x37\x02\0\0\x11\x10\0\0\x2d\xfc\x01\0\x20\x12\0\0\x37\
989
+\x02\0\0\xba\x0f\0\0\x11\xe8\x01\0\x48\x12\0\0\x37\x02\0\0\x11\x10\0\0\x46\xfc\
990
+\x01\0\x60\x12\0\0\x37\x02\0\0\x11\x10\0\0\x27\xfc\x01\0\x68\x12\0\0\x37\x02\0\
991
+\0\x11\x10\0\0\x2d\xfc\x01\0\x70\x12\0\0\x37\x02\0\0\xba\x0f\0\0\x11\xe8\x01\0\
992
+\x98\x12\0\0\x37\x02\0\0\x11\x10\0\0\x46\xfc\x01\0\xb0\x12\0\0\x37\x02\0\0\x11\
993
+\x10\0\0\x27\xfc\x01\0\xb8\x12\0\0\x37\x02\0\0\x11\x10\0\0\x2d\xfc\x01\0\xc0\
994
+\x12\0\0\x37\x02\0\0\xba\x0f\0\0\x11\xe8\x01\0\xe0\x12\0\0\x37\x02\0\0\x11\x10\
995
+\0\0\x46\xfc\x01\0\xe8\x12\0\0\x37\x02\0\0\x11\x10\0\0\x27\xfc\x01\0\xf0\x12\0\
996
+\0\x37\x02\0\0\x11\x10\0\0\x2d\xfc\x01\0\xf8\x12\0\0\x37\x02\0\0\x1d\x0f\0\0\
997
+\x3d\xd0\x01\0\x08\x13\0\0\x37\x02\0\0\x1d\x0f\0\0\x05\xd0\x01\0\x18\x13\0\0\
998
+\x37\x02\0\0\x5d\x10\0\0\x0d\x98\x08\0\x30\x13\0\0\x37\x02\0\0\x5d\x10\0\0\x0d\
999
+\x98\x08\0\x38\x13\0\0\x37\x02\0\0\x71\x10\0\0\x2e\x9c\x08\0\x58\x13\0\0\x37\
1000
+\x02\0\0\x71\x10\0\0\x24\x9c\x08\0\x70\x13\0\0\x37\x02\0\0\x71\x10\0\0\x13\x9c\
1001
+\x08\0\x80\x13\0\0\x37\x02\0\0\x71\x10\0\0\x2e\x9c\x08\0\x88\x13\0\0\x37\x02\0\
1002
+\0\xb0\x10\0\0\x15\xa8\x08\0\xa0\x13\0\0\x37\x02\0\0\xf8\x10\0\0\x11\xb4\x08\0\
1003
+\xa8\x13\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\xc8\x13\0\0\x37\x02\0\0\x11\x11\0\0\
1004
+\x01\xd8\x08\0\xd0\x13\0\0\x37\x02\0\0\x13\x11\0\0\x18\xb8\x08\0\0\0\0\0\0\0\0\
1005
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\
1006
+\0\0\0\0\xde\0\0\0\0\0\x03\0\xc8\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7a\x01\0\0\0\
1007
+\0\x03\0\xb8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\0\0\0\0\0\x03\0\xa8\x13\0\0\0\0\
1008
+\0\0\0\0\0\0\0\0\0\0\xc7\0\0\0\0\0\x03\0\xd0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1009
+\x2c\x02\0\0\0\0\x03\0\x20\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf7\0\0\0\0\0\x03\0\
1010
+\xe8\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1c\x02\0\0\0\0\x03\0\x10\x04\0\0\0\0\0\0\
1011
+\0\0\0\0\0\0\0\0\x28\x01\0\0\0\0\x03\0\xe0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf3\
1012
+\x01\0\0\0\0\x03\0\x30\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xeb\x01\0\0\0\0\x03\0\
1013
+\x38\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x44\x02\0\0\0\0\x03\0\xf0\x03\0\0\0\0\0\0\
1014
+\0\0\0\0\0\0\0\0\xe3\x01\0\0\0\0\x03\0\xf8\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\
1015
+\x01\0\0\0\0\x03\0\xe8\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x30\x01\0\0\0\0\x03\0\
1016
+\xa0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa9\x01\0\0\0\0\x03\0\x40\x10\0\0\0\0\0\0\
1017
+\0\0\0\0\0\0\0\0\x51\x01\0\0\0\0\x03\0\x78\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5c\
1018
+\x02\0\0\0\0\x03\0\xb0\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\x02\0\0\0\0\x03\0\
1019
+\x50\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc2\x01\0\0\0\0\x03\0\xc0\x06\0\0\0\0\0\0\
1020
+\0\0\0\0\0\0\0\0\x69\x01\0\0\0\0\x03\0\x20\x07\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x61\
1021
+\x01\0\0\0\0\x03\0\x60\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x38\x01\0\0\0\0\x03\0\
1022
+\x30\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x20\x01\0\0\0\0\x03\0\x40\x0a\0\0\0\0\0\0\
1023
+\0\0\0\0\0\0\0\0\xba\x01\0\0\0\0\x03\0\xe0\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa1\
1024
+\x01\0\0\0\0\x03\0\x48\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\x01\0\0\0\0\x03\0\
1025
+\x18\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xfb\x01\0\0\0\0\x03\0\x80\x08\0\0\0\0\0\0\
1026
+\0\0\0\0\0\0\0\0\x99\x01\0\0\0\0\x03\0\xf8\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x59\
1027
+\x01\0\0\0\0\x03\0\x50\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x54\x02\0\0\0\0\x03\0\
1028
+\x08\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xef\0\0\0\0\0\x03\0\xe8\x0a\0\0\0\0\0\0\0\
1029
+\0\0\0\0\0\0\0\x4c\x02\0\0\0\0\x03\0\xb0\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x24\
1030
+\x02\0\0\0\0\x03\0\xd8\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x89\x01\0\0\0\0\x03\0\
1031
+\x80\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x01\0\0\0\0\x03\0\xb0\x0b\0\0\0\0\0\0\
1032
+\0\0\0\0\0\0\0\0\xd6\0\0\0\0\0\x03\0\xc8\x0b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x14\
1033
+\x02\0\0\0\0\x03\0\xf8\x0b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb2\x01\0\0\0\0\x03\0\
1034
+\x18\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xdb\x01\0\0\0\0\x03\0\x10\x0c\0\0\0\0\0\0\
1035
+\0\0\0\0\0\0\0\0\x3c\x02\0\0\0\0\x03\0\x18\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x91\
1036
+\x01\0\0\0\0\x03\0\x60\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81\x01\0\0\0\0\x03\0\
1037
+\xc0\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe7\0\0\0\0\0\x03\0\xd0\x0d\0\0\0\0\0\0\0\
1038
+\0\0\0\0\0\0\0\x34\x02\0\0\0\0\x03\0\xe8\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd3\
1039
+\x01\0\0\0\0\x03\0\x18\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\x01\0\0\0\0\x03\0\0\
1040
+\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xce\0\0\0\0\0\x03\0\x18\x0f\0\0\0\0\0\0\0\0\0\
1041
+\0\0\0\0\0\x0b\x02\0\0\0\0\x03\0\xf0\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xca\x01\0\
1042
+\0\0\0\x03\0\x30\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x71\x01\0\0\0\0\x03\0\x60\x10\
1043
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x48\x01\0\0\0\0\x03\0\x18\x13\0\0\0\0\0\0\0\0\0\0\
1044
+\0\0\0\0\x64\x02\0\0\0\0\x03\0\xd0\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4e\0\0\0\
1045
+\x12\0\x03\0\0\0\0\0\0\0\0\0\xe0\x13\0\0\0\0\0\0\x33\0\0\0\x11\0\x05\0\0\0\0\0\
1046
+\0\0\0\0\x20\0\0\0\0\0\0\0\x01\0\0\0\x11\0\x05\0\x20\0\0\0\0\0\0\0\x20\0\0\0\0\
1047
+\0\0\0\x90\0\0\0\x11\0\x05\0\x40\0\0\0\0\0\0\0\x20\0\0\0\0\0\0\0\x87\0\0\0\x11\
1048
+\0\x06\0\0\0\0\0\0\0\0\0\x07\0\0\0\0\0\0\0\x28\0\0\0\0\0\0\0\x01\0\0\0\x37\0\0\
1049
+\0\x50\0\0\0\0\0\0\0\x01\0\0\0\x38\0\0\0\x88\x13\0\0\0\0\0\0\x01\0\0\0\x39\0\0\
1050
+\0\xd8\x04\0\0\0\0\0\0\x04\0\0\0\x37\0\0\0\xe4\x04\0\0\0\0\0\0\x04\0\0\0\x38\0\
1051
+\0\0\xf0\x04\0\0\0\0\0\0\x04\0\0\0\x39\0\0\0\x08\x05\0\0\0\0\0\0\x04\0\0\0\x3a\
1052
+\0\0\0\x2c\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\0\0\0\0\0\0\0\x04\0\0\0\x01\0\
1053
+\0\0\x50\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1054
+\0\x70\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1055
+\x90\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1056
+\xb0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1057
+\xd0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1058
+\xf0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1059
+\x10\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1060
+\0\x30\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\
1061
+\0\0\x50\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x01\0\0\0\0\0\0\x04\0\0\0\x01\
1062
+\0\0\0\x70\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x01\0\0\0\0\0\0\x04\0\0\0\
1063
+\x01\0\0\0\x90\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x01\0\0\0\0\0\0\x04\0\0\
1064
+\0\x01\0\0\0\xb0\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x01\0\0\0\0\0\0\x04\0\
1065
+\0\0\x01\0\0\0\xd0\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x01\0\0\0\0\0\0\x04\
1066
+\0\0\0\x01\0\0\0\xf0\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x02\0\0\0\0\0\0\x04\
1067
+\0\0\0\x01\0\0\0\x10\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x02\0\0\0\0\0\0\
1068
+\x04\0\0\0\x01\0\0\0\x30\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x02\0\0\0\0\0\
1069
+\0\x04\0\0\0\x01\0\0\0\x50\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x02\0\0\0\0\
1070
+\0\0\x04\0\0\0\x01\0\0\0\x70\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x02\0\0\0\
1071
+\0\0\0\x04\0\0\0\x01\0\0\0\x90\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x02\0\0\
1072
+\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x02\0\
1073
+\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x02\
1074
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x03\
1075
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\
1076
+\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1077
+\x40\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1078
+\0\x60\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\
1079
+\0\0\x80\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x03\0\0\0\0\0\0\x04\0\0\0\x01\
1080
+\0\0\0\xa0\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x03\0\0\0\0\0\0\x04\0\0\0\
1081
+\x01\0\0\0\xc0\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x03\0\0\0\0\0\0\x04\0\0\
1082
+\0\x01\0\0\0\xe0\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x03\0\0\0\0\0\0\x04\0\
1083
+\0\0\x01\0\0\0\0\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x04\0\0\0\0\0\0\x04\0\
1084
+\0\0\x01\0\0\0\x20\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x04\0\0\0\0\0\0\x04\
1085
+\0\0\0\x01\0\0\0\x40\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x04\0\0\0\0\0\0\
1086
+\x04\0\0\0\x01\0\0\0\x60\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x04\0\0\0\0\0\
1087
+\0\x04\0\0\0\x01\0\0\0\x80\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x04\0\0\0\0\
1088
+\0\0\x04\0\0\0\x01\0\0\0\xa0\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x04\0\0\0\
1089
+\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x04\0\0\
1090
+\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x04\0\
1091
+\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x05\0\
1092
+\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x05\
1093
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\
1094
+\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1095
+\x70\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1096
+\0\x90\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\
1097
+\0\0\xb0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x05\0\0\0\0\0\0\x04\0\0\0\x01\
1098
+\0\0\0\xd0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x05\0\0\0\0\0\0\x04\0\0\0\
1099
+\x01\0\0\0\xf0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x06\0\0\0\0\0\0\x04\0\0\0\
1100
+\x01\0\0\0\x10\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x06\0\0\0\0\0\0\x04\0\0\
1101
+\0\x01\0\0\0\x30\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x06\0\0\0\0\0\0\x04\0\
1102
+\0\0\x01\0\0\0\x50\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x06\0\0\0\0\0\0\x04\
1103
+\0\0\0\x01\0\0\0\x70\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x06\0\0\0\0\0\0\
1104
+\x04\0\0\0\x01\0\0\0\x90\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x06\0\0\0\0\0\
1105
+\0\x04\0\0\0\x01\0\0\0\xb0\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x06\0\0\0\0\
1106
+\0\0\x04\0\0\0\x01\0\0\0\xd0\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x06\0\0\0\
1107
+\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x07\0\0\0\
1108
+\0\0\0\x04\0\0\0\x01\0\0\0\x10\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x07\0\0\
1109
+\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x07\0\
1110
+\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x07\
1111
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\
1112
+\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1113
+\xa0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1114
+\0\xc0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\
1115
+\0\0\xe0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x07\0\0\0\0\0\0\x04\0\0\0\x01\
1116
+\0\0\0\0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x08\0\0\0\0\0\0\x04\0\0\0\x01\
1117
+\0\0\0\x20\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x08\0\0\0\0\0\0\x04\0\0\0\
1118
+\x01\0\0\0\x40\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x08\0\0\0\0\0\0\x04\0\0\
1119
+\0\x01\0\0\0\x60\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x08\0\0\0\0\0\0\x04\0\
1120
+\0\0\x01\0\0\0\x80\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x08\0\0\0\0\0\0\x04\
1121
+\0\0\0\x01\0\0\0\xa0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x08\0\0\0\0\0\0\
1122
+\x04\0\0\0\x01\0\0\0\xc0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x08\0\0\0\0\0\
1123
+\0\x04\0\0\0\x01\0\0\0\xe0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x08\0\0\0\0\
1124
+\0\0\x04\0\0\0\x01\0\0\0\0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x09\0\0\0\0\
1125
+\0\0\x04\0\0\0\x01\0\0\0\x20\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x09\0\0\0\
1126
+\0\0\0\x04\0\0\0\x01\0\0\0\x40\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x09\0\0\
1127
+\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x09\0\
1128
+\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x09\
1129
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\
1130
+\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1131
+\xd0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1132
+\0\xf0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1133
+\0\x10\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\
1134
+\0\0\x30\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x0a\0\0\0\0\0\0\x04\0\0\0\x01\
1135
+\0\0\0\x50\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x0a\0\0\0\0\0\0\x04\0\0\0\
1136
+\x01\0\0\0\x70\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x0a\0\0\0\0\0\0\x04\0\0\
1137
+\0\x01\0\0\0\x90\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x0a\0\0\0\0\0\0\x04\0\
1138
+\0\0\x01\0\0\0\xb0\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x0a\0\0\0\0\0\0\x04\
1139
+\0\0\0\x01\0\0\0\xd0\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x0a\0\0\0\0\0\0\
1140
+\x04\0\0\0\x01\0\0\0\xf0\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x0b\0\0\0\0\0\0\
1141
+\x04\0\0\0\x01\0\0\0\x10\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x0b\0\0\0\0\0\
1142
+\0\x04\0\0\0\x01\0\0\0\x30\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x0b\0\0\0\0\
1143
+\0\0\x04\0\0\0\x01\0\0\0\x50\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x0b\0\0\0\
1144
+\0\0\0\x04\0\0\0\x01\0\0\0\x70\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x0b\0\0\
1145
+\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x0b\0\
1146
+\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x0b\
1147
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\
1148
+\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\
1149
+\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1150
+\x20\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1151
+\0\x40\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\
1152
+\0\0\x60\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x0c\0\0\0\0\0\0\x04\0\0\0\x01\
1153
+\0\0\0\x80\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x0c\0\0\0\0\0\0\x04\0\0\0\
1154
+\x01\0\0\0\x40\x41\x42\x43\x44\0\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\
1155
\x5f\x74\x6f\x65\x70\x6c\x69\x74\x7a\x5f\x6b\x65\x79\0\x2e\x74\x65\x78\x74\0\
1156
-\x6d\x61\x70\x73\0\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x63\x6f\x6e\
1157
-\x66\x69\x67\x75\x72\x61\x74\x69\x6f\x6e\x73\0\x74\x75\x6e\x5f\x72\x73\x73\x5f\
1158
-\x73\x74\x65\x65\x72\x69\x6e\x67\x5f\x70\x72\x6f\x67\0\x2e\x72\x65\x6c\x74\x75\
1159
-\x6e\x5f\x72\x73\x73\x5f\x73\x74\x65\x65\x72\x69\x6e\x67\0\x5f\x6c\x69\x63\x65\
1160
-\x6e\x73\x65\0\x2e\x72\x65\x6c\x2e\x65\x68\x5f\x66\x72\x61\x6d\x65\0\x74\x61\
1161
-\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x69\
1162
-\x6f\x6e\x5f\x74\x61\x62\x6c\x65\0\x72\x73\x73\x2e\x62\x70\x66\x2e\x63\0\x2e\
1163
-\x73\x74\x72\x74\x61\x62\0\x2e\x73\x79\x6d\x74\x61\x62\0\x4c\x42\x42\x30\x5f\
1164
-\x39\0\x4c\x42\x42\x30\x5f\x38\x39\0\x4c\x42\x42\x30\x5f\x36\x39\0\x4c\x42\x42\
1165
-\x30\x5f\x35\x39\0\x4c\x42\x42\x30\x5f\x31\x39\0\x4c\x42\x42\x30\x5f\x31\x30\
1166
-\x39\0\x4c\x42\x42\x30\x5f\x39\x38\0\x4c\x42\x42\x30\x5f\x37\x38\0\x4c\x42\x42\
1167
-\x30\x5f\x34\x38\0\x4c\x42\x42\x30\x5f\x31\x38\0\x4c\x42\x42\x30\x5f\x38\x37\0\
1168
-\x4c\x42\x42\x30\x5f\x34\x37\0\x4c\x42\x42\x30\x5f\x33\x37\0\x4c\x42\x42\x30\
1169
-\x5f\x31\x37\0\x4c\x42\x42\x30\x5f\x31\x30\x37\0\x4c\x42\x42\x30\x5f\x39\x36\0\
1170
-\x4c\x42\x42\x30\x5f\x37\x36\0\x4c\x42\x42\x30\x5f\x36\x36\0\x4c\x42\x42\x30\
1171
-\x5f\x34\x36\0\x4c\x42\x42\x30\x5f\x33\x36\0\x4c\x42\x42\x30\x5f\x32\x36\0\x4c\
1172
-\x42\x42\x30\x5f\x31\x30\x36\0\x4c\x42\x42\x30\x5f\x36\x35\0\x4c\x42\x42\x30\
1173
-\x5f\x34\x35\0\x4c\x42\x42\x30\x5f\x33\x35\0\x4c\x42\x42\x30\x5f\x34\0\x4c\x42\
1174
-\x42\x30\x5f\x35\x34\0\x4c\x42\x42\x30\x5f\x34\x34\0\x4c\x42\x42\x30\x5f\x32\
1175
-\x34\0\x4c\x42\x42\x30\x5f\x31\x30\x34\0\x4c\x42\x42\x30\x5f\x39\x33\0\x4c\x42\
1176
-\x42\x30\x5f\x38\x33\0\x4c\x42\x42\x30\x5f\x35\x33\0\x4c\x42\x42\x30\x5f\x34\
1177
-\x33\0\x4c\x42\x42\x30\x5f\x32\x33\0\x4c\x42\x42\x30\x5f\x31\x30\x33\0\x4c\x42\
1178
-\x42\x30\x5f\x38\x32\0\x4c\x42\x42\x30\x5f\x35\x32\0\x4c\x42\x42\x30\x5f\x31\
1179
-\x30\x32\0\x4c\x42\x42\x30\x5f\x39\x31\0\x4c\x42\x42\x30\x5f\x38\x31\0\x4c\x42\
1180
-\x42\x30\x5f\x37\x31\0\x4c\x42\x42\x30\x5f\x36\x31\0\x4c\x42\x42\x30\x5f\x35\
1181
-\x31\0\x4c\x42\x42\x30\x5f\x34\x31\0\x4c\x42\x42\x30\x5f\x32\x31\0\x4c\x42\x42\
1182
-\x30\x5f\x31\x31\0\x4c\x42\x42\x30\x5f\x31\x31\x31\0\x4c\x42\x42\x30\x5f\x31\
1183
-\x30\x31\0\x4c\x42\x42\x30\x5f\x38\x30\0\x4c\x42\x42\x30\x5f\x36\x30\0\x4c\x42\
1184
-\x42\x30\x5f\x35\x30\0\x4c\x42\x42\x30\x5f\x31\x30\0\x4c\x42\x42\x30\x5f\x31\
1185
-\x31\x30\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1186
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xaa\
1187
-\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa0\x1a\0\0\0\0\0\0\x71\x02\0\
1188
-\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1a\0\0\0\x01\0\0\
1189
-\0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1190
-\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5a\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\
1191
-\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\xd8\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\
1192
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x56\0\0\0\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1193
-\0\x60\x1a\0\0\0\0\0\0\x30\0\0\0\0\0\0\0\x09\0\0\0\x03\0\0\0\x08\0\0\0\0\0\0\0\
1194
-\x10\0\0\0\0\0\0\0\x20\0\0\0\x01\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\
1195
-\x14\0\0\0\0\0\0\x3c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\
1196
-\0\0\0\x6c\0\0\0\x01\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x54\x14\0\0\0\0\0\
1197
-\0\x07\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x78\0\0\
1198
-\0\x01\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x60\x14\0\0\0\0\0\0\x30\0\0\0\0\
1199
-\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x74\0\0\0\x09\0\0\0\0\
1200
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\x1a\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x09\0\0\0\
1201
-\x07\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\xb2\0\0\0\x02\0\0\0\0\0\0\0\0\0\
1202
-\0\0\0\0\0\0\0\0\0\0\x90\x14\0\0\0\0\0\0\xd0\x05\0\0\0\0\0\0\x01\0\0\0\x39\0\0\
1203
-\0\x08\0\0\0\0\0\0\0\x18\0\0\0\0\0\0\0";
1204
+\x2e\x72\x65\x6c\x2e\x42\x54\x46\x2e\x65\x78\x74\0\x2e\x6d\x61\x70\x73\0\x74\
1205
+\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x63\x6f\x6e\x66\x69\x67\x75\x72\
1206
+\x61\x74\x69\x6f\x6e\x73\0\x74\x75\x6e\x5f\x72\x73\x73\x5f\x73\x74\x65\x65\x72\
1207
+\x69\x6e\x67\x5f\x70\x72\x6f\x67\0\x2e\x72\x65\x6c\x74\x75\x6e\x5f\x72\x73\x73\
1208
+\x5f\x73\x74\x65\x65\x72\x69\x6e\x67\0\x2e\x6c\x6c\x76\x6d\x5f\x61\x64\x64\x72\
1209
+\x73\x69\x67\0\x5f\x6c\x69\x63\x65\x6e\x73\x65\0\x74\x61\x70\x5f\x72\x73\x73\
1210
+\x5f\x6d\x61\x70\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x5f\x74\x61\
1211
+\x62\x6c\x65\0\x2e\x73\x74\x72\x74\x61\x62\0\x2e\x73\x79\x6d\x74\x61\x62\0\x2e\
1212
+\x72\x65\x6c\x2e\x42\x54\x46\0\x4c\x42\x42\x30\x5f\x39\0\x4c\x42\x42\x30\x5f\
1213
+\x39\x39\0\x4c\x42\x42\x30\x5f\x37\x39\0\x4c\x42\x42\x30\x5f\x31\x30\x39\0\x4c\
1214
+\x42\x42\x30\x5f\x38\x38\0\x4c\x42\x42\x30\x5f\x34\x38\0\x4c\x42\x42\x30\x5f\
1215
+\x31\x38\0\x4c\x42\x42\x30\x5f\x31\x30\x38\0\x4c\x42\x42\x30\x5f\x39\x37\0\x4c\
1216
+\x42\x42\x30\x5f\x37\x37\0\x4c\x42\x42\x30\x5f\x36\x37\0\x4c\x42\x42\x30\x5f\
1217
+\x34\x37\0\x4c\x42\x42\x30\x5f\x31\x37\0\x4c\x42\x42\x30\x5f\x36\x36\0\x4c\x42\
1218
+\x42\x30\x5f\x34\x36\0\x4c\x42\x42\x30\x5f\x33\x36\0\x4c\x42\x42\x30\x5f\x31\
1219
+\x30\x36\0\x4c\x42\x42\x30\x5f\x35\x35\0\x4c\x42\x42\x30\x5f\x34\x35\0\x4c\x42\
1220
+\x42\x30\x5f\x33\x35\0\x4c\x42\x42\x30\x5f\x32\x35\0\x4c\x42\x42\x30\x5f\x31\
1221
+\x30\x35\0\x4c\x42\x42\x30\x5f\x34\0\x4c\x42\x42\x30\x5f\x39\x34\0\x4c\x42\x42\
1222
+\x30\x5f\x38\x34\0\x4c\x42\x42\x30\x5f\x35\x34\0\x4c\x42\x42\x30\x5f\x34\x34\0\
1223
+\x4c\x42\x42\x30\x5f\x33\x34\0\x4c\x42\x42\x30\x5f\x31\x30\x34\0\x4c\x42\x42\
1224
+\x30\x5f\x38\x33\0\x4c\x42\x42\x30\x5f\x35\x33\0\x4c\x42\x42\x30\x5f\x32\x33\0\
1225
+\x4c\x42\x42\x30\x5f\x31\x30\x33\0\x4c\x42\x42\x30\x5f\x39\x32\0\x4c\x42\x42\
1226
+\x30\x5f\x38\x32\0\x4c\x42\x42\x30\x5f\x37\x32\0\x4c\x42\x42\x30\x5f\x36\x32\0\
1227
+\x4c\x42\x42\x30\x5f\x35\x32\0\x4c\x42\x42\x30\x5f\x34\x32\0\x4c\x42\x42\x30\
1228
+\x5f\x32\x32\0\x4c\x42\x42\x30\x5f\x31\x30\x32\0\x4c\x42\x42\x30\x5f\x38\x31\0\
1229
+\x4c\x42\x42\x30\x5f\x36\x31\0\x4c\x42\x42\x30\x5f\x35\x31\0\x4c\x42\x42\x30\
1230
+\x5f\x31\x31\0\x4c\x42\x42\x30\x5f\x39\x30\0\x4c\x42\x42\x30\x5f\x37\x30\0\x4c\
1231
+\x42\x42\x30\x5f\x36\x30\0\x4c\x42\x42\x30\x5f\x35\x30\0\x4c\x42\x42\x30\x5f\
1232
+\x34\x30\0\x4c\x42\x42\x30\x5f\x32\x30\0\x4c\x42\x42\x30\x5f\x31\x31\x30\0\0\0\
1233
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1234
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xae\0\0\0\x03\0\0\0\
1235
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x25\x4a\0\0\0\0\0\0\x6d\x02\0\0\0\0\0\0\0\0\0\
1236
+\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1a\0\0\0\x01\0\0\0\x06\0\0\0\0\0\
1237
+\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\
1238
+\0\0\0\0\0\0\0\0\0\0\0\0\0\x68\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1239
+\0\x40\0\0\0\0\0\0\0\xe0\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\
1240
+\0\0\0\0\0\0\x64\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\x3d\0\0\
1241
+\0\0\0\0\x30\0\0\0\0\0\0\0\x0c\0\0\0\x03\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\
1242
+\0\0\x2d\0\0\0\x01\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x20\x14\0\0\0\0\0\0\
1243
+\x60\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x88\0\0\0\
1244
+\x01\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80\x14\0\0\0\0\0\0\x07\0\0\0\0\0\
1245
+\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc2\0\0\0\x01\0\0\0\0\0\
1246
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x88\x14\0\0\0\0\0\0\x8d\x16\0\0\0\0\0\0\0\0\0\0\0\
1247
+\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbe\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\
1248
+\0\0\0\0\0\0\0\0\x70\x3d\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\x0c\0\0\0\x07\0\0\0\x08\
1249
+\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x24\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1250
+\0\0\0\x18\x2b\0\0\0\0\0\0\xa0\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\
1251
+\0\0\0\0\0\0\0\0\0\x20\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb0\
1252
+\x3d\0\0\0\0\0\0\x70\x0c\0\0\0\0\0\0\x0c\0\0\0\x09\0\0\0\x08\0\0\0\0\0\0\0\x10\
1253
+\0\0\0\0\0\0\0\x79\0\0\0\x03\x4c\xff\x6f\0\0\0\x80\0\0\0\0\0\0\0\0\0\0\0\0\x20\
1254
+\x4a\0\0\0\0\0\0\x05\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\
1255
+\0\0\0\xb6\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb8\x37\0\0\0\0\0\0\
1256
+\x88\x05\0\0\0\0\0\0\x01\0\0\0\x36\0\0\0\x08\0\0\0\0\0\0\0\x18\0\0\0\0\0\0\0";
1257
+}
1258
1259
-    return 0;
1260
-err:
1261
-    bpf_object__destroy_skeleton(s);
1262
-    return -1;
1263
+#ifdef __cplusplus
1264
+struct rss_bpf *rss_bpf::open(const struct bpf_object_open_opts *opts) { return rss_bpf__open_opts(opts); }
1265
+struct rss_bpf *rss_bpf::open_and_load() { return rss_bpf__open_and_load(); }
1266
+int rss_bpf::load(struct rss_bpf *skel) { return rss_bpf__load(skel); }
1267
+int rss_bpf::attach(struct rss_bpf *skel) { return rss_bpf__attach(skel); }
1268
+void rss_bpf::detach(struct rss_bpf *skel) { rss_bpf__detach(skel); }
1269
+void rss_bpf::destroy(struct rss_bpf *skel) { rss_bpf__destroy(skel); }
1270
+const void *rss_bpf::elf_bytes(size_t *sz) { return rss_bpf__elf_bytes(sz); }
1271
+#endif /* __cplusplus */
1272
+
1273
+__attribute__((unused)) static void
1274
+rss_bpf__assert(struct rss_bpf *s __attribute__((unused)))
1275
+{
1276
+#ifdef __cplusplus
1277
+#define _Static_assert static_assert
1278
+#endif
1279
+#ifdef __cplusplus
1280
+#undef _Static_assert
1281
+#endif
1282
}
1283
1284
#endif /* __RSS_BPF_SKEL_H__ */
1285
diff --git a/tools/ebpf/Makefile.ebpf b/tools/ebpf/Makefile.ebpf
1286
index XXXXXXX..XXXXXXX 100755
1287
--- a/tools/ebpf/Makefile.ebpf
1288
+++ b/tools/ebpf/Makefile.ebpf
1289
@@ -XXX,XX +XXX,XX @@
1290
OBJS = rss.bpf.o
1291
1292
-LLC ?= llc
1293
+LLVM_STRIP ?= llvm-strip
1294
CLANG ?= clang
1295
INC_FLAGS = `$(CLANG) -print-file-name=include`
1296
-EXTRA_CFLAGS ?= -O2 -emit-llvm -fno-stack-protector
1297
+EXTRA_CFLAGS ?= -O2 -g -target bpf
1298
1299
all: $(OBJS)
1300
1301
@@ -XXX,XX +XXX,XX @@ all: $(OBJS)
1302
1303
clean:
1304
    rm -f $(OBJS)
1305
+    rm -f rss.bpf.skeleton.h
1306
1307
$(OBJS): %.o:%.c
1308
    $(CLANG) $(INC_FLAGS) \
1309
-D__KERNEL__ -D__ASM_SYSREG_H \
1310
-I../include $(LINUXINCLUDE) \
1311
- $(EXTRA_CFLAGS) -c $< -o -| $(LLC) -march=bpf -filetype=obj -o $@
1312
+ $(EXTRA_CFLAGS) -c $< -o $@
1313
+    $(LLVM_STRIP) -g $@
1314
    bpftool gen skeleton rss.bpf.o > rss.bpf.skeleton.h
1315
    cp rss.bpf.skeleton.h ../../ebpf/
1316
diff --git a/tools/ebpf/rss.bpf.c b/tools/ebpf/rss.bpf.c
1317
index XXXXXXX..XXXXXXX 100644
1318
--- a/tools/ebpf/rss.bpf.c
1319
+++ b/tools/ebpf/rss.bpf.c
1320
@@ -XXX,XX +XXX,XX @@ struct packet_hash_info_t {
1321
};
1322
};
1323
1324
-struct bpf_map_def SEC("maps")
1325
-tap_rss_map_configurations = {
1326
- .type = BPF_MAP_TYPE_ARRAY,
1327
- .key_size = sizeof(__u32),
1328
- .value_size = sizeof(struct rss_config_t),
1329
- .max_entries = 1,
1330
-};
1331
-
1332
-struct bpf_map_def SEC("maps")
1333
-tap_rss_map_toeplitz_key = {
1334
- .type = BPF_MAP_TYPE_ARRAY,
1335
- .key_size = sizeof(__u32),
1336
- .value_size = sizeof(struct toeplitz_key_data_t),
1337
- .max_entries = 1,
1338
-};
1339
-
1340
-struct bpf_map_def SEC("maps")
1341
-tap_rss_map_indirection_table = {
1342
- .type = BPF_MAP_TYPE_ARRAY,
1343
- .key_size = sizeof(__u32),
1344
- .value_size = sizeof(__u16),
1345
- .max_entries = INDIRECTION_TABLE_SIZE,
1346
-};
1347
+struct {
1348
+ __uint(type, BPF_MAP_TYPE_ARRAY);
1349
+ __uint(key_size, sizeof(__u32));
1350
+ __uint(value_size, sizeof(struct rss_config_t));
1351
+ __uint(max_entries, 1);
1352
+} tap_rss_map_configurations SEC(".maps");
1353
+
1354
+struct {
1355
+ __uint(type, BPF_MAP_TYPE_ARRAY);
1356
+ __uint(key_size, sizeof(__u32));
1357
+ __uint(value_size, sizeof(struct toeplitz_key_data_t));
1358
+ __uint(max_entries, 1);
1359
+} tap_rss_map_toeplitz_key SEC(".maps");
1360
+
1361
+struct {
1362
+ __uint(type, BPF_MAP_TYPE_ARRAY);
1363
+ __uint(key_size, sizeof(__u32));
1364
+ __uint(value_size, sizeof(__u16));
1365
+ __uint(max_entries, INDIRECTION_TABLE_SIZE);
1366
+} tap_rss_map_indirection_table SEC(".maps");
1367
1368
static inline void net_rx_rss_add_chunk(__u8 *rss_input, size_t *bytes_written,
1369
const void *ptr, size_t size) {
1370
--
1371
2.7.4
diff view generated by jsdifflib