1 | The following changes since commit fff3159900d2b95613a9cb75fc3703e67a674729: | 1 | The following changes since commit 817fd33836e73812df2f1907612b57750fcb9491: |
---|---|---|---|
2 | 2 | ||
3 | Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190726' into staging (2019-07-26 16:23:07 +0100) | 3 | Merge tag 'audio-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging (2023-03-06 14:06:06 +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 f77bed14f01557596727c4eea042e9818c242049: | 9 | for you to fetch changes up to c19b566a3898510ec2b3e881b3fb78614b240414: |
10 | 10 | ||
11 | net/colo-compare.c: Fix memory leak and code style issue. (2019-07-29 16:29:30 +0800) | 11 | hw/net/eepro100: Replace DO_UPCAST(EEPRO100State) by EEPRO100() (2023-03-07 14:55:39 +0800) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | 14 | ||
15 | ---------------------------------------------------------------- | 15 | ---------------------------------------------------------------- |
16 | Jason Wang (1): | 16 | Akihiko Odaki (43): |
17 | e1000: don't raise interrupt in pre_save() | 17 | e1000e: Fix the code style |
18 | hw/net: Add more MII definitions | ||
19 | fsl_etsec: Use hw/net/mii.h | ||
20 | e1000: Use hw/net/mii.h | ||
21 | e1000: Mask registers when writing | ||
22 | e1000e: Introduce E1000E_LOW_BITS_SET_FUNC | ||
23 | e1000e: Mask registers when writing | ||
24 | e1000: Use more constant definitions | ||
25 | e1000e: Use more constant definitions | ||
26 | e1000: Use memcpy to intialize registers | ||
27 | e1000e: Use memcpy to intialize registers | ||
28 | e1000e: Remove pending interrupt flags | ||
29 | e1000e: Improve software reset | ||
30 | e1000: Configure ResettableClass | ||
31 | e1000e: Configure ResettableClass | ||
32 | e1000e: Introduce e1000_rx_desc_union | ||
33 | e1000e: Set MII_ANER_NWAY | ||
34 | e1000e: Remove extra pointer indirection | ||
35 | net: Check L4 header size | ||
36 | e1000x: Alter the signature of e1000x_is_vlan_packet | ||
37 | net: Strip virtio-net header when dumping | ||
38 | hw/net/net_tx_pkt: Automatically determine if virtio-net header is used | ||
39 | hw/net/net_rx_pkt: Remove net_rx_pkt_has_virt_hdr | ||
40 | e1000e: Perform software segmentation for loopback | ||
41 | hw/net/net_tx_pkt: Implement TCP segmentation | ||
42 | hw/net/net_tx_pkt: Check the payload length | ||
43 | e1000e: Do not assert when MSI-X is disabled later | ||
44 | MAINTAINERS: Add Akihiko Odaki as a e1000e reviewer | ||
45 | MAINTAINERS: Add e1000e test files | ||
46 | e1000e: Combine rx traces | ||
47 | e1000: Count CRC in Tx statistics | ||
48 | e1000e: Count CRC in Tx statistics | ||
49 | net/eth: Report if headers are actually present | ||
50 | e1000e: Implement system clock | ||
51 | net/eth: Introduce EthL4HdrProto | ||
52 | pcie: Introduce pcie_sriov_num_vfs | ||
53 | e1000: Split header files | ||
54 | Intrdocue igb device emulation | ||
55 | tests/qtest/e1000e-test: Fabricate ethernet header | ||
56 | tests/qtest/libqos/e1000e: Export macreg functions | ||
57 | igb: Introduce qtest for igb device | ||
58 | tests/avocado: Add igb test | ||
59 | docs/system/devices/igb: Add igb documentation | ||
18 | 60 | ||
19 | Prasad J Pandit (3): | 61 | Philippe Mathieu-Daudé (7): |
20 | qemu-bridge-helper: restrict interface name to IFNAMSIZ | 62 | hw/net/eepro100: Abort if pci_add_capability() ever fail |
21 | qemu-bridge-helper: move repeating code in parse_acl_file | 63 | hw/net/eepro100: Introduce TYPE_EEPRO100 QOM abstract parent |
22 | net: tap: replace snprintf with g_strdup_printf calls | 64 | hw/net/eepro100: Convert reset handler to DeviceReset |
65 | hw/net/eepro100: Pass E100PCIDeviceInfo as class init data | ||
66 | hw/net/eepro100: Remove instance EEPRO100State::has_extended_tcb_support | ||
67 | hw/net/eepro100: Remove instance's EEPRO100State::device | ||
68 | hw/net/eepro100: Replace DO_UPCAST(EEPRO100State) by EEPRO100() | ||
23 | 69 | ||
24 | Zhang Chen (1): | 70 | Shreesh Adiga (1): |
25 | net/colo-compare.c: Fix memory leak and code style issue. | 71 | ebpf: fix compatibility with libbpf 1.0+ |
26 | 72 | ||
27 | hw/net/e1000.c | 8 ++------ | 73 | MAINTAINERS | 13 + |
28 | net/colo-compare.c | 27 ++++++++++++++++++++------- | 74 | docs/system/device-emulation.rst | 1 + |
29 | net/tap.c | 19 +++++++++++-------- | 75 | docs/system/devices/igb.rst | 71 + |
30 | qemu-bridge-helper.c | 24 +++++++++++++++++------- | 76 | ebpf/rss.bpf.skeleton.h | 1171 ++++-- |
31 | 4 files changed, 50 insertions(+), 28 deletions(-) | 77 | hw/core/machine.c | 1 + |
78 | hw/net/Kconfig | 5 + | ||
79 | hw/net/e1000.c | 259 +- | ||
80 | hw/net/e1000_common.h | 102 + | ||
81 | hw/net/e1000_regs.h | 958 +---- | ||
82 | hw/net/e1000e.c | 102 +- | ||
83 | hw/net/e1000e_core.c | 719 ++-- | ||
84 | hw/net/e1000e_core.h | 70 +- | ||
85 | hw/net/e1000x_common.c | 38 +- | ||
86 | hw/net/e1000x_common.h | 133 +- | ||
87 | hw/net/e1000x_regs.h | 967 +++++ | ||
88 | hw/net/eepro100.c | 149 +- | ||
89 | hw/net/fsl_etsec/etsec.c | 11 +- | ||
90 | hw/net/fsl_etsec/etsec.h | 17 - | ||
91 | hw/net/fsl_etsec/miim.c | 5 +- | ||
92 | hw/net/igb.c | 615 +++ | ||
93 | hw/net/igb_common.h | 146 + | ||
94 | hw/net/igb_core.c | 4077 ++++++++++++++++++++ | ||
95 | hw/net/igb_core.h | 146 + | ||
96 | hw/net/igb_regs.h | 648 ++++ | ||
97 | hw/net/igbvf.c | 327 ++ | ||
98 | hw/net/meson.build | 2 + | ||
99 | hw/net/net_rx_pkt.c | 102 +- | ||
100 | hw/net/net_rx_pkt.h | 31 +- | ||
101 | hw/net/net_tx_pkt.c | 332 +- | ||
102 | hw/net/net_tx_pkt.h | 27 +- | ||
103 | hw/net/trace-events | 50 +- | ||
104 | hw/net/virtio-net.c | 85 +- | ||
105 | hw/net/vmxnet3.c | 58 +- | ||
106 | hw/pci/pcie_sriov.c | 5 + | ||
107 | include/hw/net/mii.h | 14 +- | ||
108 | include/hw/pci/pcie_sriov.h | 3 + | ||
109 | include/net/eth.h | 15 +- | ||
110 | include/net/net.h | 6 + | ||
111 | net/dump.c | 11 +- | ||
112 | net/eth.c | 118 +- | ||
113 | net/net.c | 18 + | ||
114 | net/tap.c | 16 + | ||
115 | scripts/ci/org.centos/stream/8/x86_64/test-avocado | 1 + | ||
116 | tests/avocado/igb.py | 38 + | ||
117 | tests/qtest/e1000e-test.c | 25 +- | ||
118 | tests/qtest/fuzz/generic_fuzz_configs.h | 5 + | ||
119 | tests/qtest/igb-test.c | 243 ++ | ||
120 | tests/qtest/libqos/e1000e.c | 12 - | ||
121 | tests/qtest/libqos/e1000e.h | 14 + | ||
122 | tests/qtest/libqos/igb.c | 185 + | ||
123 | tests/qtest/libqos/meson.build | 1 + | ||
124 | tests/qtest/meson.build | 1 + | ||
125 | tools/ebpf/Makefile.ebpf | 8 +- | ||
126 | tools/ebpf/rss.bpf.c | 43 +- | ||
127 | 54 files changed, 9829 insertions(+), 2391 deletions(-) | ||
128 | create mode 100644 docs/system/devices/igb.rst | ||
129 | create mode 100644 hw/net/e1000_common.h | ||
130 | create mode 100644 hw/net/e1000x_regs.h | ||
131 | create mode 100644 hw/net/igb.c | ||
132 | create mode 100644 hw/net/igb_common.h | ||
133 | create mode 100644 hw/net/igb_core.c | ||
134 | create mode 100644 hw/net/igb_core.h | ||
135 | create mode 100644 hw/net/igb_regs.h | ||
136 | create mode 100644 hw/net/igbvf.c | ||
137 | create mode 100644 tests/avocado/igb.py | ||
138 | create mode 100644 tests/qtest/igb-test.c | ||
139 | create mode 100644 tests/qtest/libqos/igb.c | ||
32 | 140 | ||
33 | 141 | ||
142 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
3 | igb implementation first starts off by copying e1000e code. Correct the | ||
4 | code style before that. | ||
5 | |||
6 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
7 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
8 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
9 | --- | ||
10 | hw/net/e1000.c | 41 ++++++++++---------- | ||
11 | hw/net/e1000e.c | 72 +++++++++++++++++----------------- | ||
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 | |||
17 | diff --git a/hw/net/e1000.c b/hw/net/e1000.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/hw/net/e1000.c | ||
20 | +++ b/hw/net/e1000.c | ||
21 | @@ -XXX,XX +XXX,XX @@ receive_filter(E1000State *s, const uint8_t *buf, int size) | ||
22 | if (e1000x_is_vlan_packet(buf, le16_to_cpu(s->mac_reg[VET])) && | ||
23 | e1000x_vlan_rx_filter_enabled(s->mac_reg)) { | ||
24 | uint16_t vid = lduw_be_p(buf + 14); | ||
25 | - uint32_t vfta = ldl_le_p((uint32_t*)(s->mac_reg + VFTA) + | ||
26 | + uint32_t vfta = ldl_le_p((uint32_t *)(s->mac_reg + VFTA) + | ||
27 | ((vid >> 5) & 0x7f)); | ||
28 | - if ((vfta & (1 << (vid & 0x1f))) == 0) | ||
29 | + if ((vfta & (1 << (vid & 0x1f))) == 0) { | ||
30 | return 0; | ||
31 | + } | ||
32 | } | ||
33 | |||
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 | -- | ||
462 | 2.7.4 | ||
463 | |||
464 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
1 | We should not raise any interrupt after VM has been stopped but this | 1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> |
---|---|---|---|
2 | is what e1000 currently did when mit timer is active in | ||
3 | pre_save(). Fixing this by scheduling a timer in post_load() which can | ||
4 | make sure the interrupt was raised when VM is running. | ||
5 | 2 | ||
6 | Reported-and-tested-by: Longpeng <longpeng2@huawei.com> | 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> | 7 | Signed-off-by: Jason Wang <jasowang@redhat.com> |
8 | --- | 8 | --- |
9 | hw/net/e1000.c | 8 ++------ | 9 | hw/net/e1000.c | 86 +++++++++++++++++++++---------------------- |
10 | 1 file changed, 2 insertions(+), 6 deletions(-) | 10 | hw/net/e1000_regs.h | 46 ----------------------- |
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(-) | ||
11 | 16 | ||
12 | diff --git a/hw/net/e1000.c b/hw/net/e1000.c | 17 | diff --git a/hw/net/e1000.c b/hw/net/e1000.c |
13 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/hw/net/e1000.c | 19 | --- a/hw/net/e1000.c |
15 | +++ b/hw/net/e1000.c | 20 | +++ b/hw/net/e1000.c |
21 | @@ -XXX,XX +XXX,XX @@ | ||
22 | |||
23 | |||
24 | #include "qemu/osdep.h" | ||
25 | +#include "hw/net/mii.h" | ||
26 | #include "hw/pci/pci_device.h" | ||
27 | #include "hw/qdev-properties.h" | ||
28 | #include "migration/vmstate.h" | ||
29 | @@ -XXX,XX +XXX,XX @@ e1000_autoneg_done(E1000State *s) | ||
30 | static bool | ||
31 | have_autoneg(E1000State *s) | ||
32 | { | ||
33 | - return chkflag(AUTONEG) && (s->phy_reg[PHY_CTRL] & MII_CR_AUTO_NEG_EN); | ||
34 | + return chkflag(AUTONEG) && (s->phy_reg[MII_BMCR] & MII_BMCR_AUTOEN); | ||
35 | } | ||
36 | |||
37 | static void | ||
38 | set_phy_ctrl(E1000State *s, int index, uint16_t val) | ||
39 | { | ||
40 | - /* bits 0-5 reserved; MII_CR_[RESTART_AUTO_NEG,RESET] are self clearing */ | ||
41 | - s->phy_reg[PHY_CTRL] = val & ~(0x3f | | ||
42 | - MII_CR_RESET | | ||
43 | - MII_CR_RESTART_AUTO_NEG); | ||
44 | + /* bits 0-5 reserved; MII_BMCR_[ANRESTART,RESET] are self clearing */ | ||
45 | + s->phy_reg[MII_BMCR] = val & ~(0x3f | | ||
46 | + MII_BMCR_RESET | | ||
47 | + MII_BMCR_ANRESTART); | ||
48 | |||
49 | /* | ||
50 | * QEMU 1.3 does not support link auto-negotiation emulation, so if we | ||
51 | * migrate during auto negotiation, after migration the link will be | ||
52 | * down. | ||
53 | */ | ||
54 | - if (have_autoneg(s) && (val & MII_CR_RESTART_AUTO_NEG)) { | ||
55 | + if (have_autoneg(s) && (val & MII_BMCR_ANRESTART)) { | ||
56 | e1000x_restart_autoneg(s->mac_reg, s->phy_reg, s->autoneg_timer); | ||
57 | } | ||
58 | } | ||
59 | |||
60 | static void (*phyreg_writeops[])(E1000State *, int, uint16_t) = { | ||
61 | - [PHY_CTRL] = set_phy_ctrl, | ||
62 | + [MII_BMCR] = set_phy_ctrl, | ||
63 | }; | ||
64 | |||
65 | enum { NPHYWRITEOPS = ARRAY_SIZE(phyreg_writeops) }; | ||
66 | |||
67 | enum { PHY_R = 1, PHY_W = 2, PHY_RW = PHY_R | PHY_W }; | ||
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 | + | ||
113 | + [MII_BMSR] = MII_BMSR_EXTCAP | | ||
114 | + MII_BMSR_LINK_ST | /* link initially up */ | ||
115 | + MII_BMSR_AUTONEG | | ||
116 | + /* MII_BMSR_AN_COMP: initially NOT completed */ | ||
117 | + MII_BMSR_MFPS | | ||
118 | + MII_BMSR_EXTSTAT | | ||
119 | + MII_BMSR_10T_HD | | ||
120 | + MII_BMSR_10T_FD | | ||
121 | + MII_BMSR_100TX_HD | | ||
122 | + MII_BMSR_100TX_FD, | ||
123 | + | ||
124 | + [MII_PHYID1] = 0x141, | ||
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); | ||
16 | @@ -XXX,XX +XXX,XX @@ static int e1000_pre_save(void *opaque) | 160 | @@ -XXX,XX +XXX,XX @@ static int e1000_pre_save(void *opaque) |
17 | E1000State *s = opaque; | ||
18 | NetClientState *nc = qemu_get_queue(s->nic); | ||
19 | |||
20 | - /* If the mitigation timer is active, emulate a timeout now. */ | ||
21 | - if (s->mit_timer_on) { | ||
22 | - e1000_mit_timer(s); | ||
23 | - } | ||
24 | - | ||
25 | /* | 161 | /* |
26 | * If link is down and auto-negotiation is supported and ongoing, | 162 | * If link is down and auto-negotiation is supported and ongoing, |
27 | * complete auto-negotiation immediately. This allows us to look | 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 */ | ||
28 | @@ -XXX,XX +XXX,XX @@ static int e1000_post_load(void *opaque, int version_id) | 173 | @@ -XXX,XX +XXX,XX @@ static int e1000_post_load(void *opaque, int version_id) |
29 | s->mit_irq_level = false; | 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 | } | ||
287 | |||
288 | static void e1000e_update_flowctl_status(E1000ECore *core) | ||
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); | ||
30 | } | 313 | } |
31 | s->mit_ide = 0; | 314 | @@ -XXX,XX +XXX,XX @@ e1000e_core_set_link_status(E1000ECore *core) |
32 | - s->mit_timer_on = false; | 315 | e1000x_update_regs_on_link_down(core->mac, core->phy[0]); |
33 | + s->mit_timer_on = true; | 316 | } else { |
34 | + timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1); | 317 | if (e1000e_have_autoneg(core) && |
35 | 318 | - !(core->phy[0][PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) { | |
36 | /* nc.link_down can't be migrated, so infer link_down according | 319 | + !(core->phy[0][MII_BMSR] & MII_BMSR_AN_COMP)) { |
37 | * to link status bit in mac_reg[STATUS]. | 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, | ||
38 | -- | 488 | -- |
39 | 2.5.0 | 489 | 2.7.4 |
40 | 490 | ||
41 | 491 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | 1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | |
2 | |||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
3 | This is part of recent efforts of refactoring e1000 and e1000e. | ||
4 | |||
5 | DeviceClass's reset member is deprecated so migrate to ResettableClass. | ||
6 | There is no behavioral difference. | ||
7 | |||
8 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
9 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
10 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
11 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
12 | --- | ||
13 | hw/net/e1000.c | 13 ++++--------- | ||
14 | 1 file changed, 4 insertions(+), 9 deletions(-) | ||
15 | |||
16 | diff --git a/hw/net/e1000.c b/hw/net/e1000.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/hw/net/e1000.c | ||
19 | +++ b/hw/net/e1000.c | ||
20 | @@ -XXX,XX +XXX,XX @@ static bool e1000_vet_init_need(void *opaque) | ||
21 | return chkflag(VET); | ||
22 | } | ||
23 | |||
24 | -static void e1000_reset(void *opaque) | ||
25 | +static void e1000_reset_hold(Object *obj) | ||
26 | { | ||
27 | - E1000State *d = opaque; | ||
28 | + E1000State *d = E1000(obj); | ||
29 | E1000BaseClass *edc = E1000_GET_CLASS(d); | ||
30 | uint8_t *macaddr = d->conf.macaddr.a; | ||
31 | |||
32 | @@ -XXX,XX +XXX,XX @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp) | ||
33 | e1000_flush_queue_timer, d); | ||
34 | } | ||
35 | |||
36 | -static void qdev_e1000_reset(DeviceState *dev) | ||
37 | -{ | ||
38 | - E1000State *d = E1000(dev); | ||
39 | - e1000_reset(d); | ||
40 | -} | ||
41 | - | ||
42 | static Property e1000_properties[] = { | ||
43 | DEFINE_NIC_PROPERTIES(E1000State, conf), | ||
44 | DEFINE_PROP_BIT("autonegotiation", E1000State, | ||
45 | @@ -XXX,XX +XXX,XX @@ typedef struct E1000Info { | ||
46 | static void e1000_class_init(ObjectClass *klass, void *data) | ||
47 | { | ||
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 | -- | ||
65 | 2.7.4 | ||
66 | |||
67 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
3 | This is part of recent efforts of refactoring e1000 and e1000e. | ||
4 | |||
5 | DeviceClass's reset member is deprecated so migrate to ResettableClass. | ||
6 | There is no behavioral difference. | ||
7 | |||
8 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
9 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | ||
10 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
11 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
12 | --- | ||
13 | hw/net/e1000e.c | 10 ++++++---- | ||
14 | hw/net/trace-events | 2 +- | ||
15 | 2 files changed, 7 insertions(+), 5 deletions(-) | ||
16 | |||
17 | diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/hw/net/e1000e.c | ||
20 | +++ b/hw/net/e1000e.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static void e1000e_pci_uninit(PCIDevice *pci_dev) | ||
22 | msi_uninit(pci_dev); | ||
23 | } | ||
24 | |||
25 | -static void e1000e_qdev_reset(DeviceState *dev) | ||
26 | +static void e1000e_qdev_reset_hold(Object *obj) | ||
27 | { | ||
28 | - E1000EState *s = E1000E(dev); | ||
29 | + E1000EState *s = E1000E(obj); | ||
30 | |||
31 | - trace_e1000e_cb_qdev_reset(); | ||
32 | + trace_e1000e_cb_qdev_reset_hold(); | ||
33 | |||
34 | e1000e_core_reset(&s->core); | ||
35 | |||
36 | @@ -XXX,XX +XXX,XX @@ static Property e1000e_properties[] = { | ||
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 | + | ||
50 | dc->desc = "Intel 82574L GbE Controller"; | ||
51 | - dc->reset = e1000e_qdev_reset; | ||
52 | dc->vmsd = &e1000e_vmstate; | ||
53 | |||
54 | e1000e_prop_disable_vnet = qdev_prop_uint8; | ||
55 | diff --git a/hw/net/trace-events b/hw/net/trace-events | ||
56 | index XXXXXXX..XXXXXXX 100644 | ||
57 | --- a/hw/net/trace-events | ||
58 | +++ b/hw/net/trace-events | ||
59 | @@ -XXX,XX +XXX,XX @@ e1000e_vm_state_stopped(void) "VM state is stopped" | ||
60 | # e1000e.c | ||
61 | e1000e_cb_pci_realize(void) "E1000E PCI realize entry" | ||
62 | e1000e_cb_pci_uninit(void) "E1000E PCI unit entry" | ||
63 | -e1000e_cb_qdev_reset(void) "E1000E qdev reset entry" | ||
64 | +e1000e_cb_qdev_reset_hold(void) "E1000E qdev reset hold" | ||
65 | e1000e_cb_pre_save(void) "E1000E pre save entry" | ||
66 | e1000e_cb_post_load(void) "E1000E post load entry" | ||
67 | |||
68 | -- | ||
69 | 2.7.4 | ||
70 | |||
71 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
3 | e1000e_write_packet_to_guest() passes the reference of variable ba as a | ||
4 | pointer to an array, and that pointer indirection is just unnecessary; | ||
5 | all functions which uses the passed reference performs no pointer | ||
6 | operation on the pointer and they simply dereference the passed | ||
7 | pointer. Remove the extra pointer indirection. | ||
8 | |||
9 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
10 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
11 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
12 | --- | ||
13 | hw/net/e1000e_core.c | 38 +++++++++++++++++++------------------- | ||
14 | 1 file changed, 19 insertions(+), 19 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_read_ext_rx_descr(E1000ECore *core, union e1000_rx_desc_extended *desc, | ||
21 | static inline void | ||
22 | e1000e_read_ps_rx_descr(E1000ECore *core, | ||
23 | union e1000_rx_desc_packet_split *desc, | ||
24 | - hwaddr (*buff_addr)[MAX_PS_BUFFERS]) | ||
25 | + hwaddr buff_addr[MAX_PS_BUFFERS]) | ||
26 | { | ||
27 | int i; | ||
28 | |||
29 | for (i = 0; i < MAX_PS_BUFFERS; i++) { | ||
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 | } | ||
39 | |||
40 | static inline void | ||
41 | e1000e_read_rx_descr(E1000ECore *core, union e1000_rx_desc_union *desc, | ||
42 | - hwaddr (*buff_addr)[MAX_PS_BUFFERS]) | ||
43 | + hwaddr buff_addr[MAX_PS_BUFFERS]) | ||
44 | { | ||
45 | if (e1000e_rx_use_legacy_descriptor(core)) { | ||
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 | -- | ||
149 | 2.7.4 | ||
150 | |||
151 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
3 | net_tx_pkt_build_vheader() inspects TCP header but had no check for | ||
4 | the header size, resulting in an undefined behavior. Check the header | ||
5 | size and drop the packet if the header is too small. | ||
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 | 19 ++++++++++++++----- | ||
11 | hw/net/net_tx_pkt.c | 13 ++++++++++--- | ||
12 | hw/net/net_tx_pkt.h | 3 ++- | ||
13 | hw/net/vmxnet3.c | 14 +++++++------- | ||
14 | 4 files changed, 33 insertions(+), 16 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_rss_parse_packet(E1000ECore *core, | ||
21 | info->queue = E1000_RSS_QUEUE(&core->mac[RETA], info->hash); | ||
22 | } | ||
23 | |||
24 | -static void | ||
25 | +static bool | ||
26 | e1000e_setup_tx_offloads(E1000ECore *core, struct e1000e_tx *tx) | ||
27 | { | ||
28 | if (tx->props.tse && tx->cptse) { | ||
29 | - net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->props.mss); | ||
30 | + if (!net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->props.mss)) { | ||
31 | + return false; | ||
32 | + } | ||
33 | + | ||
34 | net_tx_pkt_update_ip_checksums(tx->tx_pkt); | ||
35 | e1000x_inc_reg_if_not_full(core->mac, TSCTC); | ||
36 | - return; | ||
37 | + return true; | ||
38 | } | ||
39 | |||
40 | if (tx->sum_needed & E1000_TXD_POPTS_TXSM) { | ||
41 | - net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0); | ||
42 | + if (!net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0)) { | ||
43 | + return false; | ||
44 | + } | ||
45 | } | ||
46 | |||
47 | if (tx->sum_needed & E1000_TXD_POPTS_IXSM) { | ||
48 | net_tx_pkt_update_ip_hdr_checksum(tx->tx_pkt); | ||
49 | } | ||
50 | + | ||
51 | + return true; | ||
52 | } | ||
53 | |||
54 | static bool | ||
55 | @@ -XXX,XX +XXX,XX @@ e1000e_tx_pkt_send(E1000ECore *core, struct e1000e_tx *tx, int queue_index) | ||
56 | int target_queue = MIN(core->max_queue_num, queue_index); | ||
57 | NetClientState *queue = qemu_get_subqueue(core->owner_nic, target_queue); | ||
58 | |||
59 | - e1000e_setup_tx_offloads(core, tx); | ||
60 | + if (!e1000e_setup_tx_offloads(core, tx)) { | ||
61 | + return false; | ||
62 | + } | ||
63 | |||
64 | net_tx_pkt_dump(tx->tx_pkt); | ||
65 | |||
66 | diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c | ||
67 | index XXXXXXX..XXXXXXX 100644 | ||
68 | --- a/hw/net/net_tx_pkt.c | ||
69 | +++ b/hw/net/net_tx_pkt.c | ||
70 | @@ -XXX,XX +XXX,XX @@ func_exit: | ||
71 | return rc; | ||
72 | } | ||
73 | |||
74 | -void net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable, | ||
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 | -- | ||
155 | 2.7.4 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
1 | From: Prasad J Pandit <pjp@fedoraproject.org> | 1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> |
---|---|---|---|
2 | 2 | ||
3 | When invoking qemu-bridge-helper in 'net_bridge_run_helper', | 3 | filter-dump specifiees Ethernet as PCAP LinkType, which does not expect |
4 | instead of using fixed sized buffers, use dynamically allocated | 4 | virtio-net header. Having virtio-net header in such PCAP file breaks |
5 | ones initialised and returned by g_strdup_printf(). | 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. | ||
6 | 8 | ||
7 | Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> | 9 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> |
8 | Reviewed-by: Li Qiang <liq3ea@gmail.com> | ||
9 | Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> | ||
10 | Signed-off-by: Jason Wang <jasowang@redhat.com> | 10 | Signed-off-by: Jason Wang <jasowang@redhat.com> |
11 | --- | 11 | --- |
12 | net/tap.c | 19 +++++++++++-------- | 12 | include/net/net.h | 6 ++++++ |
13 | 1 file changed, 11 insertions(+), 8 deletions(-) | 13 | net/dump.c | 11 +++++++---- |
14 | net/net.c | 18 ++++++++++++++++++ | ||
15 | net/tap.c | 16 ++++++++++++++++ | ||
16 | 4 files changed, 47 insertions(+), 4 deletions(-) | ||
14 | 17 | ||
18 | diff --git a/include/net/net.h b/include/net/net.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/include/net/net.h | ||
21 | +++ b/include/net/net.h | ||
22 | @@ -XXX,XX +XXX,XX @@ typedef RxFilterInfo *(QueryRxFilter)(NetClientState *); | ||
23 | typedef bool (HasUfo)(NetClientState *); | ||
24 | typedef bool (HasVnetHdr)(NetClientState *); | ||
25 | typedef bool (HasVnetHdrLen)(NetClientState *, int); | ||
26 | +typedef bool (GetUsingVnetHdr)(NetClientState *); | ||
27 | typedef void (UsingVnetHdr)(NetClientState *, bool); | ||
28 | typedef void (SetOffload)(NetClientState *, int, int, int, int, int); | ||
29 | +typedef int (GetVnetHdrLen)(NetClientState *); | ||
30 | typedef void (SetVnetHdrLen)(NetClientState *, int); | ||
31 | typedef int (SetVnetLE)(NetClientState *, bool); | ||
32 | typedef int (SetVnetBE)(NetClientState *, bool); | ||
33 | @@ -XXX,XX +XXX,XX @@ typedef struct NetClientInfo { | ||
34 | HasUfo *has_ufo; | ||
35 | HasVnetHdr *has_vnet_hdr; | ||
36 | HasVnetHdrLen *has_vnet_hdr_len; | ||
37 | + GetUsingVnetHdr *get_using_vnet_hdr; | ||
38 | UsingVnetHdr *using_vnet_hdr; | ||
39 | SetOffload *set_offload; | ||
40 | + GetVnetHdrLen *get_vnet_hdr_len; | ||
41 | SetVnetHdrLen *set_vnet_hdr_len; | ||
42 | SetVnetLE *set_vnet_le; | ||
43 | SetVnetBE *set_vnet_be; | ||
44 | @@ -XXX,XX +XXX,XX @@ void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]); | ||
45 | bool qemu_has_ufo(NetClientState *nc); | ||
46 | bool qemu_has_vnet_hdr(NetClientState *nc); | ||
47 | bool qemu_has_vnet_hdr_len(NetClientState *nc, int len); | ||
48 | +bool qemu_get_using_vnet_hdr(NetClientState *nc); | ||
49 | void qemu_using_vnet_hdr(NetClientState *nc, bool enable); | ||
50 | void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6, | ||
51 | int ecn, int ufo); | ||
52 | +int qemu_get_vnet_hdr_len(NetClientState *nc); | ||
53 | void qemu_set_vnet_hdr_len(NetClientState *nc, int len); | ||
54 | int qemu_set_vnet_le(NetClientState *nc, bool is_le); | ||
55 | int qemu_set_vnet_be(NetClientState *nc, bool is_be); | ||
56 | diff --git a/net/dump.c b/net/dump.c | ||
57 | index XXXXXXX..XXXXXXX 100644 | ||
58 | --- a/net/dump.c | ||
59 | +++ b/net/dump.c | ||
60 | @@ -XXX,XX +XXX,XX @@ struct pcap_sf_pkthdr { | ||
61 | uint32_t len; | ||
62 | }; | ||
63 | |||
64 | -static ssize_t dump_receive_iov(DumpState *s, const struct iovec *iov, int cnt) | ||
65 | +static ssize_t dump_receive_iov(DumpState *s, const struct iovec *iov, int cnt, | ||
66 | + int offset) | ||
67 | { | ||
68 | struct pcap_sf_pkthdr hdr; | ||
69 | int64_t ts; | ||
70 | int caplen; | ||
71 | - size_t size = iov_size(iov, cnt); | ||
72 | + size_t size = iov_size(iov, cnt) - offset; | ||
73 | struct iovec dumpiov[cnt + 1]; | ||
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 | } | ||
96 | |||
97 | diff --git a/net/net.c b/net/net.c | ||
98 | index XXXXXXX..XXXXXXX 100644 | ||
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 | +{ | ||
107 | + if (!nc || !nc->info->get_using_vnet_hdr) { | ||
108 | + return false; | ||
109 | + } | ||
110 | + | ||
111 | + return nc->info->get_using_vnet_hdr(nc); | ||
112 | +} | ||
113 | + | ||
114 | void qemu_using_vnet_hdr(NetClientState *nc, bool enable) | ||
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 | +{ | ||
123 | + if (!nc || !nc->info->get_vnet_hdr_len) { | ||
124 | + return 0; | ||
125 | + } | ||
126 | + | ||
127 | + return nc->info->get_vnet_hdr_len(nc); | ||
128 | +} | ||
129 | + | ||
130 | void qemu_set_vnet_hdr_len(NetClientState *nc, int len) | ||
131 | { | ||
132 | if (!nc || !nc->info->set_vnet_hdr_len) { | ||
15 | diff --git a/net/tap.c b/net/tap.c | 133 | diff --git a/net/tap.c b/net/tap.c |
16 | index XXXXXXX..XXXXXXX 100644 | 134 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/net/tap.c | 135 | --- a/net/tap.c |
18 | +++ b/net/tap.c | 136 | +++ b/net/tap.c |
19 | @@ -XXX,XX +XXX,XX @@ static int net_bridge_run_helper(const char *helper, const char *bridge, | 137 | @@ -XXX,XX +XXX,XX @@ static bool tap_has_vnet_hdr_len(NetClientState *nc, int len) |
20 | } | 138 | return !!tap_probe_vnet_hdr_len(s->fd, len); |
21 | if (pid == 0) { | 139 | } |
22 | int open_max = sysconf(_SC_OPEN_MAX), i; | 140 | |
23 | - char fd_buf[6+10]; | 141 | +static int tap_get_vnet_hdr_len(NetClientState *nc) |
24 | - char br_buf[6+IFNAMSIZ] = {0}; | 142 | +{ |
25 | - char helper_cmd[PATH_MAX + sizeof(fd_buf) + sizeof(br_buf) + 15]; | 143 | + TAPState *s = DO_UPCAST(TAPState, nc, nc); |
26 | + char *fd_buf = NULL; | 144 | + |
27 | + char *br_buf = NULL; | 145 | + return s->host_vnet_hdr_len; |
28 | + char *helper_cmd = NULL; | 146 | +} |
29 | 147 | + | |
30 | for (i = 3; i < open_max; i++) { | 148 | static void tap_set_vnet_hdr_len(NetClientState *nc, int len) |
31 | if (i != sv[1]) { | 149 | { |
32 | @@ -XXX,XX +XXX,XX @@ static int net_bridge_run_helper(const char *helper, const char *bridge, | 150 | TAPState *s = DO_UPCAST(TAPState, nc, nc); |
33 | } | 151 | @@ -XXX,XX +XXX,XX @@ static void tap_set_vnet_hdr_len(NetClientState *nc, int len) |
34 | } | 152 | s->host_vnet_hdr_len = len; |
35 | 153 | } | |
36 | - snprintf(fd_buf, sizeof(fd_buf), "%s%d", "--fd=", sv[1]); | 154 | |
37 | + fd_buf = g_strdup_printf("%s%d", "--fd=", sv[1]); | 155 | +static bool tap_get_using_vnet_hdr(NetClientState *nc) |
38 | 156 | +{ | |
39 | if (strrchr(helper, ' ') || strrchr(helper, '\t')) { | 157 | + TAPState *s = DO_UPCAST(TAPState, nc, nc); |
40 | /* assume helper is a command */ | 158 | + |
41 | 159 | + return s->using_vnet_hdr; | |
42 | if (strstr(helper, "--br=") == NULL) { | 160 | +} |
43 | - snprintf(br_buf, sizeof(br_buf), "%s%s", "--br=", bridge); | 161 | + |
44 | + br_buf = g_strdup_printf("%s%s", "--br=", bridge); | 162 | static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr) |
45 | } | 163 | { |
46 | 164 | TAPState *s = DO_UPCAST(TAPState, nc, nc); | |
47 | - snprintf(helper_cmd, sizeof(helper_cmd), "%s %s %s %s", | 165 | @@ -XXX,XX +XXX,XX @@ static NetClientInfo net_tap_info = { |
48 | - helper, "--use-vnet", fd_buf, br_buf); | 166 | .has_ufo = tap_has_ufo, |
49 | + helper_cmd = g_strdup_printf("%s %s %s %s", helper, | 167 | .has_vnet_hdr = tap_has_vnet_hdr, |
50 | + "--use-vnet", fd_buf, br_buf ? br_buf : ""); | 168 | .has_vnet_hdr_len = tap_has_vnet_hdr_len, |
51 | 169 | + .get_using_vnet_hdr = tap_get_using_vnet_hdr, | |
52 | parg = args; | 170 | .using_vnet_hdr = tap_using_vnet_hdr, |
53 | *parg++ = (char *)"sh"; | 171 | .set_offload = tap_set_offload, |
54 | @@ -XXX,XX +XXX,XX @@ static int net_bridge_run_helper(const char *helper, const char *bridge, | 172 | + .get_vnet_hdr_len = tap_get_vnet_hdr_len, |
55 | *parg++ = NULL; | 173 | .set_vnet_hdr_len = tap_set_vnet_hdr_len, |
56 | 174 | .set_vnet_le = tap_set_vnet_le, | |
57 | execv("/bin/sh", args); | 175 | .set_vnet_be = tap_set_vnet_be, |
58 | + g_free(helper_cmd); | ||
59 | } else { | ||
60 | /* assume helper is just the executable path name */ | ||
61 | |||
62 | - snprintf(br_buf, sizeof(br_buf), "%s%s", "--br=", bridge); | ||
63 | + br_buf = g_strdup_printf("%s%s", "--br=", bridge); | ||
64 | |||
65 | parg = args; | ||
66 | *parg++ = (char *)helper; | ||
67 | @@ -XXX,XX +XXX,XX @@ static int net_bridge_run_helper(const char *helper, const char *bridge, | ||
68 | |||
69 | execv(helper, args); | ||
70 | } | ||
71 | + g_free(fd_buf); | ||
72 | + g_free(br_buf); | ||
73 | _exit(1); | ||
74 | |||
75 | } else { | ||
76 | -- | 176 | -- |
77 | 2.5.0 | 177 | 2.7.4 |
78 | |||
79 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | 1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | |
2 | |||
3 | e1000e didn't perform software segmentation for loopback if virtio-net | ||
4 | header is enabled, which is wrong. | ||
5 | |||
6 | To fix the problem, introduce net_tx_pkt_send_custom(), which allows the | ||
7 | caller to specify whether offloading should be assumed or not. | ||
8 | |||
9 | net_tx_pkt_send_custom() also allows the caller to provide a custom | ||
10 | sending function. Packets with virtio-net headers and ones without | ||
11 | virtio-net headers will be provided at the same time so the function | ||
12 | can choose the preferred version. In case of e1000e loopback, it prefers | ||
13 | to have virtio-net headers as they allows to skip the checksum | ||
14 | verification if VIRTIO_NET_HDR_F_DATA_VALID is set. | ||
15 | |||
16 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
17 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
18 | --- | ||
19 | hw/net/e1000e_core.c | 27 +++++++++++++++++-- | ||
20 | hw/net/net_rx_pkt.c | 7 +++++ | ||
21 | hw/net/net_rx_pkt.h | 8 ++++++ | ||
22 | hw/net/net_tx_pkt.c | 76 +++++++++++++++++++++++++--------------------------- | ||
23 | hw/net/net_tx_pkt.h | 21 ++++++++------- | ||
24 | 5 files changed, 88 insertions(+), 51 deletions(-) | ||
25 | |||
26 | diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c | ||
27 | index XXXXXXX..XXXXXXX 100644 | ||
28 | --- a/hw/net/e1000e_core.c | ||
29 | +++ b/hw/net/e1000e_core.c | ||
30 | @@ -XXX,XX +XXX,XX @@ union e1000_rx_desc_union { | ||
31 | union e1000_rx_desc_packet_split packet_split; | ||
32 | }; | ||
33 | |||
34 | +static ssize_t | ||
35 | +e1000e_receive_internal(E1000ECore *core, const struct iovec *iov, int iovcnt, | ||
36 | + bool has_vnet); | ||
37 | + | ||
38 | static inline void | ||
39 | e1000e_set_interrupt_cause(E1000ECore *core, uint32_t val); | ||
40 | |||
41 | @@ -XXX,XX +XXX,XX @@ e1000e_setup_tx_offloads(E1000ECore *core, struct e1000e_tx *tx) | ||
42 | return true; | ||
43 | } | ||
44 | |||
45 | +static void e1000e_tx_pkt_callback(void *core, | ||
46 | + const struct iovec *iov, | ||
47 | + int iovcnt, | ||
48 | + const struct iovec *virt_iov, | ||
49 | + int virt_iovcnt) | ||
50 | +{ | ||
51 | + e1000e_receive_internal(core, virt_iov, virt_iovcnt, true); | ||
52 | +} | ||
53 | + | ||
54 | static bool | ||
55 | e1000e_tx_pkt_send(E1000ECore *core, struct e1000e_tx *tx, int queue_index) | ||
56 | { | ||
57 | @@ -XXX,XX +XXX,XX @@ e1000e_tx_pkt_send(E1000ECore *core, struct e1000e_tx *tx, int queue_index) | ||
58 | |||
59 | if ((core->phy[0][MII_BMCR] & MII_BMCR_LOOPBACK) || | ||
60 | ((core->mac[RCTL] & E1000_RCTL_LBM_MAC) == E1000_RCTL_LBM_MAC)) { | ||
61 | - return net_tx_pkt_send_loopback(tx->tx_pkt, queue); | ||
62 | + return net_tx_pkt_send_custom(tx->tx_pkt, false, | ||
63 | + e1000e_tx_pkt_callback, core); | ||
64 | } else { | ||
65 | return net_tx_pkt_send(tx->tx_pkt, queue); | ||
66 | } | ||
67 | @@ -XXX,XX +XXX,XX @@ e1000e_rx_fix_l4_csum(E1000ECore *core, struct NetRxPkt *pkt) | ||
68 | ssize_t | ||
69 | e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt) | ||
70 | { | ||
71 | + return e1000e_receive_internal(core, iov, iovcnt, core->has_vnet); | ||
72 | +} | ||
73 | + | ||
74 | +static ssize_t | ||
75 | +e1000e_receive_internal(E1000ECore *core, const struct iovec *iov, int iovcnt, | ||
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 | } | ||
101 | |||
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 | /** | ||
120 | + * unset vhdr data from packet context | ||
121 | + * | ||
122 | + * @pkt: packet | ||
123 | + * | ||
124 | + */ | ||
125 | +void net_rx_pkt_unset_vhdr(struct NetRxPkt *pkt); | ||
126 | + | ||
127 | +/** | ||
128 | * save packet type in packet context | ||
129 | * | ||
130 | * @pkt: packet | ||
131 | diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c | ||
132 | index XXXXXXX..XXXXXXX 100644 | ||
133 | --- a/hw/net/net_tx_pkt.c | ||
134 | +++ b/hw/net/net_tx_pkt.c | ||
135 | @@ -XXX,XX +XXX,XX @@ struct NetTxPkt { | ||
136 | uint16_t hdr_len; | ||
137 | eth_pkt_types_e packet_type; | ||
138 | uint8_t l4proto; | ||
139 | - | ||
140 | - bool is_loopback; | ||
141 | }; | ||
142 | |||
143 | void net_tx_pkt_init(struct NetTxPkt **pkt, PCIDevice *pci_dev, | ||
144 | @@ -XXX,XX +XXX,XX @@ static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt) | ||
145 | iov_from_buf(iov, iov_len, csum_offset, &csum, sizeof csum); | ||
146 | } | ||
147 | |||
148 | -enum { | ||
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 | } | ||
185 | } | ||
186 | |||
187 | static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt, | ||
188 | - NetClientState *nc) | ||
189 | + NetTxPktCallback callback, | ||
190 | + void *context) | ||
191 | { | ||
192 | struct iovec fragment[NET_MAX_FRAG_SG_LIST]; | ||
193 | size_t fragment_len = 0; | ||
194 | @@ -XXX,XX +XXX,XX @@ static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt, | ||
195 | int src_idx = NET_TX_PKT_PL_START_FRAG, dst_idx; | ||
196 | size_t src_offset = 0; | ||
197 | size_t fragment_offset = 0; | ||
198 | + struct virtio_net_hdr virt_hdr = { | ||
199 | + .flags = pkt->virt_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM ? | ||
200 | + VIRTIO_NET_HDR_F_DATA_VALID : 0 | ||
201 | + }; | ||
202 | |||
203 | l2_iov_base = pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_base; | ||
204 | l2_iov_len = pkt->vec[NET_TX_PKT_L2HDR_FRAG].iov_len; | ||
205 | @@ -XXX,XX +XXX,XX @@ static bool net_tx_pkt_do_sw_fragmentation(struct NetTxPkt *pkt, | ||
206 | l3_iov_len = pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len; | ||
207 | |||
208 | /* Copy headers */ | ||
209 | - fragment[NET_TX_PKT_FRAGMENT_L2_HDR_POS].iov_base = l2_iov_base; | ||
210 | - fragment[NET_TX_PKT_FRAGMENT_L2_HDR_POS].iov_len = l2_iov_len; | ||
211 | - fragment[NET_TX_PKT_FRAGMENT_L3_HDR_POS].iov_base = l3_iov_base; | ||
212 | - fragment[NET_TX_PKT_FRAGMENT_L3_HDR_POS].iov_len = l3_iov_len; | ||
213 | + fragment[NET_TX_PKT_VHDR_FRAG].iov_base = &virt_hdr; | ||
214 | + fragment[NET_TX_PKT_VHDR_FRAG].iov_len = sizeof(virt_hdr); | ||
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 | } | ||
252 | |||
253 | @@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc) | ||
254 | } | ||
255 | } | ||
256 | |||
257 | - if (using_vnet_hdr || | ||
258 | - pkt->virt_hdr.gso_type == VIRTIO_NET_HDR_GSO_NONE) { | ||
259 | - int index = using_vnet_hdr ? | ||
260 | - NET_TX_PKT_VHDR_FRAG : NET_TX_PKT_L2HDR_FRAG; | ||
261 | + if (offload || pkt->virt_hdr.gso_type == VIRTIO_NET_HDR_GSO_NONE) { | ||
262 | net_tx_pkt_fix_ip6_payload_len(pkt); | ||
263 | - net_tx_pkt_sendv(pkt, nc, pkt->vec + index, | ||
264 | - pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - index); | ||
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 | } | ||
271 | |||
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 | -- | ||
328 | 2.7.4 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
3 | There was no proper implementation of TCP segmentation before this | ||
4 | change, and net_tx_pkt relied solely on IPv4 fragmentation. Not only | ||
5 | this is not aligned with the specification, but it also resulted in | ||
6 | corrupted IPv6 packets. | ||
7 | |||
8 | This is particularly problematic for the igb, a new proposed device | ||
9 | implementation; igb provides loopback feature for VMDq and the feature | ||
10 | relies on software segmentation. | ||
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> | ||
16 | --- | ||
17 | hw/net/net_tx_pkt.c | 248 +++++++++++++++++++++++++++++++++++++++++++--------- | ||
18 | include/net/eth.h | 5 -- | ||
19 | net/eth.c | 27 ------ | ||
20 | 3 files changed, 206 insertions(+), 74 deletions(-) | ||
21 | |||
22 | diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/hw/net/net_tx_pkt.c | ||
25 | +++ b/hw/net/net_tx_pkt.c | ||
26 | @@ -XXX,XX +XXX,XX @@ bool net_tx_pkt_build_vheader(struct NetTxPkt *pkt, bool tso_enable, | ||
27 | case VIRTIO_NET_HDR_GSO_TCPV6: | ||
28 | bytes_read = iov_to_buf(&pkt->vec[NET_TX_PKT_PL_START_FRAG], | ||
29 | pkt->payload_frags, 0, &l4hdr, sizeof(l4hdr)); | ||
30 | - if (bytes_read < sizeof(l4hdr)) { | ||
31 | + if (bytes_read < sizeof(l4hdr) || | ||
32 | + l4hdr.th_off * sizeof(uint32_t) < sizeof(l4hdr)) { | ||
33 | return false; | ||
34 | } | ||
35 | |||
36 | @@ -XXX,XX +XXX,XX @@ void net_tx_pkt_reset(struct NetTxPkt *pkt) | ||
37 | pkt->l4proto = 0; | ||
38 | } | ||
39 | |||
40 | -static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt) | ||
41 | +static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt, | ||
42 | + struct iovec *iov, uint32_t iov_len, | ||
43 | + uint16_t csl) | ||
44 | { | ||
45 | - struct iovec *iov = &pkt->vec[NET_TX_PKT_L2HDR_FRAG]; | ||
46 | uint32_t csum_cntr; | ||
47 | uint16_t csum = 0; | ||
48 | uint32_t cso; | ||
49 | /* num of iovec without vhdr */ | ||
50 | - uint32_t iov_len = pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - 1; | ||
51 | - uint16_t csl; | ||
52 | size_t csum_offset = pkt->virt_hdr.csum_start + pkt->virt_hdr.csum_offset; | ||
53 | uint16_t l3_proto = eth_get_l3_proto(iov, 1, iov->iov_len); | ||
54 | |||
55 | @@ -XXX,XX +XXX,XX @@ static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt) | ||
56 | iov_from_buf(iov, iov_len, csum_offset, &csum, sizeof csum); | ||
57 | |||
58 | /* Calculate L4 TCP/UDP checksum */ | ||
59 | - csl = pkt->payload_len; | ||
60 | - | ||
61 | csum_cntr = 0; | ||
62 | cso = 0; | ||
63 | /* add pseudo header to csum */ | ||
64 | @@ -XXX,XX +XXX,XX @@ static void net_tx_pkt_do_sw_csum(struct NetTxPkt *pkt) | ||
65 | #define NET_MAX_FRAG_SG_LIST (64) | ||
66 | |||
67 | static size_t net_tx_pkt_fetch_fragment(struct NetTxPkt *pkt, | ||
68 | - int *src_idx, size_t *src_offset, struct iovec *dst, int *dst_idx) | ||
69 | + int *src_idx, size_t *src_offset, size_t src_len, | ||
70 | + struct iovec *dst, int *dst_idx) | ||
71 | { | ||
72 | size_t fetched = 0; | ||
73 | struct iovec *src = pkt->vec; | ||
74 | |||
75 | - *dst_idx = NET_TX_PKT_PL_START_FRAG; | ||
76 | - | ||
77 | - while (fetched < IP_FRAG_ALIGN_SIZE(pkt->virt_hdr.gso_size)) { | ||
78 | + while (fetched < src_len) { | ||
79 | |||
80 | /* no more place in fragment iov */ | ||
81 | if (*dst_idx == NET_MAX_FRAG_SG_LIST) { | ||
82 | @@ -XXX,XX +XXX,XX @@ static size_t net_tx_pkt_fetch_fragment(struct NetTxPkt *pkt, | ||
83 | |||
84 | dst[*dst_idx].iov_base = src[*src_idx].iov_base + *src_offset; | ||
85 | dst[*dst_idx].iov_len = MIN(src[*src_idx].iov_len - *src_offset, | ||
86 | - IP_FRAG_ALIGN_SIZE(pkt->virt_hdr.gso_size) - fetched); | ||
87 | + src_len - fetched); | ||
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 | } | ||
93 | } | ||
94 | |||
95 | +static bool net_tx_pkt_tcp_fragment_init(struct NetTxPkt *pkt, | ||
96 | + struct iovec *fragment, | ||
97 | + int *pl_idx, | ||
98 | + size_t *l4hdr_len, | ||
99 | + int *src_idx, | ||
100 | + size_t *src_offset, | ||
101 | + size_t *src_len) | ||
102 | +{ | ||
103 | + struct iovec *l4 = fragment + NET_TX_PKT_PL_START_FRAG; | ||
104 | + size_t bytes_read = 0; | ||
105 | + struct tcp_hdr *th; | ||
106 | + | ||
107 | + if (!pkt->payload_frags) { | ||
108 | + return false; | ||
109 | + } | ||
110 | + | ||
111 | + l4->iov_len = pkt->virt_hdr.hdr_len - pkt->hdr_len; | ||
112 | + l4->iov_base = g_malloc(l4->iov_len); | ||
113 | + | ||
114 | + *src_idx = NET_TX_PKT_PL_START_FRAG; | ||
115 | + while (pkt->vec[*src_idx].iov_len < l4->iov_len - bytes_read) { | ||
116 | + memcpy((char *)l4->iov_base + bytes_read, pkt->vec[*src_idx].iov_base, | ||
117 | + pkt->vec[*src_idx].iov_len); | ||
118 | + | ||
119 | + bytes_read += pkt->vec[*src_idx].iov_len; | ||
120 | + | ||
121 | + (*src_idx)++; | ||
122 | + if (*src_idx >= pkt->payload_frags + NET_TX_PKT_PL_START_FRAG) { | ||
123 | + g_free(l4->iov_base); | ||
124 | + return false; | ||
125 | + } | ||
126 | + } | ||
127 | + | ||
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; | ||
140 | +} | ||
141 | + | ||
142 | +static void net_tx_pkt_tcp_fragment_deinit(struct iovec *fragment) | ||
143 | +{ | ||
144 | + g_free(fragment[NET_TX_PKT_PL_START_FRAG].iov_base); | ||
145 | +} | ||
146 | + | ||
147 | +static void net_tx_pkt_tcp_fragment_fix(struct NetTxPkt *pkt, | ||
148 | + struct iovec *fragment, | ||
149 | + size_t fragment_len, | ||
150 | + uint8_t gso_type) | ||
151 | +{ | ||
152 | + struct iovec *l3hdr = fragment + NET_TX_PKT_L3HDR_FRAG; | ||
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 | + } | ||
274 | + break; | ||
275 | |||
276 | - /* Put as much data as possible and send */ | ||
277 | - do { | ||
278 | - fragment_len = net_tx_pkt_fetch_fragment(pkt, &src_idx, &src_offset, | ||
279 | - fragment, &dst_idx); | ||
280 | + case VIRTIO_NET_HDR_GSO_UDP: | ||
281 | + net_tx_pkt_do_sw_csum(pkt, &pkt->vec[NET_TX_PKT_L2HDR_FRAG], | ||
282 | + pkt->payload_frags + NET_TX_PKT_PL_START_FRAG - 1, | ||
283 | + pkt->payload_len); | ||
284 | + net_tx_pkt_udp_fragment_init(pkt, &pl_idx, &l4hdr_len, | ||
285 | + &src_idx, &src_offset, &src_len); | ||
286 | + break; | ||
287 | |||
288 | - more_frags = (fragment_offset + fragment_len < pkt->payload_len); | ||
289 | + default: | ||
290 | + abort(); | ||
291 | + } | ||
292 | |||
293 | - eth_setup_ip4_fragmentation(l2_iov_base, l2_iov_len, l3_iov_base, | ||
294 | - l3_iov_len, fragment_len, fragment_offset, more_frags); | ||
295 | + /* Put as much data as possible and send */ | ||
296 | + while (true) { | ||
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 | ||
367 | --- a/include/net/eth.h | ||
368 | +++ b/include/net/eth.h | ||
369 | @@ -XXX,XX +XXX,XX @@ void eth_get_protocols(const struct iovec *iov, int iovcnt, | ||
370 | eth_ip4_hdr_info *ip4hdr_info, | ||
371 | eth_l4_hdr_info *l4hdr_info); | ||
372 | |||
373 | -void eth_setup_ip4_fragmentation(const void *l2hdr, size_t l2hdr_len, | ||
374 | - void *l3hdr, size_t l3hdr_len, | ||
375 | - size_t l3payload_len, | ||
376 | - size_t frag_offset, bool more_frags); | ||
377 | - | ||
378 | void | ||
379 | eth_fix_ip4_checksum(void *l3hdr, size_t l3hdr_len); | ||
380 | |||
381 | diff --git a/net/eth.c b/net/eth.c | ||
382 | index XXXXXXX..XXXXXXX 100644 | ||
383 | --- a/net/eth.c | ||
384 | +++ b/net/eth.c | ||
385 | @@ -XXX,XX +XXX,XX @@ eth_strip_vlan_ex(const struct iovec *iov, int iovcnt, size_t iovoff, | ||
386 | } | ||
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 | -- | ||
420 | 2.7.4 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
1 | From: Zhang Chen <chen.zhang@intel.com> | 1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> |
---|---|---|---|
2 | 2 | ||
3 | This patch to fix the origin "char *data" memory leak, code style issue | 3 | The values returned by eth_get_protocols() are used to perform RSS, |
4 | and add necessary check here. | 4 | checksumming and segmentation. Even when a packet signals the use of the |
5 | Reported-by: Coverity (CID 1402785) | 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. | ||
6 | 8 | ||
7 | Signed-off-by: Zhang Chen <chen.zhang@intel.com> | 9 | Report the presence of headers instead of whether the use of the |
8 | Reviewed-by: Peter Maydell <peter.maydell@linaro.org> | 10 | protocols are indicated with eth_get_protocols(). This also makes |
11 | corresponding changes to the callers of eth_get_protocols() to match | ||
12 | with its new signature and to remove redundant checks for fragmentation. | ||
13 | |||
14 | Fixes: 75020a7021 ("Common definitions for VMWARE devices") | ||
15 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
9 | Signed-off-by: Jason Wang <jasowang@redhat.com> | 16 | Signed-off-by: Jason Wang <jasowang@redhat.com> |
10 | --- | 17 | --- |
11 | net/colo-compare.c | 27 ++++++++++++++++++++------- | 18 | hw/net/e1000e_core.c | 65 ++++++++++++++++++------------------- |
12 | 1 file changed, 20 insertions(+), 7 deletions(-) | 19 | hw/net/net_rx_pkt.c | 86 ++++++++++++++++++++++++------------------------- |
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(-) | ||
13 | 27 | ||
14 | diff --git a/net/colo-compare.c b/net/colo-compare.c | 28 | diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c |
15 | index XXXXXXX..XXXXXXX 100644 | 29 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/net/colo-compare.c | 30 | --- a/hw/net/e1000e_core.c |
17 | +++ b/net/colo-compare.c | 31 | +++ b/hw/net/e1000e_core.c |
18 | @@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CompareState *s, | 32 | @@ -XXX,XX +XXX,XX @@ typedef struct E1000E_RSSInfo_st { |
19 | uint32_t vnet_hdr_len, | 33 | static uint32_t |
20 | bool notify_remote_frame); | 34 | e1000e_rss_get_hash_type(E1000ECore *core, struct NetRxPkt *pkt) |
21 | 35 | { | |
22 | +static bool packet_matches_str(const char *str, | 36 | - bool isip4, isip6, isudp, istcp; |
23 | + const uint8_t *buf, | 37 | + bool hasip4, hasip6, hasudp, hastcp; |
24 | + uint32_t packet_len) | 38 | |
25 | +{ | 39 | assert(e1000e_rss_enabled(core)); |
26 | + if (packet_len != strlen(str)) { | 40 | |
27 | + return false; | 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 | ||
510 | index XXXXXXX..XXXXXXX 100644 | ||
511 | --- a/hw/net/virtio-net.c | ||
512 | +++ b/hw/net/virtio-net.c | ||
513 | @@ -XXX,XX +XXX,XX @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size) | ||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | -static uint8_t virtio_net_get_hash_type(bool isip4, | ||
518 | - bool isip6, | ||
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 | } | ||
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; | ||
28 | + } | 755 | + } |
29 | + | 756 | + |
30 | + return !memcmp(str, buf, strlen(str)); | 757 | + switch (ip_p) { |
31 | +} | 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); | ||
32 | + | 766 | + |
33 | static void notify_remote_frame(CompareState *s) | 767 | + l4hdr_info->has_tcp_data = |
34 | { | 768 | + _eth_tcp_has_data(proto == ETH_P_IP, |
35 | char msg[] = "DO_CHECKPOINT"; | 769 | + &ip4hdr_info->ip4_hdr, |
36 | @@ -XXX,XX +XXX,XX @@ static void compare_notify_rs_finalize(SocketReadState *notify_rs) | 770 | + &ip6hdr_info->ip6_hdr, |
37 | { | 771 | + *l4hdr_off - *l3hdr_off, |
38 | CompareState *s = container_of(notify_rs, CompareState, notify_rs); | 772 | + &l4hdr_info->hdr.tcp); |
39 | 773 | } | |
40 | - /* Get Xen colo-frame's notify and handle the message */ | 774 | + break; |
41 | - char *data = g_memdup(notify_rs->buf, notify_rs->packet_len); | 775 | + |
42 | - char msg[] = "COLO_COMPARE_GET_XEN_INIT"; | 776 | + case IP_PROTO_UDP: |
43 | + const char msg[] = "COLO_COMPARE_GET_XEN_INIT"; | 777 | + *hasudp = _eth_copy_chunk(input_size, |
44 | int ret; | 778 | + iov, iovcnt, |
45 | 779 | + *l4hdr_off, sizeof(l4hdr_info->hdr.udp), | |
46 | - if (!strcmp(data, "COLO_USERSPACE_PROXY_INIT")) { | 780 | + &l4hdr_info->hdr.udp); |
47 | + if (packet_matches_str("COLO_USERSPACE_PROXY_INIT", | 781 | + *l5hdr_off = *l4hdr_off + sizeof(l4hdr_info->hdr.udp); |
48 | + notify_rs->buf, | 782 | + break; |
49 | + notify_rs->packet_len)) { | ||
50 | ret = compare_chr_send(s, (uint8_t *)msg, strlen(msg), 0, true); | ||
51 | if (ret < 0) { | ||
52 | error_report("Notify Xen COLO-frame INIT failed"); | ||
53 | } | ||
54 | - } | ||
55 | - | ||
56 | - if (!strcmp(data, "COLO_CHECKPOINT")) { | ||
57 | + } else if (packet_matches_str("COLO_CHECKPOINT", | ||
58 | + notify_rs->buf, | ||
59 | + notify_rs->packet_len)) { | ||
60 | /* colo-compare do checkpoint, flush pri packet and remove sec packet */ | ||
61 | g_queue_foreach(&s->conn_list, colo_flush_packets, s); | ||
62 | + } else { | ||
63 | + error_report("COLO compare got unsupported instruction"); | ||
64 | } | 783 | } |
65 | } | 784 | } |
66 | 785 | ||
67 | -- | 786 | -- |
68 | 2.5.0 | 787 | 2.7.4 |
69 | |||
70 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
3 | Some definitions in the header files are invalid for igb so extract | ||
4 | them to new header files to keep igb from referring to them. | ||
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/net/e1000.c | 1 + | ||
13 | hw/net/e1000_common.h | 102 ++++++ | ||
14 | hw/net/e1000_regs.h | 954 +----------------------------------------------- | ||
15 | hw/net/e1000e.c | 3 +- | ||
16 | hw/net/e1000e_core.c | 1 + | ||
17 | hw/net/e1000x_common.c | 1 + | ||
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 | |||
24 | diff --git a/hw/net/e1000.c b/hw/net/e1000.c | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/hw/net/e1000.c | ||
27 | +++ b/hw/net/e1000.c | ||
28 | @@ -XXX,XX +XXX,XX @@ | ||
29 | #include "qemu/module.h" | ||
30 | #include "qemu/range.h" | ||
31 | |||
32 | +#include "e1000_common.h" | ||
33 | #include "e1000x_common.h" | ||
34 | #include "trace.h" | ||
35 | #include "qom/object.h" | ||
36 | diff --git a/hw/net/e1000_common.h b/hw/net/e1000_common.h | ||
37 | new file mode 100644 | ||
38 | index XXXXXXX..XXXXXXX | ||
39 | --- /dev/null | ||
40 | +++ b/hw/net/e1000_common.h | ||
41 | @@ -XXX,XX +XXX,XX @@ | ||
42 | +/* | ||
43 | + * QEMU e1000(e) emulation - shared definitions | ||
44 | + * | ||
45 | + * Copyright (c) 2008 Qumranet | ||
46 | + * | ||
47 | + * Based on work done by: | ||
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 | + */ | ||
65 | + | ||
66 | +#ifndef HW_NET_E1000_COMMON_H | ||
67 | +#define HW_NET_E1000_COMMON_H | ||
68 | + | ||
69 | +#include "e1000_regs.h" | ||
70 | + | ||
71 | +#define defreg(x) x = (E1000_##x >> 2) | ||
72 | +enum { | ||
73 | + defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC), | ||
74 | + defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC), | ||
75 | + defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC), | ||
76 | + defreg(MPC), defreg(PBA), defreg(RCTL), defreg(RDBAH0), | ||
77 | + defreg(RDBAL0), defreg(RDH0), defreg(RDLEN0), defreg(RDT0), | ||
78 | + defreg(STATUS), defreg(SWSM), defreg(TCTL), defreg(TDBAH), | ||
79 | + defreg(TDBAL), defreg(TDH), defreg(TDLEN), defreg(TDT), | ||
80 | + defreg(TDLEN1), defreg(TDBAL1), defreg(TDBAH1), defreg(TDH1), | ||
81 | + defreg(TDT1), defreg(TORH), defreg(TORL), defreg(TOTH), | ||
82 | + defreg(TOTL), defreg(TPR), defreg(TPT), defreg(TXDCTL), | ||
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 | + | ||
135 | + /* Aliases */ | ||
136 | + defreg(RDH0_A), defreg(RDT0_A), defreg(RDTR_A), defreg(RDFH_A), | ||
137 | + defreg(RDFT_A), defreg(TDH_A), defreg(TDT_A), defreg(TIDV_A), | ||
138 | + defreg(TDFH_A), defreg(TDFT_A), defreg(RA_A), defreg(RDBAL0_A), | ||
139 | + defreg(TDBAL_A), defreg(TDLEN_A), defreg(VFTA_A), defreg(RDLEN0_A), | ||
140 | + defreg(FCRTL_A), defreg(FCRTH_A) | ||
141 | +}; | ||
142 | + | ||
143 | +#endif | ||
144 | diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h | ||
145 | index XXXXXXX..XXXXXXX 100644 | ||
146 | --- a/hw/net/e1000_regs.h | ||
147 | +++ b/hw/net/e1000_regs.h | ||
148 | @@ -XXX,XX +XXX,XX @@ | ||
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 | + | ||
476 | #define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */ | ||
477 | -#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */ | ||
478 | -#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */ | ||
479 | -#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */ | ||
480 | #define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */ | ||
481 | #define E1000_RSSIR 0x05868 /* RSS Interrupt Request */ | ||
482 | |||
483 | -#define E1000_MRQC_ENABLED(mrqc) (((mrqc) & (BIT(0) | BIT(1))) == BIT(0)) | ||
484 | - | ||
485 | -#define E1000_RETA_IDX(hash) ((hash) & (BIT(7) - 1)) | ||
486 | -#define E1000_RETA_VAL(reta, hash) (((uint8_t *)(reta))[E1000_RETA_IDX(hash)]) | ||
487 | #define E1000_RSS_QUEUE(reta, hash) ((E1000_RETA_VAL(reta, hash) & BIT(7)) >> 7) | ||
488 | |||
489 | -#define E1000_MRQC_EN_TCPIPV4(mrqc) ((mrqc) & BIT(16)) | ||
490 | -#define E1000_MRQC_EN_IPV4(mrqc) ((mrqc) & BIT(17)) | ||
491 | -#define E1000_MRQC_EN_TCPIPV6(mrqc) ((mrqc) & BIT(18)) | ||
492 | -#define E1000_MRQC_EN_IPV6EX(mrqc) ((mrqc) & BIT(19)) | ||
493 | -#define E1000_MRQC_EN_IPV6(mrqc) ((mrqc) & BIT(20)) | ||
494 | - | ||
495 | -#define E1000_MRQ_RSS_TYPE_NONE (0) | ||
496 | -#define E1000_MRQ_RSS_TYPE_IPV4TCP (1) | ||
497 | -#define E1000_MRQ_RSS_TYPE_IPV4 (2) | ||
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 | ||
1362 | index XXXXXXX..XXXXXXX | ||
1363 | --- /dev/null | ||
1364 | +++ b/hw/net/e1000x_regs.h | ||
1365 | @@ -XXX,XX +XXX,XX @@ | ||
1366 | +/******************************************************************************* | ||
1367 | + | ||
1368 | + Intel PRO/1000 Linux driver | ||
1369 | + Copyright(c) 1999 - 2006 Intel Corporation. | ||
1370 | + | ||
1371 | + This program is free software; you can redistribute it and/or modify it | ||
1372 | + under the terms and conditions of the GNU General Public License, | ||
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 | + */ | ||
1396 | + | ||
1397 | +#ifndef HW_E1000X_REGS_H | ||
1398 | +#define HW_E1000X_REGS_H | ||
1399 | + | ||
1400 | +/* PCI Device IDs */ | ||
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 | + | ||
1459 | +#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049 | ||
1460 | +#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A | ||
1461 | +#define E1000_DEV_ID_ICH8_IGP_C 0x104B | ||
1462 | +#define E1000_DEV_ID_ICH8_IFE 0x104C | ||
1463 | +#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4 | ||
1464 | +#define E1000_DEV_ID_ICH8_IFE_G 0x10C5 | ||
1465 | +#define E1000_DEV_ID_ICH8_IGP_M 0x104D | ||
1466 | + | ||
1467 | +/* Device Specific Register Defaults */ | ||
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 | + | ||
1474 | +/* Register Set. (82543, 82544) | ||
1475 | + * | ||
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 | + | ||
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 | ||
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 | -- | ||
2334 | 2.7.4 | ||
2335 | |||
2336 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
3 | This change introduces emulation for the Intel 82576 adapter, AKA igb. | ||
4 | The details of the device will be provided by the documentation that | ||
5 | will follow this change. | ||
6 | |||
7 | This initial implementation of igb does not cover the full feature set, | ||
8 | but it selectively implements changes necessary to pass tests of Linut | ||
9 | Test Project, and Windows HLK. The below is the list of the implemented | ||
10 | changes; anything not listed here is not implemented: | ||
11 | |||
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 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
54 | --- | ||
55 | MAINTAINERS | 5 + | ||
56 | hw/net/Kconfig | 5 + | ||
57 | hw/net/igb.c | 615 ++++++++ | ||
58 | hw/net/igb_common.h | 146 ++ | ||
59 | hw/net/igb_core.c | 4077 +++++++++++++++++++++++++++++++++++++++++++++++++++ | ||
60 | hw/net/igb_core.h | 146 ++ | ||
61 | hw/net/igb_regs.h | 648 ++++++++ | ||
62 | hw/net/igbvf.c | 327 +++++ | ||
63 | hw/net/meson.build | 2 + | ||
64 | hw/net/trace-events | 32 + | ||
65 | 10 files changed, 6003 insertions(+) | ||
66 | create mode 100644 hw/net/igb.c | ||
67 | create mode 100644 hw/net/igb_common.h | ||
68 | create mode 100644 hw/net/igb_core.c | ||
69 | create mode 100644 hw/net/igb_core.h | ||
70 | create mode 100644 hw/net/igb_regs.h | ||
71 | create mode 100644 hw/net/igbvf.c | ||
72 | |||
73 | diff --git a/MAINTAINERS b/MAINTAINERS | ||
74 | index XXXXXXX..XXXXXXX 100644 | ||
75 | --- a/MAINTAINERS | ||
76 | +++ b/MAINTAINERS | ||
77 | @@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-e1000e-test.c | ||
78 | F: tests/qtest/e1000e-test.c | ||
79 | F: tests/qtest/libqos/e1000e.* | ||
80 | |||
81 | +igb | ||
82 | +M: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
83 | +S: Maintained | ||
84 | +F: hw/net/igb* | ||
85 | + | ||
86 | eepro100 | ||
87 | M: Stefan Weil <sw@weilnetz.de> | ||
88 | S: Maintained | ||
89 | diff --git a/hw/net/Kconfig b/hw/net/Kconfig | ||
90 | index XXXXXXX..XXXXXXX 100644 | ||
91 | --- a/hw/net/Kconfig | ||
92 | +++ b/hw/net/Kconfig | ||
93 | @@ -XXX,XX +XXX,XX @@ config E1000E_PCI_EXPRESS | ||
94 | default y if PCI_DEVICES | ||
95 | depends on PCI_EXPRESS && MSI_NONBROKEN | ||
96 | |||
97 | +config IGB_PCI_EXPRESS | ||
98 | + bool | ||
99 | + default y if PCI_DEVICES | ||
100 | + depends on PCI_EXPRESS && MSI_NONBROKEN | ||
101 | + | ||
102 | config RTL8139_PCI | ||
103 | bool | ||
104 | default y if PCI_DEVICES | ||
105 | diff --git a/hw/net/igb.c b/hw/net/igb.c | ||
106 | new file mode 100644 | ||
107 | index XXXXXXX..XXXXXXX | ||
108 | --- /dev/null | ||
109 | +++ b/hw/net/igb.c | ||
110 | @@ -XXX,XX +XXX,XX @@ | ||
111 | +/* | ||
112 | + * QEMU Intel 82576 SR/IOV Ethernet Controller Emulation | ||
113 | + * | ||
114 | + * Datasheet: | ||
115 | + * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82576eg-gbe-datasheet.pdf | ||
116 | + * | ||
117 | + * Copyright (c) 2020-2023 Red Hat, Inc. | ||
118 | + * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) | ||
119 | + * Developed by Daynix Computing LTD (http://www.daynix.com) | ||
120 | + * | ||
121 | + * Authors: | ||
122 | + * Akihiko Odaki <akihiko.odaki@daynix.com> | ||
123 | + * Gal Hammmer <gal.hammer@sap.com> | ||
124 | + * Marcel Apfelbaum <marcel.apfelbaum@gmail.com> | ||
125 | + * Dmitry Fleytman <dmitry@daynix.com> | ||
126 | + * Leonid Bloch <leonid@daynix.com> | ||
127 | + * Yan Vugenfirer <yan@daynix.com> | ||
128 | + * | ||
129 | + * Based on work done by: | ||
130 | + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. | ||
131 | + * Copyright (c) 2008 Qumranet | ||
132 | + * Based on work done by: | ||
133 | + * Copyright (c) 2007 Dan Aloni | ||
134 | + * Copyright (c) 2004 Antony T Curtis | ||
135 | + * | ||
136 | + * This library is free software; you can redistribute it and/or | ||
137 | + * modify it under the terms of the GNU Lesser General Public | ||
138 | + * License as published by the Free Software Foundation; either | ||
139 | + * version 2.1 of the License, or (at your option) any later version. | ||
140 | + * | ||
141 | + * This library is distributed in the hope that it will be useful, | ||
142 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
143 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
144 | + * Lesser General Public License for more details. | ||
145 | + * | ||
146 | + * You should have received a copy of the GNU Lesser General Public | ||
147 | + * License along with this library; if not, see <http://www.gnu.org/licenses/>. | ||
148 | + */ | ||
149 | + | ||
150 | +#include "qemu/osdep.h" | ||
151 | +#include "qemu/units.h" | ||
152 | +#include "net/eth.h" | ||
153 | +#include "net/net.h" | ||
154 | +#include "net/tap.h" | ||
155 | +#include "qemu/module.h" | ||
156 | +#include "qemu/range.h" | ||
157 | +#include "sysemu/sysemu.h" | ||
158 | +#include "hw/hw.h" | ||
159 | +#include "hw/net/mii.h" | ||
160 | +#include "hw/pci/pci.h" | ||
161 | +#include "hw/pci/pcie.h" | ||
162 | +#include "hw/pci/pcie_sriov.h" | ||
163 | +#include "hw/pci/msi.h" | ||
164 | +#include "hw/pci/msix.h" | ||
165 | +#include "hw/qdev-properties.h" | ||
166 | +#include "migration/vmstate.h" | ||
167 | + | ||
168 | +#include "igb_common.h" | ||
169 | +#include "igb_core.h" | ||
170 | + | ||
171 | +#include "trace.h" | ||
172 | +#include "qapi/error.h" | ||
173 | +#include "qom/object.h" | ||
174 | + | ||
175 | +#define TYPE_IGB "igb" | ||
176 | +OBJECT_DECLARE_SIMPLE_TYPE(IGBState, IGB) | ||
177 | + | ||
178 | +struct IGBState { | ||
179 | + PCIDevice parent_obj; | ||
180 | + NICState *nic; | ||
181 | + NICConf conf; | ||
182 | + | ||
183 | + MemoryRegion mmio; | ||
184 | + MemoryRegion flash; | ||
185 | + MemoryRegion io; | ||
186 | + MemoryRegion msix; | ||
187 | + | ||
188 | + uint32_t ioaddr; | ||
189 | + | ||
190 | + IGBCore core; | ||
191 | +}; | ||
192 | + | ||
193 | +#define IGB_CAP_SRIOV_OFFSET (0x160) | ||
194 | +#define IGB_VF_OFFSET (0x80) | ||
195 | +#define IGB_VF_STRIDE (2) | ||
196 | + | ||
197 | +#define E1000E_MMIO_IDX 0 | ||
198 | +#define E1000E_FLASH_IDX 1 | ||
199 | +#define E1000E_IO_IDX 2 | ||
200 | +#define E1000E_MSIX_IDX 3 | ||
201 | + | ||
202 | +#define E1000E_MMIO_SIZE (128 * KiB) | ||
203 | +#define E1000E_FLASH_SIZE (128 * KiB) | ||
204 | +#define E1000E_IO_SIZE (32) | ||
205 | +#define E1000E_MSIX_SIZE (16 * KiB) | ||
206 | + | ||
207 | +static void igb_write_config(PCIDevice *dev, uint32_t addr, | ||
208 | + uint32_t val, int len) | ||
209 | +{ | ||
210 | + IGBState *s = IGB(dev); | ||
211 | + | ||
212 | + trace_igb_write_config(addr, val, len); | ||
213 | + pci_default_write_config(dev, addr, val, len); | ||
214 | + | ||
215 | + if (range_covers_byte(addr, len, PCI_COMMAND) && | ||
216 | + (dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) { | ||
217 | + igb_start_recv(&s->core); | ||
218 | + } | ||
219 | +} | ||
220 | + | ||
221 | +uint64_t | ||
222 | +igb_mmio_read(void *opaque, hwaddr addr, unsigned size) | ||
223 | +{ | ||
224 | + IGBState *s = opaque; | ||
225 | + return igb_core_read(&s->core, addr, size); | ||
226 | +} | ||
227 | + | ||
228 | +void | ||
229 | +igb_mmio_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) | ||
230 | +{ | ||
231 | + IGBState *s = opaque; | ||
232 | + igb_core_write(&s->core, addr, val, size); | ||
233 | +} | ||
234 | + | ||
235 | +static bool | ||
236 | +igb_io_get_reg_index(IGBState *s, uint32_t *idx) | ||
237 | +{ | ||
238 | + if (s->ioaddr < 0x1FFFF) { | ||
239 | + *idx = s->ioaddr; | ||
240 | + return true; | ||
241 | + } | ||
242 | + | ||
243 | + if (s->ioaddr < 0x7FFFF) { | ||
244 | + trace_e1000e_wrn_io_addr_undefined(s->ioaddr); | ||
245 | + return false; | ||
246 | + } | ||
247 | + | ||
248 | + if (s->ioaddr < 0xFFFFF) { | ||
249 | + trace_e1000e_wrn_io_addr_flash(s->ioaddr); | ||
250 | + return false; | ||
251 | + } | ||
252 | + | ||
253 | + trace_e1000e_wrn_io_addr_unknown(s->ioaddr); | ||
254 | + return false; | ||
255 | +} | ||
256 | + | ||
257 | +static uint64_t | ||
258 | +igb_io_read(void *opaque, hwaddr addr, unsigned size) | ||
259 | +{ | ||
260 | + IGBState *s = opaque; | ||
261 | + uint32_t idx = 0; | ||
262 | + uint64_t val; | ||
263 | + | ||
264 | + switch (addr) { | ||
265 | + case E1000_IOADDR: | ||
266 | + trace_e1000e_io_read_addr(s->ioaddr); | ||
267 | + return s->ioaddr; | ||
268 | + case E1000_IODATA: | ||
269 | + if (igb_io_get_reg_index(s, &idx)) { | ||
270 | + val = igb_core_read(&s->core, idx, sizeof(val)); | ||
271 | + trace_e1000e_io_read_data(idx, val); | ||
272 | + return val; | ||
273 | + } | ||
274 | + return 0; | ||
275 | + default: | ||
276 | + trace_e1000e_wrn_io_read_unknown(addr); | ||
277 | + return 0; | ||
278 | + } | ||
279 | +} | ||
280 | + | ||
281 | +static void | ||
282 | +igb_io_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) | ||
283 | +{ | ||
284 | + IGBState *s = opaque; | ||
285 | + uint32_t idx = 0; | ||
286 | + | ||
287 | + switch (addr) { | ||
288 | + case E1000_IOADDR: | ||
289 | + trace_e1000e_io_write_addr(val); | ||
290 | + s->ioaddr = (uint32_t) val; | ||
291 | + return; | ||
292 | + case E1000_IODATA: | ||
293 | + if (igb_io_get_reg_index(s, &idx)) { | ||
294 | + trace_e1000e_io_write_data(idx, val); | ||
295 | + igb_core_write(&s->core, idx, val, sizeof(val)); | ||
296 | + } | ||
297 | + return; | ||
298 | + default: | ||
299 | + trace_e1000e_wrn_io_write_unknown(addr); | ||
300 | + return; | ||
301 | + } | ||
302 | +} | ||
303 | + | ||
304 | +static const MemoryRegionOps mmio_ops = { | ||
305 | + .read = igb_mmio_read, | ||
306 | + .write = igb_mmio_write, | ||
307 | + .endianness = DEVICE_LITTLE_ENDIAN, | ||
308 | + .impl = { | ||
309 | + .min_access_size = 4, | ||
310 | + .max_access_size = 4, | ||
311 | + }, | ||
312 | +}; | ||
313 | + | ||
314 | +static const MemoryRegionOps io_ops = { | ||
315 | + .read = igb_io_read, | ||
316 | + .write = igb_io_write, | ||
317 | + .endianness = DEVICE_LITTLE_ENDIAN, | ||
318 | + .impl = { | ||
319 | + .min_access_size = 4, | ||
320 | + .max_access_size = 4, | ||
321 | + }, | ||
322 | +}; | ||
323 | + | ||
324 | +static bool | ||
325 | +igb_nc_can_receive(NetClientState *nc) | ||
326 | +{ | ||
327 | + IGBState *s = qemu_get_nic_opaque(nc); | ||
328 | + return igb_can_receive(&s->core); | ||
329 | +} | ||
330 | + | ||
331 | +static ssize_t | ||
332 | +igb_nc_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt) | ||
333 | +{ | ||
334 | + IGBState *s = qemu_get_nic_opaque(nc); | ||
335 | + return igb_receive_iov(&s->core, iov, iovcnt); | ||
336 | +} | ||
337 | + | ||
338 | +static ssize_t | ||
339 | +igb_nc_receive(NetClientState *nc, const uint8_t *buf, size_t size) | ||
340 | +{ | ||
341 | + IGBState *s = qemu_get_nic_opaque(nc); | ||
342 | + return igb_receive(&s->core, buf, size); | ||
343 | +} | ||
344 | + | ||
345 | +static void | ||
346 | +igb_set_link_status(NetClientState *nc) | ||
347 | +{ | ||
348 | + IGBState *s = qemu_get_nic_opaque(nc); | ||
349 | + igb_core_set_link_status(&s->core); | ||
350 | +} | ||
351 | + | ||
352 | +static NetClientInfo net_igb_info = { | ||
353 | + .type = NET_CLIENT_DRIVER_NIC, | ||
354 | + .size = sizeof(NICState), | ||
355 | + .can_receive = igb_nc_can_receive, | ||
356 | + .receive = igb_nc_receive, | ||
357 | + .receive_iov = igb_nc_receive_iov, | ||
358 | + .link_status_changed = igb_set_link_status, | ||
359 | +}; | ||
360 | + | ||
361 | +/* | ||
362 | + * EEPROM (NVM) contents documented in section 6.1, table 6-1: | ||
363 | + * and in 6.10 Software accessed words. | ||
364 | + */ | ||
365 | +static const uint16_t igb_eeprom_template[] = { | ||
366 | + /* Address |Compat.|OEM sp.| ImRev | OEM sp. */ | ||
367 | + 0x0000, 0x0000, 0x0000, 0x0d34, 0xffff, 0x2010, 0xffff, 0xffff, | ||
368 | + /* PBA |ICtrl1 | SSID | SVID | DevID |-------|ICtrl2 */ | ||
369 | + 0x1040, 0xffff, 0x002b, 0x0000, 0x8086, 0x10c9, 0x0000, 0x70c3, | ||
370 | + /* SwPin0| DevID | EESZ |-------|ICtrl3 |PCI-tc | MSIX | APtr */ | ||
371 | + 0x0004, 0x10c9, 0x5c00, 0x0000, 0x2880, 0x0014, 0x4a40, 0x0060, | ||
372 | + /* PCIe Init. Conf 1,2,3 |PCICtrl| LD1,3 |DDevID |DevRev | LD0,2 */ | ||
373 | + 0x6cfb, 0xc7b0, 0x0abe, 0x0403, 0x0783, 0x10a6, 0x0001, 0x0602, | ||
374 | + /* SwPin1| FunC |LAN-PWR|ManHwC |ICtrl3 | IOVct |VDevID |-------*/ | ||
375 | + 0x0004, 0x0020, 0x0000, 0x004a, 0x2080, 0x00f5, 0x10ca, 0x0000, | ||
376 | + /*---------------| LD1,3 | LD0,2 | ROEnd | ROSta | Wdog | VPD */ | ||
377 | + 0x0000, 0x0000, 0x4784, 0x4602, 0x0000, 0x0000, 0x1000, 0xffff, | ||
378 | + /* PCSet0| Ccfg0 |PXEver |IBAcap |PCSet1 | Ccfg1 |iSCVer | ?? */ | ||
379 | + 0x0100, 0x4000, 0x131f, 0x4013, 0x0100, 0x4000, 0xffff, 0xffff, | ||
380 | + /* PCSet2| Ccfg2 |PCSet3 | Ccfg3 | ?? |AltMacP| ?? |CHKSUM */ | ||
381 | + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x00e0, 0xffff, 0x0000, | ||
382 | + /* NC-SIC */ | ||
383 | + 0x0003, | ||
384 | +}; | ||
385 | + | ||
386 | +static void igb_core_realize(IGBState *s) | ||
387 | +{ | ||
388 | + s->core.owner = &s->parent_obj; | ||
389 | + s->core.owner_nic = s->nic; | ||
390 | +} | ||
391 | + | ||
392 | +static void | ||
393 | +igb_init_msix(IGBState *s) | ||
394 | +{ | ||
395 | + int i; | ||
396 | + | ||
397 | + msix_init(PCI_DEVICE(s), IGB_MSIX_VEC_NUM, | ||
398 | + &s->msix, | ||
399 | + E1000E_MSIX_IDX, 0, | ||
400 | + &s->msix, | ||
401 | + E1000E_MSIX_IDX, 0x2000, | ||
402 | + 0x70, &error_abort); | ||
403 | + | ||
404 | + for (i = 0; i < IGB_MSIX_VEC_NUM; i++) { | ||
405 | + msix_vector_use(PCI_DEVICE(s), i); | ||
406 | + } | ||
407 | +} | ||
408 | + | ||
409 | +static void | ||
410 | +igb_cleanup_msix(IGBState *s) | ||
411 | +{ | ||
412 | + msix_unuse_all_vectors(PCI_DEVICE(s)); | ||
413 | + msix_uninit(PCI_DEVICE(s), &s->msix, &s->msix); | ||
414 | +} | ||
415 | + | ||
416 | +static void | ||
417 | +igb_init_net_peer(IGBState *s, PCIDevice *pci_dev, uint8_t *macaddr) | ||
418 | +{ | ||
419 | + DeviceState *dev = DEVICE(pci_dev); | ||
420 | + NetClientState *nc; | ||
421 | + int i; | ||
422 | + | ||
423 | + s->nic = qemu_new_nic(&net_igb_info, &s->conf, | ||
424 | + object_get_typename(OBJECT(s)), dev->id, s); | ||
425 | + | ||
426 | + s->core.max_queue_num = s->conf.peers.queues ? s->conf.peers.queues - 1 : 0; | ||
427 | + | ||
428 | + trace_e1000e_mac_set_permanent(MAC_ARG(macaddr)); | ||
429 | + memcpy(s->core.permanent_mac, macaddr, sizeof(s->core.permanent_mac)); | ||
430 | + | ||
431 | + qemu_format_nic_info_str(qemu_get_queue(s->nic), macaddr); | ||
432 | + | ||
433 | + /* Setup virtio headers */ | ||
434 | + for (i = 0; i < s->conf.peers.queues; i++) { | ||
435 | + nc = qemu_get_subqueue(s->nic, i); | ||
436 | + if (!nc->peer || !qemu_has_vnet_hdr(nc->peer)) { | ||
437 | + trace_e1000e_cfg_support_virtio(false); | ||
438 | + return; | ||
439 | + } | ||
440 | + } | ||
441 | + | ||
442 | + trace_e1000e_cfg_support_virtio(true); | ||
443 | + s->core.has_vnet = true; | ||
444 | + | ||
445 | + for (i = 0; i < s->conf.peers.queues; i++) { | ||
446 | + nc = qemu_get_subqueue(s->nic, i); | ||
447 | + qemu_set_vnet_hdr_len(nc->peer, sizeof(struct virtio_net_hdr)); | ||
448 | + qemu_using_vnet_hdr(nc->peer, true); | ||
449 | + } | ||
450 | +} | ||
451 | + | ||
452 | +static int | ||
453 | +igb_add_pm_capability(PCIDevice *pdev, uint8_t offset, uint16_t pmc) | ||
454 | +{ | ||
455 | + Error *local_err = NULL; | ||
456 | + int ret = pci_add_capability(pdev, PCI_CAP_ID_PM, offset, | ||
457 | + PCI_PM_SIZEOF, &local_err); | ||
458 | + | ||
459 | + if (local_err) { | ||
460 | + error_report_err(local_err); | ||
461 | + return ret; | ||
462 | + } | ||
463 | + | ||
464 | + pci_set_word(pdev->config + offset + PCI_PM_PMC, | ||
465 | + PCI_PM_CAP_VER_1_1 | | ||
466 | + pmc); | ||
467 | + | ||
468 | + pci_set_word(pdev->wmask + offset + PCI_PM_CTRL, | ||
469 | + PCI_PM_CTRL_STATE_MASK | | ||
470 | + PCI_PM_CTRL_PME_ENABLE | | ||
471 | + PCI_PM_CTRL_DATA_SEL_MASK); | ||
472 | + | ||
473 | + pci_set_word(pdev->w1cmask + offset + PCI_PM_CTRL, | ||
474 | + PCI_PM_CTRL_PME_STATUS); | ||
475 | + | ||
476 | + return ret; | ||
477 | +} | ||
478 | + | ||
479 | +static void igb_pci_realize(PCIDevice *pci_dev, Error **errp) | ||
480 | +{ | ||
481 | + IGBState *s = IGB(pci_dev); | ||
482 | + uint8_t *macaddr; | ||
483 | + | ||
484 | + trace_e1000e_cb_pci_realize(); | ||
485 | + | ||
486 | + pci_dev->config_write = igb_write_config; | ||
487 | + | ||
488 | + pci_dev->config[PCI_CACHE_LINE_SIZE] = 0x10; | ||
489 | + pci_dev->config[PCI_INTERRUPT_PIN] = 1; | ||
490 | + | ||
491 | + /* Define IO/MMIO regions */ | ||
492 | + memory_region_init_io(&s->mmio, OBJECT(s), &mmio_ops, s, | ||
493 | + "igb-mmio", E1000E_MMIO_SIZE); | ||
494 | + pci_register_bar(pci_dev, E1000E_MMIO_IDX, | ||
495 | + PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio); | ||
496 | + | ||
497 | + /* | ||
498 | + * We provide a dummy implementation for the flash BAR | ||
499 | + * for drivers that may theoretically probe for its presence. | ||
500 | + */ | ||
501 | + memory_region_init(&s->flash, OBJECT(s), | ||
502 | + "igb-flash", E1000E_FLASH_SIZE); | ||
503 | + pci_register_bar(pci_dev, E1000E_FLASH_IDX, | ||
504 | + PCI_BASE_ADDRESS_SPACE_MEMORY, &s->flash); | ||
505 | + | ||
506 | + memory_region_init_io(&s->io, OBJECT(s), &io_ops, s, | ||
507 | + "igb-io", E1000E_IO_SIZE); | ||
508 | + pci_register_bar(pci_dev, E1000E_IO_IDX, | ||
509 | + PCI_BASE_ADDRESS_SPACE_IO, &s->io); | ||
510 | + | ||
511 | + memory_region_init(&s->msix, OBJECT(s), "igb-msix", | ||
512 | + E1000E_MSIX_SIZE); | ||
513 | + pci_register_bar(pci_dev, E1000E_MSIX_IDX, | ||
514 | + PCI_BASE_ADDRESS_MEM_TYPE_64, &s->msix); | ||
515 | + | ||
516 | + /* Create networking backend */ | ||
517 | + qemu_macaddr_default_if_unset(&s->conf.macaddr); | ||
518 | + macaddr = s->conf.macaddr.a; | ||
519 | + | ||
520 | + /* Add PCI capabilities in reverse order */ | ||
521 | + assert(pcie_endpoint_cap_init(pci_dev, 0xa0) > 0); | ||
522 | + | ||
523 | + igb_init_msix(s); | ||
524 | + | ||
525 | + msi_init(pci_dev, 0x50, 1, true, true, &error_abort); | ||
526 | + | ||
527 | + if (igb_add_pm_capability(pci_dev, 0x40, PCI_PM_CAP_DSI) < 0) { | ||
528 | + hw_error("Failed to initialize PM capability"); | ||
529 | + } | ||
530 | + | ||
531 | + /* PCIe extended capabilities (in order) */ | ||
532 | + if (pcie_aer_init(pci_dev, 1, 0x100, 0x40, errp) < 0) { | ||
533 | + hw_error("Failed to initialize AER capability"); | ||
534 | + } | ||
535 | + | ||
536 | + pcie_ari_init(pci_dev, 0x150, 1); | ||
537 | + | ||
538 | + pcie_sriov_pf_init(pci_dev, IGB_CAP_SRIOV_OFFSET, "igbvf", | ||
539 | + IGB_82576_VF_DEV_ID, IGB_MAX_VF_FUNCTIONS, IGB_MAX_VF_FUNCTIONS, | ||
540 | + IGB_VF_OFFSET, IGB_VF_STRIDE); | ||
541 | + | ||
542 | + pcie_sriov_pf_init_vf_bar(pci_dev, 0, | ||
543 | + PCI_BASE_ADDRESS_MEM_TYPE_64 | PCI_BASE_ADDRESS_MEM_PREFETCH, | ||
544 | + 16 * KiB); | ||
545 | + pcie_sriov_pf_init_vf_bar(pci_dev, 3, | ||
546 | + PCI_BASE_ADDRESS_MEM_TYPE_64 | PCI_BASE_ADDRESS_MEM_PREFETCH, | ||
547 | + 16 * KiB); | ||
548 | + | ||
549 | + igb_init_net_peer(s, pci_dev, macaddr); | ||
550 | + | ||
551 | + /* Initialize core */ | ||
552 | + igb_core_realize(s); | ||
553 | + | ||
554 | + igb_core_pci_realize(&s->core, | ||
555 | + igb_eeprom_template, | ||
556 | + sizeof(igb_eeprom_template), | ||
557 | + macaddr); | ||
558 | +} | ||
559 | + | ||
560 | +static void igb_pci_uninit(PCIDevice *pci_dev) | ||
561 | +{ | ||
562 | + IGBState *s = IGB(pci_dev); | ||
563 | + | ||
564 | + trace_e1000e_cb_pci_uninit(); | ||
565 | + | ||
566 | + igb_core_pci_uninit(&s->core); | ||
567 | + | ||
568 | + pcie_sriov_pf_exit(pci_dev); | ||
569 | + pcie_cap_exit(pci_dev); | ||
570 | + | ||
571 | + qemu_del_nic(s->nic); | ||
572 | + | ||
573 | + igb_cleanup_msix(s); | ||
574 | + msi_uninit(pci_dev); | ||
575 | +} | ||
576 | + | ||
577 | +static void igb_qdev_reset_hold(Object *obj) | ||
578 | +{ | ||
579 | + PCIDevice *d = PCI_DEVICE(obj); | ||
580 | + IGBState *s = IGB(obj); | ||
581 | + | ||
582 | + trace_e1000e_cb_qdev_reset_hold(); | ||
583 | + | ||
584 | + pcie_sriov_pf_disable_vfs(d); | ||
585 | + igb_core_reset(&s->core); | ||
586 | +} | ||
587 | + | ||
588 | +static int igb_pre_save(void *opaque) | ||
589 | +{ | ||
590 | + IGBState *s = opaque; | ||
591 | + | ||
592 | + trace_e1000e_cb_pre_save(); | ||
593 | + | ||
594 | + igb_core_pre_save(&s->core); | ||
595 | + | ||
596 | + return 0; | ||
597 | +} | ||
598 | + | ||
599 | +static int igb_post_load(void *opaque, int version_id) | ||
600 | +{ | ||
601 | + IGBState *s = opaque; | ||
602 | + | ||
603 | + trace_e1000e_cb_post_load(); | ||
604 | + return igb_core_post_load(&s->core); | ||
605 | +} | ||
606 | + | ||
607 | +static const VMStateDescription igb_vmstate_tx = { | ||
608 | + .name = "igb-tx", | ||
609 | + .version_id = 1, | ||
610 | + .minimum_version_id = 1, | ||
611 | + .fields = (VMStateField[]) { | ||
612 | + VMSTATE_UINT16(vlan, struct igb_tx), | ||
613 | + VMSTATE_UINT16(mss, struct igb_tx), | ||
614 | + VMSTATE_BOOL(tse, struct igb_tx), | ||
615 | + VMSTATE_BOOL(ixsm, struct igb_tx), | ||
616 | + VMSTATE_BOOL(txsm, struct igb_tx), | ||
617 | + VMSTATE_BOOL(first, struct igb_tx), | ||
618 | + VMSTATE_BOOL(skip_cp, struct igb_tx), | ||
619 | + VMSTATE_END_OF_LIST() | ||
620 | + } | ||
621 | +}; | ||
622 | + | ||
623 | +static const VMStateDescription igb_vmstate_intr_timer = { | ||
624 | + .name = "igb-intr-timer", | ||
625 | + .version_id = 1, | ||
626 | + .minimum_version_id = 1, | ||
627 | + .fields = (VMStateField[]) { | ||
628 | + VMSTATE_TIMER_PTR(timer, IGBIntrDelayTimer), | ||
629 | + VMSTATE_BOOL(running, IGBIntrDelayTimer), | ||
630 | + VMSTATE_END_OF_LIST() | ||
631 | + } | ||
632 | +}; | ||
633 | + | ||
634 | +#define VMSTATE_IGB_INTR_DELAY_TIMER(_f, _s) \ | ||
635 | + VMSTATE_STRUCT(_f, _s, 0, \ | ||
636 | + igb_vmstate_intr_timer, IGBIntrDelayTimer) | ||
637 | + | ||
638 | +#define VMSTATE_IGB_INTR_DELAY_TIMER_ARRAY(_f, _s, _num) \ | ||
639 | + VMSTATE_STRUCT_ARRAY(_f, _s, _num, 0, \ | ||
640 | + igb_vmstate_intr_timer, IGBIntrDelayTimer) | ||
641 | + | ||
642 | +static const VMStateDescription igb_vmstate = { | ||
643 | + .name = "igb", | ||
644 | + .version_id = 1, | ||
645 | + .minimum_version_id = 1, | ||
646 | + .pre_save = igb_pre_save, | ||
647 | + .post_load = igb_post_load, | ||
648 | + .fields = (VMStateField[]) { | ||
649 | + VMSTATE_PCI_DEVICE(parent_obj, IGBState), | ||
650 | + VMSTATE_MSIX(parent_obj, IGBState), | ||
651 | + | ||
652 | + VMSTATE_UINT32(ioaddr, IGBState), | ||
653 | + VMSTATE_UINT8(core.rx_desc_len, IGBState), | ||
654 | + VMSTATE_UINT16_ARRAY(core.eeprom, IGBState, IGB_EEPROM_SIZE), | ||
655 | + VMSTATE_UINT16_ARRAY(core.phy, IGBState, MAX_PHY_REG_ADDRESS + 1), | ||
656 | + VMSTATE_UINT32_ARRAY(core.mac, IGBState, E1000E_MAC_SIZE), | ||
657 | + VMSTATE_UINT8_ARRAY(core.permanent_mac, IGBState, ETH_ALEN), | ||
658 | + | ||
659 | + VMSTATE_IGB_INTR_DELAY_TIMER_ARRAY(core.eitr, IGBState, | ||
660 | + IGB_INTR_NUM), | ||
661 | + | ||
662 | + VMSTATE_UINT32_ARRAY(core.eitr_guest_value, IGBState, IGB_INTR_NUM), | ||
663 | + | ||
664 | + VMSTATE_STRUCT_ARRAY(core.tx, IGBState, IGB_NUM_QUEUES, 0, | ||
665 | + igb_vmstate_tx, struct igb_tx), | ||
666 | + | ||
667 | + VMSTATE_INT64(core.timadj, IGBState), | ||
668 | + | ||
669 | + VMSTATE_END_OF_LIST() | ||
670 | + } | ||
671 | +}; | ||
672 | + | ||
673 | +static Property igb_properties[] = { | ||
674 | + DEFINE_NIC_PROPERTIES(IGBState, conf), | ||
675 | + DEFINE_PROP_END_OF_LIST(), | ||
676 | +}; | ||
677 | + | ||
678 | +static void igb_class_init(ObjectClass *class, void *data) | ||
679 | +{ | ||
680 | + DeviceClass *dc = DEVICE_CLASS(class); | ||
681 | + ResettableClass *rc = RESETTABLE_CLASS(class); | ||
682 | + PCIDeviceClass *c = PCI_DEVICE_CLASS(class); | ||
683 | + | ||
684 | + c->realize = igb_pci_realize; | ||
685 | + c->exit = igb_pci_uninit; | ||
686 | + c->vendor_id = PCI_VENDOR_ID_INTEL; | ||
687 | + c->device_id = E1000_DEV_ID_82576; | ||
688 | + c->revision = 1; | ||
689 | + c->class_id = PCI_CLASS_NETWORK_ETHERNET; | ||
690 | + | ||
691 | + rc->phases.hold = igb_qdev_reset_hold; | ||
692 | + | ||
693 | + dc->desc = "Intel 82576 Gigabit Ethernet Controller"; | ||
694 | + dc->vmsd = &igb_vmstate; | ||
695 | + | ||
696 | + device_class_set_props(dc, igb_properties); | ||
697 | + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); | ||
698 | +} | ||
699 | + | ||
700 | +static void igb_instance_init(Object *obj) | ||
701 | +{ | ||
702 | + IGBState *s = IGB(obj); | ||
703 | + device_add_bootindex_property(obj, &s->conf.bootindex, | ||
704 | + "bootindex", "/ethernet-phy@0", | ||
705 | + DEVICE(obj)); | ||
706 | +} | ||
707 | + | ||
708 | +static const TypeInfo igb_info = { | ||
709 | + .name = TYPE_IGB, | ||
710 | + .parent = TYPE_PCI_DEVICE, | ||
711 | + .instance_size = sizeof(IGBState), | ||
712 | + .class_init = igb_class_init, | ||
713 | + .instance_init = igb_instance_init, | ||
714 | + .interfaces = (InterfaceInfo[]) { | ||
715 | + { INTERFACE_PCIE_DEVICE }, | ||
716 | + { } | ||
717 | + }, | ||
718 | +}; | ||
719 | + | ||
720 | +static void igb_register_types(void) | ||
721 | +{ | ||
722 | + type_register_static(&igb_info); | ||
723 | +} | ||
724 | + | ||
725 | +type_init(igb_register_types) | ||
726 | diff --git a/hw/net/igb_common.h b/hw/net/igb_common.h | ||
727 | new file mode 100644 | ||
728 | index XXXXXXX..XXXXXXX | ||
729 | --- /dev/null | ||
730 | +++ b/hw/net/igb_common.h | ||
731 | @@ -XXX,XX +XXX,XX @@ | ||
732 | +/* | ||
733 | + * QEMU igb emulation - shared definitions | ||
734 | + * | ||
735 | + * Copyright (c) 2020-2023 Red Hat, Inc. | ||
736 | + * Copyright (c) 2008 Qumranet | ||
737 | + * | ||
738 | + * Based on work done by: | ||
739 | + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. | ||
740 | + * Copyright (c) 2007 Dan Aloni | ||
741 | + * Copyright (c) 2004 Antony T Curtis | ||
742 | + * | ||
743 | + * This library is free software; you can redistribute it and/or | ||
744 | + * modify it under the terms of the GNU Lesser General Public | ||
745 | + * License as published by the Free Software Foundation; either | ||
746 | + * version 2.1 of the License, or (at your option) any later version. | ||
747 | + * | ||
748 | + * This library is distributed in the hope that it will be useful, | ||
749 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
750 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
751 | + * Lesser General Public License for more details. | ||
752 | + * | ||
753 | + * You should have received a copy of the GNU Lesser General Public | ||
754 | + * License along with this library; if not, see <http://www.gnu.org/licenses/>. | ||
755 | + */ | ||
756 | + | ||
757 | +#ifndef HW_NET_IGB_COMMON_H | ||
758 | +#define HW_NET_IGB_COMMON_H | ||
759 | + | ||
760 | +#include "igb_regs.h" | ||
761 | + | ||
762 | +#define defreg(x) x = (E1000_##x >> 2) | ||
763 | +#define defreg_indexed(x, i) x##i = (E1000_##x(i) >> 2) | ||
764 | +#define defreg_indexeda(x, i) x##i##_A = (E1000_##x##_A(i) >> 2) | ||
765 | + | ||
766 | +#define defregd(x) defreg_indexed(x, 0), defreg_indexed(x, 1), \ | ||
767 | + defreg_indexed(x, 2), defreg_indexed(x, 3), \ | ||
768 | + defreg_indexed(x, 4), defreg_indexed(x, 5), \ | ||
769 | + defreg_indexed(x, 6), defreg_indexed(x, 7), \ | ||
770 | + defreg_indexed(x, 8), defreg_indexed(x, 9), \ | ||
771 | + defreg_indexed(x, 10), defreg_indexed(x, 11), \ | ||
772 | + defreg_indexed(x, 12), defreg_indexed(x, 13), \ | ||
773 | + defreg_indexed(x, 14), defreg_indexed(x, 15), \ | ||
774 | + defreg_indexeda(x, 0), defreg_indexeda(x, 1), \ | ||
775 | + defreg_indexeda(x, 2), defreg_indexeda(x, 3) | ||
776 | + | ||
777 | +#define defregv(x) defreg_indexed(x, 0), defreg_indexed(x, 1), \ | ||
778 | + defreg_indexed(x, 2), defreg_indexed(x, 3), \ | ||
779 | + defreg_indexed(x, 4), defreg_indexed(x, 5), \ | ||
780 | + defreg_indexed(x, 6), defreg_indexed(x, 7) | ||
781 | + | ||
782 | +enum { | ||
783 | + defreg(CTRL), defreg(EECD), defreg(EERD), defreg(GPRC), | ||
784 | + defreg(GPTC), defreg(ICR), defreg(ICS), defreg(IMC), | ||
785 | + defreg(IMS), defreg(LEDCTL), defreg(MANC), defreg(MDIC), | ||
786 | + defreg(MPC), defreg(RCTL), | ||
787 | + defreg(STATUS), defreg(SWSM), defreg(TCTL), | ||
788 | + defreg(TORH), defreg(TORL), defreg(TOTH), | ||
789 | + defreg(TOTL), defreg(TPR), defreg(TPT), | ||
790 | + defreg(WUFC), defreg(RA), defreg(MTA), defreg(CRCERRS), | ||
791 | + defreg(VFTA), defreg(VET), | ||
792 | + defreg(SCC), defreg(ECOL), | ||
793 | + defreg(MCC), defreg(LATECOL), defreg(COLC), defreg(DC), | ||
794 | + defreg(TNCRS), defreg(RLEC), | ||
795 | + defreg(XONRXC), defreg(XONTXC), defreg(XOFFRXC), defreg(XOFFTXC), | ||
796 | + defreg(FCRUC), defreg(TDFH), defreg(TDFT), | ||
797 | + defreg(TDFHS), defreg(TDFTS), defreg(TDFPC), defreg(WUC), | ||
798 | + defreg(WUS), defreg(RDFH), | ||
799 | + defreg(RDFT), defreg(RDFHS), defreg(RDFTS), defreg(RDFPC), | ||
800 | + defreg(IPAV), defreg(IP4AT), defreg(IP6AT), | ||
801 | + defreg(WUPM), defreg(FFMT), | ||
802 | + defreg(IAM), | ||
803 | + defreg(GCR), defreg(TIMINCA), defreg(EIAC), defreg(CTRL_EXT), | ||
804 | + defreg(IVAR0), defreg(MANC2H), | ||
805 | + defreg(MFVAL), defreg(MDEF), defreg(FACTPS), defreg(FTFT), | ||
806 | + defreg(RUC), defreg(ROC), defreg(RFC), defreg(RJC), | ||
807 | + defreg(PRC64), defreg(PRC127), defreg(PRC255), defreg(PRC511), | ||
808 | + defreg(PRC1023), defreg(PRC1522), defreg(PTC64), defreg(PTC127), | ||
809 | + defreg(PTC255), defreg(PTC511), defreg(PTC1023), defreg(PTC1522), | ||
810 | + defreg(GORCL), defreg(GORCH), defreg(GOTCL), defreg(GOTCH), | ||
811 | + defreg(RNBC), defreg(BPRC), defreg(MPRC), defreg(RFCTL), | ||
812 | + defreg(MPTC), defreg(BPTC), | ||
813 | + defreg(IAC), defreg(MGTPRC), defreg(MGTPDC), defreg(MGTPTC), | ||
814 | + defreg(TSCTC), defreg(RXCSUM), defreg(FUNCTAG), defreg(GSCL_1), | ||
815 | + defreg(GSCL_2), defreg(GSCL_3), defreg(GSCL_4), defreg(GSCN_0), | ||
816 | + defreg(GSCN_1), defreg(GSCN_2), defreg(GSCN_3), | ||
817 | + defreg_indexed(EITR, 0), | ||
818 | + defreg(MRQC), defreg(RETA), defreg(RSSRK), | ||
819 | + defreg(PBACLR), defreg(FCAL), defreg(FCAH), defreg(FCT), | ||
820 | + defreg(FCRTH), defreg(FCRTL), defreg(FCTTV), defreg(FCRTV), | ||
821 | + defreg(FLA), defreg(FLOP), | ||
822 | + defreg(MAVTV0), defreg(MAVTV1), defreg(MAVTV2), defreg(MAVTV3), | ||
823 | + defreg(TXSTMPL), defreg(TXSTMPH), defreg(SYSTIML), defreg(SYSTIMH), | ||
824 | + defreg(TIMADJL), defreg(TIMADJH), | ||
825 | + defreg(RXSTMPH), defreg(RXSTMPL), defreg(RXSATRL), defreg(RXSATRH), | ||
826 | + defreg(TIPG), | ||
827 | + defreg(CTRL_DUP), | ||
828 | + defreg(EEMNGCTL), | ||
829 | + defreg(EEMNGDATA), | ||
830 | + defreg(FLMNGCTL), | ||
831 | + defreg(FLMNGDATA), | ||
832 | + defreg(FLMNGCNT), | ||
833 | + defreg(TSYNCRXCTL), | ||
834 | + defreg(TSYNCTXCTL), | ||
835 | + defreg(RLPML), | ||
836 | + defreg(UTA), | ||
837 | + | ||
838 | + /* Aliases */ | ||
839 | + defreg(RDFH_A), defreg(RDFT_A), defreg(TDFH_A), defreg(TDFT_A), | ||
840 | + defreg(RA_A), defreg(VFTA_A), defreg(FCRTL_A), | ||
841 | + | ||
842 | + /* Additional regs used by IGB */ | ||
843 | + defreg(FWSM), defreg(SW_FW_SYNC), | ||
844 | + | ||
845 | + defreg(EICS), defreg(EIMS), defreg(EIMC), defreg(EIAM), | ||
846 | + defreg(EICR), defreg(IVAR_MISC), defreg(GPIE), | ||
847 | + | ||
848 | + defreg(RXPBS), defregd(RDBAL), defregd(RDBAH), defregd(RDLEN), | ||
849 | + defregd(SRRCTL), defregd(RDH), defregd(RDT), | ||
850 | + defregd(RXDCTL), defregd(RXCTL), defregd(RQDPC), defreg(RA2), | ||
851 | + | ||
852 | + defreg(TXPBS), defreg(TCTL_EXT), defreg(DTXCTL), defreg(HTCBDPC), | ||
853 | + defregd(TDBAL), defregd(TDBAH), defregd(TDLEN), defregd(TDH), | ||
854 | + defregd(TDT), defregd(TXDCTL), defregd(TXCTL), | ||
855 | + defregd(TDWBAL), defregd(TDWBAH), | ||
856 | + | ||
857 | + defreg(VT_CTL), | ||
858 | + | ||
859 | + defregv(P2VMAILBOX), defregv(V2PMAILBOX), defreg(MBVFICR), defreg(MBVFIMR), | ||
860 | + defreg(VFLRE), defreg(VFRE), defreg(VFTE), defreg(WVBR), | ||
861 | + defreg(QDE), defreg(DTXSWC), defreg_indexed(VLVF, 0), | ||
862 | + defregv(VMOLR), defreg(RPLOLR), defregv(VMBMEM), defregv(VMVIR), | ||
863 | + | ||
864 | + defregv(PVTCTRL), defregv(PVTEICS), defregv(PVTEIMS), defregv(PVTEIMC), | ||
865 | + defregv(PVTEIAC), defregv(PVTEIAM), defregv(PVTEICR), defregv(PVFGPRC), | ||
866 | + defregv(PVFGPTC), defregv(PVFGORC), defregv(PVFGOTC), defregv(PVFMPRC), | ||
867 | + defregv(PVFGPRLBC), defregv(PVFGPTLBC), defregv(PVFGORLBC), defregv(PVFGOTLBC), | ||
868 | + | ||
869 | + defreg(MTA_A), | ||
870 | + | ||
871 | + defreg(VTIVAR), defreg(VTIVAR_MISC), | ||
872 | +}; | ||
873 | + | ||
874 | +uint64_t igb_mmio_read(void *opaque, hwaddr addr, unsigned size); | ||
875 | +void igb_mmio_write(void *opaque, hwaddr addr, uint64_t val, unsigned size); | ||
876 | + | ||
877 | +#endif | ||
878 | diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c | ||
879 | new file mode 100644 | ||
880 | index XXXXXXX..XXXXXXX | ||
881 | --- /dev/null | ||
882 | +++ b/hw/net/igb_core.c | ||
883 | @@ -XXX,XX +XXX,XX @@ | ||
884 | +/* | ||
885 | + * Core code for QEMU igb emulation | ||
886 | + * | ||
887 | + * Datasheet: | ||
888 | + * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82576eg-gbe-datasheet.pdf | ||
889 | + * | ||
890 | + * Copyright (c) 2020-2023 Red Hat, Inc. | ||
891 | + * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) | ||
892 | + * Developed by Daynix Computing LTD (http://www.daynix.com) | ||
893 | + * | ||
894 | + * Authors: | ||
895 | + * Akihiko Odaki <akihiko.odaki@daynix.com> | ||
896 | + * Gal Hammmer <gal.hammer@sap.com> | ||
897 | + * Marcel Apfelbaum <marcel.apfelbaum@gmail.com> | ||
898 | + * Dmitry Fleytman <dmitry@daynix.com> | ||
899 | + * Leonid Bloch <leonid@daynix.com> | ||
900 | + * Yan Vugenfirer <yan@daynix.com> | ||
901 | + * | ||
902 | + * Based on work done by: | ||
903 | + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. | ||
904 | + * Copyright (c) 2008 Qumranet | ||
905 | + * Based on work done by: | ||
906 | + * Copyright (c) 2007 Dan Aloni | ||
907 | + * Copyright (c) 2004 Antony T Curtis | ||
908 | + * | ||
909 | + * This library is free software; you can redistribute it and/or | ||
910 | + * modify it under the terms of the GNU Lesser General Public | ||
911 | + * License as published by the Free Software Foundation; either | ||
912 | + * version 2.1 of the License, or (at your option) any later version. | ||
913 | + * | ||
914 | + * This library is distributed in the hope that it will be useful, | ||
915 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
916 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
917 | + * Lesser General Public License for more details. | ||
918 | + * | ||
919 | + * You should have received a copy of the GNU Lesser General Public | ||
920 | + * License along with this library; if not, see <http://www.gnu.org/licenses/>. | ||
921 | + */ | ||
922 | + | ||
923 | +#include "qemu/osdep.h" | ||
924 | +#include "qemu/log.h" | ||
925 | +#include "net/net.h" | ||
926 | +#include "net/tap.h" | ||
927 | +#include "hw/net/mii.h" | ||
928 | +#include "hw/pci/msi.h" | ||
929 | +#include "hw/pci/msix.h" | ||
930 | +#include "sysemu/runstate.h" | ||
931 | + | ||
932 | +#include "net_tx_pkt.h" | ||
933 | +#include "net_rx_pkt.h" | ||
934 | + | ||
935 | +#include "igb_common.h" | ||
936 | +#include "e1000x_common.h" | ||
937 | +#include "igb_core.h" | ||
938 | + | ||
939 | +#include "trace.h" | ||
940 | + | ||
941 | +#define E1000E_MAX_TX_FRAGS (64) | ||
942 | + | ||
943 | +union e1000_rx_desc_union { | ||
944 | + struct e1000_rx_desc legacy; | ||
945 | + union e1000_adv_rx_desc adv; | ||
946 | +}; | ||
947 | + | ||
948 | +typedef struct IGBTxPktVmdqCallbackContext { | ||
949 | + IGBCore *core; | ||
950 | + NetClientState *nc; | ||
951 | +} IGBTxPktVmdqCallbackContext; | ||
952 | + | ||
953 | +static ssize_t | ||
954 | +igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt, | ||
955 | + bool has_vnet, bool *external_tx); | ||
956 | + | ||
957 | +static inline void | ||
958 | +igb_set_interrupt_cause(IGBCore *core, uint32_t val); | ||
959 | + | ||
960 | +static void igb_update_interrupt_state(IGBCore *core); | ||
961 | +static void igb_reset(IGBCore *core, bool sw); | ||
962 | + | ||
963 | +static inline void | ||
964 | +igb_raise_legacy_irq(IGBCore *core) | ||
965 | +{ | ||
966 | + trace_e1000e_irq_legacy_notify(true); | ||
967 | + e1000x_inc_reg_if_not_full(core->mac, IAC); | ||
968 | + pci_set_irq(core->owner, 1); | ||
969 | +} | ||
970 | + | ||
971 | +static inline void | ||
972 | +igb_lower_legacy_irq(IGBCore *core) | ||
973 | +{ | ||
974 | + trace_e1000e_irq_legacy_notify(false); | ||
975 | + pci_set_irq(core->owner, 0); | ||
976 | +} | ||
977 | + | ||
978 | +static void igb_msix_notify(IGBCore *core, unsigned int vector) | ||
979 | +{ | ||
980 | + PCIDevice *dev = core->owner; | ||
981 | + uint16_t vfn; | ||
982 | + | ||
983 | + vfn = 8 - (vector + 2) / IGBVF_MSIX_VEC_NUM; | ||
984 | + if (vfn < pcie_sriov_num_vfs(core->owner)) { | ||
985 | + dev = pcie_sriov_get_vf_at_index(core->owner, vfn); | ||
986 | + assert(dev); | ||
987 | + vector = (vector + 2) % IGBVF_MSIX_VEC_NUM; | ||
988 | + } else if (vector >= IGB_MSIX_VEC_NUM) { | ||
989 | + qemu_log_mask(LOG_GUEST_ERROR, | ||
990 | + "igb: Tried to use vector unavailable for PF"); | ||
991 | + return; | ||
992 | + } | ||
993 | + | ||
994 | + msix_notify(dev, vector); | ||
995 | +} | ||
996 | + | ||
997 | +static inline void | ||
998 | +igb_intrmgr_rearm_timer(IGBIntrDelayTimer *timer) | ||
999 | +{ | ||
1000 | + int64_t delay_ns = (int64_t) timer->core->mac[timer->delay_reg] * | ||
1001 | + timer->delay_resolution_ns; | ||
1002 | + | ||
1003 | + trace_e1000e_irq_rearm_timer(timer->delay_reg << 2, delay_ns); | ||
1004 | + | ||
1005 | + timer_mod(timer->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + delay_ns); | ||
1006 | + | ||
1007 | + timer->running = true; | ||
1008 | +} | ||
1009 | + | ||
1010 | +static void | ||
1011 | +igb_intmgr_timer_resume(IGBIntrDelayTimer *timer) | ||
1012 | +{ | ||
1013 | + if (timer->running) { | ||
1014 | + igb_intrmgr_rearm_timer(timer); | ||
1015 | + } | ||
1016 | +} | ||
1017 | + | ||
1018 | +static void | ||
1019 | +igb_intmgr_timer_pause(IGBIntrDelayTimer *timer) | ||
1020 | +{ | ||
1021 | + if (timer->running) { | ||
1022 | + timer_del(timer->timer); | ||
1023 | + } | ||
1024 | +} | ||
1025 | + | ||
1026 | +static void | ||
1027 | +igb_intrmgr_on_msix_throttling_timer(void *opaque) | ||
1028 | +{ | ||
1029 | + IGBIntrDelayTimer *timer = opaque; | ||
1030 | + int idx = timer - &timer->core->eitr[0]; | ||
1031 | + | ||
1032 | + timer->running = false; | ||
1033 | + | ||
1034 | + trace_e1000e_irq_msix_notify_postponed_vec(idx); | ||
1035 | + igb_msix_notify(timer->core, idx); | ||
1036 | +} | ||
1037 | + | ||
1038 | +static void | ||
1039 | +igb_intrmgr_initialize_all_timers(IGBCore *core, bool create) | ||
1040 | +{ | ||
1041 | + int i; | ||
1042 | + | ||
1043 | + for (i = 0; i < IGB_INTR_NUM; i++) { | ||
1044 | + core->eitr[i].core = core; | ||
1045 | + core->eitr[i].delay_reg = EITR0 + i; | ||
1046 | + core->eitr[i].delay_resolution_ns = E1000_INTR_DELAY_NS_RES; | ||
1047 | + } | ||
1048 | + | ||
1049 | + if (!create) { | ||
1050 | + return; | ||
1051 | + } | ||
1052 | + | ||
1053 | + for (i = 0; i < IGB_INTR_NUM; i++) { | ||
1054 | + core->eitr[i].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, | ||
1055 | + igb_intrmgr_on_msix_throttling_timer, | ||
1056 | + &core->eitr[i]); | ||
1057 | + } | ||
1058 | +} | ||
1059 | + | ||
1060 | +static void | ||
1061 | +igb_intrmgr_resume(IGBCore *core) | ||
1062 | +{ | ||
1063 | + int i; | ||
1064 | + | ||
1065 | + for (i = 0; i < IGB_INTR_NUM; i++) { | ||
1066 | + igb_intmgr_timer_resume(&core->eitr[i]); | ||
1067 | + } | ||
1068 | +} | ||
1069 | + | ||
1070 | +static void | ||
1071 | +igb_intrmgr_pause(IGBCore *core) | ||
1072 | +{ | ||
1073 | + int i; | ||
1074 | + | ||
1075 | + for (i = 0; i < IGB_INTR_NUM; i++) { | ||
1076 | + igb_intmgr_timer_pause(&core->eitr[i]); | ||
1077 | + } | ||
1078 | +} | ||
1079 | + | ||
1080 | +static void | ||
1081 | +igb_intrmgr_reset(IGBCore *core) | ||
1082 | +{ | ||
1083 | + int i; | ||
1084 | + | ||
1085 | + for (i = 0; i < IGB_INTR_NUM; i++) { | ||
1086 | + if (core->eitr[i].running) { | ||
1087 | + timer_del(core->eitr[i].timer); | ||
1088 | + igb_intrmgr_on_msix_throttling_timer(&core->eitr[i]); | ||
1089 | + } | ||
1090 | + } | ||
1091 | +} | ||
1092 | + | ||
1093 | +static void | ||
1094 | +igb_intrmgr_pci_unint(IGBCore *core) | ||
1095 | +{ | ||
1096 | + int i; | ||
1097 | + | ||
1098 | + for (i = 0; i < IGB_INTR_NUM; i++) { | ||
1099 | + timer_free(core->eitr[i].timer); | ||
1100 | + } | ||
1101 | +} | ||
1102 | + | ||
1103 | +static void | ||
1104 | +igb_intrmgr_pci_realize(IGBCore *core) | ||
1105 | +{ | ||
1106 | + igb_intrmgr_initialize_all_timers(core, true); | ||
1107 | +} | ||
1108 | + | ||
1109 | +static inline bool | ||
1110 | +igb_rx_csum_enabled(IGBCore *core) | ||
1111 | +{ | ||
1112 | + return (core->mac[RXCSUM] & E1000_RXCSUM_PCSD) ? false : true; | ||
1113 | +} | ||
1114 | + | ||
1115 | +static inline bool | ||
1116 | +igb_rx_use_legacy_descriptor(IGBCore *core) | ||
1117 | +{ | ||
1118 | + /* | ||
1119 | + * TODO: If SRRCTL[n],DESCTYPE = 000b, the 82576 uses the legacy Rx | ||
1120 | + * descriptor. | ||
1121 | + */ | ||
1122 | + return false; | ||
1123 | +} | ||
1124 | + | ||
1125 | +static inline bool | ||
1126 | +igb_rss_enabled(IGBCore *core) | ||
1127 | +{ | ||
1128 | + return (core->mac[MRQC] & 3) == E1000_MRQC_ENABLE_RSS_MQ && | ||
1129 | + !igb_rx_csum_enabled(core) && | ||
1130 | + !igb_rx_use_legacy_descriptor(core); | ||
1131 | +} | ||
1132 | + | ||
1133 | +typedef struct E1000E_RSSInfo_st { | ||
1134 | + bool enabled; | ||
1135 | + uint32_t hash; | ||
1136 | + uint32_t queue; | ||
1137 | + uint32_t type; | ||
1138 | +} E1000E_RSSInfo; | ||
1139 | + | ||
1140 | +static uint32_t | ||
1141 | +igb_rss_get_hash_type(IGBCore *core, struct NetRxPkt *pkt) | ||
1142 | +{ | ||
1143 | + bool hasip4, hasip6; | ||
1144 | + EthL4HdrProto l4hdr_proto; | ||
1145 | + | ||
1146 | + assert(igb_rss_enabled(core)); | ||
1147 | + | ||
1148 | + net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto); | ||
1149 | + | ||
1150 | + if (hasip4) { | ||
1151 | + trace_e1000e_rx_rss_ip4(l4hdr_proto, core->mac[MRQC], | ||
1152 | + E1000_MRQC_EN_TCPIPV4(core->mac[MRQC]), | ||
1153 | + E1000_MRQC_EN_IPV4(core->mac[MRQC])); | ||
1154 | + | ||
1155 | + if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP && | ||
1156 | + E1000_MRQC_EN_TCPIPV4(core->mac[MRQC])) { | ||
1157 | + return E1000_MRQ_RSS_TYPE_IPV4TCP; | ||
1158 | + } | ||
1159 | + | ||
1160 | + if (E1000_MRQC_EN_IPV4(core->mac[MRQC])) { | ||
1161 | + return E1000_MRQ_RSS_TYPE_IPV4; | ||
1162 | + } | ||
1163 | + } else if (hasip6) { | ||
1164 | + eth_ip6_hdr_info *ip6info = net_rx_pkt_get_ip6_info(pkt); | ||
1165 | + | ||
1166 | + bool ex_dis = core->mac[RFCTL] & E1000_RFCTL_IPV6_EX_DIS; | ||
1167 | + bool new_ex_dis = core->mac[RFCTL] & E1000_RFCTL_NEW_IPV6_EXT_DIS; | ||
1168 | + | ||
1169 | + /* | ||
1170 | + * Following two traces must not be combined because resulting | ||
1171 | + * event will have 11 arguments totally and some trace backends | ||
1172 | + * (at least "ust") have limitation of maximum 10 arguments per | ||
1173 | + * event. Events with more arguments fail to compile for | ||
1174 | + * backends like these. | ||
1175 | + */ | ||
1176 | + trace_e1000e_rx_rss_ip6_rfctl(core->mac[RFCTL]); | ||
1177 | + trace_e1000e_rx_rss_ip6(ex_dis, new_ex_dis, l4hdr_proto, | ||
1178 | + ip6info->has_ext_hdrs, | ||
1179 | + ip6info->rss_ex_dst_valid, | ||
1180 | + ip6info->rss_ex_src_valid, | ||
1181 | + core->mac[MRQC], | ||
1182 | + E1000_MRQC_EN_TCPIPV6(core->mac[MRQC]), | ||
1183 | + E1000_MRQC_EN_IPV6EX(core->mac[MRQC]), | ||
1184 | + E1000_MRQC_EN_IPV6(core->mac[MRQC])); | ||
1185 | + | ||
1186 | + if ((!ex_dis || !ip6info->has_ext_hdrs) && | ||
1187 | + (!new_ex_dis || !(ip6info->rss_ex_dst_valid || | ||
1188 | + ip6info->rss_ex_src_valid))) { | ||
1189 | + | ||
1190 | + if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP && | ||
1191 | + E1000_MRQC_EN_TCPIPV6(core->mac[MRQC])) { | ||
1192 | + return E1000_MRQ_RSS_TYPE_IPV6TCP; | ||
1193 | + } | ||
1194 | + | ||
1195 | + if (E1000_MRQC_EN_IPV6EX(core->mac[MRQC])) { | ||
1196 | + return E1000_MRQ_RSS_TYPE_IPV6EX; | ||
1197 | + } | ||
1198 | + | ||
1199 | + } | ||
1200 | + | ||
1201 | + if (E1000_MRQC_EN_IPV6(core->mac[MRQC])) { | ||
1202 | + return E1000_MRQ_RSS_TYPE_IPV6; | ||
1203 | + } | ||
1204 | + | ||
1205 | + } | ||
1206 | + | ||
1207 | + return E1000_MRQ_RSS_TYPE_NONE; | ||
1208 | +} | ||
1209 | + | ||
1210 | +static uint32_t | ||
1211 | +igb_rss_calc_hash(IGBCore *core, struct NetRxPkt *pkt, E1000E_RSSInfo *info) | ||
1212 | +{ | ||
1213 | + NetRxPktRssType type; | ||
1214 | + | ||
1215 | + assert(igb_rss_enabled(core)); | ||
1216 | + | ||
1217 | + switch (info->type) { | ||
1218 | + case E1000_MRQ_RSS_TYPE_IPV4: | ||
1219 | + type = NetPktRssIpV4; | ||
1220 | + break; | ||
1221 | + case E1000_MRQ_RSS_TYPE_IPV4TCP: | ||
1222 | + type = NetPktRssIpV4Tcp; | ||
1223 | + break; | ||
1224 | + case E1000_MRQ_RSS_TYPE_IPV6TCP: | ||
1225 | + type = NetPktRssIpV6TcpEx; | ||
1226 | + break; | ||
1227 | + case E1000_MRQ_RSS_TYPE_IPV6: | ||
1228 | + type = NetPktRssIpV6; | ||
1229 | + break; | ||
1230 | + case E1000_MRQ_RSS_TYPE_IPV6EX: | ||
1231 | + type = NetPktRssIpV6Ex; | ||
1232 | + break; | ||
1233 | + default: | ||
1234 | + assert(false); | ||
1235 | + return 0; | ||
1236 | + } | ||
1237 | + | ||
1238 | + return net_rx_pkt_calc_rss_hash(pkt, type, (uint8_t *) &core->mac[RSSRK]); | ||
1239 | +} | ||
1240 | + | ||
1241 | +static void | ||
1242 | +igb_rss_parse_packet(IGBCore *core, struct NetRxPkt *pkt, bool tx, | ||
1243 | + E1000E_RSSInfo *info) | ||
1244 | +{ | ||
1245 | + trace_e1000e_rx_rss_started(); | ||
1246 | + | ||
1247 | + if (tx || !igb_rss_enabled(core)) { | ||
1248 | + info->enabled = false; | ||
1249 | + info->hash = 0; | ||
1250 | + info->queue = 0; | ||
1251 | + info->type = 0; | ||
1252 | + trace_e1000e_rx_rss_disabled(); | ||
1253 | + return; | ||
1254 | + } | ||
1255 | + | ||
1256 | + info->enabled = true; | ||
1257 | + | ||
1258 | + info->type = igb_rss_get_hash_type(core, pkt); | ||
1259 | + | ||
1260 | + trace_e1000e_rx_rss_type(info->type); | ||
1261 | + | ||
1262 | + if (info->type == E1000_MRQ_RSS_TYPE_NONE) { | ||
1263 | + info->hash = 0; | ||
1264 | + info->queue = 0; | ||
1265 | + return; | ||
1266 | + } | ||
1267 | + | ||
1268 | + info->hash = igb_rss_calc_hash(core, pkt, info); | ||
1269 | + info->queue = E1000_RSS_QUEUE(&core->mac[RETA], info->hash); | ||
1270 | +} | ||
1271 | + | ||
1272 | +static bool | ||
1273 | +igb_setup_tx_offloads(IGBCore *core, struct igb_tx *tx) | ||
1274 | +{ | ||
1275 | + if (tx->tse) { | ||
1276 | + if (!net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->mss)) { | ||
1277 | + return false; | ||
1278 | + } | ||
1279 | + | ||
1280 | + net_tx_pkt_update_ip_checksums(tx->tx_pkt); | ||
1281 | + e1000x_inc_reg_if_not_full(core->mac, TSCTC); | ||
1282 | + return true; | ||
1283 | + } | ||
1284 | + | ||
1285 | + if (tx->txsm) { | ||
1286 | + if (!net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0)) { | ||
1287 | + return false; | ||
1288 | + } | ||
1289 | + } | ||
1290 | + | ||
1291 | + if (tx->ixsm) { | ||
1292 | + net_tx_pkt_update_ip_hdr_checksum(tx->tx_pkt); | ||
1293 | + } | ||
1294 | + | ||
1295 | + return true; | ||
1296 | +} | ||
1297 | + | ||
1298 | +static void igb_tx_pkt_mac_callback(void *core, | ||
1299 | + const struct iovec *iov, | ||
1300 | + int iovcnt, | ||
1301 | + const struct iovec *virt_iov, | ||
1302 | + int virt_iovcnt) | ||
1303 | +{ | ||
1304 | + igb_receive_internal(core, virt_iov, virt_iovcnt, true, NULL); | ||
1305 | +} | ||
1306 | + | ||
1307 | +static void igb_tx_pkt_vmdq_callback(void *opaque, | ||
1308 | + const struct iovec *iov, | ||
1309 | + int iovcnt, | ||
1310 | + const struct iovec *virt_iov, | ||
1311 | + int virt_iovcnt) | ||
1312 | +{ | ||
1313 | + IGBTxPktVmdqCallbackContext *context = opaque; | ||
1314 | + bool external_tx; | ||
1315 | + | ||
1316 | + igb_receive_internal(context->core, virt_iov, virt_iovcnt, true, | ||
1317 | + &external_tx); | ||
1318 | + | ||
1319 | + if (external_tx) { | ||
1320 | + if (context->core->has_vnet) { | ||
1321 | + qemu_sendv_packet(context->nc, virt_iov, virt_iovcnt); | ||
1322 | + } else { | ||
1323 | + qemu_sendv_packet(context->nc, iov, iovcnt); | ||
1324 | + } | ||
1325 | + } | ||
1326 | +} | ||
1327 | + | ||
1328 | +/* TX Packets Switching (7.10.3.6) */ | ||
1329 | +static bool igb_tx_pkt_switch(IGBCore *core, struct igb_tx *tx, | ||
1330 | + NetClientState *nc) | ||
1331 | +{ | ||
1332 | + IGBTxPktVmdqCallbackContext context; | ||
1333 | + | ||
1334 | + /* TX switching is only used to serve VM to VM traffic. */ | ||
1335 | + if (!(core->mac[MRQC] & 1)) { | ||
1336 | + goto send_out; | ||
1337 | + } | ||
1338 | + | ||
1339 | + /* TX switching requires DTXSWC.Loopback_en bit enabled. */ | ||
1340 | + if (!(core->mac[DTXSWC] & E1000_DTXSWC_VMDQ_LOOPBACK_EN)) { | ||
1341 | + goto send_out; | ||
1342 | + } | ||
1343 | + | ||
1344 | + context.core = core; | ||
1345 | + context.nc = nc; | ||
1346 | + | ||
1347 | + return net_tx_pkt_send_custom(tx->tx_pkt, false, | ||
1348 | + igb_tx_pkt_vmdq_callback, &context); | ||
1349 | + | ||
1350 | +send_out: | ||
1351 | + return net_tx_pkt_send(tx->tx_pkt, nc); | ||
1352 | +} | ||
1353 | + | ||
1354 | +static bool | ||
1355 | +igb_tx_pkt_send(IGBCore *core, struct igb_tx *tx, int queue_index) | ||
1356 | +{ | ||
1357 | + int target_queue = MIN(core->max_queue_num, queue_index); | ||
1358 | + NetClientState *queue = qemu_get_subqueue(core->owner_nic, target_queue); | ||
1359 | + | ||
1360 | + if (!igb_setup_tx_offloads(core, tx)) { | ||
1361 | + return false; | ||
1362 | + } | ||
1363 | + | ||
1364 | + net_tx_pkt_dump(tx->tx_pkt); | ||
1365 | + | ||
1366 | + if ((core->phy[MII_BMCR] & MII_BMCR_LOOPBACK) || | ||
1367 | + ((core->mac[RCTL] & E1000_RCTL_LBM_MAC) == E1000_RCTL_LBM_MAC)) { | ||
1368 | + return net_tx_pkt_send_custom(tx->tx_pkt, false, | ||
1369 | + igb_tx_pkt_mac_callback, core); | ||
1370 | + } else { | ||
1371 | + return igb_tx_pkt_switch(core, tx, queue); | ||
1372 | + } | ||
1373 | +} | ||
1374 | + | ||
1375 | +static void | ||
1376 | +igb_on_tx_done_update_stats(IGBCore *core, struct NetTxPkt *tx_pkt) | ||
1377 | +{ | ||
1378 | + static const int PTCregs[6] = { PTC64, PTC127, PTC255, PTC511, | ||
1379 | + PTC1023, PTC1522 }; | ||
1380 | + | ||
1381 | + size_t tot_len = net_tx_pkt_get_total_len(tx_pkt) + 4; | ||
1382 | + | ||
1383 | + e1000x_increase_size_stats(core->mac, PTCregs, tot_len); | ||
1384 | + e1000x_inc_reg_if_not_full(core->mac, TPT); | ||
1385 | + e1000x_grow_8reg_if_not_full(core->mac, TOTL, tot_len); | ||
1386 | + | ||
1387 | + switch (net_tx_pkt_get_packet_type(tx_pkt)) { | ||
1388 | + case ETH_PKT_BCAST: | ||
1389 | + e1000x_inc_reg_if_not_full(core->mac, BPTC); | ||
1390 | + break; | ||
1391 | + case ETH_PKT_MCAST: | ||
1392 | + e1000x_inc_reg_if_not_full(core->mac, MPTC); | ||
1393 | + break; | ||
1394 | + case ETH_PKT_UCAST: | ||
1395 | + break; | ||
1396 | + default: | ||
1397 | + g_assert_not_reached(); | ||
1398 | + } | ||
1399 | + | ||
1400 | + core->mac[GPTC] = core->mac[TPT]; | ||
1401 | + core->mac[GOTCL] = core->mac[TOTL]; | ||
1402 | + core->mac[GOTCH] = core->mac[TOTH]; | ||
1403 | +} | ||
1404 | + | ||
1405 | +static void | ||
1406 | +igb_process_tx_desc(IGBCore *core, | ||
1407 | + struct igb_tx *tx, | ||
1408 | + union e1000_adv_tx_desc *tx_desc, | ||
1409 | + int queue_index) | ||
1410 | +{ | ||
1411 | + struct e1000_adv_tx_context_desc *tx_ctx_desc; | ||
1412 | + uint32_t cmd_type_len; | ||
1413 | + uint32_t olinfo_status; | ||
1414 | + uint64_t buffer_addr; | ||
1415 | + uint16_t length; | ||
1416 | + | ||
1417 | + cmd_type_len = le32_to_cpu(tx_desc->read.cmd_type_len); | ||
1418 | + | ||
1419 | + if (cmd_type_len & E1000_ADVTXD_DCMD_DEXT) { | ||
1420 | + if ((cmd_type_len & E1000_ADVTXD_DTYP_DATA) == | ||
1421 | + E1000_ADVTXD_DTYP_DATA) { | ||
1422 | + /* advanced transmit data descriptor */ | ||
1423 | + if (tx->first) { | ||
1424 | + olinfo_status = le32_to_cpu(tx_desc->read.olinfo_status); | ||
1425 | + | ||
1426 | + tx->tse = !!(cmd_type_len & E1000_ADVTXD_DCMD_TSE); | ||
1427 | + tx->ixsm = !!(olinfo_status & E1000_ADVTXD_POTS_IXSM); | ||
1428 | + tx->txsm = !!(olinfo_status & E1000_ADVTXD_POTS_TXSM); | ||
1429 | + | ||
1430 | + tx->first = false; | ||
1431 | + } | ||
1432 | + } else if ((cmd_type_len & E1000_ADVTXD_DTYP_CTXT) == | ||
1433 | + E1000_ADVTXD_DTYP_CTXT) { | ||
1434 | + /* advanced transmit context descriptor */ | ||
1435 | + tx_ctx_desc = (struct e1000_adv_tx_context_desc *)tx_desc; | ||
1436 | + tx->vlan = le32_to_cpu(tx_ctx_desc->vlan_macip_lens) >> 16; | ||
1437 | + tx->mss = le32_to_cpu(tx_ctx_desc->mss_l4len_idx) >> 16; | ||
1438 | + return; | ||
1439 | + } else { | ||
1440 | + /* unknown descriptor type */ | ||
1441 | + return; | ||
1442 | + } | ||
1443 | + } else { | ||
1444 | + /* legacy descriptor */ | ||
1445 | + | ||
1446 | + /* TODO: Implement a support for legacy descriptors (7.2.2.1). */ | ||
1447 | + } | ||
1448 | + | ||
1449 | + buffer_addr = le64_to_cpu(tx_desc->read.buffer_addr); | ||
1450 | + length = cmd_type_len & 0xFFFF; | ||
1451 | + | ||
1452 | + if (!tx->skip_cp) { | ||
1453 | + if (!net_tx_pkt_add_raw_fragment(tx->tx_pkt, buffer_addr, length)) { | ||
1454 | + tx->skip_cp = true; | ||
1455 | + } | ||
1456 | + } | ||
1457 | + | ||
1458 | + if (cmd_type_len & E1000_TXD_CMD_EOP) { | ||
1459 | + if (!tx->skip_cp && net_tx_pkt_parse(tx->tx_pkt)) { | ||
1460 | + if (cmd_type_len & E1000_TXD_CMD_VLE) { | ||
1461 | + net_tx_pkt_setup_vlan_header_ex(tx->tx_pkt, tx->vlan, | ||
1462 | + core->mac[VET] & 0xffff); | ||
1463 | + } | ||
1464 | + if (igb_tx_pkt_send(core, tx, queue_index)) { | ||
1465 | + igb_on_tx_done_update_stats(core, tx->tx_pkt); | ||
1466 | + } | ||
1467 | + } | ||
1468 | + | ||
1469 | + tx->first = true; | ||
1470 | + tx->skip_cp = false; | ||
1471 | + net_tx_pkt_reset(tx->tx_pkt); | ||
1472 | + } | ||
1473 | +} | ||
1474 | + | ||
1475 | +static uint32_t igb_tx_wb_eic(IGBCore *core, int queue_idx) | ||
1476 | +{ | ||
1477 | + uint32_t n, ent = 0; | ||
1478 | + | ||
1479 | + n = igb_ivar_entry_tx(queue_idx); | ||
1480 | + ent = (core->mac[IVAR0 + n / 4] >> (8 * (n % 4))) & 0xff; | ||
1481 | + | ||
1482 | + return (ent & E1000_IVAR_VALID) ? BIT(ent & 0x1f) : 0; | ||
1483 | +} | ||
1484 | + | ||
1485 | +static uint32_t igb_rx_wb_eic(IGBCore *core, int queue_idx) | ||
1486 | +{ | ||
1487 | + uint32_t n, ent = 0; | ||
1488 | + | ||
1489 | + n = igb_ivar_entry_rx(queue_idx); | ||
1490 | + ent = (core->mac[IVAR0 + n / 4] >> (8 * (n % 4))) & 0xff; | ||
1491 | + | ||
1492 | + return (ent & E1000_IVAR_VALID) ? BIT(ent & 0x1f) : 0; | ||
1493 | +} | ||
1494 | + | ||
1495 | +typedef struct E1000E_RingInfo_st { | ||
1496 | + int dbah; | ||
1497 | + int dbal; | ||
1498 | + int dlen; | ||
1499 | + int dh; | ||
1500 | + int dt; | ||
1501 | + int idx; | ||
1502 | +} E1000E_RingInfo; | ||
1503 | + | ||
1504 | +static inline bool | ||
1505 | +igb_ring_empty(IGBCore *core, const E1000E_RingInfo *r) | ||
1506 | +{ | ||
1507 | + return core->mac[r->dh] == core->mac[r->dt] || | ||
1508 | + core->mac[r->dt] >= core->mac[r->dlen] / E1000_RING_DESC_LEN; | ||
1509 | +} | ||
1510 | + | ||
1511 | +static inline uint64_t | ||
1512 | +igb_ring_base(IGBCore *core, const E1000E_RingInfo *r) | ||
1513 | +{ | ||
1514 | + uint64_t bah = core->mac[r->dbah]; | ||
1515 | + uint64_t bal = core->mac[r->dbal]; | ||
1516 | + | ||
1517 | + return (bah << 32) + bal; | ||
1518 | +} | ||
1519 | + | ||
1520 | +static inline uint64_t | ||
1521 | +igb_ring_head_descr(IGBCore *core, const E1000E_RingInfo *r) | ||
1522 | +{ | ||
1523 | + return igb_ring_base(core, r) + E1000_RING_DESC_LEN * core->mac[r->dh]; | ||
1524 | +} | ||
1525 | + | ||
1526 | +static inline void | ||
1527 | +igb_ring_advance(IGBCore *core, const E1000E_RingInfo *r, uint32_t count) | ||
1528 | +{ | ||
1529 | + core->mac[r->dh] += count; | ||
1530 | + | ||
1531 | + if (core->mac[r->dh] * E1000_RING_DESC_LEN >= core->mac[r->dlen]) { | ||
1532 | + core->mac[r->dh] = 0; | ||
1533 | + } | ||
1534 | +} | ||
1535 | + | ||
1536 | +static inline uint32_t | ||
1537 | +igb_ring_free_descr_num(IGBCore *core, const E1000E_RingInfo *r) | ||
1538 | +{ | ||
1539 | + trace_e1000e_ring_free_space(r->idx, core->mac[r->dlen], | ||
1540 | + core->mac[r->dh], core->mac[r->dt]); | ||
1541 | + | ||
1542 | + if (core->mac[r->dh] <= core->mac[r->dt]) { | ||
1543 | + return core->mac[r->dt] - core->mac[r->dh]; | ||
1544 | + } | ||
1545 | + | ||
1546 | + if (core->mac[r->dh] > core->mac[r->dt]) { | ||
1547 | + return core->mac[r->dlen] / E1000_RING_DESC_LEN + | ||
1548 | + core->mac[r->dt] - core->mac[r->dh]; | ||
1549 | + } | ||
1550 | + | ||
1551 | + g_assert_not_reached(); | ||
1552 | + return 0; | ||
1553 | +} | ||
1554 | + | ||
1555 | +static inline bool | ||
1556 | +igb_ring_enabled(IGBCore *core, const E1000E_RingInfo *r) | ||
1557 | +{ | ||
1558 | + return core->mac[r->dlen] > 0; | ||
1559 | +} | ||
1560 | + | ||
1561 | +typedef struct IGB_TxRing_st { | ||
1562 | + const E1000E_RingInfo *i; | ||
1563 | + struct igb_tx *tx; | ||
1564 | +} IGB_TxRing; | ||
1565 | + | ||
1566 | +static inline int | ||
1567 | +igb_mq_queue_idx(int base_reg_idx, int reg_idx) | ||
1568 | +{ | ||
1569 | + return (reg_idx - base_reg_idx) / 16; | ||
1570 | +} | ||
1571 | + | ||
1572 | +static inline void | ||
1573 | +igb_tx_ring_init(IGBCore *core, IGB_TxRing *txr, int idx) | ||
1574 | +{ | ||
1575 | + static const E1000E_RingInfo i[IGB_NUM_QUEUES] = { | ||
1576 | + { TDBAH0, TDBAL0, TDLEN0, TDH0, TDT0, 0 }, | ||
1577 | + { TDBAH1, TDBAL1, TDLEN1, TDH1, TDT1, 1 }, | ||
1578 | + { TDBAH2, TDBAL2, TDLEN2, TDH2, TDT2, 2 }, | ||
1579 | + { TDBAH3, TDBAL3, TDLEN3, TDH3, TDT3, 3 }, | ||
1580 | + { TDBAH4, TDBAL4, TDLEN4, TDH4, TDT4, 4 }, | ||
1581 | + { TDBAH5, TDBAL5, TDLEN5, TDH5, TDT5, 5 }, | ||
1582 | + { TDBAH6, TDBAL6, TDLEN6, TDH6, TDT6, 6 }, | ||
1583 | + { TDBAH7, TDBAL7, TDLEN7, TDH7, TDT7, 7 }, | ||
1584 | + { TDBAH8, TDBAL8, TDLEN8, TDH8, TDT8, 8 }, | ||
1585 | + { TDBAH9, TDBAL9, TDLEN9, TDH9, TDT9, 9 }, | ||
1586 | + { TDBAH10, TDBAL10, TDLEN10, TDH10, TDT10, 10 }, | ||
1587 | + { TDBAH11, TDBAL11, TDLEN11, TDH11, TDT11, 11 }, | ||
1588 | + { TDBAH12, TDBAL12, TDLEN12, TDH12, TDT12, 12 }, | ||
1589 | + { TDBAH13, TDBAL13, TDLEN13, TDH13, TDT13, 13 }, | ||
1590 | + { TDBAH14, TDBAL14, TDLEN14, TDH14, TDT14, 14 }, | ||
1591 | + { TDBAH15, TDBAL15, TDLEN15, TDH15, TDT15, 15 } | ||
1592 | + }; | ||
1593 | + | ||
1594 | + assert(idx < ARRAY_SIZE(i)); | ||
1595 | + | ||
1596 | + txr->i = &i[idx]; | ||
1597 | + txr->tx = &core->tx[idx]; | ||
1598 | +} | ||
1599 | + | ||
1600 | +typedef struct E1000E_RxRing_st { | ||
1601 | + const E1000E_RingInfo *i; | ||
1602 | +} E1000E_RxRing; | ||
1603 | + | ||
1604 | +static inline void | ||
1605 | +igb_rx_ring_init(IGBCore *core, E1000E_RxRing *rxr, int idx) | ||
1606 | +{ | ||
1607 | + static const E1000E_RingInfo i[IGB_NUM_QUEUES] = { | ||
1608 | + { RDBAH0, RDBAL0, RDLEN0, RDH0, RDT0, 0 }, | ||
1609 | + { RDBAH1, RDBAL1, RDLEN1, RDH1, RDT1, 1 }, | ||
1610 | + { RDBAH2, RDBAL2, RDLEN2, RDH2, RDT2, 2 }, | ||
1611 | + { RDBAH3, RDBAL3, RDLEN3, RDH3, RDT3, 3 }, | ||
1612 | + { RDBAH4, RDBAL4, RDLEN4, RDH4, RDT4, 4 }, | ||
1613 | + { RDBAH5, RDBAL5, RDLEN5, RDH5, RDT5, 5 }, | ||
1614 | + { RDBAH6, RDBAL6, RDLEN6, RDH6, RDT6, 6 }, | ||
1615 | + { RDBAH7, RDBAL7, RDLEN7, RDH7, RDT7, 7 }, | ||
1616 | + { RDBAH8, RDBAL8, RDLEN8, RDH8, RDT8, 8 }, | ||
1617 | + { RDBAH9, RDBAL9, RDLEN9, RDH9, RDT9, 9 }, | ||
1618 | + { RDBAH10, RDBAL10, RDLEN10, RDH10, RDT10, 10 }, | ||
1619 | + { RDBAH11, RDBAL11, RDLEN11, RDH11, RDT11, 11 }, | ||
1620 | + { RDBAH12, RDBAL12, RDLEN12, RDH12, RDT12, 12 }, | ||
1621 | + { RDBAH13, RDBAL13, RDLEN13, RDH13, RDT13, 13 }, | ||
1622 | + { RDBAH14, RDBAL14, RDLEN14, RDH14, RDT14, 14 }, | ||
1623 | + { RDBAH15, RDBAL15, RDLEN15, RDH15, RDT15, 15 } | ||
1624 | + }; | ||
1625 | + | ||
1626 | + assert(idx < ARRAY_SIZE(i)); | ||
1627 | + | ||
1628 | + rxr->i = &i[idx]; | ||
1629 | +} | ||
1630 | + | ||
1631 | +static uint32_t | ||
1632 | +igb_txdesc_writeback(IGBCore *core, dma_addr_t base, | ||
1633 | + union e1000_adv_tx_desc *tx_desc, | ||
1634 | + const E1000E_RingInfo *txi) | ||
1635 | +{ | ||
1636 | + PCIDevice *d; | ||
1637 | + uint32_t cmd_type_len = le32_to_cpu(tx_desc->read.cmd_type_len); | ||
1638 | + uint64_t tdwba; | ||
1639 | + | ||
1640 | + tdwba = core->mac[E1000_TDWBAL(txi->idx) >> 2]; | ||
1641 | + tdwba |= (uint64_t)core->mac[E1000_TDWBAH(txi->idx) >> 2] << 32; | ||
1642 | + | ||
1643 | + if (!(cmd_type_len & E1000_TXD_CMD_RS)) { | ||
1644 | + return 0; | ||
1645 | + } | ||
1646 | + | ||
1647 | + d = pcie_sriov_get_vf_at_index(core->owner, txi->idx % 8); | ||
1648 | + if (!d) { | ||
1649 | + d = core->owner; | ||
1650 | + } | ||
1651 | + | ||
1652 | + if (tdwba & 1) { | ||
1653 | + uint32_t buffer = cpu_to_le32(core->mac[txi->dh]); | ||
1654 | + pci_dma_write(d, tdwba & ~3, &buffer, sizeof(buffer)); | ||
1655 | + } else { | ||
1656 | + uint32_t status = le32_to_cpu(tx_desc->wb.status) | E1000_TXD_STAT_DD; | ||
1657 | + | ||
1658 | + tx_desc->wb.status = cpu_to_le32(status); | ||
1659 | + pci_dma_write(d, base + offsetof(union e1000_adv_tx_desc, wb), | ||
1660 | + &tx_desc->wb, sizeof(tx_desc->wb)); | ||
1661 | + } | ||
1662 | + | ||
1663 | + return igb_tx_wb_eic(core, txi->idx); | ||
1664 | +} | ||
1665 | + | ||
1666 | +static void | ||
1667 | +igb_start_xmit(IGBCore *core, const IGB_TxRing *txr) | ||
1668 | +{ | ||
1669 | + PCIDevice *d; | ||
1670 | + dma_addr_t base; | ||
1671 | + union e1000_adv_tx_desc desc; | ||
1672 | + const E1000E_RingInfo *txi = txr->i; | ||
1673 | + uint32_t eic = 0; | ||
1674 | + | ||
1675 | + /* TODO: check if the queue itself is enabled too. */ | ||
1676 | + if (!(core->mac[TCTL] & E1000_TCTL_EN)) { | ||
1677 | + trace_e1000e_tx_disabled(); | ||
1678 | + return; | ||
1679 | + } | ||
1680 | + | ||
1681 | + d = pcie_sriov_get_vf_at_index(core->owner, txi->idx % 8); | ||
1682 | + if (!d) { | ||
1683 | + d = core->owner; | ||
1684 | + } | ||
1685 | + | ||
1686 | + while (!igb_ring_empty(core, txi)) { | ||
1687 | + base = igb_ring_head_descr(core, txi); | ||
1688 | + | ||
1689 | + pci_dma_read(d, base, &desc, sizeof(desc)); | ||
1690 | + | ||
1691 | + trace_e1000e_tx_descr((void *)(intptr_t)desc.read.buffer_addr, | ||
1692 | + desc.read.cmd_type_len, desc.wb.status); | ||
1693 | + | ||
1694 | + igb_process_tx_desc(core, txr->tx, &desc, txi->idx); | ||
1695 | + igb_ring_advance(core, txi, 1); | ||
1696 | + eic |= igb_txdesc_writeback(core, base, &desc, txi); | ||
1697 | + } | ||
1698 | + | ||
1699 | + if (eic) { | ||
1700 | + core->mac[EICR] |= eic; | ||
1701 | + igb_set_interrupt_cause(core, E1000_ICR_TXDW); | ||
1702 | + } | ||
1703 | +} | ||
1704 | + | ||
1705 | +static uint32_t | ||
1706 | +igb_rxbufsize(IGBCore *core, const E1000E_RingInfo *r) | ||
1707 | +{ | ||
1708 | + uint32_t srrctl = core->mac[E1000_SRRCTL(r->idx) >> 2]; | ||
1709 | + uint32_t bsizepkt = srrctl & E1000_SRRCTL_BSIZEPKT_MASK; | ||
1710 | + if (bsizepkt) { | ||
1711 | + return bsizepkt << E1000_SRRCTL_BSIZEPKT_SHIFT; | ||
1712 | + } | ||
1713 | + | ||
1714 | + return e1000x_rxbufsize(core->mac[RCTL]); | ||
1715 | +} | ||
1716 | + | ||
1717 | +static bool | ||
1718 | +igb_has_rxbufs(IGBCore *core, const E1000E_RingInfo *r, size_t total_size) | ||
1719 | +{ | ||
1720 | + uint32_t bufs = igb_ring_free_descr_num(core, r); | ||
1721 | + uint32_t bufsize = igb_rxbufsize(core, r); | ||
1722 | + | ||
1723 | + trace_e1000e_rx_has_buffers(r->idx, bufs, total_size, bufsize); | ||
1724 | + | ||
1725 | + return total_size <= bufs / (core->rx_desc_len / E1000_MIN_RX_DESC_LEN) * | ||
1726 | + bufsize; | ||
1727 | +} | ||
1728 | + | ||
1729 | +void | ||
1730 | +igb_start_recv(IGBCore *core) | ||
1731 | +{ | ||
1732 | + int i; | ||
1733 | + | ||
1734 | + trace_e1000e_rx_start_recv(); | ||
1735 | + | ||
1736 | + for (i = 0; i <= core->max_queue_num; i++) { | ||
1737 | + qemu_flush_queued_packets(qemu_get_subqueue(core->owner_nic, i)); | ||
1738 | + } | ||
1739 | +} | ||
1740 | + | ||
1741 | +bool | ||
1742 | +igb_can_receive(IGBCore *core) | ||
1743 | +{ | ||
1744 | + int i; | ||
1745 | + | ||
1746 | + if (!e1000x_rx_ready(core->owner, core->mac)) { | ||
1747 | + return false; | ||
1748 | + } | ||
1749 | + | ||
1750 | + for (i = 0; i < IGB_NUM_QUEUES; i++) { | ||
1751 | + E1000E_RxRing rxr; | ||
1752 | + | ||
1753 | + igb_rx_ring_init(core, &rxr, i); | ||
1754 | + if (igb_ring_enabled(core, rxr.i) && igb_has_rxbufs(core, rxr.i, 1)) { | ||
1755 | + trace_e1000e_rx_can_recv(); | ||
1756 | + return true; | ||
1757 | + } | ||
1758 | + } | ||
1759 | + | ||
1760 | + trace_e1000e_rx_can_recv_rings_full(); | ||
1761 | + return false; | ||
1762 | +} | ||
1763 | + | ||
1764 | +ssize_t | ||
1765 | +igb_receive(IGBCore *core, const uint8_t *buf, size_t size) | ||
1766 | +{ | ||
1767 | + const struct iovec iov = { | ||
1768 | + .iov_base = (uint8_t *)buf, | ||
1769 | + .iov_len = size | ||
1770 | + }; | ||
1771 | + | ||
1772 | + return igb_receive_iov(core, &iov, 1); | ||
1773 | +} | ||
1774 | + | ||
1775 | +static inline bool | ||
1776 | +igb_rx_l3_cso_enabled(IGBCore *core) | ||
1777 | +{ | ||
1778 | + return !!(core->mac[RXCSUM] & E1000_RXCSUM_IPOFLD); | ||
1779 | +} | ||
1780 | + | ||
1781 | +static inline bool | ||
1782 | +igb_rx_l4_cso_enabled(IGBCore *core) | ||
1783 | +{ | ||
1784 | + return !!(core->mac[RXCSUM] & E1000_RXCSUM_TUOFLD); | ||
1785 | +} | ||
1786 | + | ||
1787 | +static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr, | ||
1788 | + E1000E_RSSInfo *rss_info, bool *external_tx) | ||
1789 | +{ | ||
1790 | + static const int ta_shift[] = { 4, 3, 2, 0 }; | ||
1791 | + uint32_t f, ra[2], *macp, rctl = core->mac[RCTL]; | ||
1792 | + uint16_t queues = 0; | ||
1793 | + uint16_t vid = lduw_be_p(&PKT_GET_VLAN_HDR(ehdr)->h_tci) & VLAN_VID_MASK; | ||
1794 | + bool accepted = false; | ||
1795 | + int i; | ||
1796 | + | ||
1797 | + memset(rss_info, 0, sizeof(E1000E_RSSInfo)); | ||
1798 | + | ||
1799 | + if (external_tx) { | ||
1800 | + *external_tx = true; | ||
1801 | + } | ||
1802 | + | ||
1803 | + if (e1000x_is_vlan_packet(ehdr, core->mac[VET] & 0xffff) && | ||
1804 | + e1000x_vlan_rx_filter_enabled(core->mac)) { | ||
1805 | + uint32_t vfta = | ||
1806 | + ldl_le_p((uint32_t *)(core->mac + VFTA) + | ||
1807 | + ((vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK)); | ||
1808 | + if ((vfta & (1 << (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK))) == 0) { | ||
1809 | + trace_e1000e_rx_flt_vlan_mismatch(vid); | ||
1810 | + return queues; | ||
1811 | + } else { | ||
1812 | + trace_e1000e_rx_flt_vlan_match(vid); | ||
1813 | + } | ||
1814 | + } | ||
1815 | + | ||
1816 | + if (core->mac[MRQC] & 1) { | ||
1817 | + if (is_broadcast_ether_addr(ehdr->h_dest)) { | ||
1818 | + for (i = 0; i < 8; i++) { | ||
1819 | + if (core->mac[VMOLR0 + i] & E1000_VMOLR_BAM) { | ||
1820 | + queues |= BIT(i); | ||
1821 | + } | ||
1822 | + } | ||
1823 | + } else { | ||
1824 | + for (macp = core->mac + RA; macp < core->mac + RA + 32; macp += 2) { | ||
1825 | + if (!(macp[1] & E1000_RAH_AV)) { | ||
1826 | + continue; | ||
1827 | + } | ||
1828 | + ra[0] = cpu_to_le32(macp[0]); | ||
1829 | + ra[1] = cpu_to_le32(macp[1]); | ||
1830 | + if (!memcmp(ehdr->h_dest, (uint8_t *)ra, ETH_ALEN)) { | ||
1831 | + queues |= (macp[1] & E1000_RAH_POOL_MASK) / E1000_RAH_POOL_1; | ||
1832 | + } | ||
1833 | + } | ||
1834 | + | ||
1835 | + for (macp = core->mac + RA2; macp < core->mac + RA2 + 16; macp += 2) { | ||
1836 | + if (!(macp[1] & E1000_RAH_AV)) { | ||
1837 | + continue; | ||
1838 | + } | ||
1839 | + ra[0] = cpu_to_le32(macp[0]); | ||
1840 | + ra[1] = cpu_to_le32(macp[1]); | ||
1841 | + if (!memcmp(ehdr->h_dest, (uint8_t *)ra, ETH_ALEN)) { | ||
1842 | + queues |= (macp[1] & E1000_RAH_POOL_MASK) / E1000_RAH_POOL_1; | ||
1843 | + } | ||
1844 | + } | ||
1845 | + | ||
1846 | + if (!queues) { | ||
1847 | + macp = core->mac + (is_multicast_ether_addr(ehdr->h_dest) ? MTA : UTA); | ||
1848 | + | ||
1849 | + f = ta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3]; | ||
1850 | + f = (((ehdr->h_dest[5] << 8) | ehdr->h_dest[4]) >> f) & 0xfff; | ||
1851 | + if (macp[f >> 5] & (1 << (f & 0x1f))) { | ||
1852 | + for (i = 0; i < 8; i++) { | ||
1853 | + if (core->mac[VMOLR0 + i] & E1000_VMOLR_ROMPE) { | ||
1854 | + queues |= BIT(i); | ||
1855 | + } | ||
1856 | + } | ||
1857 | + } | ||
1858 | + } else if (is_unicast_ether_addr(ehdr->h_dest) && external_tx) { | ||
1859 | + *external_tx = false; | ||
1860 | + } | ||
1861 | + } | ||
1862 | + | ||
1863 | + if (e1000x_vlan_rx_filter_enabled(core->mac)) { | ||
1864 | + uint16_t mask = 0; | ||
1865 | + | ||
1866 | + if (e1000x_is_vlan_packet(ehdr, core->mac[VET] & 0xffff)) { | ||
1867 | + for (i = 0; i < E1000_VLVF_ARRAY_SIZE; i++) { | ||
1868 | + if ((core->mac[VLVF0 + i] & E1000_VLVF_VLANID_MASK) == vid && | ||
1869 | + (core->mac[VLVF0 + i] & E1000_VLVF_VLANID_ENABLE)) { | ||
1870 | + uint32_t poolsel = core->mac[VLVF0 + i] & E1000_VLVF_POOLSEL_MASK; | ||
1871 | + mask |= poolsel >> E1000_VLVF_POOLSEL_SHIFT; | ||
1872 | + } | ||
1873 | + } | ||
1874 | + } else { | ||
1875 | + for (i = 0; i < 8; i++) { | ||
1876 | + if (core->mac[VMOLR0 + i] & E1000_VMOLR_AUPE) { | ||
1877 | + mask |= BIT(i); | ||
1878 | + } | ||
1879 | + } | ||
1880 | + } | ||
1881 | + | ||
1882 | + queues &= mask; | ||
1883 | + } | ||
1884 | + | ||
1885 | + if (is_unicast_ether_addr(ehdr->h_dest) && !queues && !external_tx && | ||
1886 | + !(core->mac[VT_CTL] & E1000_VT_CTL_DISABLE_DEF_POOL)) { | ||
1887 | + uint32_t def_pl = core->mac[VT_CTL] & E1000_VT_CTL_DEFAULT_POOL_MASK; | ||
1888 | + queues = BIT(def_pl >> E1000_VT_CTL_DEFAULT_POOL_SHIFT); | ||
1889 | + } | ||
1890 | + | ||
1891 | + igb_rss_parse_packet(core, core->rx_pkt, external_tx != NULL, rss_info); | ||
1892 | + if (rss_info->queue & 1) { | ||
1893 | + queues <<= 8; | ||
1894 | + } | ||
1895 | + } else { | ||
1896 | + switch (net_rx_pkt_get_packet_type(core->rx_pkt)) { | ||
1897 | + case ETH_PKT_UCAST: | ||
1898 | + if (rctl & E1000_RCTL_UPE) { | ||
1899 | + accepted = true; /* promiscuous ucast */ | ||
1900 | + } | ||
1901 | + break; | ||
1902 | + | ||
1903 | + case ETH_PKT_BCAST: | ||
1904 | + if (rctl & E1000_RCTL_BAM) { | ||
1905 | + accepted = true; /* broadcast enabled */ | ||
1906 | + } | ||
1907 | + break; | ||
1908 | + | ||
1909 | + case ETH_PKT_MCAST: | ||
1910 | + if (rctl & E1000_RCTL_MPE) { | ||
1911 | + accepted = true; /* promiscuous mcast */ | ||
1912 | + } | ||
1913 | + break; | ||
1914 | + | ||
1915 | + default: | ||
1916 | + g_assert_not_reached(); | ||
1917 | + } | ||
1918 | + | ||
1919 | + if (!accepted) { | ||
1920 | + accepted = e1000x_rx_group_filter(core->mac, ehdr->h_dest); | ||
1921 | + } | ||
1922 | + | ||
1923 | + if (!accepted) { | ||
1924 | + for (macp = core->mac + RA2; macp < core->mac + RA2 + 16; macp += 2) { | ||
1925 | + if (!(macp[1] & E1000_RAH_AV)) { | ||
1926 | + continue; | ||
1927 | + } | ||
1928 | + ra[0] = cpu_to_le32(macp[0]); | ||
1929 | + ra[1] = cpu_to_le32(macp[1]); | ||
1930 | + if (!memcmp(ehdr->h_dest, (uint8_t *)ra, ETH_ALEN)) { | ||
1931 | + trace_e1000x_rx_flt_ucast_match((int)(macp - core->mac - RA2) / 2, | ||
1932 | + MAC_ARG(ehdr->h_dest)); | ||
1933 | + | ||
1934 | + accepted = true; | ||
1935 | + break; | ||
1936 | + } | ||
1937 | + } | ||
1938 | + } | ||
1939 | + | ||
1940 | + if (accepted) { | ||
1941 | + igb_rss_parse_packet(core, core->rx_pkt, false, rss_info); | ||
1942 | + queues = BIT(rss_info->queue); | ||
1943 | + } | ||
1944 | + } | ||
1945 | + | ||
1946 | + return queues; | ||
1947 | +} | ||
1948 | + | ||
1949 | +static inline void | ||
1950 | +igb_read_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc, | ||
1951 | + hwaddr *buff_addr) | ||
1952 | +{ | ||
1953 | + *buff_addr = le64_to_cpu(desc->buffer_addr); | ||
1954 | +} | ||
1955 | + | ||
1956 | +static inline void | ||
1957 | +igb_read_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc, | ||
1958 | + hwaddr *buff_addr) | ||
1959 | +{ | ||
1960 | + *buff_addr = le64_to_cpu(desc->read.pkt_addr); | ||
1961 | +} | ||
1962 | + | ||
1963 | +static inline void | ||
1964 | +igb_read_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc, | ||
1965 | + hwaddr *buff_addr) | ||
1966 | +{ | ||
1967 | + if (igb_rx_use_legacy_descriptor(core)) { | ||
1968 | + igb_read_lgcy_rx_descr(core, &desc->legacy, buff_addr); | ||
1969 | + } else { | ||
1970 | + igb_read_adv_rx_descr(core, &desc->adv, buff_addr); | ||
1971 | + } | ||
1972 | +} | ||
1973 | + | ||
1974 | +static void | ||
1975 | +igb_verify_csum_in_sw(IGBCore *core, | ||
1976 | + struct NetRxPkt *pkt, | ||
1977 | + uint32_t *status_flags, | ||
1978 | + EthL4HdrProto l4hdr_proto) | ||
1979 | +{ | ||
1980 | + bool csum_valid; | ||
1981 | + uint32_t csum_error; | ||
1982 | + | ||
1983 | + if (igb_rx_l3_cso_enabled(core)) { | ||
1984 | + if (!net_rx_pkt_validate_l3_csum(pkt, &csum_valid)) { | ||
1985 | + trace_e1000e_rx_metadata_l3_csum_validation_failed(); | ||
1986 | + } else { | ||
1987 | + csum_error = csum_valid ? 0 : E1000_RXDEXT_STATERR_IPE; | ||
1988 | + *status_flags |= E1000_RXD_STAT_IPCS | csum_error; | ||
1989 | + } | ||
1990 | + } else { | ||
1991 | + trace_e1000e_rx_metadata_l3_cso_disabled(); | ||
1992 | + } | ||
1993 | + | ||
1994 | + if (!igb_rx_l4_cso_enabled(core)) { | ||
1995 | + trace_e1000e_rx_metadata_l4_cso_disabled(); | ||
1996 | + return; | ||
1997 | + } | ||
1998 | + | ||
1999 | + if (!net_rx_pkt_validate_l4_csum(pkt, &csum_valid)) { | ||
2000 | + trace_e1000e_rx_metadata_l4_csum_validation_failed(); | ||
2001 | + return; | ||
2002 | + } | ||
2003 | + | ||
2004 | + csum_error = csum_valid ? 0 : E1000_RXDEXT_STATERR_TCPE; | ||
2005 | + *status_flags |= E1000_RXD_STAT_TCPCS | csum_error; | ||
2006 | + | ||
2007 | + if (l4hdr_proto == ETH_L4_HDR_PROTO_UDP) { | ||
2008 | + *status_flags |= E1000_RXD_STAT_UDPCS; | ||
2009 | + } | ||
2010 | +} | ||
2011 | + | ||
2012 | +static void | ||
2013 | +igb_build_rx_metadata(IGBCore *core, | ||
2014 | + struct NetRxPkt *pkt, | ||
2015 | + bool is_eop, | ||
2016 | + const E1000E_RSSInfo *rss_info, | ||
2017 | + uint16_t *pkt_info, uint16_t *hdr_info, | ||
2018 | + uint32_t *rss, | ||
2019 | + uint32_t *status_flags, | ||
2020 | + uint16_t *ip_id, | ||
2021 | + uint16_t *vlan_tag) | ||
2022 | +{ | ||
2023 | + struct virtio_net_hdr *vhdr; | ||
2024 | + bool hasip4, hasip6; | ||
2025 | + EthL4HdrProto l4hdr_proto; | ||
2026 | + uint32_t pkt_type; | ||
2027 | + | ||
2028 | + *status_flags = E1000_RXD_STAT_DD; | ||
2029 | + | ||
2030 | + /* No additional metadata needed for non-EOP descriptors */ | ||
2031 | + /* TODO: EOP apply only to status so don't skip whole function. */ | ||
2032 | + if (!is_eop) { | ||
2033 | + goto func_exit; | ||
2034 | + } | ||
2035 | + | ||
2036 | + *status_flags |= E1000_RXD_STAT_EOP; | ||
2037 | + | ||
2038 | + net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto); | ||
2039 | + trace_e1000e_rx_metadata_protocols(hasip4, hasip6, l4hdr_proto); | ||
2040 | + | ||
2041 | + /* VLAN state */ | ||
2042 | + if (net_rx_pkt_is_vlan_stripped(pkt)) { | ||
2043 | + *status_flags |= E1000_RXD_STAT_VP; | ||
2044 | + *vlan_tag = cpu_to_le16(net_rx_pkt_get_vlan_tag(pkt)); | ||
2045 | + trace_e1000e_rx_metadata_vlan(*vlan_tag); | ||
2046 | + } | ||
2047 | + | ||
2048 | + /* Packet parsing results */ | ||
2049 | + if ((core->mac[RXCSUM] & E1000_RXCSUM_PCSD) != 0) { | ||
2050 | + if (rss_info->enabled) { | ||
2051 | + *rss = cpu_to_le32(rss_info->hash); | ||
2052 | + trace_igb_rx_metadata_rss(*rss); | ||
2053 | + } | ||
2054 | + } else if (hasip4) { | ||
2055 | + *status_flags |= E1000_RXD_STAT_IPIDV; | ||
2056 | + *ip_id = cpu_to_le16(net_rx_pkt_get_ip_id(pkt)); | ||
2057 | + trace_e1000e_rx_metadata_ip_id(*ip_id); | ||
2058 | + } | ||
2059 | + | ||
2060 | + if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP && net_rx_pkt_is_tcp_ack(pkt)) { | ||
2061 | + *status_flags |= E1000_RXD_STAT_ACK; | ||
2062 | + trace_e1000e_rx_metadata_ack(); | ||
2063 | + } | ||
2064 | + | ||
2065 | + if (hasip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_DIS)) { | ||
2066 | + trace_e1000e_rx_metadata_ipv6_filtering_disabled(); | ||
2067 | + pkt_type = E1000_RXD_PKT_MAC; | ||
2068 | + } else if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP || | ||
2069 | + l4hdr_proto == ETH_L4_HDR_PROTO_UDP) { | ||
2070 | + pkt_type = hasip4 ? E1000_RXD_PKT_IP4_XDP : E1000_RXD_PKT_IP6_XDP; | ||
2071 | + } else if (hasip4 || hasip6) { | ||
2072 | + pkt_type = hasip4 ? E1000_RXD_PKT_IP4 : E1000_RXD_PKT_IP6; | ||
2073 | + } else { | ||
2074 | + pkt_type = E1000_RXD_PKT_MAC; | ||
2075 | + } | ||
2076 | + | ||
2077 | + trace_e1000e_rx_metadata_pkt_type(pkt_type); | ||
2078 | + | ||
2079 | + if (pkt_info) { | ||
2080 | + if (rss_info->enabled) { | ||
2081 | + *pkt_info = rss_info->type; | ||
2082 | + } | ||
2083 | + | ||
2084 | + *pkt_info |= (pkt_type << 4); | ||
2085 | + } else { | ||
2086 | + *status_flags |= E1000_RXD_PKT_TYPE(pkt_type); | ||
2087 | + } | ||
2088 | + | ||
2089 | + if (hdr_info) { | ||
2090 | + *hdr_info = 0; | ||
2091 | + } | ||
2092 | + | ||
2093 | + /* RX CSO information */ | ||
2094 | + if (hasip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_XSUM_DIS)) { | ||
2095 | + trace_e1000e_rx_metadata_ipv6_sum_disabled(); | ||
2096 | + goto func_exit; | ||
2097 | + } | ||
2098 | + | ||
2099 | + vhdr = net_rx_pkt_get_vhdr(pkt); | ||
2100 | + | ||
2101 | + if (!(vhdr->flags & VIRTIO_NET_HDR_F_DATA_VALID) && | ||
2102 | + !(vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM)) { | ||
2103 | + trace_e1000e_rx_metadata_virthdr_no_csum_info(); | ||
2104 | + igb_verify_csum_in_sw(core, pkt, status_flags, l4hdr_proto); | ||
2105 | + goto func_exit; | ||
2106 | + } | ||
2107 | + | ||
2108 | + if (igb_rx_l3_cso_enabled(core)) { | ||
2109 | + *status_flags |= hasip4 ? E1000_RXD_STAT_IPCS : 0; | ||
2110 | + } else { | ||
2111 | + trace_e1000e_rx_metadata_l3_cso_disabled(); | ||
2112 | + } | ||
2113 | + | ||
2114 | + if (igb_rx_l4_cso_enabled(core)) { | ||
2115 | + switch (l4hdr_proto) { | ||
2116 | + case ETH_L4_HDR_PROTO_TCP: | ||
2117 | + *status_flags |= E1000_RXD_STAT_TCPCS; | ||
2118 | + break; | ||
2119 | + | ||
2120 | + case ETH_L4_HDR_PROTO_UDP: | ||
2121 | + *status_flags |= E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS; | ||
2122 | + break; | ||
2123 | + | ||
2124 | + default: | ||
2125 | + goto func_exit; | ||
2126 | + } | ||
2127 | + } else { | ||
2128 | + trace_e1000e_rx_metadata_l4_cso_disabled(); | ||
2129 | + } | ||
2130 | + | ||
2131 | + trace_e1000e_rx_metadata_status_flags(*status_flags); | ||
2132 | + | ||
2133 | +func_exit: | ||
2134 | + *status_flags = cpu_to_le32(*status_flags); | ||
2135 | +} | ||
2136 | + | ||
2137 | +static inline void | ||
2138 | +igb_write_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc, | ||
2139 | + struct NetRxPkt *pkt, | ||
2140 | + const E1000E_RSSInfo *rss_info, | ||
2141 | + uint16_t length) | ||
2142 | +{ | ||
2143 | + uint32_t status_flags, rss; | ||
2144 | + uint16_t ip_id; | ||
2145 | + | ||
2146 | + assert(!rss_info->enabled); | ||
2147 | + desc->length = cpu_to_le16(length); | ||
2148 | + desc->csum = 0; | ||
2149 | + | ||
2150 | + igb_build_rx_metadata(core, pkt, pkt != NULL, | ||
2151 | + rss_info, | ||
2152 | + NULL, NULL, &rss, | ||
2153 | + &status_flags, &ip_id, | ||
2154 | + &desc->special); | ||
2155 | + desc->errors = (uint8_t) (le32_to_cpu(status_flags) >> 24); | ||
2156 | + desc->status = (uint8_t) le32_to_cpu(status_flags); | ||
2157 | +} | ||
2158 | + | ||
2159 | +static inline void | ||
2160 | +igb_write_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc, | ||
2161 | + struct NetRxPkt *pkt, | ||
2162 | + const E1000E_RSSInfo *rss_info, | ||
2163 | + uint16_t length) | ||
2164 | +{ | ||
2165 | + memset(&desc->wb, 0, sizeof(desc->wb)); | ||
2166 | + | ||
2167 | + desc->wb.upper.length = cpu_to_le16(length); | ||
2168 | + | ||
2169 | + igb_build_rx_metadata(core, pkt, pkt != NULL, | ||
2170 | + rss_info, | ||
2171 | + &desc->wb.lower.lo_dword.pkt_info, | ||
2172 | + &desc->wb.lower.lo_dword.hdr_info, | ||
2173 | + &desc->wb.lower.hi_dword.rss, | ||
2174 | + &desc->wb.upper.status_error, | ||
2175 | + &desc->wb.lower.hi_dword.csum_ip.ip_id, | ||
2176 | + &desc->wb.upper.vlan); | ||
2177 | +} | ||
2178 | + | ||
2179 | +static inline void | ||
2180 | +igb_write_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc, | ||
2181 | +struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info, uint16_t length) | ||
2182 | +{ | ||
2183 | + if (igb_rx_use_legacy_descriptor(core)) { | ||
2184 | + igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info, length); | ||
2185 | + } else { | ||
2186 | + igb_write_adv_rx_descr(core, &desc->adv, pkt, rss_info, length); | ||
2187 | + } | ||
2188 | +} | ||
2189 | + | ||
2190 | +static inline void | ||
2191 | +igb_pci_dma_write_rx_desc(IGBCore *core, PCIDevice *dev, dma_addr_t addr, | ||
2192 | + union e1000_rx_desc_union *desc, dma_addr_t len) | ||
2193 | +{ | ||
2194 | + if (igb_rx_use_legacy_descriptor(core)) { | ||
2195 | + struct e1000_rx_desc *d = &desc->legacy; | ||
2196 | + size_t offset = offsetof(struct e1000_rx_desc, status); | ||
2197 | + uint8_t status = d->status; | ||
2198 | + | ||
2199 | + d->status &= ~E1000_RXD_STAT_DD; | ||
2200 | + pci_dma_write(dev, addr, desc, len); | ||
2201 | + | ||
2202 | + if (status & E1000_RXD_STAT_DD) { | ||
2203 | + d->status = status; | ||
2204 | + pci_dma_write(dev, addr + offset, &status, sizeof(status)); | ||
2205 | + } | ||
2206 | + } else { | ||
2207 | + union e1000_adv_rx_desc *d = &desc->adv; | ||
2208 | + size_t offset = | ||
2209 | + offsetof(union e1000_adv_rx_desc, wb.upper.status_error); | ||
2210 | + uint32_t status = d->wb.upper.status_error; | ||
2211 | + | ||
2212 | + d->wb.upper.status_error &= ~E1000_RXD_STAT_DD; | ||
2213 | + pci_dma_write(dev, addr, desc, len); | ||
2214 | + | ||
2215 | + if (status & E1000_RXD_STAT_DD) { | ||
2216 | + d->wb.upper.status_error = status; | ||
2217 | + pci_dma_write(dev, addr + offset, &status, sizeof(status)); | ||
2218 | + } | ||
2219 | + } | ||
2220 | +} | ||
2221 | + | ||
2222 | +static void | ||
2223 | +igb_write_to_rx_buffers(IGBCore *core, | ||
2224 | + PCIDevice *d, | ||
2225 | + hwaddr ba, | ||
2226 | + uint16_t *written, | ||
2227 | + const char *data, | ||
2228 | + dma_addr_t data_len) | ||
2229 | +{ | ||
2230 | + trace_igb_rx_desc_buff_write(ba, *written, data, data_len); | ||
2231 | + pci_dma_write(d, ba + *written, data, data_len); | ||
2232 | + *written += data_len; | ||
2233 | +} | ||
2234 | + | ||
2235 | +static void | ||
2236 | +igb_update_rx_stats(IGBCore *core, size_t data_size, size_t data_fcs_size) | ||
2237 | +{ | ||
2238 | + e1000x_update_rx_total_stats(core->mac, data_size, data_fcs_size); | ||
2239 | + | ||
2240 | + switch (net_rx_pkt_get_packet_type(core->rx_pkt)) { | ||
2241 | + case ETH_PKT_BCAST: | ||
2242 | + e1000x_inc_reg_if_not_full(core->mac, BPRC); | ||
2243 | + break; | ||
2244 | + | ||
2245 | + case ETH_PKT_MCAST: | ||
2246 | + e1000x_inc_reg_if_not_full(core->mac, MPRC); | ||
2247 | + break; | ||
2248 | + | ||
2249 | + default: | ||
2250 | + break; | ||
2251 | + } | ||
2252 | +} | ||
2253 | + | ||
2254 | +static inline bool | ||
2255 | +igb_rx_descr_threshold_hit(IGBCore *core, const E1000E_RingInfo *rxi) | ||
2256 | +{ | ||
2257 | + return igb_ring_free_descr_num(core, rxi) == | ||
2258 | + ((core->mac[E1000_SRRCTL(rxi->idx) >> 2] >> 20) & 31) * 16; | ||
2259 | +} | ||
2260 | + | ||
2261 | +static void | ||
2262 | +igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt, | ||
2263 | + const E1000E_RxRing *rxr, | ||
2264 | + const E1000E_RSSInfo *rss_info) | ||
2265 | +{ | ||
2266 | + PCIDevice *d; | ||
2267 | + dma_addr_t base; | ||
2268 | + union e1000_rx_desc_union desc; | ||
2269 | + size_t desc_size; | ||
2270 | + size_t desc_offset = 0; | ||
2271 | + size_t iov_ofs = 0; | ||
2272 | + | ||
2273 | + struct iovec *iov = net_rx_pkt_get_iovec(pkt); | ||
2274 | + size_t size = net_rx_pkt_get_total_len(pkt); | ||
2275 | + size_t total_size = size + e1000x_fcs_len(core->mac); | ||
2276 | + const E1000E_RingInfo *rxi = rxr->i; | ||
2277 | + size_t bufsize = igb_rxbufsize(core, rxi); | ||
2278 | + | ||
2279 | + d = pcie_sriov_get_vf_at_index(core->owner, rxi->idx % 8); | ||
2280 | + if (!d) { | ||
2281 | + d = core->owner; | ||
2282 | + } | ||
2283 | + | ||
2284 | + do { | ||
2285 | + hwaddr ba; | ||
2286 | + uint16_t written = 0; | ||
2287 | + bool is_last = false; | ||
2288 | + | ||
2289 | + desc_size = total_size - desc_offset; | ||
2290 | + | ||
2291 | + if (desc_size > bufsize) { | ||
2292 | + desc_size = bufsize; | ||
2293 | + } | ||
2294 | + | ||
2295 | + if (igb_ring_empty(core, rxi)) { | ||
2296 | + return; | ||
2297 | + } | ||
2298 | + | ||
2299 | + base = igb_ring_head_descr(core, rxi); | ||
2300 | + | ||
2301 | + pci_dma_read(d, base, &desc, core->rx_desc_len); | ||
2302 | + | ||
2303 | + trace_e1000e_rx_descr(rxi->idx, base, core->rx_desc_len); | ||
2304 | + | ||
2305 | + igb_read_rx_descr(core, &desc, &ba); | ||
2306 | + | ||
2307 | + if (ba) { | ||
2308 | + if (desc_offset < size) { | ||
2309 | + static const uint32_t fcs_pad; | ||
2310 | + size_t iov_copy; | ||
2311 | + size_t copy_size = size - desc_offset; | ||
2312 | + if (copy_size > bufsize) { | ||
2313 | + copy_size = bufsize; | ||
2314 | + } | ||
2315 | + | ||
2316 | + /* Copy packet payload */ | ||
2317 | + while (copy_size) { | ||
2318 | + iov_copy = MIN(copy_size, iov->iov_len - iov_ofs); | ||
2319 | + | ||
2320 | + igb_write_to_rx_buffers(core, d, ba, &written, | ||
2321 | + iov->iov_base + iov_ofs, iov_copy); | ||
2322 | + | ||
2323 | + copy_size -= iov_copy; | ||
2324 | + iov_ofs += iov_copy; | ||
2325 | + if (iov_ofs == iov->iov_len) { | ||
2326 | + iov++; | ||
2327 | + iov_ofs = 0; | ||
2328 | + } | ||
2329 | + } | ||
2330 | + | ||
2331 | + if (desc_offset + desc_size >= total_size) { | ||
2332 | + /* Simulate FCS checksum presence in the last descriptor */ | ||
2333 | + igb_write_to_rx_buffers(core, d, ba, &written, | ||
2334 | + (const char *) &fcs_pad, e1000x_fcs_len(core->mac)); | ||
2335 | + } | ||
2336 | + } | ||
2337 | + } else { /* as per intel docs; skip descriptors with null buf addr */ | ||
2338 | + trace_e1000e_rx_null_descriptor(); | ||
2339 | + } | ||
2340 | + desc_offset += desc_size; | ||
2341 | + if (desc_offset >= total_size) { | ||
2342 | + is_last = true; | ||
2343 | + } | ||
2344 | + | ||
2345 | + igb_write_rx_descr(core, &desc, is_last ? core->rx_pkt : NULL, | ||
2346 | + rss_info, written); | ||
2347 | + igb_pci_dma_write_rx_desc(core, d, base, &desc, core->rx_desc_len); | ||
2348 | + | ||
2349 | + igb_ring_advance(core, rxi, core->rx_desc_len / E1000_MIN_RX_DESC_LEN); | ||
2350 | + | ||
2351 | + } while (desc_offset < total_size); | ||
2352 | + | ||
2353 | + igb_update_rx_stats(core, size, total_size); | ||
2354 | +} | ||
2355 | + | ||
2356 | +static inline void | ||
2357 | +igb_rx_fix_l4_csum(IGBCore *core, struct NetRxPkt *pkt) | ||
2358 | +{ | ||
2359 | + struct virtio_net_hdr *vhdr = net_rx_pkt_get_vhdr(pkt); | ||
2360 | + | ||
2361 | + if (vhdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) { | ||
2362 | + net_rx_pkt_fix_l4_csum(pkt); | ||
2363 | + } | ||
2364 | +} | ||
2365 | + | ||
2366 | +ssize_t | ||
2367 | +igb_receive_iov(IGBCore *core, const struct iovec *iov, int iovcnt) | ||
2368 | +{ | ||
2369 | + return igb_receive_internal(core, iov, iovcnt, core->has_vnet, NULL); | ||
2370 | +} | ||
2371 | + | ||
2372 | +static ssize_t | ||
2373 | +igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt, | ||
2374 | + bool has_vnet, bool *external_tx) | ||
2375 | +{ | ||
2376 | + static const int maximum_ethernet_hdr_len = (ETH_HLEN + 4); | ||
2377 | + | ||
2378 | + uint16_t queues = 0; | ||
2379 | + uint32_t n = 0; | ||
2380 | + uint8_t min_buf[ETH_ZLEN]; | ||
2381 | + struct iovec min_iov; | ||
2382 | + struct eth_header *ehdr; | ||
2383 | + uint8_t *filter_buf; | ||
2384 | + size_t size, orig_size; | ||
2385 | + size_t iov_ofs = 0; | ||
2386 | + E1000E_RxRing rxr; | ||
2387 | + E1000E_RSSInfo rss_info; | ||
2388 | + size_t total_size; | ||
2389 | + int i; | ||
2390 | + | ||
2391 | + trace_e1000e_rx_receive_iov(iovcnt); | ||
2392 | + | ||
2393 | + if (external_tx) { | ||
2394 | + *external_tx = true; | ||
2395 | + } | ||
2396 | + | ||
2397 | + if (!e1000x_hw_rx_enabled(core->mac)) { | ||
2398 | + return -1; | ||
2399 | + } | ||
2400 | + | ||
2401 | + /* Pull virtio header in */ | ||
2402 | + if (has_vnet) { | ||
2403 | + net_rx_pkt_set_vhdr_iovec(core->rx_pkt, iov, iovcnt); | ||
2404 | + iov_ofs = sizeof(struct virtio_net_hdr); | ||
2405 | + } else { | ||
2406 | + net_rx_pkt_unset_vhdr(core->rx_pkt); | ||
2407 | + } | ||
2408 | + | ||
2409 | + filter_buf = iov->iov_base + iov_ofs; | ||
2410 | + orig_size = iov_size(iov, iovcnt); | ||
2411 | + size = orig_size - iov_ofs; | ||
2412 | + | ||
2413 | + /* Pad to minimum Ethernet frame length */ | ||
2414 | + if (size < sizeof(min_buf)) { | ||
2415 | + iov_to_buf(iov, iovcnt, iov_ofs, min_buf, size); | ||
2416 | + memset(&min_buf[size], 0, sizeof(min_buf) - size); | ||
2417 | + e1000x_inc_reg_if_not_full(core->mac, RUC); | ||
2418 | + min_iov.iov_base = filter_buf = min_buf; | ||
2419 | + min_iov.iov_len = size = sizeof(min_buf); | ||
2420 | + iovcnt = 1; | ||
2421 | + iov = &min_iov; | ||
2422 | + iov_ofs = 0; | ||
2423 | + } else if (iov->iov_len < maximum_ethernet_hdr_len) { | ||
2424 | + /* This is very unlikely, but may happen. */ | ||
2425 | + iov_to_buf(iov, iovcnt, iov_ofs, min_buf, maximum_ethernet_hdr_len); | ||
2426 | + filter_buf = min_buf; | ||
2427 | + } | ||
2428 | + | ||
2429 | + /* Discard oversized packets if !LPE and !SBP. */ | ||
2430 | + if (e1000x_is_oversized(core->mac, size)) { | ||
2431 | + return orig_size; | ||
2432 | + } | ||
2433 | + | ||
2434 | + ehdr = PKT_GET_ETH_HDR(filter_buf); | ||
2435 | + net_rx_pkt_set_packet_type(core->rx_pkt, get_eth_packet_type(ehdr)); | ||
2436 | + | ||
2437 | + net_rx_pkt_attach_iovec_ex(core->rx_pkt, iov, iovcnt, iov_ofs, | ||
2438 | + e1000x_vlan_enabled(core->mac), | ||
2439 | + core->mac[VET] & 0xffff); | ||
2440 | + | ||
2441 | + queues = igb_receive_assign(core, ehdr, &rss_info, external_tx); | ||
2442 | + if (!queues) { | ||
2443 | + trace_e1000e_rx_flt_dropped(); | ||
2444 | + return orig_size; | ||
2445 | + } | ||
2446 | + | ||
2447 | + total_size = net_rx_pkt_get_total_len(core->rx_pkt) + | ||
2448 | + e1000x_fcs_len(core->mac); | ||
2449 | + | ||
2450 | + for (i = 0; i < IGB_NUM_QUEUES; i++) { | ||
2451 | + if (!(queues & BIT(i))) { | ||
2452 | + continue; | ||
2453 | + } | ||
2454 | + | ||
2455 | + igb_rx_ring_init(core, &rxr, i); | ||
2456 | + | ||
2457 | + if (!igb_has_rxbufs(core, rxr.i, total_size)) { | ||
2458 | + n |= E1000_ICS_RXO; | ||
2459 | + trace_e1000e_rx_not_written_to_guest(rxr.i->idx); | ||
2460 | + continue; | ||
2461 | + } | ||
2462 | + | ||
2463 | + n |= E1000_ICR_RXT0; | ||
2464 | + | ||
2465 | + igb_rx_fix_l4_csum(core, core->rx_pkt); | ||
2466 | + igb_write_packet_to_guest(core, core->rx_pkt, &rxr, &rss_info); | ||
2467 | + | ||
2468 | + /* Check if receive descriptor minimum threshold hit */ | ||
2469 | + if (igb_rx_descr_threshold_hit(core, rxr.i)) { | ||
2470 | + n |= E1000_ICS_RXDMT0; | ||
2471 | + } | ||
2472 | + | ||
2473 | + core->mac[EICR] |= igb_rx_wb_eic(core, rxr.i->idx); | ||
2474 | + | ||
2475 | + trace_e1000e_rx_written_to_guest(rxr.i->idx); | ||
2476 | + } | ||
2477 | + | ||
2478 | + trace_e1000e_rx_interrupt_set(n); | ||
2479 | + igb_set_interrupt_cause(core, n); | ||
2480 | + | ||
2481 | + return orig_size; | ||
2482 | +} | ||
2483 | + | ||
2484 | +static inline bool | ||
2485 | +igb_have_autoneg(IGBCore *core) | ||
2486 | +{ | ||
2487 | + return core->phy[MII_BMCR] & MII_BMCR_AUTOEN; | ||
2488 | +} | ||
2489 | + | ||
2490 | +static void igb_update_flowctl_status(IGBCore *core) | ||
2491 | +{ | ||
2492 | + if (igb_have_autoneg(core) && core->phy[MII_BMSR] & MII_BMSR_AN_COMP) { | ||
2493 | + trace_e1000e_link_autoneg_flowctl(true); | ||
2494 | + core->mac[CTRL] |= E1000_CTRL_TFCE | E1000_CTRL_RFCE; | ||
2495 | + } else { | ||
2496 | + trace_e1000e_link_autoneg_flowctl(false); | ||
2497 | + } | ||
2498 | +} | ||
2499 | + | ||
2500 | +static inline void | ||
2501 | +igb_link_down(IGBCore *core) | ||
2502 | +{ | ||
2503 | + e1000x_update_regs_on_link_down(core->mac, core->phy); | ||
2504 | + igb_update_flowctl_status(core); | ||
2505 | +} | ||
2506 | + | ||
2507 | +static inline void | ||
2508 | +igb_set_phy_ctrl(IGBCore *core, uint16_t val) | ||
2509 | +{ | ||
2510 | + /* bits 0-5 reserved; MII_BMCR_[ANRESTART,RESET] are self clearing */ | ||
2511 | + core->phy[MII_BMCR] = val & ~(0x3f | MII_BMCR_RESET | MII_BMCR_ANRESTART); | ||
2512 | + | ||
2513 | + if ((val & MII_BMCR_ANRESTART) && igb_have_autoneg(core)) { | ||
2514 | + e1000x_restart_autoneg(core->mac, core->phy, core->autoneg_timer); | ||
2515 | + } | ||
2516 | +} | ||
2517 | + | ||
2518 | +void igb_core_set_link_status(IGBCore *core) | ||
2519 | +{ | ||
2520 | + NetClientState *nc = qemu_get_queue(core->owner_nic); | ||
2521 | + uint32_t old_status = core->mac[STATUS]; | ||
2522 | + | ||
2523 | + trace_e1000e_link_status_changed(nc->link_down ? false : true); | ||
2524 | + | ||
2525 | + if (nc->link_down) { | ||
2526 | + e1000x_update_regs_on_link_down(core->mac, core->phy); | ||
2527 | + } else { | ||
2528 | + if (igb_have_autoneg(core) && | ||
2529 | + !(core->phy[MII_BMSR] & MII_BMSR_AN_COMP)) { | ||
2530 | + e1000x_restart_autoneg(core->mac, core->phy, | ||
2531 | + core->autoneg_timer); | ||
2532 | + } else { | ||
2533 | + e1000x_update_regs_on_link_up(core->mac, core->phy); | ||
2534 | + igb_start_recv(core); | ||
2535 | + } | ||
2536 | + } | ||
2537 | + | ||
2538 | + if (core->mac[STATUS] != old_status) { | ||
2539 | + igb_set_interrupt_cause(core, E1000_ICR_LSC); | ||
2540 | + } | ||
2541 | +} | ||
2542 | + | ||
2543 | +static void | ||
2544 | +igb_set_ctrl(IGBCore *core, int index, uint32_t val) | ||
2545 | +{ | ||
2546 | + trace_e1000e_core_ctrl_write(index, val); | ||
2547 | + | ||
2548 | + /* RST is self clearing */ | ||
2549 | + core->mac[CTRL] = val & ~E1000_CTRL_RST; | ||
2550 | + core->mac[CTRL_DUP] = core->mac[CTRL]; | ||
2551 | + | ||
2552 | + trace_e1000e_link_set_params( | ||
2553 | + !!(val & E1000_CTRL_ASDE), | ||
2554 | + (val & E1000_CTRL_SPD_SEL) >> E1000_CTRL_SPD_SHIFT, | ||
2555 | + !!(val & E1000_CTRL_FRCSPD), | ||
2556 | + !!(val & E1000_CTRL_FRCDPX), | ||
2557 | + !!(val & E1000_CTRL_RFCE), | ||
2558 | + !!(val & E1000_CTRL_TFCE)); | ||
2559 | + | ||
2560 | + if (val & E1000_CTRL_RST) { | ||
2561 | + trace_e1000e_core_ctrl_sw_reset(); | ||
2562 | + igb_reset(core, true); | ||
2563 | + } | ||
2564 | + | ||
2565 | + if (val & E1000_CTRL_PHY_RST) { | ||
2566 | + trace_e1000e_core_ctrl_phy_reset(); | ||
2567 | + core->mac[STATUS] |= E1000_STATUS_PHYRA; | ||
2568 | + } | ||
2569 | +} | ||
2570 | + | ||
2571 | +static void | ||
2572 | +igb_set_rfctl(IGBCore *core, int index, uint32_t val) | ||
2573 | +{ | ||
2574 | + trace_e1000e_rx_set_rfctl(val); | ||
2575 | + | ||
2576 | + if (!(val & E1000_RFCTL_ISCSI_DIS)) { | ||
2577 | + trace_e1000e_wrn_iscsi_filtering_not_supported(); | ||
2578 | + } | ||
2579 | + | ||
2580 | + if (!(val & E1000_RFCTL_NFSW_DIS)) { | ||
2581 | + trace_e1000e_wrn_nfsw_filtering_not_supported(); | ||
2582 | + } | ||
2583 | + | ||
2584 | + if (!(val & E1000_RFCTL_NFSR_DIS)) { | ||
2585 | + trace_e1000e_wrn_nfsr_filtering_not_supported(); | ||
2586 | + } | ||
2587 | + | ||
2588 | + core->mac[RFCTL] = val; | ||
2589 | +} | ||
2590 | + | ||
2591 | +static void | ||
2592 | +igb_calc_rxdesclen(IGBCore *core) | ||
2593 | +{ | ||
2594 | + if (igb_rx_use_legacy_descriptor(core)) { | ||
2595 | + core->rx_desc_len = sizeof(struct e1000_rx_desc); | ||
2596 | + } else { | ||
2597 | + core->rx_desc_len = sizeof(union e1000_adv_rx_desc); | ||
2598 | + } | ||
2599 | + trace_e1000e_rx_desc_len(core->rx_desc_len); | ||
2600 | +} | ||
2601 | + | ||
2602 | +static void | ||
2603 | +igb_set_rx_control(IGBCore *core, int index, uint32_t val) | ||
2604 | +{ | ||
2605 | + core->mac[RCTL] = val; | ||
2606 | + trace_e1000e_rx_set_rctl(core->mac[RCTL]); | ||
2607 | + | ||
2608 | + if (val & E1000_RCTL_DTYP_MASK) { | ||
2609 | + qemu_log_mask(LOG_GUEST_ERROR, | ||
2610 | + "igb: RCTL.DTYP must be zero for compatibility"); | ||
2611 | + } | ||
2612 | + | ||
2613 | + if (val & E1000_RCTL_EN) { | ||
2614 | + igb_calc_rxdesclen(core); | ||
2615 | + igb_start_recv(core); | ||
2616 | + } | ||
2617 | +} | ||
2618 | + | ||
2619 | +static inline void | ||
2620 | +igb_clear_ims_bits(IGBCore *core, uint32_t bits) | ||
2621 | +{ | ||
2622 | + trace_e1000e_irq_clear_ims(bits, core->mac[IMS], core->mac[IMS] & ~bits); | ||
2623 | + core->mac[IMS] &= ~bits; | ||
2624 | +} | ||
2625 | + | ||
2626 | +static inline bool | ||
2627 | +igb_postpone_interrupt(IGBIntrDelayTimer *timer) | ||
2628 | +{ | ||
2629 | + if (timer->running) { | ||
2630 | + trace_e1000e_irq_postponed_by_xitr(timer->delay_reg << 2); | ||
2631 | + | ||
2632 | + return true; | ||
2633 | + } | ||
2634 | + | ||
2635 | + if (timer->core->mac[timer->delay_reg] != 0) { | ||
2636 | + igb_intrmgr_rearm_timer(timer); | ||
2637 | + } | ||
2638 | + | ||
2639 | + return false; | ||
2640 | +} | ||
2641 | + | ||
2642 | +static inline bool | ||
2643 | +igb_eitr_should_postpone(IGBCore *core, int idx) | ||
2644 | +{ | ||
2645 | + return igb_postpone_interrupt(&core->eitr[idx]); | ||
2646 | +} | ||
2647 | + | ||
2648 | +static void igb_send_msix(IGBCore *core) | ||
2649 | +{ | ||
2650 | + uint32_t causes = core->mac[EICR] & core->mac[EIMS]; | ||
2651 | + uint32_t effective_eiac; | ||
2652 | + int vector; | ||
2653 | + | ||
2654 | + for (vector = 0; vector < IGB_INTR_NUM; ++vector) { | ||
2655 | + if ((causes & BIT(vector)) && !igb_eitr_should_postpone(core, vector)) { | ||
2656 | + | ||
2657 | + trace_e1000e_irq_msix_notify_vec(vector); | ||
2658 | + igb_msix_notify(core, vector); | ||
2659 | + | ||
2660 | + trace_e1000e_irq_icr_clear_eiac(core->mac[EICR], core->mac[EIAC]); | ||
2661 | + effective_eiac = core->mac[EIAC] & BIT(vector); | ||
2662 | + core->mac[EICR] &= ~effective_eiac; | ||
2663 | + } | ||
2664 | + } | ||
2665 | +} | ||
2666 | + | ||
2667 | +static inline void | ||
2668 | +igb_fix_icr_asserted(IGBCore *core) | ||
2669 | +{ | ||
2670 | + core->mac[ICR] &= ~E1000_ICR_ASSERTED; | ||
2671 | + if (core->mac[ICR]) { | ||
2672 | + core->mac[ICR] |= E1000_ICR_ASSERTED; | ||
2673 | + } | ||
2674 | + | ||
2675 | + trace_e1000e_irq_fix_icr_asserted(core->mac[ICR]); | ||
2676 | +} | ||
2677 | + | ||
2678 | +static void | ||
2679 | +igb_update_interrupt_state(IGBCore *core) | ||
2680 | +{ | ||
2681 | + uint32_t icr; | ||
2682 | + uint32_t causes; | ||
2683 | + uint32_t int_alloc; | ||
2684 | + | ||
2685 | + icr = core->mac[ICR] & core->mac[IMS]; | ||
2686 | + | ||
2687 | + if (msix_enabled(core->owner)) { | ||
2688 | + if (icr) { | ||
2689 | + causes = 0; | ||
2690 | + if (icr & E1000_ICR_DRSTA) { | ||
2691 | + int_alloc = core->mac[IVAR_MISC] & 0xff; | ||
2692 | + if (int_alloc & E1000_IVAR_VALID) { | ||
2693 | + causes |= BIT(int_alloc & 0x1f); | ||
2694 | + } | ||
2695 | + } | ||
2696 | + /* Check if other bits (excluding the TCP Timer) are enabled. */ | ||
2697 | + if (icr & ~E1000_ICR_DRSTA) { | ||
2698 | + int_alloc = (core->mac[IVAR_MISC] >> 8) & 0xff; | ||
2699 | + if (int_alloc & E1000_IVAR_VALID) { | ||
2700 | + causes |= BIT(int_alloc & 0x1f); | ||
2701 | + } | ||
2702 | + trace_e1000e_irq_add_msi_other(core->mac[EICR]); | ||
2703 | + } | ||
2704 | + core->mac[EICR] |= causes; | ||
2705 | + } | ||
2706 | + | ||
2707 | + if ((core->mac[EICR] & core->mac[EIMS])) { | ||
2708 | + igb_send_msix(core); | ||
2709 | + } | ||
2710 | + } else { | ||
2711 | + igb_fix_icr_asserted(core); | ||
2712 | + | ||
2713 | + if (icr) { | ||
2714 | + core->mac[EICR] |= (icr & E1000_ICR_DRSTA) | E1000_EICR_OTHER; | ||
2715 | + } else { | ||
2716 | + core->mac[EICR] &= ~E1000_EICR_OTHER; | ||
2717 | + } | ||
2718 | + | ||
2719 | + trace_e1000e_irq_pending_interrupts(core->mac[ICR] & core->mac[IMS], | ||
2720 | + core->mac[ICR], core->mac[IMS]); | ||
2721 | + | ||
2722 | + if (msi_enabled(core->owner)) { | ||
2723 | + if (icr) { | ||
2724 | + msi_notify(core->owner, 0); | ||
2725 | + } | ||
2726 | + } else { | ||
2727 | + if (icr) { | ||
2728 | + igb_raise_legacy_irq(core); | ||
2729 | + } else { | ||
2730 | + igb_lower_legacy_irq(core); | ||
2731 | + } | ||
2732 | + } | ||
2733 | + } | ||
2734 | +} | ||
2735 | + | ||
2736 | +static void | ||
2737 | +igb_set_interrupt_cause(IGBCore *core, uint32_t val) | ||
2738 | +{ | ||
2739 | + trace_e1000e_irq_set_cause_entry(val, core->mac[ICR]); | ||
2740 | + | ||
2741 | + core->mac[ICR] |= val; | ||
2742 | + | ||
2743 | + trace_e1000e_irq_set_cause_exit(val, core->mac[ICR]); | ||
2744 | + | ||
2745 | + igb_update_interrupt_state(core); | ||
2746 | +} | ||
2747 | + | ||
2748 | +static void igb_set_eics(IGBCore *core, int index, uint32_t val) | ||
2749 | +{ | ||
2750 | + bool msix = !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE); | ||
2751 | + | ||
2752 | + trace_igb_irq_write_eics(val, msix); | ||
2753 | + | ||
2754 | + core->mac[EICS] |= | ||
2755 | + val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK); | ||
2756 | + | ||
2757 | + /* | ||
2758 | + * TODO: Move to igb_update_interrupt_state if EICS is modified in other | ||
2759 | + * places. | ||
2760 | + */ | ||
2761 | + core->mac[EICR] = core->mac[EICS]; | ||
2762 | + | ||
2763 | + igb_update_interrupt_state(core); | ||
2764 | +} | ||
2765 | + | ||
2766 | +static void igb_set_eims(IGBCore *core, int index, uint32_t val) | ||
2767 | +{ | ||
2768 | + bool msix = !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE); | ||
2769 | + | ||
2770 | + trace_igb_irq_write_eims(val, msix); | ||
2771 | + | ||
2772 | + core->mac[EIMS] |= | ||
2773 | + val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK); | ||
2774 | + | ||
2775 | + igb_update_interrupt_state(core); | ||
2776 | +} | ||
2777 | + | ||
2778 | +static void igb_vf_reset(IGBCore *core, uint16_t vfn) | ||
2779 | +{ | ||
2780 | + /* TODO: Reset of the queue enable and the interrupt registers of the VF. */ | ||
2781 | + | ||
2782 | + core->mac[V2PMAILBOX0 + vfn] &= ~E1000_V2PMAILBOX_RSTI; | ||
2783 | + core->mac[V2PMAILBOX0 + vfn] = E1000_V2PMAILBOX_RSTD; | ||
2784 | +} | ||
2785 | + | ||
2786 | +static void mailbox_interrupt_to_vf(IGBCore *core, uint16_t vfn) | ||
2787 | +{ | ||
2788 | + uint32_t ent = core->mac[VTIVAR_MISC + vfn]; | ||
2789 | + | ||
2790 | + if ((ent & E1000_IVAR_VALID)) { | ||
2791 | + core->mac[EICR] |= (ent & 0x3) << (22 - vfn * IGBVF_MSIX_VEC_NUM); | ||
2792 | + igb_update_interrupt_state(core); | ||
2793 | + } | ||
2794 | +} | ||
2795 | + | ||
2796 | +static void mailbox_interrupt_to_pf(IGBCore *core) | ||
2797 | +{ | ||
2798 | + igb_set_interrupt_cause(core, E1000_ICR_VMMB); | ||
2799 | +} | ||
2800 | + | ||
2801 | +static void igb_set_pfmailbox(IGBCore *core, int index, uint32_t val) | ||
2802 | +{ | ||
2803 | + uint16_t vfn = index - P2VMAILBOX0; | ||
2804 | + | ||
2805 | + trace_igb_set_pfmailbox(vfn, val); | ||
2806 | + | ||
2807 | + if (val & E1000_P2VMAILBOX_STS) { | ||
2808 | + core->mac[V2PMAILBOX0 + vfn] |= E1000_V2PMAILBOX_PFSTS; | ||
2809 | + mailbox_interrupt_to_vf(core, vfn); | ||
2810 | + } | ||
2811 | + | ||
2812 | + if (val & E1000_P2VMAILBOX_ACK) { | ||
2813 | + core->mac[V2PMAILBOX0 + vfn] |= E1000_V2PMAILBOX_PFACK; | ||
2814 | + mailbox_interrupt_to_vf(core, vfn); | ||
2815 | + } | ||
2816 | + | ||
2817 | + /* Buffer Taken by PF (can be set only if the VFU is cleared). */ | ||
2818 | + if (val & E1000_P2VMAILBOX_PFU) { | ||
2819 | + if (!(core->mac[index] & E1000_P2VMAILBOX_VFU)) { | ||
2820 | + core->mac[index] |= E1000_P2VMAILBOX_PFU; | ||
2821 | + core->mac[V2PMAILBOX0 + vfn] |= E1000_V2PMAILBOX_PFU; | ||
2822 | + } | ||
2823 | + } else { | ||
2824 | + core->mac[index] &= ~E1000_P2VMAILBOX_PFU; | ||
2825 | + core->mac[V2PMAILBOX0 + vfn] &= ~E1000_V2PMAILBOX_PFU; | ||
2826 | + } | ||
2827 | + | ||
2828 | + if (val & E1000_P2VMAILBOX_RVFU) { | ||
2829 | + core->mac[V2PMAILBOX0 + vfn] &= ~E1000_V2PMAILBOX_VFU; | ||
2830 | + core->mac[MBVFICR] &= ~((E1000_MBVFICR_VFACK_VF1 << vfn) | | ||
2831 | + (E1000_MBVFICR_VFREQ_VF1 << vfn)); | ||
2832 | + } | ||
2833 | +} | ||
2834 | + | ||
2835 | +static void igb_set_vfmailbox(IGBCore *core, int index, uint32_t val) | ||
2836 | +{ | ||
2837 | + uint16_t vfn = index - V2PMAILBOX0; | ||
2838 | + | ||
2839 | + trace_igb_set_vfmailbox(vfn, val); | ||
2840 | + | ||
2841 | + if (val & E1000_V2PMAILBOX_REQ) { | ||
2842 | + core->mac[MBVFICR] |= E1000_MBVFICR_VFREQ_VF1 << vfn; | ||
2843 | + mailbox_interrupt_to_pf(core); | ||
2844 | + } | ||
2845 | + | ||
2846 | + if (val & E1000_V2PMAILBOX_ACK) { | ||
2847 | + core->mac[MBVFICR] |= E1000_MBVFICR_VFACK_VF1 << vfn; | ||
2848 | + mailbox_interrupt_to_pf(core); | ||
2849 | + } | ||
2850 | + | ||
2851 | + /* Buffer Taken by VF (can be set only if the PFU is cleared). */ | ||
2852 | + if (val & E1000_V2PMAILBOX_VFU) { | ||
2853 | + if (!(core->mac[index] & E1000_V2PMAILBOX_PFU)) { | ||
2854 | + core->mac[index] |= E1000_V2PMAILBOX_VFU; | ||
2855 | + core->mac[P2VMAILBOX0 + vfn] |= E1000_P2VMAILBOX_VFU; | ||
2856 | + } | ||
2857 | + } else { | ||
2858 | + core->mac[index] &= ~E1000_V2PMAILBOX_VFU; | ||
2859 | + core->mac[P2VMAILBOX0 + vfn] &= ~E1000_P2VMAILBOX_VFU; | ||
2860 | + } | ||
2861 | +} | ||
2862 | + | ||
2863 | +static void igb_w1c(IGBCore *core, int index, uint32_t val) | ||
2864 | +{ | ||
2865 | + core->mac[index] &= ~val; | ||
2866 | +} | ||
2867 | + | ||
2868 | +static void igb_set_eimc(IGBCore *core, int index, uint32_t val) | ||
2869 | +{ | ||
2870 | + bool msix = !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE); | ||
2871 | + | ||
2872 | + /* Interrupts are disabled via a write to EIMC and reflected in EIMS. */ | ||
2873 | + core->mac[EIMS] &= | ||
2874 | + ~(val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK)); | ||
2875 | + | ||
2876 | + trace_igb_irq_write_eimc(val, core->mac[EIMS], msix); | ||
2877 | + igb_update_interrupt_state(core); | ||
2878 | +} | ||
2879 | + | ||
2880 | +static void igb_set_eiac(IGBCore *core, int index, uint32_t val) | ||
2881 | +{ | ||
2882 | + bool msix = !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE); | ||
2883 | + | ||
2884 | + if (msix) { | ||
2885 | + trace_igb_irq_write_eiac(val); | ||
2886 | + | ||
2887 | + /* | ||
2888 | + * TODO: When using IOV, the bits that correspond to MSI-X vectors | ||
2889 | + * that are assigned to a VF are read-only. | ||
2890 | + */ | ||
2891 | + core->mac[EIAC] |= (val & E1000_EICR_MSIX_MASK); | ||
2892 | + } | ||
2893 | +} | ||
2894 | + | ||
2895 | +static void igb_set_eiam(IGBCore *core, int index, uint32_t val) | ||
2896 | +{ | ||
2897 | + bool msix = !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE); | ||
2898 | + | ||
2899 | + /* | ||
2900 | + * TODO: When using IOV, the bits that correspond to MSI-X vectors that | ||
2901 | + * are assigned to a VF are read-only. | ||
2902 | + */ | ||
2903 | + core->mac[EIAM] |= | ||
2904 | + ~(val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK)); | ||
2905 | + | ||
2906 | + trace_igb_irq_write_eiam(val, msix); | ||
2907 | +} | ||
2908 | + | ||
2909 | +static void igb_set_eicr(IGBCore *core, int index, uint32_t val) | ||
2910 | +{ | ||
2911 | + bool msix = !!(core->mac[GPIE] & E1000_GPIE_MSIX_MODE); | ||
2912 | + | ||
2913 | + /* | ||
2914 | + * TODO: In IOV mode, only bit zero of this vector is available for the PF | ||
2915 | + * function. | ||
2916 | + */ | ||
2917 | + core->mac[EICR] &= | ||
2918 | + ~(val & (msix ? E1000_EICR_MSIX_MASK : E1000_EICR_LEGACY_MASK)); | ||
2919 | + | ||
2920 | + trace_igb_irq_write_eicr(val, msix); | ||
2921 | + igb_update_interrupt_state(core); | ||
2922 | +} | ||
2923 | + | ||
2924 | +static void igb_set_vtctrl(IGBCore *core, int index, uint32_t val) | ||
2925 | +{ | ||
2926 | + uint16_t vfn; | ||
2927 | + | ||
2928 | + if (val & E1000_CTRL_RST) { | ||
2929 | + vfn = (index - PVTCTRL0) / 0x40; | ||
2930 | + igb_vf_reset(core, vfn); | ||
2931 | + } | ||
2932 | +} | ||
2933 | + | ||
2934 | +static void igb_set_vteics(IGBCore *core, int index, uint32_t val) | ||
2935 | +{ | ||
2936 | + uint16_t vfn = (index - PVTEICS0) / 0x40; | ||
2937 | + | ||
2938 | + core->mac[index] = val; | ||
2939 | + igb_set_eics(core, EICS, (val & 0x7) << (22 - vfn * IGBVF_MSIX_VEC_NUM)); | ||
2940 | +} | ||
2941 | + | ||
2942 | +static void igb_set_vteims(IGBCore *core, int index, uint32_t val) | ||
2943 | +{ | ||
2944 | + uint16_t vfn = (index - PVTEIMS0) / 0x40; | ||
2945 | + | ||
2946 | + core->mac[index] = val; | ||
2947 | + igb_set_eims(core, EIMS, (val & 0x7) << (22 - vfn * IGBVF_MSIX_VEC_NUM)); | ||
2948 | +} | ||
2949 | + | ||
2950 | +static void igb_set_vteimc(IGBCore *core, int index, uint32_t val) | ||
2951 | +{ | ||
2952 | + uint16_t vfn = (index - PVTEIMC0) / 0x40; | ||
2953 | + | ||
2954 | + core->mac[index] = val; | ||
2955 | + igb_set_eimc(core, EIMC, (val & 0x7) << (22 - vfn * IGBVF_MSIX_VEC_NUM)); | ||
2956 | +} | ||
2957 | + | ||
2958 | +static void igb_set_vteiac(IGBCore *core, int index, uint32_t val) | ||
2959 | +{ | ||
2960 | + uint16_t vfn = (index - PVTEIAC0) / 0x40; | ||
2961 | + | ||
2962 | + core->mac[index] = val; | ||
2963 | + igb_set_eiac(core, EIAC, (val & 0x7) << (22 - vfn * IGBVF_MSIX_VEC_NUM)); | ||
2964 | +} | ||
2965 | + | ||
2966 | +static void igb_set_vteiam(IGBCore *core, int index, uint32_t val) | ||
2967 | +{ | ||
2968 | + uint16_t vfn = (index - PVTEIAM0) / 0x40; | ||
2969 | + | ||
2970 | + core->mac[index] = val; | ||
2971 | + igb_set_eiam(core, EIAM, (val & 0x7) << (22 - vfn * IGBVF_MSIX_VEC_NUM)); | ||
2972 | +} | ||
2973 | + | ||
2974 | +static void igb_set_vteicr(IGBCore *core, int index, uint32_t val) | ||
2975 | +{ | ||
2976 | + uint16_t vfn = (index - PVTEICR0) / 0x40; | ||
2977 | + | ||
2978 | + core->mac[index] = val; | ||
2979 | + igb_set_eicr(core, EICR, (val & 0x7) << (22 - vfn * IGBVF_MSIX_VEC_NUM)); | ||
2980 | +} | ||
2981 | + | ||
2982 | +static void igb_set_vtivar(IGBCore *core, int index, uint32_t val) | ||
2983 | +{ | ||
2984 | + uint16_t vfn = (index - VTIVAR); | ||
2985 | + uint16_t qn = vfn; | ||
2986 | + uint8_t ent; | ||
2987 | + int n; | ||
2988 | + | ||
2989 | + core->mac[index] = val; | ||
2990 | + | ||
2991 | + /* Get assigned vector associated with queue Rx#0. */ | ||
2992 | + if ((val & E1000_IVAR_VALID)) { | ||
2993 | + n = igb_ivar_entry_rx(qn); | ||
2994 | + ent = E1000_IVAR_VALID | (24 - vfn * IGBVF_MSIX_VEC_NUM - (2 - (val & 0x7))); | ||
2995 | + core->mac[IVAR0 + n / 4] |= ent << 8 * (n % 4); | ||
2996 | + } | ||
2997 | + | ||
2998 | + /* Get assigned vector associated with queue Tx#0 */ | ||
2999 | + ent = val >> 8; | ||
3000 | + if ((ent & E1000_IVAR_VALID)) { | ||
3001 | + n = igb_ivar_entry_tx(qn); | ||
3002 | + ent = E1000_IVAR_VALID | (24 - vfn * IGBVF_MSIX_VEC_NUM - (2 - (ent & 0x7))); | ||
3003 | + core->mac[IVAR0 + n / 4] |= ent << 8 * (n % 4); | ||
3004 | + } | ||
3005 | + | ||
3006 | + /* | ||
3007 | + * Ignoring assigned vectors associated with queues Rx#1 and Tx#1 for now. | ||
3008 | + */ | ||
3009 | +} | ||
3010 | + | ||
3011 | +static inline void | ||
3012 | +igb_autoneg_timer(void *opaque) | ||
3013 | +{ | ||
3014 | + IGBCore *core = opaque; | ||
3015 | + if (!qemu_get_queue(core->owner_nic)->link_down) { | ||
3016 | + e1000x_update_regs_on_autoneg_done(core->mac, core->phy); | ||
3017 | + igb_start_recv(core); | ||
3018 | + | ||
3019 | + igb_update_flowctl_status(core); | ||
3020 | + /* signal link status change to the guest */ | ||
3021 | + igb_set_interrupt_cause(core, E1000_ICR_LSC); | ||
3022 | + } | ||
3023 | +} | ||
3024 | + | ||
3025 | +static inline uint16_t | ||
3026 | +igb_get_reg_index_with_offset(const uint16_t *mac_reg_access, hwaddr addr) | ||
3027 | +{ | ||
3028 | + uint16_t index = (addr & 0x1ffff) >> 2; | ||
3029 | + return index + (mac_reg_access[index] & 0xfffe); | ||
3030 | +} | ||
3031 | + | ||
3032 | +static const char igb_phy_regcap[MAX_PHY_REG_ADDRESS + 1] = { | ||
3033 | + [MII_BMCR] = PHY_RW, | ||
3034 | + [MII_BMSR] = PHY_R, | ||
3035 | + [MII_PHYID1] = PHY_R, | ||
3036 | + [MII_PHYID2] = PHY_R, | ||
3037 | + [MII_ANAR] = PHY_RW, | ||
3038 | + [MII_ANLPAR] = PHY_R, | ||
3039 | + [MII_ANER] = PHY_R, | ||
3040 | + [MII_ANNP] = PHY_RW, | ||
3041 | + [MII_ANLPRNP] = PHY_R, | ||
3042 | + [MII_CTRL1000] = PHY_RW, | ||
3043 | + [MII_STAT1000] = PHY_R, | ||
3044 | + [MII_EXTSTAT] = PHY_R, | ||
3045 | + | ||
3046 | + [IGP01E1000_PHY_PORT_CONFIG] = PHY_RW, | ||
3047 | + [IGP01E1000_PHY_PORT_STATUS] = PHY_R, | ||
3048 | + [IGP01E1000_PHY_PORT_CTRL] = PHY_RW, | ||
3049 | + [IGP01E1000_PHY_LINK_HEALTH] = PHY_R, | ||
3050 | + [IGP02E1000_PHY_POWER_MGMT] = PHY_RW, | ||
3051 | + [IGP01E1000_PHY_PAGE_SELECT] = PHY_W | ||
3052 | +}; | ||
3053 | + | ||
3054 | +static void | ||
3055 | +igb_phy_reg_write(IGBCore *core, uint32_t addr, uint16_t data) | ||
3056 | +{ | ||
3057 | + assert(addr <= MAX_PHY_REG_ADDRESS); | ||
3058 | + | ||
3059 | + if (addr == MII_BMCR) { | ||
3060 | + igb_set_phy_ctrl(core, data); | ||
3061 | + } else { | ||
3062 | + core->phy[addr] = data; | ||
3063 | + } | ||
3064 | +} | ||
3065 | + | ||
3066 | +static void | ||
3067 | +igb_set_mdic(IGBCore *core, int index, uint32_t val) | ||
3068 | +{ | ||
3069 | + uint32_t data = val & E1000_MDIC_DATA_MASK; | ||
3070 | + uint32_t addr = ((val & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT); | ||
3071 | + | ||
3072 | + if ((val & E1000_MDIC_PHY_MASK) >> E1000_MDIC_PHY_SHIFT != 1) { /* phy # */ | ||
3073 | + val = core->mac[MDIC] | E1000_MDIC_ERROR; | ||
3074 | + } else if (val & E1000_MDIC_OP_READ) { | ||
3075 | + if (!(igb_phy_regcap[addr] & PHY_R)) { | ||
3076 | + trace_igb_core_mdic_read_unhandled(addr); | ||
3077 | + val |= E1000_MDIC_ERROR; | ||
3078 | + } else { | ||
3079 | + val = (val ^ data) | core->phy[addr]; | ||
3080 | + trace_igb_core_mdic_read(addr, val); | ||
3081 | + } | ||
3082 | + } else if (val & E1000_MDIC_OP_WRITE) { | ||
3083 | + if (!(igb_phy_regcap[addr] & PHY_W)) { | ||
3084 | + trace_igb_core_mdic_write_unhandled(addr); | ||
3085 | + val |= E1000_MDIC_ERROR; | ||
3086 | + } else { | ||
3087 | + trace_igb_core_mdic_write(addr, data); | ||
3088 | + igb_phy_reg_write(core, addr, data); | ||
3089 | + } | ||
3090 | + } | ||
3091 | + core->mac[MDIC] = val | E1000_MDIC_READY; | ||
3092 | + | ||
3093 | + if (val & E1000_MDIC_INT_EN) { | ||
3094 | + igb_set_interrupt_cause(core, E1000_ICR_MDAC); | ||
3095 | + } | ||
3096 | +} | ||
3097 | + | ||
3098 | +static void | ||
3099 | +igb_set_rdt(IGBCore *core, int index, uint32_t val) | ||
3100 | +{ | ||
3101 | + core->mac[index] = val & 0xffff; | ||
3102 | + trace_e1000e_rx_set_rdt(igb_mq_queue_idx(RDT0, index), val); | ||
3103 | + igb_start_recv(core); | ||
3104 | +} | ||
3105 | + | ||
3106 | +static void | ||
3107 | +igb_set_status(IGBCore *core, int index, uint32_t val) | ||
3108 | +{ | ||
3109 | + if ((val & E1000_STATUS_PHYRA) == 0) { | ||
3110 | + core->mac[index] &= ~E1000_STATUS_PHYRA; | ||
3111 | + } | ||
3112 | +} | ||
3113 | + | ||
3114 | +static void | ||
3115 | +igb_set_ctrlext(IGBCore *core, int index, uint32_t val) | ||
3116 | +{ | ||
3117 | + trace_e1000e_link_set_ext_params(!!(val & E1000_CTRL_EXT_ASDCHK), | ||
3118 | + !!(val & E1000_CTRL_EXT_SPD_BYPS)); | ||
3119 | + | ||
3120 | + /* TODO: PFRSTD */ | ||
3121 | + | ||
3122 | + /* Zero self-clearing bits */ | ||
3123 | + val &= ~(E1000_CTRL_EXT_ASDCHK | E1000_CTRL_EXT_EE_RST); | ||
3124 | + core->mac[CTRL_EXT] = val; | ||
3125 | +} | ||
3126 | + | ||
3127 | +static void | ||
3128 | +igb_set_pbaclr(IGBCore *core, int index, uint32_t val) | ||
3129 | +{ | ||
3130 | + int i; | ||
3131 | + | ||
3132 | + core->mac[PBACLR] = val & E1000_PBACLR_VALID_MASK; | ||
3133 | + | ||
3134 | + if (!msix_enabled(core->owner)) { | ||
3135 | + return; | ||
3136 | + } | ||
3137 | + | ||
3138 | + for (i = 0; i < IGB_INTR_NUM; i++) { | ||
3139 | + if (core->mac[PBACLR] & BIT(i)) { | ||
3140 | + msix_clr_pending(core->owner, i); | ||
3141 | + } | ||
3142 | + } | ||
3143 | +} | ||
3144 | + | ||
3145 | +static void | ||
3146 | +igb_set_fcrth(IGBCore *core, int index, uint32_t val) | ||
3147 | +{ | ||
3148 | + core->mac[FCRTH] = val & 0xFFF8; | ||
3149 | +} | ||
3150 | + | ||
3151 | +static void | ||
3152 | +igb_set_fcrtl(IGBCore *core, int index, uint32_t val) | ||
3153 | +{ | ||
3154 | + core->mac[FCRTL] = val & 0x8000FFF8; | ||
3155 | +} | ||
3156 | + | ||
3157 | +#define IGB_LOW_BITS_SET_FUNC(num) \ | ||
3158 | + static void \ | ||
3159 | + igb_set_##num##bit(IGBCore *core, int index, uint32_t val) \ | ||
3160 | + { \ | ||
3161 | + core->mac[index] = val & (BIT(num) - 1); \ | ||
3162 | + } | ||
3163 | + | ||
3164 | +IGB_LOW_BITS_SET_FUNC(4) | ||
3165 | +IGB_LOW_BITS_SET_FUNC(13) | ||
3166 | +IGB_LOW_BITS_SET_FUNC(16) | ||
3167 | + | ||
3168 | +static void | ||
3169 | +igb_set_dlen(IGBCore *core, int index, uint32_t val) | ||
3170 | +{ | ||
3171 | + core->mac[index] = val & 0xffff0; | ||
3172 | +} | ||
3173 | + | ||
3174 | +static void | ||
3175 | +igb_set_dbal(IGBCore *core, int index, uint32_t val) | ||
3176 | +{ | ||
3177 | + core->mac[index] = val & E1000_XDBAL_MASK; | ||
3178 | +} | ||
3179 | + | ||
3180 | +static void | ||
3181 | +igb_set_tdt(IGBCore *core, int index, uint32_t val) | ||
3182 | +{ | ||
3183 | + IGB_TxRing txr; | ||
3184 | + int qn = igb_mq_queue_idx(TDT0, index); | ||
3185 | + | ||
3186 | + core->mac[index] = val & 0xffff; | ||
3187 | + | ||
3188 | + igb_tx_ring_init(core, &txr, qn); | ||
3189 | + igb_start_xmit(core, &txr); | ||
3190 | +} | ||
3191 | + | ||
3192 | +static void | ||
3193 | +igb_set_ics(IGBCore *core, int index, uint32_t val) | ||
3194 | +{ | ||
3195 | + trace_e1000e_irq_write_ics(val); | ||
3196 | + igb_set_interrupt_cause(core, val); | ||
3197 | +} | ||
3198 | + | ||
3199 | +static void | ||
3200 | +igb_set_imc(IGBCore *core, int index, uint32_t val) | ||
3201 | +{ | ||
3202 | + trace_e1000e_irq_ims_clear_set_imc(val); | ||
3203 | + igb_clear_ims_bits(core, val); | ||
3204 | + igb_update_interrupt_state(core); | ||
3205 | +} | ||
3206 | + | ||
3207 | +static void | ||
3208 | +igb_set_ims(IGBCore *core, int index, uint32_t val) | ||
3209 | +{ | ||
3210 | + uint32_t valid_val = val & 0x77D4FBFD; | ||
3211 | + | ||
3212 | + trace_e1000e_irq_set_ims(val, core->mac[IMS], core->mac[IMS] | valid_val); | ||
3213 | + core->mac[IMS] |= valid_val; | ||
3214 | + igb_update_interrupt_state(core); | ||
3215 | +} | ||
3216 | + | ||
3217 | +static void igb_commit_icr(IGBCore *core) | ||
3218 | +{ | ||
3219 | + /* | ||
3220 | + * If GPIE.NSICR = 0, then the copy of IAM to IMS will occur only if at | ||
3221 | + * least one bit is set in the IMS and there is a true interrupt as | ||
3222 | + * reflected in ICR.INTA. | ||
3223 | + */ | ||
3224 | + if ((core->mac[GPIE] & E1000_GPIE_NSICR) || | ||
3225 | + (core->mac[IMS] && (core->mac[ICR] & E1000_ICR_INT_ASSERTED))) { | ||
3226 | + igb_set_ims(core, IMS, core->mac[IAM]); | ||
3227 | + } else { | ||
3228 | + igb_update_interrupt_state(core); | ||
3229 | + } | ||
3230 | +} | ||
3231 | + | ||
3232 | +static void igb_set_icr(IGBCore *core, int index, uint32_t val) | ||
3233 | +{ | ||
3234 | + uint32_t icr = core->mac[ICR] & ~val; | ||
3235 | + | ||
3236 | + trace_igb_irq_icr_write(val, core->mac[ICR], icr); | ||
3237 | + core->mac[ICR] = icr; | ||
3238 | + igb_commit_icr(core); | ||
3239 | +} | ||
3240 | + | ||
3241 | +static uint32_t | ||
3242 | +igb_mac_readreg(IGBCore *core, int index) | ||
3243 | +{ | ||
3244 | + return core->mac[index]; | ||
3245 | +} | ||
3246 | + | ||
3247 | +static uint32_t | ||
3248 | +igb_mac_ics_read(IGBCore *core, int index) | ||
3249 | +{ | ||
3250 | + trace_e1000e_irq_read_ics(core->mac[ICS]); | ||
3251 | + return core->mac[ICS]; | ||
3252 | +} | ||
3253 | + | ||
3254 | +static uint32_t | ||
3255 | +igb_mac_ims_read(IGBCore *core, int index) | ||
3256 | +{ | ||
3257 | + trace_e1000e_irq_read_ims(core->mac[IMS]); | ||
3258 | + return core->mac[IMS]; | ||
3259 | +} | ||
3260 | + | ||
3261 | +static uint32_t | ||
3262 | +igb_mac_swsm_read(IGBCore *core, int index) | ||
3263 | +{ | ||
3264 | + uint32_t val = core->mac[SWSM]; | ||
3265 | + core->mac[SWSM] = val | E1000_SWSM_SMBI; | ||
3266 | + return val; | ||
3267 | +} | ||
3268 | + | ||
3269 | +static uint32_t | ||
3270 | +igb_mac_eitr_read(IGBCore *core, int index) | ||
3271 | +{ | ||
3272 | + return core->eitr_guest_value[index - EITR0]; | ||
3273 | +} | ||
3274 | + | ||
3275 | +static uint32_t igb_mac_vfmailbox_read(IGBCore *core, int index) | ||
3276 | +{ | ||
3277 | + uint32_t val = core->mac[index]; | ||
3278 | + | ||
3279 | + core->mac[index] &= ~(E1000_V2PMAILBOX_PFSTS | E1000_V2PMAILBOX_PFACK | | ||
3280 | + E1000_V2PMAILBOX_RSTD); | ||
3281 | + | ||
3282 | + return val; | ||
3283 | +} | ||
3284 | + | ||
3285 | +static uint32_t | ||
3286 | +igb_mac_icr_read(IGBCore *core, int index) | ||
3287 | +{ | ||
3288 | + uint32_t ret = core->mac[ICR]; | ||
3289 | + trace_e1000e_irq_icr_read_entry(ret); | ||
3290 | + | ||
3291 | + if (core->mac[GPIE] & E1000_GPIE_NSICR) { | ||
3292 | + trace_igb_irq_icr_clear_gpie_nsicr(); | ||
3293 | + core->mac[ICR] = 0; | ||
3294 | + } else if (core->mac[IMS] == 0) { | ||
3295 | + trace_e1000e_irq_icr_clear_zero_ims(); | ||
3296 | + core->mac[ICR] = 0; | ||
3297 | + } else if (!msix_enabled(core->owner)) { | ||
3298 | + trace_e1000e_irq_icr_clear_nonmsix_icr_read(); | ||
3299 | + core->mac[ICR] = 0; | ||
3300 | + } | ||
3301 | + | ||
3302 | + trace_e1000e_irq_icr_read_exit(core->mac[ICR]); | ||
3303 | + igb_commit_icr(core); | ||
3304 | + return ret; | ||
3305 | +} | ||
3306 | + | ||
3307 | +static uint32_t | ||
3308 | +igb_mac_read_clr4(IGBCore *core, int index) | ||
3309 | +{ | ||
3310 | + uint32_t ret = core->mac[index]; | ||
3311 | + | ||
3312 | + core->mac[index] = 0; | ||
3313 | + return ret; | ||
3314 | +} | ||
3315 | + | ||
3316 | +static uint32_t | ||
3317 | +igb_mac_read_clr8(IGBCore *core, int index) | ||
3318 | +{ | ||
3319 | + uint32_t ret = core->mac[index]; | ||
3320 | + | ||
3321 | + core->mac[index] = 0; | ||
3322 | + core->mac[index - 1] = 0; | ||
3323 | + return ret; | ||
3324 | +} | ||
3325 | + | ||
3326 | +static uint32_t | ||
3327 | +igb_get_ctrl(IGBCore *core, int index) | ||
3328 | +{ | ||
3329 | + uint32_t val = core->mac[CTRL]; | ||
3330 | + | ||
3331 | + trace_e1000e_link_read_params( | ||
3332 | + !!(val & E1000_CTRL_ASDE), | ||
3333 | + (val & E1000_CTRL_SPD_SEL) >> E1000_CTRL_SPD_SHIFT, | ||
3334 | + !!(val & E1000_CTRL_FRCSPD), | ||
3335 | + !!(val & E1000_CTRL_FRCDPX), | ||
3336 | + !!(val & E1000_CTRL_RFCE), | ||
3337 | + !!(val & E1000_CTRL_TFCE)); | ||
3338 | + | ||
3339 | + return val; | ||
3340 | +} | ||
3341 | + | ||
3342 | +static uint32_t igb_get_status(IGBCore *core, int index) | ||
3343 | +{ | ||
3344 | + uint32_t res = core->mac[STATUS]; | ||
3345 | + uint16_t num_vfs = pcie_sriov_num_vfs(core->owner); | ||
3346 | + | ||
3347 | + if (core->mac[CTRL] & E1000_CTRL_FRCDPX) { | ||
3348 | + res |= (core->mac[CTRL] & E1000_CTRL_FD) ? E1000_STATUS_FD : 0; | ||
3349 | + } else { | ||
3350 | + res |= E1000_STATUS_FD; | ||
3351 | + } | ||
3352 | + | ||
3353 | + if ((core->mac[CTRL] & E1000_CTRL_FRCSPD) || | ||
3354 | + (core->mac[CTRL_EXT] & E1000_CTRL_EXT_SPD_BYPS)) { | ||
3355 | + switch (core->mac[CTRL] & E1000_CTRL_SPD_SEL) { | ||
3356 | + case E1000_CTRL_SPD_10: | ||
3357 | + res |= E1000_STATUS_SPEED_10; | ||
3358 | + break; | ||
3359 | + case E1000_CTRL_SPD_100: | ||
3360 | + res |= E1000_STATUS_SPEED_100; | ||
3361 | + break; | ||
3362 | + case E1000_CTRL_SPD_1000: | ||
3363 | + default: | ||
3364 | + res |= E1000_STATUS_SPEED_1000; | ||
3365 | + break; | ||
3366 | + } | ||
3367 | + } else { | ||
3368 | + res |= E1000_STATUS_SPEED_1000; | ||
3369 | + } | ||
3370 | + | ||
3371 | + if (num_vfs) { | ||
3372 | + res |= num_vfs << E1000_STATUS_NUM_VFS_SHIFT; | ||
3373 | + res |= E1000_STATUS_IOV_MODE; | ||
3374 | + } | ||
3375 | + | ||
3376 | + /* | ||
3377 | + * Windows driver 12.18.9.23 resets if E1000_STATUS_GIO_MASTER_ENABLE is | ||
3378 | + * left set after E1000_CTRL_LRST is set. | ||
3379 | + */ | ||
3380 | + if (!(core->mac[CTRL] & E1000_CTRL_GIO_MASTER_DISABLE) && | ||
3381 | + !(core->mac[CTRL] & E1000_CTRL_LRST)) { | ||
3382 | + res |= E1000_STATUS_GIO_MASTER_ENABLE; | ||
3383 | + } | ||
3384 | + | ||
3385 | + return res; | ||
3386 | +} | ||
3387 | + | ||
3388 | +static void | ||
3389 | +igb_mac_writereg(IGBCore *core, int index, uint32_t val) | ||
3390 | +{ | ||
3391 | + core->mac[index] = val; | ||
3392 | +} | ||
3393 | + | ||
3394 | +static void | ||
3395 | +igb_mac_setmacaddr(IGBCore *core, int index, uint32_t val) | ||
3396 | +{ | ||
3397 | + uint32_t macaddr[2]; | ||
3398 | + | ||
3399 | + core->mac[index] = val; | ||
3400 | + | ||
3401 | + macaddr[0] = cpu_to_le32(core->mac[RA]); | ||
3402 | + macaddr[1] = cpu_to_le32(core->mac[RA + 1]); | ||
3403 | + qemu_format_nic_info_str(qemu_get_queue(core->owner_nic), | ||
3404 | + (uint8_t *) macaddr); | ||
3405 | + | ||
3406 | + trace_e1000e_mac_set_sw(MAC_ARG(macaddr)); | ||
3407 | +} | ||
3408 | + | ||
3409 | +static void | ||
3410 | +igb_set_eecd(IGBCore *core, int index, uint32_t val) | ||
3411 | +{ | ||
3412 | + static const uint32_t ro_bits = E1000_EECD_PRES | | ||
3413 | + E1000_EECD_AUTO_RD | | ||
3414 | + E1000_EECD_SIZE_EX_MASK; | ||
3415 | + | ||
3416 | + core->mac[EECD] = (core->mac[EECD] & ro_bits) | (val & ~ro_bits); | ||
3417 | +} | ||
3418 | + | ||
3419 | +static void | ||
3420 | +igb_set_eerd(IGBCore *core, int index, uint32_t val) | ||
3421 | +{ | ||
3422 | + uint32_t addr = (val >> E1000_EERW_ADDR_SHIFT) & E1000_EERW_ADDR_MASK; | ||
3423 | + uint32_t flags = 0; | ||
3424 | + uint32_t data = 0; | ||
3425 | + | ||
3426 | + if ((addr < IGB_EEPROM_SIZE) && (val & E1000_EERW_START)) { | ||
3427 | + data = core->eeprom[addr]; | ||
3428 | + flags = E1000_EERW_DONE; | ||
3429 | + } | ||
3430 | + | ||
3431 | + core->mac[EERD] = flags | | ||
3432 | + (addr << E1000_EERW_ADDR_SHIFT) | | ||
3433 | + (data << E1000_EERW_DATA_SHIFT); | ||
3434 | +} | ||
3435 | + | ||
3436 | +static void | ||
3437 | +igb_set_eitr(IGBCore *core, int index, uint32_t val) | ||
3438 | +{ | ||
3439 | + uint32_t eitr_num = index - EITR0; | ||
3440 | + | ||
3441 | + trace_igb_irq_eitr_set(eitr_num, val); | ||
3442 | + | ||
3443 | + core->eitr_guest_value[eitr_num] = val & ~E1000_EITR_CNT_IGNR; | ||
3444 | + core->mac[index] = val & 0x7FFE; | ||
3445 | +} | ||
3446 | + | ||
3447 | +static void | ||
3448 | +igb_update_rx_offloads(IGBCore *core) | ||
3449 | +{ | ||
3450 | + int cso_state = igb_rx_l4_cso_enabled(core); | ||
3451 | + | ||
3452 | + trace_e1000e_rx_set_cso(cso_state); | ||
3453 | + | ||
3454 | + if (core->has_vnet) { | ||
3455 | + qemu_set_offload(qemu_get_queue(core->owner_nic)->peer, | ||
3456 | + cso_state, 0, 0, 0, 0); | ||
3457 | + } | ||
3458 | +} | ||
3459 | + | ||
3460 | +static void | ||
3461 | +igb_set_rxcsum(IGBCore *core, int index, uint32_t val) | ||
3462 | +{ | ||
3463 | + core->mac[RXCSUM] = val; | ||
3464 | + igb_update_rx_offloads(core); | ||
3465 | +} | ||
3466 | + | ||
3467 | +static void | ||
3468 | +igb_set_gcr(IGBCore *core, int index, uint32_t val) | ||
3469 | +{ | ||
3470 | + uint32_t ro_bits = core->mac[GCR] & E1000_GCR_RO_BITS; | ||
3471 | + core->mac[GCR] = (val & ~E1000_GCR_RO_BITS) | ro_bits; | ||
3472 | +} | ||
3473 | + | ||
3474 | +static uint32_t igb_get_systiml(IGBCore *core, int index) | ||
3475 | +{ | ||
3476 | + e1000x_timestamp(core->mac, core->timadj, SYSTIML, SYSTIMH); | ||
3477 | + return core->mac[SYSTIML]; | ||
3478 | +} | ||
3479 | + | ||
3480 | +static uint32_t igb_get_rxsatrh(IGBCore *core, int index) | ||
3481 | +{ | ||
3482 | + core->mac[TSYNCRXCTL] &= ~E1000_TSYNCRXCTL_VALID; | ||
3483 | + return core->mac[RXSATRH]; | ||
3484 | +} | ||
3485 | + | ||
3486 | +static uint32_t igb_get_txstmph(IGBCore *core, int index) | ||
3487 | +{ | ||
3488 | + core->mac[TSYNCTXCTL] &= ~E1000_TSYNCTXCTL_VALID; | ||
3489 | + return core->mac[TXSTMPH]; | ||
3490 | +} | ||
3491 | + | ||
3492 | +static void igb_set_timinca(IGBCore *core, int index, uint32_t val) | ||
3493 | +{ | ||
3494 | + e1000x_set_timinca(core->mac, &core->timadj, val); | ||
3495 | +} | ||
3496 | + | ||
3497 | +static void igb_set_timadjh(IGBCore *core, int index, uint32_t val) | ||
3498 | +{ | ||
3499 | + core->mac[TIMADJH] = val; | ||
3500 | + core->timadj += core->mac[TIMADJL] | ((int64_t)core->mac[TIMADJH] << 32); | ||
3501 | +} | ||
3502 | + | ||
3503 | +#define igb_getreg(x) [x] = igb_mac_readreg | ||
3504 | +typedef uint32_t (*readops)(IGBCore *, int); | ||
3505 | +static const readops igb_macreg_readops[] = { | ||
3506 | + igb_getreg(WUFC), | ||
3507 | + igb_getreg(MANC), | ||
3508 | + igb_getreg(TOTL), | ||
3509 | + igb_getreg(RDT0), | ||
3510 | + igb_getreg(RDT1), | ||
3511 | + igb_getreg(RDT2), | ||
3512 | + igb_getreg(RDT3), | ||
3513 | + igb_getreg(RDT4), | ||
3514 | + igb_getreg(RDT5), | ||
3515 | + igb_getreg(RDT6), | ||
3516 | + igb_getreg(RDT7), | ||
3517 | + igb_getreg(RDT8), | ||
3518 | + igb_getreg(RDT9), | ||
3519 | + igb_getreg(RDT10), | ||
3520 | + igb_getreg(RDT11), | ||
3521 | + igb_getreg(RDT12), | ||
3522 | + igb_getreg(RDT13), | ||
3523 | + igb_getreg(RDT14), | ||
3524 | + igb_getreg(RDT15), | ||
3525 | + igb_getreg(RDBAH0), | ||
3526 | + igb_getreg(RDBAH1), | ||
3527 | + igb_getreg(RDBAH2), | ||
3528 | + igb_getreg(RDBAH3), | ||
3529 | + igb_getreg(RDBAH4), | ||
3530 | + igb_getreg(RDBAH5), | ||
3531 | + igb_getreg(RDBAH6), | ||
3532 | + igb_getreg(RDBAH7), | ||
3533 | + igb_getreg(RDBAH8), | ||
3534 | + igb_getreg(RDBAH9), | ||
3535 | + igb_getreg(RDBAH10), | ||
3536 | + igb_getreg(RDBAH11), | ||
3537 | + igb_getreg(RDBAH12), | ||
3538 | + igb_getreg(RDBAH13), | ||
3539 | + igb_getreg(RDBAH14), | ||
3540 | + igb_getreg(RDBAH15), | ||
3541 | + igb_getreg(TDBAL0), | ||
3542 | + igb_getreg(TDBAL1), | ||
3543 | + igb_getreg(TDBAL2), | ||
3544 | + igb_getreg(TDBAL3), | ||
3545 | + igb_getreg(TDBAL4), | ||
3546 | + igb_getreg(TDBAL5), | ||
3547 | + igb_getreg(TDBAL6), | ||
3548 | + igb_getreg(TDBAL7), | ||
3549 | + igb_getreg(TDBAL8), | ||
3550 | + igb_getreg(TDBAL9), | ||
3551 | + igb_getreg(TDBAL10), | ||
3552 | + igb_getreg(TDBAL11), | ||
3553 | + igb_getreg(TDBAL12), | ||
3554 | + igb_getreg(TDBAL13), | ||
3555 | + igb_getreg(TDBAL14), | ||
3556 | + igb_getreg(TDBAL15), | ||
3557 | + igb_getreg(RDLEN0), | ||
3558 | + igb_getreg(RDLEN1), | ||
3559 | + igb_getreg(RDLEN2), | ||
3560 | + igb_getreg(RDLEN3), | ||
3561 | + igb_getreg(RDLEN4), | ||
3562 | + igb_getreg(RDLEN5), | ||
3563 | + igb_getreg(RDLEN6), | ||
3564 | + igb_getreg(RDLEN7), | ||
3565 | + igb_getreg(RDLEN8), | ||
3566 | + igb_getreg(RDLEN9), | ||
3567 | + igb_getreg(RDLEN10), | ||
3568 | + igb_getreg(RDLEN11), | ||
3569 | + igb_getreg(RDLEN12), | ||
3570 | + igb_getreg(RDLEN13), | ||
3571 | + igb_getreg(RDLEN14), | ||
3572 | + igb_getreg(RDLEN15), | ||
3573 | + igb_getreg(SRRCTL0), | ||
3574 | + igb_getreg(SRRCTL1), | ||
3575 | + igb_getreg(SRRCTL2), | ||
3576 | + igb_getreg(SRRCTL3), | ||
3577 | + igb_getreg(SRRCTL4), | ||
3578 | + igb_getreg(SRRCTL5), | ||
3579 | + igb_getreg(SRRCTL6), | ||
3580 | + igb_getreg(SRRCTL7), | ||
3581 | + igb_getreg(SRRCTL8), | ||
3582 | + igb_getreg(SRRCTL9), | ||
3583 | + igb_getreg(SRRCTL10), | ||
3584 | + igb_getreg(SRRCTL11), | ||
3585 | + igb_getreg(SRRCTL12), | ||
3586 | + igb_getreg(SRRCTL13), | ||
3587 | + igb_getreg(SRRCTL14), | ||
3588 | + igb_getreg(SRRCTL15), | ||
3589 | + igb_getreg(LATECOL), | ||
3590 | + igb_getreg(XONTXC), | ||
3591 | + igb_getreg(TDFH), | ||
3592 | + igb_getreg(TDFT), | ||
3593 | + igb_getreg(TDFHS), | ||
3594 | + igb_getreg(TDFTS), | ||
3595 | + igb_getreg(TDFPC), | ||
3596 | + igb_getreg(WUS), | ||
3597 | + igb_getreg(RDFH), | ||
3598 | + igb_getreg(RDFT), | ||
3599 | + igb_getreg(RDFHS), | ||
3600 | + igb_getreg(RDFTS), | ||
3601 | + igb_getreg(RDFPC), | ||
3602 | + igb_getreg(GORCL), | ||
3603 | + igb_getreg(MGTPRC), | ||
3604 | + igb_getreg(EERD), | ||
3605 | + igb_getreg(EIAC), | ||
3606 | + igb_getreg(MANC2H), | ||
3607 | + igb_getreg(RXCSUM), | ||
3608 | + igb_getreg(GSCL_3), | ||
3609 | + igb_getreg(GSCN_2), | ||
3610 | + igb_getreg(FCAH), | ||
3611 | + igb_getreg(FCRTH), | ||
3612 | + igb_getreg(FLOP), | ||
3613 | + igb_getreg(RXSTMPH), | ||
3614 | + igb_getreg(TXSTMPL), | ||
3615 | + igb_getreg(TIMADJL), | ||
3616 | + igb_getreg(RDH0), | ||
3617 | + igb_getreg(RDH1), | ||
3618 | + igb_getreg(RDH2), | ||
3619 | + igb_getreg(RDH3), | ||
3620 | + igb_getreg(RDH4), | ||
3621 | + igb_getreg(RDH5), | ||
3622 | + igb_getreg(RDH6), | ||
3623 | + igb_getreg(RDH7), | ||
3624 | + igb_getreg(RDH8), | ||
3625 | + igb_getreg(RDH9), | ||
3626 | + igb_getreg(RDH10), | ||
3627 | + igb_getreg(RDH11), | ||
3628 | + igb_getreg(RDH12), | ||
3629 | + igb_getreg(RDH13), | ||
3630 | + igb_getreg(RDH14), | ||
3631 | + igb_getreg(RDH15), | ||
3632 | + igb_getreg(TDT0), | ||
3633 | + igb_getreg(TDT1), | ||
3634 | + igb_getreg(TDT2), | ||
3635 | + igb_getreg(TDT3), | ||
3636 | + igb_getreg(TDT4), | ||
3637 | + igb_getreg(TDT5), | ||
3638 | + igb_getreg(TDT6), | ||
3639 | + igb_getreg(TDT7), | ||
3640 | + igb_getreg(TDT8), | ||
3641 | + igb_getreg(TDT9), | ||
3642 | + igb_getreg(TDT10), | ||
3643 | + igb_getreg(TDT11), | ||
3644 | + igb_getreg(TDT12), | ||
3645 | + igb_getreg(TDT13), | ||
3646 | + igb_getreg(TDT14), | ||
3647 | + igb_getreg(TDT15), | ||
3648 | + igb_getreg(TNCRS), | ||
3649 | + igb_getreg(RJC), | ||
3650 | + igb_getreg(IAM), | ||
3651 | + igb_getreg(GSCL_2), | ||
3652 | + igb_getreg(TIPG), | ||
3653 | + igb_getreg(FLMNGCTL), | ||
3654 | + igb_getreg(FLMNGCNT), | ||
3655 | + igb_getreg(TSYNCTXCTL), | ||
3656 | + igb_getreg(EEMNGDATA), | ||
3657 | + igb_getreg(CTRL_EXT), | ||
3658 | + igb_getreg(SYSTIMH), | ||
3659 | + igb_getreg(EEMNGCTL), | ||
3660 | + igb_getreg(FLMNGDATA), | ||
3661 | + igb_getreg(TSYNCRXCTL), | ||
3662 | + igb_getreg(LEDCTL), | ||
3663 | + igb_getreg(TCTL), | ||
3664 | + igb_getreg(TCTL_EXT), | ||
3665 | + igb_getreg(DTXCTL), | ||
3666 | + igb_getreg(RXPBS), | ||
3667 | + igb_getreg(TDH0), | ||
3668 | + igb_getreg(TDH1), | ||
3669 | + igb_getreg(TDH2), | ||
3670 | + igb_getreg(TDH3), | ||
3671 | + igb_getreg(TDH4), | ||
3672 | + igb_getreg(TDH5), | ||
3673 | + igb_getreg(TDH6), | ||
3674 | + igb_getreg(TDH7), | ||
3675 | + igb_getreg(TDH8), | ||
3676 | + igb_getreg(TDH9), | ||
3677 | + igb_getreg(TDH10), | ||
3678 | + igb_getreg(TDH11), | ||
3679 | + igb_getreg(TDH12), | ||
3680 | + igb_getreg(TDH13), | ||
3681 | + igb_getreg(TDH14), | ||
3682 | + igb_getreg(TDH15), | ||
3683 | + igb_getreg(ECOL), | ||
3684 | + igb_getreg(DC), | ||
3685 | + igb_getreg(RLEC), | ||
3686 | + igb_getreg(XOFFTXC), | ||
3687 | + igb_getreg(RFC), | ||
3688 | + igb_getreg(RNBC), | ||
3689 | + igb_getreg(MGTPTC), | ||
3690 | + igb_getreg(TIMINCA), | ||
3691 | + igb_getreg(FACTPS), | ||
3692 | + igb_getreg(GSCL_1), | ||
3693 | + igb_getreg(GSCN_0), | ||
3694 | + igb_getreg(PBACLR), | ||
3695 | + igb_getreg(FCTTV), | ||
3696 | + igb_getreg(RXSATRL), | ||
3697 | + igb_getreg(TORL), | ||
3698 | + igb_getreg(TDLEN0), | ||
3699 | + igb_getreg(TDLEN1), | ||
3700 | + igb_getreg(TDLEN2), | ||
3701 | + igb_getreg(TDLEN3), | ||
3702 | + igb_getreg(TDLEN4), | ||
3703 | + igb_getreg(TDLEN5), | ||
3704 | + igb_getreg(TDLEN6), | ||
3705 | + igb_getreg(TDLEN7), | ||
3706 | + igb_getreg(TDLEN8), | ||
3707 | + igb_getreg(TDLEN9), | ||
3708 | + igb_getreg(TDLEN10), | ||
3709 | + igb_getreg(TDLEN11), | ||
3710 | + igb_getreg(TDLEN12), | ||
3711 | + igb_getreg(TDLEN13), | ||
3712 | + igb_getreg(TDLEN14), | ||
3713 | + igb_getreg(TDLEN15), | ||
3714 | + igb_getreg(MCC), | ||
3715 | + igb_getreg(WUC), | ||
3716 | + igb_getreg(EECD), | ||
3717 | + igb_getreg(FCRTV), | ||
3718 | + igb_getreg(TXDCTL0), | ||
3719 | + igb_getreg(TXDCTL1), | ||
3720 | + igb_getreg(TXDCTL2), | ||
3721 | + igb_getreg(TXDCTL3), | ||
3722 | + igb_getreg(TXDCTL4), | ||
3723 | + igb_getreg(TXDCTL5), | ||
3724 | + igb_getreg(TXDCTL6), | ||
3725 | + igb_getreg(TXDCTL7), | ||
3726 | + igb_getreg(TXDCTL8), | ||
3727 | + igb_getreg(TXDCTL9), | ||
3728 | + igb_getreg(TXDCTL10), | ||
3729 | + igb_getreg(TXDCTL11), | ||
3730 | + igb_getreg(TXDCTL12), | ||
3731 | + igb_getreg(TXDCTL13), | ||
3732 | + igb_getreg(TXDCTL14), | ||
3733 | + igb_getreg(TXDCTL15), | ||
3734 | + igb_getreg(TXCTL0), | ||
3735 | + igb_getreg(TXCTL1), | ||
3736 | + igb_getreg(TXCTL2), | ||
3737 | + igb_getreg(TXCTL3), | ||
3738 | + igb_getreg(TXCTL4), | ||
3739 | + igb_getreg(TXCTL5), | ||
3740 | + igb_getreg(TXCTL6), | ||
3741 | + igb_getreg(TXCTL7), | ||
3742 | + igb_getreg(TXCTL8), | ||
3743 | + igb_getreg(TXCTL9), | ||
3744 | + igb_getreg(TXCTL10), | ||
3745 | + igb_getreg(TXCTL11), | ||
3746 | + igb_getreg(TXCTL12), | ||
3747 | + igb_getreg(TXCTL13), | ||
3748 | + igb_getreg(TXCTL14), | ||
3749 | + igb_getreg(TXCTL15), | ||
3750 | + igb_getreg(TDWBAL0), | ||
3751 | + igb_getreg(TDWBAL1), | ||
3752 | + igb_getreg(TDWBAL2), | ||
3753 | + igb_getreg(TDWBAL3), | ||
3754 | + igb_getreg(TDWBAL4), | ||
3755 | + igb_getreg(TDWBAL5), | ||
3756 | + igb_getreg(TDWBAL6), | ||
3757 | + igb_getreg(TDWBAL7), | ||
3758 | + igb_getreg(TDWBAL8), | ||
3759 | + igb_getreg(TDWBAL9), | ||
3760 | + igb_getreg(TDWBAL10), | ||
3761 | + igb_getreg(TDWBAL11), | ||
3762 | + igb_getreg(TDWBAL12), | ||
3763 | + igb_getreg(TDWBAL13), | ||
3764 | + igb_getreg(TDWBAL14), | ||
3765 | + igb_getreg(TDWBAL15), | ||
3766 | + igb_getreg(TDWBAH0), | ||
3767 | + igb_getreg(TDWBAH1), | ||
3768 | + igb_getreg(TDWBAH2), | ||
3769 | + igb_getreg(TDWBAH3), | ||
3770 | + igb_getreg(TDWBAH4), | ||
3771 | + igb_getreg(TDWBAH5), | ||
3772 | + igb_getreg(TDWBAH6), | ||
3773 | + igb_getreg(TDWBAH7), | ||
3774 | + igb_getreg(TDWBAH8), | ||
3775 | + igb_getreg(TDWBAH9), | ||
3776 | + igb_getreg(TDWBAH10), | ||
3777 | + igb_getreg(TDWBAH11), | ||
3778 | + igb_getreg(TDWBAH12), | ||
3779 | + igb_getreg(TDWBAH13), | ||
3780 | + igb_getreg(TDWBAH14), | ||
3781 | + igb_getreg(TDWBAH15), | ||
3782 | + igb_getreg(PVTCTRL0), | ||
3783 | + igb_getreg(PVTCTRL1), | ||
3784 | + igb_getreg(PVTCTRL2), | ||
3785 | + igb_getreg(PVTCTRL3), | ||
3786 | + igb_getreg(PVTCTRL4), | ||
3787 | + igb_getreg(PVTCTRL5), | ||
3788 | + igb_getreg(PVTCTRL6), | ||
3789 | + igb_getreg(PVTCTRL7), | ||
3790 | + igb_getreg(PVTEIMS0), | ||
3791 | + igb_getreg(PVTEIMS1), | ||
3792 | + igb_getreg(PVTEIMS2), | ||
3793 | + igb_getreg(PVTEIMS3), | ||
3794 | + igb_getreg(PVTEIMS4), | ||
3795 | + igb_getreg(PVTEIMS5), | ||
3796 | + igb_getreg(PVTEIMS6), | ||
3797 | + igb_getreg(PVTEIMS7), | ||
3798 | + igb_getreg(PVTEIAC0), | ||
3799 | + igb_getreg(PVTEIAC1), | ||
3800 | + igb_getreg(PVTEIAC2), | ||
3801 | + igb_getreg(PVTEIAC3), | ||
3802 | + igb_getreg(PVTEIAC4), | ||
3803 | + igb_getreg(PVTEIAC5), | ||
3804 | + igb_getreg(PVTEIAC6), | ||
3805 | + igb_getreg(PVTEIAC7), | ||
3806 | + igb_getreg(PVTEIAM0), | ||
3807 | + igb_getreg(PVTEIAM1), | ||
3808 | + igb_getreg(PVTEIAM2), | ||
3809 | + igb_getreg(PVTEIAM3), | ||
3810 | + igb_getreg(PVTEIAM4), | ||
3811 | + igb_getreg(PVTEIAM5), | ||
3812 | + igb_getreg(PVTEIAM6), | ||
3813 | + igb_getreg(PVTEIAM7), | ||
3814 | + igb_getreg(PVFGPRC0), | ||
3815 | + igb_getreg(PVFGPRC1), | ||
3816 | + igb_getreg(PVFGPRC2), | ||
3817 | + igb_getreg(PVFGPRC3), | ||
3818 | + igb_getreg(PVFGPRC4), | ||
3819 | + igb_getreg(PVFGPRC5), | ||
3820 | + igb_getreg(PVFGPRC6), | ||
3821 | + igb_getreg(PVFGPRC7), | ||
3822 | + igb_getreg(PVFGPTC0), | ||
3823 | + igb_getreg(PVFGPTC1), | ||
3824 | + igb_getreg(PVFGPTC2), | ||
3825 | + igb_getreg(PVFGPTC3), | ||
3826 | + igb_getreg(PVFGPTC4), | ||
3827 | + igb_getreg(PVFGPTC5), | ||
3828 | + igb_getreg(PVFGPTC6), | ||
3829 | + igb_getreg(PVFGPTC7), | ||
3830 | + igb_getreg(PVFGORC0), | ||
3831 | + igb_getreg(PVFGORC1), | ||
3832 | + igb_getreg(PVFGORC2), | ||
3833 | + igb_getreg(PVFGORC3), | ||
3834 | + igb_getreg(PVFGORC4), | ||
3835 | + igb_getreg(PVFGORC5), | ||
3836 | + igb_getreg(PVFGORC6), | ||
3837 | + igb_getreg(PVFGORC7), | ||
3838 | + igb_getreg(PVFGOTC0), | ||
3839 | + igb_getreg(PVFGOTC1), | ||
3840 | + igb_getreg(PVFGOTC2), | ||
3841 | + igb_getreg(PVFGOTC3), | ||
3842 | + igb_getreg(PVFGOTC4), | ||
3843 | + igb_getreg(PVFGOTC5), | ||
3844 | + igb_getreg(PVFGOTC6), | ||
3845 | + igb_getreg(PVFGOTC7), | ||
3846 | + igb_getreg(PVFMPRC0), | ||
3847 | + igb_getreg(PVFMPRC1), | ||
3848 | + igb_getreg(PVFMPRC2), | ||
3849 | + igb_getreg(PVFMPRC3), | ||
3850 | + igb_getreg(PVFMPRC4), | ||
3851 | + igb_getreg(PVFMPRC5), | ||
3852 | + igb_getreg(PVFMPRC6), | ||
3853 | + igb_getreg(PVFMPRC7), | ||
3854 | + igb_getreg(PVFGPRLBC0), | ||
3855 | + igb_getreg(PVFGPRLBC1), | ||
3856 | + igb_getreg(PVFGPRLBC2), | ||
3857 | + igb_getreg(PVFGPRLBC3), | ||
3858 | + igb_getreg(PVFGPRLBC4), | ||
3859 | + igb_getreg(PVFGPRLBC5), | ||
3860 | + igb_getreg(PVFGPRLBC6), | ||
3861 | + igb_getreg(PVFGPRLBC7), | ||
3862 | + igb_getreg(PVFGPTLBC0), | ||
3863 | + igb_getreg(PVFGPTLBC1), | ||
3864 | + igb_getreg(PVFGPTLBC2), | ||
3865 | + igb_getreg(PVFGPTLBC3), | ||
3866 | + igb_getreg(PVFGPTLBC4), | ||
3867 | + igb_getreg(PVFGPTLBC5), | ||
3868 | + igb_getreg(PVFGPTLBC6), | ||
3869 | + igb_getreg(PVFGPTLBC7), | ||
3870 | + igb_getreg(PVFGORLBC0), | ||
3871 | + igb_getreg(PVFGORLBC1), | ||
3872 | + igb_getreg(PVFGORLBC2), | ||
3873 | + igb_getreg(PVFGORLBC3), | ||
3874 | + igb_getreg(PVFGORLBC4), | ||
3875 | + igb_getreg(PVFGORLBC5), | ||
3876 | + igb_getreg(PVFGORLBC6), | ||
3877 | + igb_getreg(PVFGORLBC7), | ||
3878 | + igb_getreg(PVFGOTLBC0), | ||
3879 | + igb_getreg(PVFGOTLBC1), | ||
3880 | + igb_getreg(PVFGOTLBC2), | ||
3881 | + igb_getreg(PVFGOTLBC3), | ||
3882 | + igb_getreg(PVFGOTLBC4), | ||
3883 | + igb_getreg(PVFGOTLBC5), | ||
3884 | + igb_getreg(PVFGOTLBC6), | ||
3885 | + igb_getreg(PVFGOTLBC7), | ||
3886 | + igb_getreg(RCTL), | ||
3887 | + igb_getreg(MDIC), | ||
3888 | + igb_getreg(FCRUC), | ||
3889 | + igb_getreg(VET), | ||
3890 | + igb_getreg(RDBAL0), | ||
3891 | + igb_getreg(RDBAL1), | ||
3892 | + igb_getreg(RDBAL2), | ||
3893 | + igb_getreg(RDBAL3), | ||
3894 | + igb_getreg(RDBAL4), | ||
3895 | + igb_getreg(RDBAL5), | ||
3896 | + igb_getreg(RDBAL6), | ||
3897 | + igb_getreg(RDBAL7), | ||
3898 | + igb_getreg(RDBAL8), | ||
3899 | + igb_getreg(RDBAL9), | ||
3900 | + igb_getreg(RDBAL10), | ||
3901 | + igb_getreg(RDBAL11), | ||
3902 | + igb_getreg(RDBAL12), | ||
3903 | + igb_getreg(RDBAL13), | ||
3904 | + igb_getreg(RDBAL14), | ||
3905 | + igb_getreg(RDBAL15), | ||
3906 | + igb_getreg(TDBAH0), | ||
3907 | + igb_getreg(TDBAH1), | ||
3908 | + igb_getreg(TDBAH2), | ||
3909 | + igb_getreg(TDBAH3), | ||
3910 | + igb_getreg(TDBAH4), | ||
3911 | + igb_getreg(TDBAH5), | ||
3912 | + igb_getreg(TDBAH6), | ||
3913 | + igb_getreg(TDBAH7), | ||
3914 | + igb_getreg(TDBAH8), | ||
3915 | + igb_getreg(TDBAH9), | ||
3916 | + igb_getreg(TDBAH10), | ||
3917 | + igb_getreg(TDBAH11), | ||
3918 | + igb_getreg(TDBAH12), | ||
3919 | + igb_getreg(TDBAH13), | ||
3920 | + igb_getreg(TDBAH14), | ||
3921 | + igb_getreg(TDBAH15), | ||
3922 | + igb_getreg(SCC), | ||
3923 | + igb_getreg(COLC), | ||
3924 | + igb_getreg(XOFFRXC), | ||
3925 | + igb_getreg(IPAV), | ||
3926 | + igb_getreg(GOTCL), | ||
3927 | + igb_getreg(MGTPDC), | ||
3928 | + igb_getreg(GCR), | ||
3929 | + igb_getreg(MFVAL), | ||
3930 | + igb_getreg(FUNCTAG), | ||
3931 | + igb_getreg(GSCL_4), | ||
3932 | + igb_getreg(GSCN_3), | ||
3933 | + igb_getreg(MRQC), | ||
3934 | + igb_getreg(FCT), | ||
3935 | + igb_getreg(FLA), | ||
3936 | + igb_getreg(RXDCTL0), | ||
3937 | + igb_getreg(RXDCTL1), | ||
3938 | + igb_getreg(RXDCTL2), | ||
3939 | + igb_getreg(RXDCTL3), | ||
3940 | + igb_getreg(RXDCTL4), | ||
3941 | + igb_getreg(RXDCTL5), | ||
3942 | + igb_getreg(RXDCTL6), | ||
3943 | + igb_getreg(RXDCTL7), | ||
3944 | + igb_getreg(RXDCTL8), | ||
3945 | + igb_getreg(RXDCTL9), | ||
3946 | + igb_getreg(RXDCTL10), | ||
3947 | + igb_getreg(RXDCTL11), | ||
3948 | + igb_getreg(RXDCTL12), | ||
3949 | + igb_getreg(RXDCTL13), | ||
3950 | + igb_getreg(RXDCTL14), | ||
3951 | + igb_getreg(RXDCTL15), | ||
3952 | + igb_getreg(RXSTMPL), | ||
3953 | + igb_getreg(TIMADJH), | ||
3954 | + igb_getreg(FCRTL), | ||
3955 | + igb_getreg(XONRXC), | ||
3956 | + igb_getreg(RFCTL), | ||
3957 | + igb_getreg(GSCN_1), | ||
3958 | + igb_getreg(FCAL), | ||
3959 | + igb_getreg(GPIE), | ||
3960 | + igb_getreg(TXPBS), | ||
3961 | + igb_getreg(RLPML), | ||
3962 | + | ||
3963 | + [TOTH] = igb_mac_read_clr8, | ||
3964 | + [GOTCH] = igb_mac_read_clr8, | ||
3965 | + [PRC64] = igb_mac_read_clr4, | ||
3966 | + [PRC255] = igb_mac_read_clr4, | ||
3967 | + [PRC1023] = igb_mac_read_clr4, | ||
3968 | + [PTC64] = igb_mac_read_clr4, | ||
3969 | + [PTC255] = igb_mac_read_clr4, | ||
3970 | + [PTC1023] = igb_mac_read_clr4, | ||
3971 | + [GPRC] = igb_mac_read_clr4, | ||
3972 | + [TPT] = igb_mac_read_clr4, | ||
3973 | + [RUC] = igb_mac_read_clr4, | ||
3974 | + [BPRC] = igb_mac_read_clr4, | ||
3975 | + [MPTC] = igb_mac_read_clr4, | ||
3976 | + [IAC] = igb_mac_read_clr4, | ||
3977 | + [ICR] = igb_mac_icr_read, | ||
3978 | + [STATUS] = igb_get_status, | ||
3979 | + [ICS] = igb_mac_ics_read, | ||
3980 | + /* | ||
3981 | + * 8.8.10: Reading the IMC register returns the value of the IMS register. | ||
3982 | + */ | ||
3983 | + [IMC] = igb_mac_ims_read, | ||
3984 | + [TORH] = igb_mac_read_clr8, | ||
3985 | + [GORCH] = igb_mac_read_clr8, | ||
3986 | + [PRC127] = igb_mac_read_clr4, | ||
3987 | + [PRC511] = igb_mac_read_clr4, | ||
3988 | + [PRC1522] = igb_mac_read_clr4, | ||
3989 | + [PTC127] = igb_mac_read_clr4, | ||
3990 | + [PTC511] = igb_mac_read_clr4, | ||
3991 | + [PTC1522] = igb_mac_read_clr4, | ||
3992 | + [GPTC] = igb_mac_read_clr4, | ||
3993 | + [TPR] = igb_mac_read_clr4, | ||
3994 | + [ROC] = igb_mac_read_clr4, | ||
3995 | + [MPRC] = igb_mac_read_clr4, | ||
3996 | + [BPTC] = igb_mac_read_clr4, | ||
3997 | + [TSCTC] = igb_mac_read_clr4, | ||
3998 | + [CTRL] = igb_get_ctrl, | ||
3999 | + [SWSM] = igb_mac_swsm_read, | ||
4000 | + [IMS] = igb_mac_ims_read, | ||
4001 | + [SYSTIML] = igb_get_systiml, | ||
4002 | + [RXSATRH] = igb_get_rxsatrh, | ||
4003 | + [TXSTMPH] = igb_get_txstmph, | ||
4004 | + | ||
4005 | + [CRCERRS ... MPC] = igb_mac_readreg, | ||
4006 | + [IP6AT ... IP6AT + 3] = igb_mac_readreg, | ||
4007 | + [IP4AT ... IP4AT + 6] = igb_mac_readreg, | ||
4008 | + [RA ... RA + 31] = igb_mac_readreg, | ||
4009 | + [RA2 ... RA2 + 31] = igb_mac_readreg, | ||
4010 | + [WUPM ... WUPM + 31] = igb_mac_readreg, | ||
4011 | + [MTA ... MTA + E1000_MC_TBL_SIZE - 1] = igb_mac_readreg, | ||
4012 | + [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] = igb_mac_readreg, | ||
4013 | + [FFMT ... FFMT + 254] = igb_mac_readreg, | ||
4014 | + [MDEF ... MDEF + 7] = igb_mac_readreg, | ||
4015 | + [FTFT ... FTFT + 254] = igb_mac_readreg, | ||
4016 | + [RETA ... RETA + 31] = igb_mac_readreg, | ||
4017 | + [RSSRK ... RSSRK + 9] = igb_mac_readreg, | ||
4018 | + [MAVTV0 ... MAVTV3] = igb_mac_readreg, | ||
4019 | + [EITR0 ... EITR0 + IGB_INTR_NUM - 1] = igb_mac_eitr_read, | ||
4020 | + [PVTEICR0] = igb_mac_read_clr4, | ||
4021 | + [PVTEICR1] = igb_mac_read_clr4, | ||
4022 | + [PVTEICR2] = igb_mac_read_clr4, | ||
4023 | + [PVTEICR3] = igb_mac_read_clr4, | ||
4024 | + [PVTEICR4] = igb_mac_read_clr4, | ||
4025 | + [PVTEICR5] = igb_mac_read_clr4, | ||
4026 | + [PVTEICR6] = igb_mac_read_clr4, | ||
4027 | + [PVTEICR7] = igb_mac_read_clr4, | ||
4028 | + | ||
4029 | + /* IGB specific: */ | ||
4030 | + [FWSM] = igb_mac_readreg, | ||
4031 | + [SW_FW_SYNC] = igb_mac_readreg, | ||
4032 | + [HTCBDPC] = igb_mac_read_clr4, | ||
4033 | + [EICR] = igb_mac_read_clr4, | ||
4034 | + [EIMS] = igb_mac_readreg, | ||
4035 | + [EIAM] = igb_mac_readreg, | ||
4036 | + [IVAR0 ... IVAR0 + 7] = igb_mac_readreg, | ||
4037 | + igb_getreg(IVAR_MISC), | ||
4038 | + igb_getreg(VT_CTL), | ||
4039 | + [P2VMAILBOX0 ... P2VMAILBOX7] = igb_mac_readreg, | ||
4040 | + [V2PMAILBOX0 ... V2PMAILBOX7] = igb_mac_vfmailbox_read, | ||
4041 | + igb_getreg(MBVFICR), | ||
4042 | + [VMBMEM0 ... VMBMEM0 + 127] = igb_mac_readreg, | ||
4043 | + igb_getreg(MBVFIMR), | ||
4044 | + igb_getreg(VFLRE), | ||
4045 | + igb_getreg(VFRE), | ||
4046 | + igb_getreg(VFTE), | ||
4047 | + igb_getreg(QDE), | ||
4048 | + igb_getreg(DTXSWC), | ||
4049 | + igb_getreg(RPLOLR), | ||
4050 | + [VLVF0 ... VLVF0 + E1000_VLVF_ARRAY_SIZE - 1] = igb_mac_readreg, | ||
4051 | + [VMVIR0 ... VMVIR7] = igb_mac_readreg, | ||
4052 | + [VMOLR0 ... VMOLR7] = igb_mac_readreg, | ||
4053 | + [WVBR] = igb_mac_read_clr4, | ||
4054 | + [RQDPC0] = igb_mac_read_clr4, | ||
4055 | + [RQDPC1] = igb_mac_read_clr4, | ||
4056 | + [RQDPC2] = igb_mac_read_clr4, | ||
4057 | + [RQDPC3] = igb_mac_read_clr4, | ||
4058 | + [RQDPC4] = igb_mac_read_clr4, | ||
4059 | + [RQDPC5] = igb_mac_read_clr4, | ||
4060 | + [RQDPC6] = igb_mac_read_clr4, | ||
4061 | + [RQDPC7] = igb_mac_read_clr4, | ||
4062 | + [RQDPC8] = igb_mac_read_clr4, | ||
4063 | + [RQDPC9] = igb_mac_read_clr4, | ||
4064 | + [RQDPC10] = igb_mac_read_clr4, | ||
4065 | + [RQDPC11] = igb_mac_read_clr4, | ||
4066 | + [RQDPC12] = igb_mac_read_clr4, | ||
4067 | + [RQDPC13] = igb_mac_read_clr4, | ||
4068 | + [RQDPC14] = igb_mac_read_clr4, | ||
4069 | + [RQDPC15] = igb_mac_read_clr4, | ||
4070 | + [VTIVAR ... VTIVAR + 7] = igb_mac_readreg, | ||
4071 | + [VTIVAR_MISC ... VTIVAR_MISC + 7] = igb_mac_readreg, | ||
4072 | +}; | ||
4073 | +enum { IGB_NREADOPS = ARRAY_SIZE(igb_macreg_readops) }; | ||
4074 | + | ||
4075 | +#define igb_putreg(x) [x] = igb_mac_writereg | ||
4076 | +typedef void (*writeops)(IGBCore *, int, uint32_t); | ||
4077 | +static const writeops igb_macreg_writeops[] = { | ||
4078 | + igb_putreg(SWSM), | ||
4079 | + igb_putreg(WUFC), | ||
4080 | + igb_putreg(RDBAH0), | ||
4081 | + igb_putreg(RDBAH1), | ||
4082 | + igb_putreg(RDBAH2), | ||
4083 | + igb_putreg(RDBAH3), | ||
4084 | + igb_putreg(RDBAH4), | ||
4085 | + igb_putreg(RDBAH5), | ||
4086 | + igb_putreg(RDBAH6), | ||
4087 | + igb_putreg(RDBAH7), | ||
4088 | + igb_putreg(RDBAH8), | ||
4089 | + igb_putreg(RDBAH9), | ||
4090 | + igb_putreg(RDBAH10), | ||
4091 | + igb_putreg(RDBAH11), | ||
4092 | + igb_putreg(RDBAH12), | ||
4093 | + igb_putreg(RDBAH13), | ||
4094 | + igb_putreg(RDBAH14), | ||
4095 | + igb_putreg(RDBAH15), | ||
4096 | + igb_putreg(SRRCTL0), | ||
4097 | + igb_putreg(SRRCTL1), | ||
4098 | + igb_putreg(SRRCTL2), | ||
4099 | + igb_putreg(SRRCTL3), | ||
4100 | + igb_putreg(SRRCTL4), | ||
4101 | + igb_putreg(SRRCTL5), | ||
4102 | + igb_putreg(SRRCTL6), | ||
4103 | + igb_putreg(SRRCTL7), | ||
4104 | + igb_putreg(SRRCTL8), | ||
4105 | + igb_putreg(SRRCTL9), | ||
4106 | + igb_putreg(SRRCTL10), | ||
4107 | + igb_putreg(SRRCTL11), | ||
4108 | + igb_putreg(SRRCTL12), | ||
4109 | + igb_putreg(SRRCTL13), | ||
4110 | + igb_putreg(SRRCTL14), | ||
4111 | + igb_putreg(SRRCTL15), | ||
4112 | + igb_putreg(RXDCTL0), | ||
4113 | + igb_putreg(RXDCTL1), | ||
4114 | + igb_putreg(RXDCTL2), | ||
4115 | + igb_putreg(RXDCTL3), | ||
4116 | + igb_putreg(RXDCTL4), | ||
4117 | + igb_putreg(RXDCTL5), | ||
4118 | + igb_putreg(RXDCTL6), | ||
4119 | + igb_putreg(RXDCTL7), | ||
4120 | + igb_putreg(RXDCTL8), | ||
4121 | + igb_putreg(RXDCTL9), | ||
4122 | + igb_putreg(RXDCTL10), | ||
4123 | + igb_putreg(RXDCTL11), | ||
4124 | + igb_putreg(RXDCTL12), | ||
4125 | + igb_putreg(RXDCTL13), | ||
4126 | + igb_putreg(RXDCTL14), | ||
4127 | + igb_putreg(RXDCTL15), | ||
4128 | + igb_putreg(LEDCTL), | ||
4129 | + igb_putreg(TCTL), | ||
4130 | + igb_putreg(TCTL_EXT), | ||
4131 | + igb_putreg(DTXCTL), | ||
4132 | + igb_putreg(RXPBS), | ||
4133 | + igb_putreg(RQDPC0), | ||
4134 | + igb_putreg(FCAL), | ||
4135 | + igb_putreg(FCRUC), | ||
4136 | + igb_putreg(WUC), | ||
4137 | + igb_putreg(WUS), | ||
4138 | + igb_putreg(IPAV), | ||
4139 | + igb_putreg(TDBAH0), | ||
4140 | + igb_putreg(TDBAH1), | ||
4141 | + igb_putreg(TDBAH2), | ||
4142 | + igb_putreg(TDBAH3), | ||
4143 | + igb_putreg(TDBAH4), | ||
4144 | + igb_putreg(TDBAH5), | ||
4145 | + igb_putreg(TDBAH6), | ||
4146 | + igb_putreg(TDBAH7), | ||
4147 | + igb_putreg(TDBAH8), | ||
4148 | + igb_putreg(TDBAH9), | ||
4149 | + igb_putreg(TDBAH10), | ||
4150 | + igb_putreg(TDBAH11), | ||
4151 | + igb_putreg(TDBAH12), | ||
4152 | + igb_putreg(TDBAH13), | ||
4153 | + igb_putreg(TDBAH14), | ||
4154 | + igb_putreg(TDBAH15), | ||
4155 | + igb_putreg(IAM), | ||
4156 | + igb_putreg(MANC), | ||
4157 | + igb_putreg(MANC2H), | ||
4158 | + igb_putreg(MFVAL), | ||
4159 | + igb_putreg(FACTPS), | ||
4160 | + igb_putreg(FUNCTAG), | ||
4161 | + igb_putreg(GSCL_1), | ||
4162 | + igb_putreg(GSCL_2), | ||
4163 | + igb_putreg(GSCL_3), | ||
4164 | + igb_putreg(GSCL_4), | ||
4165 | + igb_putreg(GSCN_0), | ||
4166 | + igb_putreg(GSCN_1), | ||
4167 | + igb_putreg(GSCN_2), | ||
4168 | + igb_putreg(GSCN_3), | ||
4169 | + igb_putreg(MRQC), | ||
4170 | + igb_putreg(FLOP), | ||
4171 | + igb_putreg(FLA), | ||
4172 | + igb_putreg(TXDCTL0), | ||
4173 | + igb_putreg(TXDCTL1), | ||
4174 | + igb_putreg(TXDCTL2), | ||
4175 | + igb_putreg(TXDCTL3), | ||
4176 | + igb_putreg(TXDCTL4), | ||
4177 | + igb_putreg(TXDCTL5), | ||
4178 | + igb_putreg(TXDCTL6), | ||
4179 | + igb_putreg(TXDCTL7), | ||
4180 | + igb_putreg(TXDCTL8), | ||
4181 | + igb_putreg(TXDCTL9), | ||
4182 | + igb_putreg(TXDCTL10), | ||
4183 | + igb_putreg(TXDCTL11), | ||
4184 | + igb_putreg(TXDCTL12), | ||
4185 | + igb_putreg(TXDCTL13), | ||
4186 | + igb_putreg(TXDCTL14), | ||
4187 | + igb_putreg(TXDCTL15), | ||
4188 | + igb_putreg(TXCTL0), | ||
4189 | + igb_putreg(TXCTL1), | ||
4190 | + igb_putreg(TXCTL2), | ||
4191 | + igb_putreg(TXCTL3), | ||
4192 | + igb_putreg(TXCTL4), | ||
4193 | + igb_putreg(TXCTL5), | ||
4194 | + igb_putreg(TXCTL6), | ||
4195 | + igb_putreg(TXCTL7), | ||
4196 | + igb_putreg(TXCTL8), | ||
4197 | + igb_putreg(TXCTL9), | ||
4198 | + igb_putreg(TXCTL10), | ||
4199 | + igb_putreg(TXCTL11), | ||
4200 | + igb_putreg(TXCTL12), | ||
4201 | + igb_putreg(TXCTL13), | ||
4202 | + igb_putreg(TXCTL14), | ||
4203 | + igb_putreg(TXCTL15), | ||
4204 | + igb_putreg(TDWBAL0), | ||
4205 | + igb_putreg(TDWBAL1), | ||
4206 | + igb_putreg(TDWBAL2), | ||
4207 | + igb_putreg(TDWBAL3), | ||
4208 | + igb_putreg(TDWBAL4), | ||
4209 | + igb_putreg(TDWBAL5), | ||
4210 | + igb_putreg(TDWBAL6), | ||
4211 | + igb_putreg(TDWBAL7), | ||
4212 | + igb_putreg(TDWBAL8), | ||
4213 | + igb_putreg(TDWBAL9), | ||
4214 | + igb_putreg(TDWBAL10), | ||
4215 | + igb_putreg(TDWBAL11), | ||
4216 | + igb_putreg(TDWBAL12), | ||
4217 | + igb_putreg(TDWBAL13), | ||
4218 | + igb_putreg(TDWBAL14), | ||
4219 | + igb_putreg(TDWBAL15), | ||
4220 | + igb_putreg(TDWBAH0), | ||
4221 | + igb_putreg(TDWBAH1), | ||
4222 | + igb_putreg(TDWBAH2), | ||
4223 | + igb_putreg(TDWBAH3), | ||
4224 | + igb_putreg(TDWBAH4), | ||
4225 | + igb_putreg(TDWBAH5), | ||
4226 | + igb_putreg(TDWBAH6), | ||
4227 | + igb_putreg(TDWBAH7), | ||
4228 | + igb_putreg(TDWBAH8), | ||
4229 | + igb_putreg(TDWBAH9), | ||
4230 | + igb_putreg(TDWBAH10), | ||
4231 | + igb_putreg(TDWBAH11), | ||
4232 | + igb_putreg(TDWBAH12), | ||
4233 | + igb_putreg(TDWBAH13), | ||
4234 | + igb_putreg(TDWBAH14), | ||
4235 | + igb_putreg(TDWBAH15), | ||
4236 | + igb_putreg(TIPG), | ||
4237 | + igb_putreg(RXSTMPH), | ||
4238 | + igb_putreg(RXSTMPL), | ||
4239 | + igb_putreg(RXSATRL), | ||
4240 | + igb_putreg(RXSATRH), | ||
4241 | + igb_putreg(TXSTMPL), | ||
4242 | + igb_putreg(TXSTMPH), | ||
4243 | + igb_putreg(SYSTIML), | ||
4244 | + igb_putreg(SYSTIMH), | ||
4245 | + igb_putreg(TIMADJL), | ||
4246 | + igb_putreg(TSYNCRXCTL), | ||
4247 | + igb_putreg(TSYNCTXCTL), | ||
4248 | + igb_putreg(EEMNGCTL), | ||
4249 | + igb_putreg(GPIE), | ||
4250 | + igb_putreg(TXPBS), | ||
4251 | + igb_putreg(RLPML), | ||
4252 | + igb_putreg(VET), | ||
4253 | + | ||
4254 | + [TDH0] = igb_set_16bit, | ||
4255 | + [TDH1] = igb_set_16bit, | ||
4256 | + [TDH2] = igb_set_16bit, | ||
4257 | + [TDH3] = igb_set_16bit, | ||
4258 | + [TDH4] = igb_set_16bit, | ||
4259 | + [TDH5] = igb_set_16bit, | ||
4260 | + [TDH6] = igb_set_16bit, | ||
4261 | + [TDH7] = igb_set_16bit, | ||
4262 | + [TDH8] = igb_set_16bit, | ||
4263 | + [TDH9] = igb_set_16bit, | ||
4264 | + [TDH10] = igb_set_16bit, | ||
4265 | + [TDH11] = igb_set_16bit, | ||
4266 | + [TDH12] = igb_set_16bit, | ||
4267 | + [TDH13] = igb_set_16bit, | ||
4268 | + [TDH14] = igb_set_16bit, | ||
4269 | + [TDH15] = igb_set_16bit, | ||
4270 | + [TDT0] = igb_set_tdt, | ||
4271 | + [TDT1] = igb_set_tdt, | ||
4272 | + [TDT2] = igb_set_tdt, | ||
4273 | + [TDT3] = igb_set_tdt, | ||
4274 | + [TDT4] = igb_set_tdt, | ||
4275 | + [TDT5] = igb_set_tdt, | ||
4276 | + [TDT6] = igb_set_tdt, | ||
4277 | + [TDT7] = igb_set_tdt, | ||
4278 | + [TDT8] = igb_set_tdt, | ||
4279 | + [TDT9] = igb_set_tdt, | ||
4280 | + [TDT10] = igb_set_tdt, | ||
4281 | + [TDT11] = igb_set_tdt, | ||
4282 | + [TDT12] = igb_set_tdt, | ||
4283 | + [TDT13] = igb_set_tdt, | ||
4284 | + [TDT14] = igb_set_tdt, | ||
4285 | + [TDT15] = igb_set_tdt, | ||
4286 | + [MDIC] = igb_set_mdic, | ||
4287 | + [ICS] = igb_set_ics, | ||
4288 | + [RDH0] = igb_set_16bit, | ||
4289 | + [RDH1] = igb_set_16bit, | ||
4290 | + [RDH2] = igb_set_16bit, | ||
4291 | + [RDH3] = igb_set_16bit, | ||
4292 | + [RDH4] = igb_set_16bit, | ||
4293 | + [RDH5] = igb_set_16bit, | ||
4294 | + [RDH6] = igb_set_16bit, | ||
4295 | + [RDH7] = igb_set_16bit, | ||
4296 | + [RDH8] = igb_set_16bit, | ||
4297 | + [RDH9] = igb_set_16bit, | ||
4298 | + [RDH10] = igb_set_16bit, | ||
4299 | + [RDH11] = igb_set_16bit, | ||
4300 | + [RDH12] = igb_set_16bit, | ||
4301 | + [RDH13] = igb_set_16bit, | ||
4302 | + [RDH14] = igb_set_16bit, | ||
4303 | + [RDH15] = igb_set_16bit, | ||
4304 | + [RDT0] = igb_set_rdt, | ||
4305 | + [RDT1] = igb_set_rdt, | ||
4306 | + [RDT2] = igb_set_rdt, | ||
4307 | + [RDT3] = igb_set_rdt, | ||
4308 | + [RDT4] = igb_set_rdt, | ||
4309 | + [RDT5] = igb_set_rdt, | ||
4310 | + [RDT6] = igb_set_rdt, | ||
4311 | + [RDT7] = igb_set_rdt, | ||
4312 | + [RDT8] = igb_set_rdt, | ||
4313 | + [RDT9] = igb_set_rdt, | ||
4314 | + [RDT10] = igb_set_rdt, | ||
4315 | + [RDT11] = igb_set_rdt, | ||
4316 | + [RDT12] = igb_set_rdt, | ||
4317 | + [RDT13] = igb_set_rdt, | ||
4318 | + [RDT14] = igb_set_rdt, | ||
4319 | + [RDT15] = igb_set_rdt, | ||
4320 | + [IMC] = igb_set_imc, | ||
4321 | + [IMS] = igb_set_ims, | ||
4322 | + [ICR] = igb_set_icr, | ||
4323 | + [EECD] = igb_set_eecd, | ||
4324 | + [RCTL] = igb_set_rx_control, | ||
4325 | + [CTRL] = igb_set_ctrl, | ||
4326 | + [EERD] = igb_set_eerd, | ||
4327 | + [TDFH] = igb_set_13bit, | ||
4328 | + [TDFT] = igb_set_13bit, | ||
4329 | + [TDFHS] = igb_set_13bit, | ||
4330 | + [TDFTS] = igb_set_13bit, | ||
4331 | + [TDFPC] = igb_set_13bit, | ||
4332 | + [RDFH] = igb_set_13bit, | ||
4333 | + [RDFT] = igb_set_13bit, | ||
4334 | + [RDFHS] = igb_set_13bit, | ||
4335 | + [RDFTS] = igb_set_13bit, | ||
4336 | + [RDFPC] = igb_set_13bit, | ||
4337 | + [GCR] = igb_set_gcr, | ||
4338 | + [RXCSUM] = igb_set_rxcsum, | ||
4339 | + [TDLEN0] = igb_set_dlen, | ||
4340 | + [TDLEN1] = igb_set_dlen, | ||
4341 | + [TDLEN2] = igb_set_dlen, | ||
4342 | + [TDLEN3] = igb_set_dlen, | ||
4343 | + [TDLEN4] = igb_set_dlen, | ||
4344 | + [TDLEN5] = igb_set_dlen, | ||
4345 | + [TDLEN6] = igb_set_dlen, | ||
4346 | + [TDLEN7] = igb_set_dlen, | ||
4347 | + [TDLEN8] = igb_set_dlen, | ||
4348 | + [TDLEN9] = igb_set_dlen, | ||
4349 | + [TDLEN10] = igb_set_dlen, | ||
4350 | + [TDLEN11] = igb_set_dlen, | ||
4351 | + [TDLEN12] = igb_set_dlen, | ||
4352 | + [TDLEN13] = igb_set_dlen, | ||
4353 | + [TDLEN14] = igb_set_dlen, | ||
4354 | + [TDLEN15] = igb_set_dlen, | ||
4355 | + [RDLEN0] = igb_set_dlen, | ||
4356 | + [RDLEN1] = igb_set_dlen, | ||
4357 | + [RDLEN2] = igb_set_dlen, | ||
4358 | + [RDLEN3] = igb_set_dlen, | ||
4359 | + [RDLEN4] = igb_set_dlen, | ||
4360 | + [RDLEN5] = igb_set_dlen, | ||
4361 | + [RDLEN6] = igb_set_dlen, | ||
4362 | + [RDLEN7] = igb_set_dlen, | ||
4363 | + [RDLEN8] = igb_set_dlen, | ||
4364 | + [RDLEN9] = igb_set_dlen, | ||
4365 | + [RDLEN10] = igb_set_dlen, | ||
4366 | + [RDLEN11] = igb_set_dlen, | ||
4367 | + [RDLEN12] = igb_set_dlen, | ||
4368 | + [RDLEN13] = igb_set_dlen, | ||
4369 | + [RDLEN14] = igb_set_dlen, | ||
4370 | + [RDLEN15] = igb_set_dlen, | ||
4371 | + [TDBAL0] = igb_set_dbal, | ||
4372 | + [TDBAL1] = igb_set_dbal, | ||
4373 | + [TDBAL2] = igb_set_dbal, | ||
4374 | + [TDBAL3] = igb_set_dbal, | ||
4375 | + [TDBAL4] = igb_set_dbal, | ||
4376 | + [TDBAL5] = igb_set_dbal, | ||
4377 | + [TDBAL6] = igb_set_dbal, | ||
4378 | + [TDBAL7] = igb_set_dbal, | ||
4379 | + [TDBAL8] = igb_set_dbal, | ||
4380 | + [TDBAL9] = igb_set_dbal, | ||
4381 | + [TDBAL10] = igb_set_dbal, | ||
4382 | + [TDBAL11] = igb_set_dbal, | ||
4383 | + [TDBAL12] = igb_set_dbal, | ||
4384 | + [TDBAL13] = igb_set_dbal, | ||
4385 | + [TDBAL14] = igb_set_dbal, | ||
4386 | + [TDBAL15] = igb_set_dbal, | ||
4387 | + [RDBAL0] = igb_set_dbal, | ||
4388 | + [RDBAL1] = igb_set_dbal, | ||
4389 | + [RDBAL2] = igb_set_dbal, | ||
4390 | + [RDBAL3] = igb_set_dbal, | ||
4391 | + [RDBAL4] = igb_set_dbal, | ||
4392 | + [RDBAL5] = igb_set_dbal, | ||
4393 | + [RDBAL6] = igb_set_dbal, | ||
4394 | + [RDBAL7] = igb_set_dbal, | ||
4395 | + [RDBAL8] = igb_set_dbal, | ||
4396 | + [RDBAL9] = igb_set_dbal, | ||
4397 | + [RDBAL10] = igb_set_dbal, | ||
4398 | + [RDBAL11] = igb_set_dbal, | ||
4399 | + [RDBAL12] = igb_set_dbal, | ||
4400 | + [RDBAL13] = igb_set_dbal, | ||
4401 | + [RDBAL14] = igb_set_dbal, | ||
4402 | + [RDBAL15] = igb_set_dbal, | ||
4403 | + [STATUS] = igb_set_status, | ||
4404 | + [PBACLR] = igb_set_pbaclr, | ||
4405 | + [CTRL_EXT] = igb_set_ctrlext, | ||
4406 | + [FCAH] = igb_set_16bit, | ||
4407 | + [FCT] = igb_set_16bit, | ||
4408 | + [FCTTV] = igb_set_16bit, | ||
4409 | + [FCRTV] = igb_set_16bit, | ||
4410 | + [FCRTH] = igb_set_fcrth, | ||
4411 | + [FCRTL] = igb_set_fcrtl, | ||
4412 | + [CTRL_DUP] = igb_set_ctrl, | ||
4413 | + [RFCTL] = igb_set_rfctl, | ||
4414 | + [TIMINCA] = igb_set_timinca, | ||
4415 | + [TIMADJH] = igb_set_timadjh, | ||
4416 | + | ||
4417 | + [IP6AT ... IP6AT + 3] = igb_mac_writereg, | ||
4418 | + [IP4AT ... IP4AT + 6] = igb_mac_writereg, | ||
4419 | + [RA] = igb_mac_writereg, | ||
4420 | + [RA + 1] = igb_mac_setmacaddr, | ||
4421 | + [RA + 2 ... RA + 31] = igb_mac_writereg, | ||
4422 | + [RA2 ... RA2 + 31] = igb_mac_writereg, | ||
4423 | + [WUPM ... WUPM + 31] = igb_mac_writereg, | ||
4424 | + [MTA ... MTA + E1000_MC_TBL_SIZE - 1] = igb_mac_writereg, | ||
4425 | + [VFTA ... VFTA + E1000_VLAN_FILTER_TBL_SIZE - 1] = igb_mac_writereg, | ||
4426 | + [FFMT ... FFMT + 254] = igb_set_4bit, | ||
4427 | + [MDEF ... MDEF + 7] = igb_mac_writereg, | ||
4428 | + [FTFT ... FTFT + 254] = igb_mac_writereg, | ||
4429 | + [RETA ... RETA + 31] = igb_mac_writereg, | ||
4430 | + [RSSRK ... RSSRK + 9] = igb_mac_writereg, | ||
4431 | + [MAVTV0 ... MAVTV3] = igb_mac_writereg, | ||
4432 | + [EITR0 ... EITR0 + IGB_INTR_NUM - 1] = igb_set_eitr, | ||
4433 | + | ||
4434 | + /* IGB specific: */ | ||
4435 | + [FWSM] = igb_mac_writereg, | ||
4436 | + [SW_FW_SYNC] = igb_mac_writereg, | ||
4437 | + [EICR] = igb_set_eicr, | ||
4438 | + [EICS] = igb_set_eics, | ||
4439 | + [EIAC] = igb_set_eiac, | ||
4440 | + [EIAM] = igb_set_eiam, | ||
4441 | + [EIMC] = igb_set_eimc, | ||
4442 | + [EIMS] = igb_set_eims, | ||
4443 | + [IVAR0 ... IVAR0 + 7] = igb_mac_writereg, | ||
4444 | + igb_putreg(IVAR_MISC), | ||
4445 | + igb_putreg(VT_CTL), | ||
4446 | + [P2VMAILBOX0 ... P2VMAILBOX7] = igb_set_pfmailbox, | ||
4447 | + [V2PMAILBOX0 ... V2PMAILBOX7] = igb_set_vfmailbox, | ||
4448 | + [MBVFICR] = igb_w1c, | ||
4449 | + [VMBMEM0 ... VMBMEM0 + 127] = igb_mac_writereg, | ||
4450 | + igb_putreg(MBVFIMR), | ||
4451 | + [VFLRE] = igb_w1c, | ||
4452 | + igb_putreg(VFRE), | ||
4453 | + igb_putreg(VFTE), | ||
4454 | + igb_putreg(QDE), | ||
4455 | + igb_putreg(DTXSWC), | ||
4456 | + igb_putreg(RPLOLR), | ||
4457 | + [VLVF0 ... VLVF0 + E1000_VLVF_ARRAY_SIZE - 1] = igb_mac_writereg, | ||
4458 | + [VMVIR0 ... VMVIR7] = igb_mac_writereg, | ||
4459 | + [VMOLR0 ... VMOLR7] = igb_mac_writereg, | ||
4460 | + [UTA ... UTA + E1000_MC_TBL_SIZE - 1] = igb_mac_writereg, | ||
4461 | + [PVTCTRL0] = igb_set_vtctrl, | ||
4462 | + [PVTCTRL1] = igb_set_vtctrl, | ||
4463 | + [PVTCTRL2] = igb_set_vtctrl, | ||
4464 | + [PVTCTRL3] = igb_set_vtctrl, | ||
4465 | + [PVTCTRL4] = igb_set_vtctrl, | ||
4466 | + [PVTCTRL5] = igb_set_vtctrl, | ||
4467 | + [PVTCTRL6] = igb_set_vtctrl, | ||
4468 | + [PVTCTRL7] = igb_set_vtctrl, | ||
4469 | + [PVTEICS0] = igb_set_vteics, | ||
4470 | + [PVTEICS1] = igb_set_vteics, | ||
4471 | + [PVTEICS2] = igb_set_vteics, | ||
4472 | + [PVTEICS3] = igb_set_vteics, | ||
4473 | + [PVTEICS4] = igb_set_vteics, | ||
4474 | + [PVTEICS5] = igb_set_vteics, | ||
4475 | + [PVTEICS6] = igb_set_vteics, | ||
4476 | + [PVTEICS7] = igb_set_vteics, | ||
4477 | + [PVTEIMS0] = igb_set_vteims, | ||
4478 | + [PVTEIMS1] = igb_set_vteims, | ||
4479 | + [PVTEIMS2] = igb_set_vteims, | ||
4480 | + [PVTEIMS3] = igb_set_vteims, | ||
4481 | + [PVTEIMS4] = igb_set_vteims, | ||
4482 | + [PVTEIMS5] = igb_set_vteims, | ||
4483 | + [PVTEIMS6] = igb_set_vteims, | ||
4484 | + [PVTEIMS7] = igb_set_vteims, | ||
4485 | + [PVTEIMC0] = igb_set_vteimc, | ||
4486 | + [PVTEIMC1] = igb_set_vteimc, | ||
4487 | + [PVTEIMC2] = igb_set_vteimc, | ||
4488 | + [PVTEIMC3] = igb_set_vteimc, | ||
4489 | + [PVTEIMC4] = igb_set_vteimc, | ||
4490 | + [PVTEIMC5] = igb_set_vteimc, | ||
4491 | + [PVTEIMC6] = igb_set_vteimc, | ||
4492 | + [PVTEIMC7] = igb_set_vteimc, | ||
4493 | + [PVTEIAC0] = igb_set_vteiac, | ||
4494 | + [PVTEIAC1] = igb_set_vteiac, | ||
4495 | + [PVTEIAC2] = igb_set_vteiac, | ||
4496 | + [PVTEIAC3] = igb_set_vteiac, | ||
4497 | + [PVTEIAC4] = igb_set_vteiac, | ||
4498 | + [PVTEIAC5] = igb_set_vteiac, | ||
4499 | + [PVTEIAC6] = igb_set_vteiac, | ||
4500 | + [PVTEIAC7] = igb_set_vteiac, | ||
4501 | + [PVTEIAM0] = igb_set_vteiam, | ||
4502 | + [PVTEIAM1] = igb_set_vteiam, | ||
4503 | + [PVTEIAM2] = igb_set_vteiam, | ||
4504 | + [PVTEIAM3] = igb_set_vteiam, | ||
4505 | + [PVTEIAM4] = igb_set_vteiam, | ||
4506 | + [PVTEIAM5] = igb_set_vteiam, | ||
4507 | + [PVTEIAM6] = igb_set_vteiam, | ||
4508 | + [PVTEIAM7] = igb_set_vteiam, | ||
4509 | + [PVTEICR0] = igb_set_vteicr, | ||
4510 | + [PVTEICR1] = igb_set_vteicr, | ||
4511 | + [PVTEICR2] = igb_set_vteicr, | ||
4512 | + [PVTEICR3] = igb_set_vteicr, | ||
4513 | + [PVTEICR4] = igb_set_vteicr, | ||
4514 | + [PVTEICR5] = igb_set_vteicr, | ||
4515 | + [PVTEICR6] = igb_set_vteicr, | ||
4516 | + [PVTEICR7] = igb_set_vteicr, | ||
4517 | + [VTIVAR ... VTIVAR + 7] = igb_set_vtivar, | ||
4518 | + [VTIVAR_MISC ... VTIVAR_MISC + 7] = igb_mac_writereg | ||
4519 | +}; | ||
4520 | +enum { IGB_NWRITEOPS = ARRAY_SIZE(igb_macreg_writeops) }; | ||
4521 | + | ||
4522 | +enum { MAC_ACCESS_PARTIAL = 1 }; | ||
4523 | + | ||
4524 | +/* | ||
4525 | + * The array below combines alias offsets of the index values for the | ||
4526 | + * MAC registers that have aliases, with the indication of not fully | ||
4527 | + * implemented registers (lowest bit). This combination is possible | ||
4528 | + * because all of the offsets are even. | ||
4529 | + */ | ||
4530 | +static const uint16_t mac_reg_access[E1000E_MAC_SIZE] = { | ||
4531 | + /* Alias index offsets */ | ||
4532 | + [FCRTL_A] = 0x07fe, | ||
4533 | + [RDFH_A] = 0xe904, [RDFT_A] = 0xe904, | ||
4534 | + [TDFH_A] = 0xed00, [TDFT_A] = 0xed00, | ||
4535 | + [RA_A ... RA_A + 31] = 0x14f0, | ||
4536 | + [VFTA_A ... VFTA_A + E1000_VLAN_FILTER_TBL_SIZE - 1] = 0x1400, | ||
4537 | + | ||
4538 | + [RDBAL0_A] = 0x2600, | ||
4539 | + [RDBAH0_A] = 0x2600, | ||
4540 | + [RDLEN0_A] = 0x2600, | ||
4541 | + [SRRCTL0_A] = 0x2600, | ||
4542 | + [RDH0_A] = 0x2600, | ||
4543 | + [RDT0_A] = 0x2600, | ||
4544 | + [RXDCTL0_A] = 0x2600, | ||
4545 | + [RXCTL0_A] = 0x2600, | ||
4546 | + [RQDPC0_A] = 0x2600, | ||
4547 | + [RDBAL1_A] = 0x25D0, | ||
4548 | + [RDBAL2_A] = 0x25A0, | ||
4549 | + [RDBAL3_A] = 0x2570, | ||
4550 | + [RDBAH1_A] = 0x25D0, | ||
4551 | + [RDBAH2_A] = 0x25A0, | ||
4552 | + [RDBAH3_A] = 0x2570, | ||
4553 | + [RDLEN1_A] = 0x25D0, | ||
4554 | + [RDLEN2_A] = 0x25A0, | ||
4555 | + [RDLEN3_A] = 0x2570, | ||
4556 | + [SRRCTL1_A] = 0x25D0, | ||
4557 | + [SRRCTL2_A] = 0x25A0, | ||
4558 | + [SRRCTL3_A] = 0x2570, | ||
4559 | + [RDH1_A] = 0x25D0, | ||
4560 | + [RDH2_A] = 0x25A0, | ||
4561 | + [RDH3_A] = 0x2570, | ||
4562 | + [RDT1_A] = 0x25D0, | ||
4563 | + [RDT2_A] = 0x25A0, | ||
4564 | + [RDT3_A] = 0x2570, | ||
4565 | + [RXDCTL1_A] = 0x25D0, | ||
4566 | + [RXDCTL2_A] = 0x25A0, | ||
4567 | + [RXDCTL3_A] = 0x2570, | ||
4568 | + [RXCTL1_A] = 0x25D0, | ||
4569 | + [RXCTL2_A] = 0x25A0, | ||
4570 | + [RXCTL3_A] = 0x2570, | ||
4571 | + [RQDPC1_A] = 0x25D0, | ||
4572 | + [RQDPC2_A] = 0x25A0, | ||
4573 | + [RQDPC3_A] = 0x2570, | ||
4574 | + [TDBAL0_A] = 0x2A00, | ||
4575 | + [TDBAH0_A] = 0x2A00, | ||
4576 | + [TDLEN0_A] = 0x2A00, | ||
4577 | + [TDH0_A] = 0x2A00, | ||
4578 | + [TDT0_A] = 0x2A00, | ||
4579 | + [TXCTL0_A] = 0x2A00, | ||
4580 | + [TDWBAL0_A] = 0x2A00, | ||
4581 | + [TDWBAH0_A] = 0x2A00, | ||
4582 | + [TDBAL1_A] = 0x29D0, | ||
4583 | + [TDBAL2_A] = 0x29A0, | ||
4584 | + [TDBAL3_A] = 0x2970, | ||
4585 | + [TDBAH1_A] = 0x29D0, | ||
4586 | + [TDBAH2_A] = 0x29A0, | ||
4587 | + [TDBAH3_A] = 0x2970, | ||
4588 | + [TDLEN1_A] = 0x29D0, | ||
4589 | + [TDLEN2_A] = 0x29A0, | ||
4590 | + [TDLEN3_A] = 0x2970, | ||
4591 | + [TDH1_A] = 0x29D0, | ||
4592 | + [TDH2_A] = 0x29A0, | ||
4593 | + [TDH3_A] = 0x2970, | ||
4594 | + [TDT1_A] = 0x29D0, | ||
4595 | + [TDT2_A] = 0x29A0, | ||
4596 | + [TDT3_A] = 0x2970, | ||
4597 | + [TXDCTL0_A] = 0x2A00, | ||
4598 | + [TXDCTL1_A] = 0x29D0, | ||
4599 | + [TXDCTL2_A] = 0x29A0, | ||
4600 | + [TXDCTL3_A] = 0x2970, | ||
4601 | + [TXCTL1_A] = 0x29D0, | ||
4602 | + [TXCTL2_A] = 0x29A0, | ||
4603 | + [TXCTL3_A] = 0x29D0, | ||
4604 | + [TDWBAL1_A] = 0x29D0, | ||
4605 | + [TDWBAL2_A] = 0x29A0, | ||
4606 | + [TDWBAL3_A] = 0x2970, | ||
4607 | + [TDWBAH1_A] = 0x29D0, | ||
4608 | + [TDWBAH2_A] = 0x29A0, | ||
4609 | + [TDWBAH3_A] = 0x2970, | ||
4610 | + | ||
4611 | + /* Access options */ | ||
4612 | + [RDFH] = MAC_ACCESS_PARTIAL, [RDFT] = MAC_ACCESS_PARTIAL, | ||
4613 | + [RDFHS] = MAC_ACCESS_PARTIAL, [RDFTS] = MAC_ACCESS_PARTIAL, | ||
4614 | + [RDFPC] = MAC_ACCESS_PARTIAL, | ||
4615 | + [TDFH] = MAC_ACCESS_PARTIAL, [TDFT] = MAC_ACCESS_PARTIAL, | ||
4616 | + [TDFHS] = MAC_ACCESS_PARTIAL, [TDFTS] = MAC_ACCESS_PARTIAL, | ||
4617 | + [TDFPC] = MAC_ACCESS_PARTIAL, [EECD] = MAC_ACCESS_PARTIAL, | ||
4618 | + [FLA] = MAC_ACCESS_PARTIAL, | ||
4619 | + [FCAL] = MAC_ACCESS_PARTIAL, [FCAH] = MAC_ACCESS_PARTIAL, | ||
4620 | + [FCT] = MAC_ACCESS_PARTIAL, [FCTTV] = MAC_ACCESS_PARTIAL, | ||
4621 | + [FCRTV] = MAC_ACCESS_PARTIAL, [FCRTL] = MAC_ACCESS_PARTIAL, | ||
4622 | + [FCRTH] = MAC_ACCESS_PARTIAL, | ||
4623 | + [MAVTV0 ... MAVTV3] = MAC_ACCESS_PARTIAL | ||
4624 | +}; | ||
4625 | + | ||
4626 | +void | ||
4627 | +igb_core_write(IGBCore *core, hwaddr addr, uint64_t val, unsigned size) | ||
4628 | +{ | ||
4629 | + uint16_t index = igb_get_reg_index_with_offset(mac_reg_access, addr); | ||
4630 | + | ||
4631 | + if (index < IGB_NWRITEOPS && igb_macreg_writeops[index]) { | ||
4632 | + if (mac_reg_access[index] & MAC_ACCESS_PARTIAL) { | ||
4633 | + trace_e1000e_wrn_regs_write_trivial(index << 2); | ||
4634 | + } | ||
4635 | + trace_e1000e_core_write(index << 2, size, val); | ||
4636 | + igb_macreg_writeops[index](core, index, val); | ||
4637 | + } else if (index < IGB_NREADOPS && igb_macreg_readops[index]) { | ||
4638 | + trace_e1000e_wrn_regs_write_ro(index << 2, size, val); | ||
4639 | + } else { | ||
4640 | + trace_e1000e_wrn_regs_write_unknown(index << 2, size, val); | ||
4641 | + } | ||
4642 | +} | ||
4643 | + | ||
4644 | +uint64_t | ||
4645 | +igb_core_read(IGBCore *core, hwaddr addr, unsigned size) | ||
4646 | +{ | ||
4647 | + uint64_t val; | ||
4648 | + uint16_t index = igb_get_reg_index_with_offset(mac_reg_access, addr); | ||
4649 | + | ||
4650 | + if (index < IGB_NREADOPS && igb_macreg_readops[index]) { | ||
4651 | + if (mac_reg_access[index] & MAC_ACCESS_PARTIAL) { | ||
4652 | + trace_e1000e_wrn_regs_read_trivial(index << 2); | ||
4653 | + } | ||
4654 | + val = igb_macreg_readops[index](core, index); | ||
4655 | + trace_e1000e_core_read(index << 2, size, val); | ||
4656 | + return val; | ||
4657 | + } else { | ||
4658 | + trace_e1000e_wrn_regs_read_unknown(index << 2, size); | ||
4659 | + } | ||
4660 | + return 0; | ||
4661 | +} | ||
4662 | + | ||
4663 | +static inline void | ||
4664 | +igb_autoneg_pause(IGBCore *core) | ||
4665 | +{ | ||
4666 | + timer_del(core->autoneg_timer); | ||
4667 | +} | ||
4668 | + | ||
4669 | +static void | ||
4670 | +igb_autoneg_resume(IGBCore *core) | ||
4671 | +{ | ||
4672 | + if (igb_have_autoneg(core) && | ||
4673 | + !(core->phy[MII_BMSR] & MII_BMSR_AN_COMP)) { | ||
4674 | + qemu_get_queue(core->owner_nic)->link_down = false; | ||
4675 | + timer_mod(core->autoneg_timer, | ||
4676 | + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500); | ||
4677 | + } | ||
4678 | +} | ||
4679 | + | ||
4680 | +static void | ||
4681 | +igb_vm_state_change(void *opaque, bool running, RunState state) | ||
4682 | +{ | ||
4683 | + IGBCore *core = opaque; | ||
4684 | + | ||
4685 | + if (running) { | ||
4686 | + trace_e1000e_vm_state_running(); | ||
4687 | + igb_intrmgr_resume(core); | ||
4688 | + igb_autoneg_resume(core); | ||
4689 | + } else { | ||
4690 | + trace_e1000e_vm_state_stopped(); | ||
4691 | + igb_autoneg_pause(core); | ||
4692 | + igb_intrmgr_pause(core); | ||
4693 | + } | ||
4694 | +} | ||
4695 | + | ||
4696 | +void | ||
4697 | +igb_core_pci_realize(IGBCore *core, | ||
4698 | + const uint16_t *eeprom_templ, | ||
4699 | + uint32_t eeprom_size, | ||
4700 | + const uint8_t *macaddr) | ||
4701 | +{ | ||
4702 | + int i; | ||
4703 | + | ||
4704 | + core->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, | ||
4705 | + igb_autoneg_timer, core); | ||
4706 | + igb_intrmgr_pci_realize(core); | ||
4707 | + | ||
4708 | + core->vmstate = qemu_add_vm_change_state_handler(igb_vm_state_change, core); | ||
4709 | + | ||
4710 | + for (i = 0; i < IGB_NUM_QUEUES; i++) { | ||
4711 | + net_tx_pkt_init(&core->tx[i].tx_pkt, core->owner, E1000E_MAX_TX_FRAGS); | ||
4712 | + } | ||
4713 | + | ||
4714 | + net_rx_pkt_init(&core->rx_pkt); | ||
4715 | + | ||
4716 | + e1000x_core_prepare_eeprom(core->eeprom, | ||
4717 | + eeprom_templ, | ||
4718 | + eeprom_size, | ||
4719 | + PCI_DEVICE_GET_CLASS(core->owner)->device_id, | ||
4720 | + macaddr); | ||
4721 | + igb_update_rx_offloads(core); | ||
4722 | +} | ||
4723 | + | ||
4724 | +void | ||
4725 | +igb_core_pci_uninit(IGBCore *core) | ||
4726 | +{ | ||
4727 | + int i; | ||
4728 | + | ||
4729 | + timer_free(core->autoneg_timer); | ||
4730 | + | ||
4731 | + igb_intrmgr_pci_unint(core); | ||
4732 | + | ||
4733 | + qemu_del_vm_change_state_handler(core->vmstate); | ||
4734 | + | ||
4735 | + for (i = 0; i < IGB_NUM_QUEUES; i++) { | ||
4736 | + net_tx_pkt_reset(core->tx[i].tx_pkt); | ||
4737 | + net_tx_pkt_uninit(core->tx[i].tx_pkt); | ||
4738 | + } | ||
4739 | + | ||
4740 | + net_rx_pkt_uninit(core->rx_pkt); | ||
4741 | +} | ||
4742 | + | ||
4743 | +static const uint16_t | ||
4744 | +igb_phy_reg_init[] = { | ||
4745 | + [MII_BMCR] = MII_BMCR_SPEED1000 | | ||
4746 | + MII_BMCR_FD | | ||
4747 | + MII_BMCR_AUTOEN, | ||
4748 | + | ||
4749 | + [MII_BMSR] = MII_BMSR_EXTCAP | | ||
4750 | + MII_BMSR_LINK_ST | | ||
4751 | + MII_BMSR_AUTONEG | | ||
4752 | + MII_BMSR_MFPS | | ||
4753 | + MII_BMSR_EXTSTAT | | ||
4754 | + MII_BMSR_10T_HD | | ||
4755 | + MII_BMSR_10T_FD | | ||
4756 | + MII_BMSR_100TX_HD | | ||
4757 | + MII_BMSR_100TX_FD, | ||
4758 | + | ||
4759 | + [MII_PHYID1] = IGP03E1000_E_PHY_ID >> 16, | ||
4760 | + [MII_PHYID2] = (IGP03E1000_E_PHY_ID & 0xfff0) | 1, | ||
4761 | + [MII_ANAR] = MII_ANAR_CSMACD | MII_ANAR_10 | | ||
4762 | + MII_ANAR_10FD | MII_ANAR_TX | | ||
4763 | + MII_ANAR_TXFD | MII_ANAR_PAUSE | | ||
4764 | + MII_ANAR_PAUSE_ASYM, | ||
4765 | + [MII_ANLPAR] = MII_ANLPAR_10 | MII_ANLPAR_10FD | | ||
4766 | + MII_ANLPAR_TX | MII_ANLPAR_TXFD | | ||
4767 | + MII_ANLPAR_T4 | MII_ANLPAR_PAUSE, | ||
4768 | + [MII_ANER] = MII_ANER_NP | MII_ANER_NWAY, | ||
4769 | + [MII_ANNP] = 0x1 | MII_ANNP_MP, | ||
4770 | + [MII_CTRL1000] = MII_CTRL1000_HALF | MII_CTRL1000_FULL | | ||
4771 | + MII_CTRL1000_PORT | MII_CTRL1000_MASTER, | ||
4772 | + [MII_STAT1000] = MII_STAT1000_HALF | MII_STAT1000_FULL | | ||
4773 | + MII_STAT1000_ROK | MII_STAT1000_LOK, | ||
4774 | + [MII_EXTSTAT] = MII_EXTSTAT_1000T_HD | MII_EXTSTAT_1000T_FD, | ||
4775 | + | ||
4776 | + [IGP01E1000_PHY_PORT_CONFIG] = BIT(5) | BIT(8), | ||
4777 | + [IGP01E1000_PHY_PORT_STATUS] = IGP01E1000_PSSR_SPEED_1000MBPS, | ||
4778 | + [IGP02E1000_PHY_POWER_MGMT] = BIT(0) | BIT(3) | IGP02E1000_PM_D3_LPLU | | ||
4779 | + IGP01E1000_PSCFR_SMART_SPEED | ||
4780 | +}; | ||
4781 | + | ||
4782 | +static const uint32_t igb_mac_reg_init[] = { | ||
4783 | + [LEDCTL] = 2 | (3 << 8) | BIT(15) | (6 << 16) | (7 << 24), | ||
4784 | + [EEMNGCTL] = BIT(31), | ||
4785 | + [RXDCTL0] = E1000_RXDCTL_QUEUE_ENABLE | (1 << 16), | ||
4786 | + [RXDCTL1] = 1 << 16, | ||
4787 | + [RXDCTL2] = 1 << 16, | ||
4788 | + [RXDCTL3] = 1 << 16, | ||
4789 | + [RXDCTL4] = 1 << 16, | ||
4790 | + [RXDCTL5] = 1 << 16, | ||
4791 | + [RXDCTL6] = 1 << 16, | ||
4792 | + [RXDCTL7] = 1 << 16, | ||
4793 | + [RXDCTL8] = 1 << 16, | ||
4794 | + [RXDCTL9] = 1 << 16, | ||
4795 | + [RXDCTL10] = 1 << 16, | ||
4796 | + [RXDCTL11] = 1 << 16, | ||
4797 | + [RXDCTL12] = 1 << 16, | ||
4798 | + [RXDCTL13] = 1 << 16, | ||
4799 | + [RXDCTL14] = 1 << 16, | ||
4800 | + [RXDCTL15] = 1 << 16, | ||
4801 | + [TIPG] = 0x08 | (0x04 << 10) | (0x06 << 20), | ||
4802 | + [CTRL] = E1000_CTRL_FD | E1000_CTRL_LRST | E1000_CTRL_SPD_1000 | | ||
4803 | + E1000_CTRL_ADVD3WUC, | ||
4804 | + [STATUS] = E1000_STATUS_PHYRA | BIT(31), | ||
4805 | + [EECD] = E1000_EECD_FWE_DIS | E1000_EECD_PRES | | ||
4806 | + (2 << E1000_EECD_SIZE_EX_SHIFT), | ||
4807 | + [GCR] = E1000_L0S_ADJUST | | ||
4808 | + E1000_GCR_CMPL_TMOUT_RESEND | | ||
4809 | + E1000_GCR_CAP_VER2 | | ||
4810 | + E1000_L1_ENTRY_LATENCY_MSB | | ||
4811 | + E1000_L1_ENTRY_LATENCY_LSB, | ||
4812 | + [RXCSUM] = E1000_RXCSUM_IPOFLD | E1000_RXCSUM_TUOFLD, | ||
4813 | + [TXPBS] = 0x28, | ||
4814 | + [RXPBS] = 0x40, | ||
4815 | + [TCTL] = E1000_TCTL_PSP | (0xF << E1000_CT_SHIFT) | | ||
4816 | + (0x40 << E1000_COLD_SHIFT) | (0x1 << 26) | (0xA << 28), | ||
4817 | + [TCTL_EXT] = 0x40 | (0x42 << 10), | ||
4818 | + [DTXCTL] = E1000_DTXCTL_8023LL | E1000_DTXCTL_SPOOF_INT, | ||
4819 | + [VET] = ETH_P_VLAN | (ETH_P_VLAN << 16), | ||
4820 | + | ||
4821 | + [V2PMAILBOX0 ... V2PMAILBOX0 + IGB_MAX_VF_FUNCTIONS - 1] = E1000_V2PMAILBOX_RSTI, | ||
4822 | + [MBVFIMR] = 0xFF, | ||
4823 | + [VFRE] = 0xFF, | ||
4824 | + [VFTE] = 0xFF, | ||
4825 | + [VMOLR0 ... VMOLR0 + 7] = 0x2600 | E1000_VMOLR_STRCRC, | ||
4826 | + [RPLOLR] = E1000_RPLOLR_STRCRC, | ||
4827 | + [RLPML] = 0x2600, | ||
4828 | + [TXCTL0] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4829 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4830 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4831 | + [TXCTL1] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4832 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4833 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4834 | + [TXCTL2] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4835 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4836 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4837 | + [TXCTL3] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4838 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4839 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4840 | + [TXCTL4] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4841 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4842 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4843 | + [TXCTL5] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4844 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4845 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4846 | + [TXCTL6] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4847 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4848 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4849 | + [TXCTL7] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4850 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4851 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4852 | + [TXCTL8] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4853 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4854 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4855 | + [TXCTL9] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4856 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4857 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4858 | + [TXCTL10] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4859 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4860 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4861 | + [TXCTL11] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4862 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4863 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4864 | + [TXCTL12] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4865 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4866 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4867 | + [TXCTL13] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4868 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4869 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4870 | + [TXCTL14] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4871 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4872 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4873 | + [TXCTL15] = E1000_DCA_TXCTRL_DATA_RRO_EN | | ||
4874 | + E1000_DCA_TXCTRL_TX_WB_RO_EN | | ||
4875 | + E1000_DCA_TXCTRL_DESC_RRO_EN, | ||
4876 | +}; | ||
4877 | + | ||
4878 | +static void igb_reset(IGBCore *core, bool sw) | ||
4879 | +{ | ||
4880 | + struct igb_tx *tx; | ||
4881 | + int i; | ||
4882 | + | ||
4883 | + timer_del(core->autoneg_timer); | ||
4884 | + | ||
4885 | + igb_intrmgr_reset(core); | ||
4886 | + | ||
4887 | + memset(core->phy, 0, sizeof core->phy); | ||
4888 | + memcpy(core->phy, igb_phy_reg_init, sizeof igb_phy_reg_init); | ||
4889 | + | ||
4890 | + for (i = 0; i < E1000E_MAC_SIZE; i++) { | ||
4891 | + if (sw && | ||
4892 | + (i == RXPBS || i == TXPBS || | ||
4893 | + (i >= EITR0 && i < EITR0 + IGB_INTR_NUM))) { | ||
4894 | + continue; | ||
4895 | + } | ||
4896 | + | ||
4897 | + core->mac[i] = i < ARRAY_SIZE(igb_mac_reg_init) ? | ||
4898 | + igb_mac_reg_init[i] : 0; | ||
4899 | + } | ||
4900 | + | ||
4901 | + if (qemu_get_queue(core->owner_nic)->link_down) { | ||
4902 | + igb_link_down(core); | ||
4903 | + } | ||
4904 | + | ||
4905 | + e1000x_reset_mac_addr(core->owner_nic, core->mac, core->permanent_mac); | ||
4906 | + | ||
4907 | + for (i = 0; i < ARRAY_SIZE(core->tx); i++) { | ||
4908 | + tx = &core->tx[i]; | ||
4909 | + net_tx_pkt_reset(tx->tx_pkt); | ||
4910 | + tx->vlan = 0; | ||
4911 | + tx->mss = 0; | ||
4912 | + tx->tse = false; | ||
4913 | + tx->ixsm = false; | ||
4914 | + tx->txsm = false; | ||
4915 | + tx->first = true; | ||
4916 | + tx->skip_cp = false; | ||
4917 | + } | ||
4918 | +} | ||
4919 | + | ||
4920 | +void | ||
4921 | +igb_core_reset(IGBCore *core) | ||
4922 | +{ | ||
4923 | + igb_reset(core, false); | ||
4924 | +} | ||
4925 | + | ||
4926 | +void igb_core_pre_save(IGBCore *core) | ||
4927 | +{ | ||
4928 | + int i; | ||
4929 | + NetClientState *nc = qemu_get_queue(core->owner_nic); | ||
4930 | + | ||
4931 | + /* | ||
4932 | + * If link is down and auto-negotiation is supported and ongoing, | ||
4933 | + * complete auto-negotiation immediately. This allows us to look | ||
4934 | + * at MII_BMSR_AN_COMP to infer link status on load. | ||
4935 | + */ | ||
4936 | + if (nc->link_down && igb_have_autoneg(core)) { | ||
4937 | + core->phy[MII_BMSR] |= MII_BMSR_AN_COMP; | ||
4938 | + igb_update_flowctl_status(core); | ||
4939 | + } | ||
4940 | + | ||
4941 | + for (i = 0; i < ARRAY_SIZE(core->tx); i++) { | ||
4942 | + if (net_tx_pkt_has_fragments(core->tx[i].tx_pkt)) { | ||
4943 | + core->tx[i].skip_cp = true; | ||
4944 | + } | ||
4945 | + } | ||
4946 | +} | ||
4947 | + | ||
4948 | +int | ||
4949 | +igb_core_post_load(IGBCore *core) | ||
4950 | +{ | ||
4951 | + NetClientState *nc = qemu_get_queue(core->owner_nic); | ||
4952 | + | ||
4953 | + /* | ||
4954 | + * nc.link_down can't be migrated, so infer link_down according | ||
4955 | + * to link status bit in core.mac[STATUS]. | ||
4956 | + */ | ||
4957 | + nc->link_down = (core->mac[STATUS] & E1000_STATUS_LU) == 0; | ||
4958 | + | ||
4959 | + return 0; | ||
4960 | +} | ||
4961 | diff --git a/hw/net/igb_core.h b/hw/net/igb_core.h | ||
4962 | new file mode 100644 | ||
4963 | index XXXXXXX..XXXXXXX | ||
4964 | --- /dev/null | ||
4965 | +++ b/hw/net/igb_core.h | ||
4966 | @@ -XXX,XX +XXX,XX @@ | ||
4967 | +/* | ||
4968 | + * Core code for QEMU igb emulation | ||
4969 | + * | ||
4970 | + * Datasheet: | ||
4971 | + * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82576eg-gbe-datasheet.pdf | ||
4972 | + * | ||
4973 | + * Copyright (c) 2020-2023 Red Hat, Inc. | ||
4974 | + * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) | ||
4975 | + * Developed by Daynix Computing LTD (http://www.daynix.com) | ||
4976 | + * | ||
4977 | + * Authors: | ||
4978 | + * Akihiko Odaki <akihiko.odaki@daynix.com> | ||
4979 | + * Gal Hammmer <gal.hammer@sap.com> | ||
4980 | + * Marcel Apfelbaum <marcel.apfelbaum@gmail.com> | ||
4981 | + * Dmitry Fleytman <dmitry@daynix.com> | ||
4982 | + * Leonid Bloch <leonid@daynix.com> | ||
4983 | + * Yan Vugenfirer <yan@daynix.com> | ||
4984 | + * | ||
4985 | + * Based on work done by: | ||
4986 | + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. | ||
4987 | + * Copyright (c) 2008 Qumranet | ||
4988 | + * Based on work done by: | ||
4989 | + * Copyright (c) 2007 Dan Aloni | ||
4990 | + * Copyright (c) 2004 Antony T Curtis | ||
4991 | + * | ||
4992 | + * This library is free software; you can redistribute it and/or | ||
4993 | + * modify it under the terms of the GNU Lesser General Public | ||
4994 | + * License as published by the Free Software Foundation; either | ||
4995 | + * version 2.1 of the License, or (at your option) any later version. | ||
4996 | + * | ||
4997 | + * This library is distributed in the hope that it will be useful, | ||
4998 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
4999 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
5000 | + * Lesser General Public License for more details. | ||
5001 | + * | ||
5002 | + * You should have received a copy of the GNU Lesser General Public | ||
5003 | + * License along with this library; if not, see <http://www.gnu.org/licenses/>. | ||
5004 | + */ | ||
5005 | + | ||
5006 | +#ifndef HW_NET_IGB_CORE_H | ||
5007 | +#define HW_NET_IGB_CORE_H | ||
5008 | + | ||
5009 | +#define E1000E_MAC_SIZE (0x8000) | ||
5010 | +#define IGB_EEPROM_SIZE (1024) | ||
5011 | + | ||
5012 | +#define IGB_INTR_NUM (25) | ||
5013 | +#define IGB_MSIX_VEC_NUM (10) | ||
5014 | +#define IGBVF_MSIX_VEC_NUM (3) | ||
5015 | +#define IGB_NUM_QUEUES (16) | ||
5016 | + | ||
5017 | +typedef struct IGBCore IGBCore; | ||
5018 | + | ||
5019 | +enum { PHY_R = BIT(0), | ||
5020 | + PHY_W = BIT(1), | ||
5021 | + PHY_RW = PHY_R | PHY_W }; | ||
5022 | + | ||
5023 | +typedef struct IGBIntrDelayTimer_st { | ||
5024 | + QEMUTimer *timer; | ||
5025 | + bool running; | ||
5026 | + uint32_t delay_reg; | ||
5027 | + uint32_t delay_resolution_ns; | ||
5028 | + IGBCore *core; | ||
5029 | +} IGBIntrDelayTimer; | ||
5030 | + | ||
5031 | +struct IGBCore { | ||
5032 | + uint32_t mac[E1000E_MAC_SIZE]; | ||
5033 | + uint16_t phy[MAX_PHY_REG_ADDRESS + 1]; | ||
5034 | + uint16_t eeprom[IGB_EEPROM_SIZE]; | ||
5035 | + | ||
5036 | + uint8_t rx_desc_len; | ||
5037 | + | ||
5038 | + QEMUTimer *autoneg_timer; | ||
5039 | + | ||
5040 | + struct igb_tx { | ||
5041 | + uint16_t vlan; /* VLAN Tag */ | ||
5042 | + uint16_t mss; /* Maximum Segment Size */ | ||
5043 | + bool tse; /* TCP/UDP Segmentation Enable */ | ||
5044 | + bool ixsm; /* Insert IP Checksum */ | ||
5045 | + bool txsm; /* Insert TCP/UDP Checksum */ | ||
5046 | + | ||
5047 | + bool first; | ||
5048 | + bool skip_cp; | ||
5049 | + | ||
5050 | + struct NetTxPkt *tx_pkt; | ||
5051 | + } tx[IGB_NUM_QUEUES]; | ||
5052 | + | ||
5053 | + struct NetRxPkt *rx_pkt; | ||
5054 | + | ||
5055 | + bool has_vnet; | ||
5056 | + int max_queue_num; | ||
5057 | + | ||
5058 | + IGBIntrDelayTimer eitr[IGB_INTR_NUM]; | ||
5059 | + | ||
5060 | + VMChangeStateEntry *vmstate; | ||
5061 | + | ||
5062 | + uint32_t eitr_guest_value[IGB_INTR_NUM]; | ||
5063 | + | ||
5064 | + uint8_t permanent_mac[ETH_ALEN]; | ||
5065 | + | ||
5066 | + NICState *owner_nic; | ||
5067 | + PCIDevice *owner; | ||
5068 | + void (*owner_start_recv)(PCIDevice *d); | ||
5069 | + | ||
5070 | + int64_t timadj; | ||
5071 | +}; | ||
5072 | + | ||
5073 | +void | ||
5074 | +igb_core_write(IGBCore *core, hwaddr addr, uint64_t val, unsigned size); | ||
5075 | + | ||
5076 | +uint64_t | ||
5077 | +igb_core_read(IGBCore *core, hwaddr addr, unsigned size); | ||
5078 | + | ||
5079 | +void | ||
5080 | +igb_core_pci_realize(IGBCore *regs, | ||
5081 | + const uint16_t *eeprom_templ, | ||
5082 | + uint32_t eeprom_size, | ||
5083 | + const uint8_t *macaddr); | ||
5084 | + | ||
5085 | +void | ||
5086 | +igb_core_reset(IGBCore *core); | ||
5087 | + | ||
5088 | +void | ||
5089 | +igb_core_pre_save(IGBCore *core); | ||
5090 | + | ||
5091 | +int | ||
5092 | +igb_core_post_load(IGBCore *core); | ||
5093 | + | ||
5094 | +void | ||
5095 | +igb_core_set_link_status(IGBCore *core); | ||
5096 | + | ||
5097 | +void | ||
5098 | +igb_core_pci_uninit(IGBCore *core); | ||
5099 | + | ||
5100 | +bool | ||
5101 | +igb_can_receive(IGBCore *core); | ||
5102 | + | ||
5103 | +ssize_t | ||
5104 | +igb_receive(IGBCore *core, const uint8_t *buf, size_t size); | ||
5105 | + | ||
5106 | +ssize_t | ||
5107 | +igb_receive_iov(IGBCore *core, const struct iovec *iov, int iovcnt); | ||
5108 | + | ||
5109 | +void | ||
5110 | +igb_start_recv(IGBCore *core); | ||
5111 | + | ||
5112 | +#endif | ||
5113 | diff --git a/hw/net/igb_regs.h b/hw/net/igb_regs.h | ||
5114 | new file mode 100644 | ||
5115 | index XXXXXXX..XXXXXXX | ||
5116 | --- /dev/null | ||
5117 | +++ b/hw/net/igb_regs.h | ||
5118 | @@ -XXX,XX +XXX,XX @@ | ||
5119 | +/* SPDX-License-Identifier: GPL-2.0 */ | ||
5120 | +/* | ||
5121 | + * This is copied + edited from kernel header files in | ||
5122 | + * drivers/net/ethernet/intel/igb | ||
5123 | + */ | ||
5124 | + | ||
5125 | +#ifndef HW_IGB_REGS_H_ | ||
5126 | +#define HW_IGB_REGS_H_ | ||
5127 | + | ||
5128 | +#include "e1000x_regs.h" | ||
5129 | + | ||
5130 | +/* from igb/e1000_hw.h */ | ||
5131 | + | ||
5132 | +#define E1000_DEV_ID_82576 0x10C9 | ||
5133 | +#define E1000_DEV_ID_82576_FIBER 0x10E6 | ||
5134 | +#define E1000_DEV_ID_82576_SERDES 0x10E7 | ||
5135 | +#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8 | ||
5136 | +#define E1000_DEV_ID_82576_QUAD_COPPER_ET2 0x1526 | ||
5137 | +#define E1000_DEV_ID_82576_NS 0x150A | ||
5138 | +#define E1000_DEV_ID_82576_NS_SERDES 0x1518 | ||
5139 | +#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D | ||
5140 | + | ||
5141 | +/* Context Descriptor */ | ||
5142 | +struct e1000_adv_tx_context_desc { | ||
5143 | + uint32_t vlan_macip_lens; | ||
5144 | + uint32_t seqnum_seed; | ||
5145 | + uint32_t type_tucmd_mlhl; | ||
5146 | + uint32_t mss_l4len_idx; | ||
5147 | +}; | ||
5148 | + | ||
5149 | +/* Advanced Transmit Descriptor */ | ||
5150 | +union e1000_adv_tx_desc { | ||
5151 | + struct { | ||
5152 | + uint64_t buffer_addr; /* Address of descriptor's data buffer */ | ||
5153 | + uint32_t cmd_type_len; | ||
5154 | + uint32_t olinfo_status; | ||
5155 | + } read; | ||
5156 | + struct { | ||
5157 | + uint64_t rsvd; /* Reserved */ | ||
5158 | + uint32_t nxtseq_seed; | ||
5159 | + uint32_t status; | ||
5160 | + } wb; | ||
5161 | +}; | ||
5162 | + | ||
5163 | +#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */ | ||
5164 | +#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */ | ||
5165 | +#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor Extension (1=Adv) */ | ||
5166 | +#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP/UDP Segmentation Enable */ | ||
5167 | + | ||
5168 | +#define E1000_ADVTXD_POTS_IXSM 0x00000100 /* Insert TCP/UDP Checksum */ | ||
5169 | +#define E1000_ADVTXD_POTS_TXSM 0x00000200 /* Insert TCP/UDP Checksum */ | ||
5170 | + | ||
5171 | +#define E1000_TXD_POPTS_IXSM 0x00000001 /* Insert IP checksum */ | ||
5172 | +#define E1000_TXD_POPTS_TXSM 0x00000002 /* Insert TCP/UDP checksum */ | ||
5173 | + | ||
5174 | +/* Receive Descriptor - Advanced */ | ||
5175 | +union e1000_adv_rx_desc { | ||
5176 | + struct { | ||
5177 | + uint64_t pkt_addr; /* Packet Buffer Address */ | ||
5178 | + uint64_t hdr_addr; /* Header Buffer Address */ | ||
5179 | + } read; | ||
5180 | + struct { | ||
5181 | + struct { | ||
5182 | + struct { | ||
5183 | + uint16_t pkt_info; /* RSS Type, Packet Type */ | ||
5184 | + uint16_t hdr_info; /* Split Head, Buffer Length */ | ||
5185 | + } lo_dword; | ||
5186 | + union { | ||
5187 | + uint32_t rss; /* RSS Hash */ | ||
5188 | + struct { | ||
5189 | + uint16_t ip_id; /* IP Id */ | ||
5190 | + uint16_t csum; /* Packet Checksum */ | ||
5191 | + } csum_ip; | ||
5192 | + } hi_dword; | ||
5193 | + } lower; | ||
5194 | + struct { | ||
5195 | + uint32_t status_error; /* Ext Status/Error */ | ||
5196 | + uint16_t length; /* Packet Length */ | ||
5197 | + uint16_t vlan; /* VLAN tag */ | ||
5198 | + } upper; | ||
5199 | + } wb; /* writeback */ | ||
5200 | +}; | ||
5201 | + | ||
5202 | +/* from igb/e1000_phy.h */ | ||
5203 | + | ||
5204 | +/* IGP01E1000 Specific Registers */ | ||
5205 | +#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */ | ||
5206 | +#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */ | ||
5207 | +#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */ | ||
5208 | +#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */ | ||
5209 | +#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */ | ||
5210 | +#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ | ||
5211 | +#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 | ||
5212 | +#define IGP01E1000_PHY_POLARITY_MASK 0x0078 | ||
5213 | +#define IGP01E1000_PSCR_AUTO_MDIX 0x1000 | ||
5214 | +#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */ | ||
5215 | +#define IGP01E1000_PSCFR_SMART_SPEED 0x0080 | ||
5216 | + | ||
5217 | +/* Enable flexible speed on link-up */ | ||
5218 | +#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */ | ||
5219 | +#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */ | ||
5220 | +#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000 | ||
5221 | +#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002 | ||
5222 | +#define IGP01E1000_PSSR_MDIX 0x0800 | ||
5223 | +#define IGP01E1000_PSSR_SPEED_MASK 0xC000 | ||
5224 | +#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000 | ||
5225 | +#define IGP02E1000_PHY_CHANNEL_NUM 4 | ||
5226 | +#define IGP02E1000_PHY_AGC_A 0x11B1 | ||
5227 | +#define IGP02E1000_PHY_AGC_B 0x12B1 | ||
5228 | +#define IGP02E1000_PHY_AGC_C 0x14B1 | ||
5229 | +#define IGP02E1000_PHY_AGC_D 0x18B1 | ||
5230 | +#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */ | ||
5231 | +#define IGP02E1000_AGC_LENGTH_MASK 0x7F | ||
5232 | +#define IGP02E1000_AGC_RANGE 15 | ||
5233 | + | ||
5234 | +/* from igb/igb.h */ | ||
5235 | + | ||
5236 | +#define E1000_PCS_CFG_IGN_SD 1 | ||
5237 | + | ||
5238 | +/* Interrupt defines */ | ||
5239 | +#define IGB_START_ITR 648 /* ~6000 ints/sec */ | ||
5240 | +#define IGB_4K_ITR 980 | ||
5241 | +#define IGB_20K_ITR 196 | ||
5242 | +#define IGB_70K_ITR 56 | ||
5243 | + | ||
5244 | +/* TX/RX descriptor defines */ | ||
5245 | +#define IGB_DEFAULT_TXD 256 | ||
5246 | +#define IGB_DEFAULT_TX_WORK 128 | ||
5247 | +#define IGB_MIN_TXD 80 | ||
5248 | +#define IGB_MAX_TXD 4096 | ||
5249 | + | ||
5250 | +#define IGB_DEFAULT_RXD 256 | ||
5251 | +#define IGB_MIN_RXD 80 | ||
5252 | +#define IGB_MAX_RXD 4096 | ||
5253 | + | ||
5254 | +#define IGB_DEFAULT_ITR 3 /* dynamic */ | ||
5255 | +#define IGB_MAX_ITR_USECS 10000 | ||
5256 | +#define IGB_MIN_ITR_USECS 10 | ||
5257 | +#define NON_Q_VECTORS 1 | ||
5258 | +#define MAX_Q_VECTORS 8 | ||
5259 | +#define MAX_MSIX_ENTRIES 10 | ||
5260 | + | ||
5261 | +/* Transmit and receive queues */ | ||
5262 | +#define IGB_MAX_RX_QUEUES 8 | ||
5263 | +#define IGB_MAX_RX_QUEUES_82575 4 | ||
5264 | +#define IGB_MAX_RX_QUEUES_I211 2 | ||
5265 | +#define IGB_MAX_TX_QUEUES 8 | ||
5266 | +#define IGB_MAX_VF_MC_ENTRIES 30 | ||
5267 | +#define IGB_MAX_VF_FUNCTIONS 8 | ||
5268 | +#define IGB_MAX_VFTA_ENTRIES 128 | ||
5269 | +#define IGB_82576_VF_DEV_ID 0x10CA | ||
5270 | +#define IGB_I350_VF_DEV_ID 0x1520 | ||
5271 | + | ||
5272 | +/* from igb/e1000_82575.h */ | ||
5273 | + | ||
5274 | +#define E1000_MRQC_ENABLE_RSS_MQ 0x00000002 | ||
5275 | +#define E1000_MRQC_ENABLE_VMDQ 0x00000003 | ||
5276 | +#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000 | ||
5277 | +#define E1000_MRQC_ENABLE_VMDQ_RSS_MQ 0x00000005 | ||
5278 | +#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000 | ||
5279 | +#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000 | ||
5280 | + | ||
5281 | +/* Additional Receive Descriptor Control definitions */ | ||
5282 | +#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */ | ||
5283 | + | ||
5284 | +/* Direct Cache Access (DCA) definitions */ | ||
5285 | +#define E1000_DCA_CTRL_DCA_MODE_DISABLE 0x01 /* DCA Disable */ | ||
5286 | +#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */ | ||
5287 | + | ||
5288 | +#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */ | ||
5289 | +#define E1000_DCA_RXCTRL_DESC_DCA_EN BIT(5) /* DCA Rx Desc enable */ | ||
5290 | +#define E1000_DCA_RXCTRL_HEAD_DCA_EN BIT(6) /* DCA Rx Desc header enable */ | ||
5291 | +#define E1000_DCA_RXCTRL_DATA_DCA_EN BIT(7) /* DCA Rx Desc payload enable */ | ||
5292 | +#define E1000_DCA_RXCTRL_DESC_RRO_EN BIT(9) /* DCA Rx rd Desc Relax Order */ | ||
5293 | + | ||
5294 | +#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */ | ||
5295 | +#define E1000_DCA_TXCTRL_DESC_DCA_EN BIT(5) /* DCA Tx Desc enable */ | ||
5296 | +#define E1000_DCA_TXCTRL_DESC_RRO_EN BIT(9) /* Tx rd Desc Relax Order */ | ||
5297 | +#define E1000_DCA_TXCTRL_TX_WB_RO_EN BIT(11) /* Tx Desc writeback RO bit */ | ||
5298 | +#define E1000_DCA_TXCTRL_DATA_RRO_EN BIT(13) /* Tx rd data Relax Order */ | ||
5299 | + | ||
5300 | +/* Additional DCA related definitions, note change in position of CPUID */ | ||
5301 | +#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */ | ||
5302 | +#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */ | ||
5303 | +#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */ | ||
5304 | +#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */ | ||
5305 | + | ||
5306 | +#define E1000_DTXSWC_MAC_SPOOF_MASK 0x000000FF /* Per VF MAC spoof control */ | ||
5307 | +#define E1000_DTXSWC_VLAN_SPOOF_MASK 0x0000FF00 /* Per VF VLAN spoof control */ | ||
5308 | +#define E1000_DTXSWC_LLE_MASK 0x00FF0000 /* Per VF Local LB enables */ | ||
5309 | +#define E1000_DTXSWC_VLAN_SPOOF_SHIFT 8 | ||
5310 | +#define E1000_DTXSWC_VMDQ_LOOPBACK_EN BIT(31) /* global VF LB enable */ | ||
5311 | + | ||
5312 | +/* Easy defines for setting default pool, would normally be left a zero */ | ||
5313 | +#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7 | ||
5314 | +#define E1000_VT_CTL_DEFAULT_POOL_MASK (0x7 << E1000_VT_CTL_DEFAULT_POOL_SHIFT) | ||
5315 | + | ||
5316 | +/* Other useful VMD_CTL register defines */ | ||
5317 | +#define E1000_VT_CTL_IGNORE_MAC BIT(28) | ||
5318 | +#define E1000_VT_CTL_DISABLE_DEF_POOL BIT(29) | ||
5319 | +#define E1000_VT_CTL_VM_REPL_EN BIT(30) | ||
5320 | + | ||
5321 | +/* Per VM Offload register setup */ | ||
5322 | +#define E1000_VMOLR_RLPML_MASK 0x00003FFF /* Long Packet Maximum Length mask */ | ||
5323 | +#define E1000_VMOLR_LPE 0x00010000 /* Accept Long packet */ | ||
5324 | +#define E1000_VMOLR_RSSE 0x00020000 /* Enable RSS */ | ||
5325 | +#define E1000_VMOLR_AUPE 0x01000000 /* Accept untagged packets */ | ||
5326 | +#define E1000_VMOLR_ROMPE 0x02000000 /* Accept overflow multicast */ | ||
5327 | +#define E1000_VMOLR_ROPE 0x04000000 /* Accept overflow unicast */ | ||
5328 | +#define E1000_VMOLR_BAM 0x08000000 /* Accept Broadcast packets */ | ||
5329 | +#define E1000_VMOLR_MPME 0x10000000 /* Multicast promiscuous mode */ | ||
5330 | +#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */ | ||
5331 | +#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */ | ||
5332 | + | ||
5333 | +#define E1000_DVMOLR_HIDEVLAN 0x20000000 /* Hide vlan enable */ | ||
5334 | +#define E1000_DVMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */ | ||
5335 | +#define E1000_DVMOLR_STRCRC 0x80000000 /* CRC stripping enable */ | ||
5336 | + | ||
5337 | +#define E1000_VLVF_ARRAY_SIZE 32 | ||
5338 | +#define E1000_VLVF_VLANID_MASK 0x00000FFF | ||
5339 | +#define E1000_VLVF_POOLSEL_SHIFT 12 | ||
5340 | +#define E1000_VLVF_POOLSEL_MASK (0xFF << E1000_VLVF_POOLSEL_SHIFT) | ||
5341 | +#define E1000_VLVF_LVLAN 0x00100000 | ||
5342 | +#define E1000_VLVF_VLANID_ENABLE 0x80000000 | ||
5343 | + | ||
5344 | +#define E1000_VMVIR_VLANA_DEFAULT 0x40000000 /* Always use default VLAN */ | ||
5345 | +#define E1000_VMVIR_VLANA_NEVER 0x80000000 /* Never insert VLAN tag */ | ||
5346 | + | ||
5347 | +#define E1000_IOVCTL 0x05BBC | ||
5348 | +#define E1000_IOVCTL_REUSE_VFQ 0x00000001 | ||
5349 | + | ||
5350 | +#define E1000_RPLOLR_STRVLAN 0x40000000 | ||
5351 | +#define E1000_RPLOLR_STRCRC 0x80000000 | ||
5352 | + | ||
5353 | +#define E1000_DTXCTL_8023LL 0x0004 | ||
5354 | +#define E1000_DTXCTL_VLAN_ADDED 0x0008 | ||
5355 | +#define E1000_DTXCTL_OOS_ENABLE 0x0010 | ||
5356 | +#define E1000_DTXCTL_MDP_EN 0x0020 | ||
5357 | +#define E1000_DTXCTL_SPOOF_INT 0x0040 | ||
5358 | + | ||
5359 | +/* from igb/e1000_defines.h */ | ||
5360 | + | ||
5361 | +#define E1000_IVAR_VALID 0x80 | ||
5362 | +#define E1000_GPIE_NSICR 0x00000001 | ||
5363 | +#define E1000_GPIE_MSIX_MODE 0x00000010 | ||
5364 | +#define E1000_GPIE_EIAME 0x40000000 | ||
5365 | +#define E1000_GPIE_PBA 0x80000000 | ||
5366 | + | ||
5367 | +/* Transmit Control */ | ||
5368 | +#define E1000_TCTL_EN 0x00000002 /* enable tx */ | ||
5369 | +#define E1000_TCTL_PSP 0x00000008 /* pad short packets */ | ||
5370 | +#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */ | ||
5371 | +#define E1000_TCTL_COLD 0x003ff000 /* collision distance */ | ||
5372 | +#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ | ||
5373 | + | ||
5374 | +/* Collision related configuration parameters */ | ||
5375 | +#define E1000_COLLISION_THRESHOLD 15 | ||
5376 | +#define E1000_CT_SHIFT 4 | ||
5377 | +#define E1000_COLLISION_DISTANCE 63 | ||
5378 | +#define E1000_COLD_SHIFT 12 | ||
5379 | + | ||
5380 | +#define E1000_RAH_POOL_MASK 0x03FC0000 | ||
5381 | +#define E1000_RAH_POOL_1 0x00040000 | ||
5382 | + | ||
5383 | +#define E1000_ICR_VMMB 0x00000100 /* VM MB event */ | ||
5384 | +#define E1000_ICR_TS 0x00080000 /* Time Sync Interrupt */ | ||
5385 | +#define E1000_ICR_DRSTA 0x40000000 /* Device Reset Asserted */ | ||
5386 | +/* If this bit asserted, the driver should claim the interrupt */ | ||
5387 | +#define E1000_ICR_INT_ASSERTED 0x80000000 | ||
5388 | +/* LAN connected device generates an interrupt */ | ||
5389 | +#define E1000_ICR_DOUTSYNC 0x10000000 /* NIC DMA out of sync */ | ||
5390 | + | ||
5391 | +/* Extended Interrupt Cause Read */ | ||
5392 | +#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */ | ||
5393 | +#define E1000_EICR_RX_QUEUE1 0x00000002 /* Rx Queue 1 Interrupt */ | ||
5394 | +#define E1000_EICR_RX_QUEUE2 0x00000004 /* Rx Queue 2 Interrupt */ | ||
5395 | +#define E1000_EICR_RX_QUEUE3 0x00000008 /* Rx Queue 3 Interrupt */ | ||
5396 | +#define E1000_EICR_TX_QUEUE0 0x00000100 /* Tx Queue 0 Interrupt */ | ||
5397 | +#define E1000_EICR_TX_QUEUE1 0x00000200 /* Tx Queue 1 Interrupt */ | ||
5398 | +#define E1000_EICR_TX_QUEUE2 0x00000400 /* Tx Queue 2 Interrupt */ | ||
5399 | +#define E1000_EICR_TX_QUEUE3 0x00000800 /* Tx Queue 3 Interrupt */ | ||
5400 | +#define E1000_EICR_OTHER 0x80000000 /* Interrupt Cause Active */ | ||
5401 | + | ||
5402 | +/* Extended Interrupt Cause Set */ | ||
5403 | +/* E1000_EITR_CNT_IGNR is only for 82576 and newer */ | ||
5404 | +#define E1000_EITR_CNT_IGNR 0x80000000 /* Don't reset counters on write */ | ||
5405 | + | ||
5406 | +/* PCI Express Control */ | ||
5407 | +#define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000 | ||
5408 | +#define E1000_GCR_CMPL_TMOUT_10ms 0x00001000 | ||
5409 | +#define E1000_GCR_CMPL_TMOUT_RESEND 0x00010000 | ||
5410 | +#define E1000_GCR_CAP_VER2 0x00040000 | ||
5411 | + | ||
5412 | +#define PHY_REVISION_MASK 0xFFFFFFF0 | ||
5413 | +#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ | ||
5414 | +#define MAX_PHY_MULTI_PAGE_REG 0xF | ||
5415 | + | ||
5416 | +#define IGP03E1000_E_PHY_ID 0x02A80390 | ||
5417 | + | ||
5418 | +/* from igb/e1000_mbox.h */ | ||
5419 | + | ||
5420 | +#define E1000_P2VMAILBOX_STS 0x00000001 /* Initiate message send to VF */ | ||
5421 | +#define E1000_P2VMAILBOX_ACK 0x00000002 /* Ack message recv'd from VF */ | ||
5422 | +#define E1000_P2VMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */ | ||
5423 | +#define E1000_P2VMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */ | ||
5424 | +#define E1000_P2VMAILBOX_RVFU 0x00000010 /* Reset VFU - used when VF stuck */ | ||
5425 | + | ||
5426 | +#define E1000_MBVFICR_VFREQ_MASK 0x000000FF /* bits for VF messages */ | ||
5427 | +#define E1000_MBVFICR_VFREQ_VF1 0x00000001 /* bit for VF 1 message */ | ||
5428 | +#define E1000_MBVFICR_VFACK_MASK 0x00FF0000 /* bits for VF acks */ | ||
5429 | +#define E1000_MBVFICR_VFACK_VF1 0x00010000 /* bit for VF 1 ack */ | ||
5430 | + | ||
5431 | +#define E1000_V2PMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */ | ||
5432 | + | ||
5433 | +/* | ||
5434 | + * If it's a E1000_VF_* msg then it originates in the VF and is sent to the | ||
5435 | + * PF. The reverse is true if it is E1000_PF_*. | ||
5436 | + * Message ACK's are the value or'd with 0xF0000000 | ||
5437 | + */ | ||
5438 | +/* Messages below or'd with this are the ACK */ | ||
5439 | +#define E1000_VT_MSGTYPE_ACK 0x80000000 | ||
5440 | +/* Messages below or'd with this are the NACK */ | ||
5441 | +#define E1000_VT_MSGTYPE_NACK 0x40000000 | ||
5442 | +/* Indicates that VF is still clear to send requests */ | ||
5443 | +#define E1000_VT_MSGTYPE_CTS 0x20000000 | ||
5444 | +#define E1000_VT_MSGINFO_SHIFT 16 | ||
5445 | +/* bits 23:16 are used for exra info for certain messages */ | ||
5446 | +#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT) | ||
5447 | + | ||
5448 | +#define E1000_VF_RESET 0x01 /* VF requests reset */ | ||
5449 | +#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests to set MAC addr */ | ||
5450 | +/* VF requests to clear all unicast MAC filters */ | ||
5451 | +#define E1000_VF_MAC_FILTER_CLR (0x01 << E1000_VT_MSGINFO_SHIFT) | ||
5452 | +/* VF requests to add unicast MAC filter */ | ||
5453 | +#define E1000_VF_MAC_FILTER_ADD (0x02 << E1000_VT_MSGINFO_SHIFT) | ||
5454 | +#define E1000_VF_SET_MULTICAST 0x03 /* VF requests to set MC addr */ | ||
5455 | +#define E1000_VF_SET_VLAN 0x04 /* VF requests to set VLAN */ | ||
5456 | +#define E1000_VF_SET_LPE 0x05 /* VF requests to set VMOLR.LPE */ | ||
5457 | +#define E1000_VF_SET_PROMISC 0x06 /*VF requests to clear VMOLR.ROPE/MPME*/ | ||
5458 | +#define E1000_VF_SET_PROMISC_MULTICAST (0x02 << E1000_VT_MSGINFO_SHIFT) | ||
5459 | + | ||
5460 | +#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */ | ||
5461 | + | ||
5462 | +/* from igb/e1000_regs.h */ | ||
5463 | + | ||
5464 | +#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */ | ||
5465 | +#define E1000_EITR(_n) (0x01680 + (0x4 * (_n))) | ||
5466 | +#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */ | ||
5467 | +#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */ | ||
5468 | +#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */ | ||
5469 | +#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */ | ||
5470 | +#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */ | ||
5471 | +#define E1000_GPIE 0x01514 /* General Purpose Interrupt Enable; RW */ | ||
5472 | +#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation Register - RW */ | ||
5473 | +#define E1000_IVAR_MISC 0x01740 /* Interrupt Vector Allocation Register (last) - RW */ | ||
5474 | +#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */ | ||
5475 | +#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */ | ||
5476 | + | ||
5477 | +#define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40)) | ||
5478 | + | ||
5479 | +#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */ | ||
5480 | +#define E1000_TXPBS 0x03404 /* Tx Packet Buffer Size - RW */ | ||
5481 | + | ||
5482 | +#define E1000_DTXCTL 0x03590 /* DMA TX Control - RW */ | ||
5483 | + | ||
5484 | +#define E1000_HTCBDPC 0x04124 /* Host TX Circuit Breaker Dropped Count */ | ||
5485 | +#define E1000_RLPML 0x05004 /* RX Long Packet Max Length */ | ||
5486 | +#define E1000_RA2 0x054E0 /* 2nd half of Rx address array - RW Array */ | ||
5487 | +#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4)) | ||
5488 | +#define E1000_VT_CTL 0x0581C /* VMDq Control - RW */ | ||
5489 | + | ||
5490 | +/* VT Registers */ | ||
5491 | +#define E1000_MBVFICR 0x00C80 /* Mailbox VF Cause - RWC */ | ||
5492 | +#define E1000_MBVFIMR 0x00C84 /* Mailbox VF int Mask - RW */ | ||
5493 | +#define E1000_VFLRE 0x00C88 /* VF Register Events - RWC */ | ||
5494 | +#define E1000_VFRE 0x00C8C /* VF Receive Enables */ | ||
5495 | +#define E1000_VFTE 0x00C90 /* VF Transmit Enables */ | ||
5496 | +#define E1000_QDE 0x02408 /* Queue Drop Enable - RW */ | ||
5497 | +#define E1000_DTXSWC 0x03500 /* DMA Tx Switch Control - RW */ | ||
5498 | +#define E1000_WVBR 0x03554 /* VM Wrong Behavior - RWS */ | ||
5499 | +#define E1000_RPLOLR 0x05AF0 /* Replication Offload - RW */ | ||
5500 | +#define E1000_UTA 0x0A000 /* Unicast Table Array - RW */ | ||
5501 | +#define E1000_IOVTCL 0x05BBC /* IOV Control Register */ | ||
5502 | +#define E1000_TXSWC 0x05ACC /* Tx Switch Control */ | ||
5503 | +#define E1000_LVMMC 0x03548 /* Last VM Misbehavior cause */ | ||
5504 | +/* These act per VF so an array friendly macro is used */ | ||
5505 | +#define E1000_P2VMAILBOX(_n) (0x00C00 + (4 * (_n))) | ||
5506 | +#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n))) | ||
5507 | +#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n))) | ||
5508 | +#define E1000_DVMOLR(_n) (0x0C038 + (64 * (_n))) | ||
5509 | +#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN VM Filter */ | ||
5510 | +#define E1000_VMVIR(_n) (0x03700 + (4 * (_n))) | ||
5511 | + | ||
5512 | +/* from igbvf/defines.h */ | ||
5513 | + | ||
5514 | +/* SRRCTL bit definitions */ | ||
5515 | +#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */ | ||
5516 | +#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00 | ||
5517 | +#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */ | ||
5518 | +#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 | ||
5519 | +#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 | ||
5520 | +#define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000 | ||
5521 | +#define E1000_SRRCTL_DROP_EN 0x80000000 | ||
5522 | + | ||
5523 | +#define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F | ||
5524 | +#define E1000_SRRCTL_BSIZEHDR_MASK 0x00003F00 | ||
5525 | + | ||
5526 | +/* from igbvf/mbox.h */ | ||
5527 | + | ||
5528 | +#define E1000_V2PMAILBOX_REQ 0x00000001 /* Request for PF Ready bit */ | ||
5529 | +#define E1000_V2PMAILBOX_ACK 0x00000002 /* Ack PF message received */ | ||
5530 | +#define E1000_V2PMAILBOX_VFU 0x00000004 /* VF owns the mailbox buffer */ | ||
5531 | +#define E1000_V2PMAILBOX_PFU 0x00000008 /* PF owns the mailbox buffer */ | ||
5532 | +#define E1000_V2PMAILBOX_PFSTS 0x00000010 /* PF wrote a message in the MB */ | ||
5533 | +#define E1000_V2PMAILBOX_PFACK 0x00000020 /* PF ack the previous VF msg */ | ||
5534 | +#define E1000_V2PMAILBOX_RSTI 0x00000040 /* PF has reset indication */ | ||
5535 | +#define E1000_V2PMAILBOX_RSTD 0x00000080 /* PF has indicated reset done */ | ||
5536 | +#define E1000_V2PMAILBOX_R2C_BITS 0x000000B0 /* All read to clear bits */ | ||
5537 | + | ||
5538 | +#define E1000_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */ | ||
5539 | + | ||
5540 | +/* | ||
5541 | + * If it's a E1000_VF_* msg then it originates in the VF and is sent to the | ||
5542 | + * PF. The reverse is true if it is E1000_PF_*. | ||
5543 | + * Message ACK's are the value or'd with 0xF0000000 | ||
5544 | + */ | ||
5545 | +/* Messages below or'd with this are the ACK */ | ||
5546 | +#define E1000_VT_MSGTYPE_ACK 0x80000000 | ||
5547 | +/* Messages below or'd with this are the NACK */ | ||
5548 | +#define E1000_VT_MSGTYPE_NACK 0x40000000 | ||
5549 | +/* Indicates that VF is still clear to send requests */ | ||
5550 | +#define E1000_VT_MSGTYPE_CTS 0x20000000 | ||
5551 | + | ||
5552 | +/* We have a total wait time of 1s for vf mailbox posted messages */ | ||
5553 | +#define E1000_VF_MBX_INIT_TIMEOUT 2000 /* retry count for mbx timeout */ | ||
5554 | +#define E1000_VF_MBX_INIT_DELAY 500 /* usec delay between retries */ | ||
5555 | + | ||
5556 | +#define E1000_VT_MSGINFO_SHIFT 16 | ||
5557 | +/* bits 23:16 are used for exra info for certain messages */ | ||
5558 | +#define E1000_VT_MSGINFO_MASK (0xFF << E1000_VT_MSGINFO_SHIFT) | ||
5559 | + | ||
5560 | +#define E1000_VF_RESET 0x01 /* VF requests reset */ | ||
5561 | +#define E1000_VF_SET_MAC_ADDR 0x02 /* VF requests PF to set MAC addr */ | ||
5562 | +/* VF requests PF to clear all unicast MAC filters */ | ||
5563 | +#define E1000_VF_MAC_FILTER_CLR (0x01 << E1000_VT_MSGINFO_SHIFT) | ||
5564 | +/* VF requests PF to add unicast MAC filter */ | ||
5565 | +#define E1000_VF_MAC_FILTER_ADD (0x02 << E1000_VT_MSGINFO_SHIFT) | ||
5566 | +#define E1000_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */ | ||
5567 | +#define E1000_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */ | ||
5568 | +#define E1000_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */ | ||
5569 | + | ||
5570 | +#define E1000_PF_CONTROL_MSG 0x0100 /* PF control message */ | ||
5571 | + | ||
5572 | +/* from igbvf/regs.h */ | ||
5573 | + | ||
5574 | +/* Statistics registers */ | ||
5575 | +#define E1000_VFGPRC 0x00F10 | ||
5576 | +#define E1000_VFGORC 0x00F18 | ||
5577 | +#define E1000_VFMPRC 0x00F3C | ||
5578 | +#define E1000_VFGPTC 0x00F14 | ||
5579 | +#define E1000_VFGOTC 0x00F34 | ||
5580 | +#define E1000_VFGOTLBC 0x00F50 | ||
5581 | +#define E1000_VFGPTLBC 0x00F44 | ||
5582 | +#define E1000_VFGORLBC 0x00F48 | ||
5583 | +#define E1000_VFGPRLBC 0x00F40 | ||
5584 | + | ||
5585 | +/* These act per VF so an array friendly macro is used */ | ||
5586 | +#define E1000_V2PMAILBOX(_n) (0x00C40 + (4 * (_n))) | ||
5587 | +#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n))) | ||
5588 | + | ||
5589 | +/* from igbvf/vf.h */ | ||
5590 | + | ||
5591 | +#define E1000_DEV_ID_82576_VF 0x10CA | ||
5592 | + | ||
5593 | +/* new */ | ||
5594 | + | ||
5595 | +/* Receive Registers */ | ||
5596 | + | ||
5597 | +/* RX Descriptor Base Low; RW */ | ||
5598 | +#define E1000_RDBAL(_n) (0x0C000 + (0x40 * (_n))) | ||
5599 | +#define E1000_RDBAL_A(_n) (0x02800 + (0x100 * (_n))) | ||
5600 | + | ||
5601 | +/* RX Descriptor Base High; RW */ | ||
5602 | +#define E1000_RDBAH(_n) (0x0C004 + (0x40 * (_n))) | ||
5603 | +#define E1000_RDBAH_A(_n) (0x02804 + (0x100 * (_n))) | ||
5604 | + | ||
5605 | +/* RX Descriptor Ring Length; RW */ | ||
5606 | +#define E1000_RDLEN(_n) (0x0C008 + (0x40 * (_n))) | ||
5607 | +#define E1000_RDLEN_A(_n) (0x02808 + (0x100 * (_n))) | ||
5608 | + | ||
5609 | +/* Split and Replication Receive Control; RW */ | ||
5610 | +#define E1000_SRRCTL(_n) (0x0C00C + (0x40 * (_n))) | ||
5611 | +#define E1000_SRRCTL_A(_n) (0x0280C + (0x100 * (_n))) | ||
5612 | + | ||
5613 | +/* RX Descriptor Head; RW */ | ||
5614 | +#define E1000_RDH(_n) (0x0C010 + (0x40 * (_n))) | ||
5615 | +#define E1000_RDH_A(_n) (0x02810 + (0x100 * (_n))) | ||
5616 | + | ||
5617 | +/* RX DCA Control; RW */ | ||
5618 | +#define E1000_RXCTL(_n) (0x0C014 + (0x40 * (_n))) | ||
5619 | +#define E1000_RXCTL_A(_n) (0x02814 + (0x100 * (_n))) | ||
5620 | + | ||
5621 | +/* RX Descriptor Tail; RW */ | ||
5622 | +#define E1000_RDT(_n) (0x0C018 + (0x40 * (_n))) | ||
5623 | +#define E1000_RDT_A(_n) (0x02818 + (0x100 * (_n))) | ||
5624 | + | ||
5625 | +/* RX Descriptor Control; RW */ | ||
5626 | +#define E1000_RXDCTL(_n) (0x0C028 + (0x40 * (_n))) | ||
5627 | +#define E1000_RXDCTL_A(_n) (0x02828 + (0x100 * (_n))) | ||
5628 | + | ||
5629 | +/* RX Queue Drop Packet Count; RC */ | ||
5630 | +#define E1000_RQDPC_A(_n) (0x02830 + (0x100 * (_n))) | ||
5631 | + | ||
5632 | +/* Transmit Registers */ | ||
5633 | + | ||
5634 | +/* TX Descriptor Base Low; RW */ | ||
5635 | +#define E1000_TDBAL(_n) (0x0E000 + (0x40 * (_n))) | ||
5636 | +#define E1000_TDBAL_A(_n) (0x03800 + (0x100 * (_n))) | ||
5637 | + | ||
5638 | +/* TX Descriptor Base High; RW */ | ||
5639 | +#define E1000_TDBAH(_n) (0x0E004 + (0x40 * (_n))) | ||
5640 | +#define E1000_TDBAH_A(_n) (0x03804 + (0x100 * (_n))) | ||
5641 | + | ||
5642 | +/* TX Descriptor Ring Length; RW */ | ||
5643 | +#define E1000_TDLEN(_n) (0x0E008 + (0x40 * (_n))) | ||
5644 | +#define E1000_TDLEN_A(_n) (0x03808 + (0x100 * (_n))) | ||
5645 | + | ||
5646 | +/* TX Descriptor Head; RW */ | ||
5647 | +#define E1000_TDH(_n) (0x0E010 + (0x40 * (_n))) | ||
5648 | +#define E1000_TDH_A(_n) (0x03810 + (0x100 * (_n))) | ||
5649 | + | ||
5650 | +/* TX DCA Control; RW */ | ||
5651 | +#define E1000_TXCTL(_n) (0x0E014 + (0x40 * (_n))) | ||
5652 | +#define E1000_TXCTL_A(_n) (0x03814 + (0x100 * (_n))) | ||
5653 | + | ||
5654 | +/* TX Descriptor Tail; RW */ | ||
5655 | +#define E1000_TDT(_n) (0x0E018 + (0x40 * (_n))) | ||
5656 | +#define E1000_TDT_A(_n) (0x03818 + (0x100 * (_n))) | ||
5657 | + | ||
5658 | +/* TX Descriptor Control; RW */ | ||
5659 | +#define E1000_TXDCTL(_n) (0x0E028 + (0x40 * (_n))) | ||
5660 | +#define E1000_TXDCTL_A(_n) (0x03828 + (0x100 * (_n))) | ||
5661 | + | ||
5662 | +/* TX Descriptor Completion Write\ufffd\ufffd\ufffdBack Address Low; RW */ | ||
5663 | +#define E1000_TDWBAL(_n) (0x0E038 + (0x40 * (_n))) | ||
5664 | +#define E1000_TDWBAL_A(_n) (0x03838 + (0x100 * (_n))) | ||
5665 | + | ||
5666 | +/* TX Descriptor Completion Write\ufffd\ufffd\ufffdBack Address High; RW */ | ||
5667 | +#define E1000_TDWBAH(_n) (0x0E03C + (0x40 * (_n))) | ||
5668 | +#define E1000_TDWBAH_A(_n) (0x0383C + (0x100 * (_n))) | ||
5669 | + | ||
5670 | +#define E1000_MTA_A 0x0200 | ||
5671 | + | ||
5672 | +#define E1000_XDBAL_MASK (~(BIT(5) - 1)) /* TDBAL and RDBAL Registers Mask */ | ||
5673 | + | ||
5674 | +#define E1000_ICR_MACSEC 0x00000020 /* MACSec */ | ||
5675 | +#define E1000_ICR_RX0 0x00000040 /* Receiver Overrun */ | ||
5676 | +#define E1000_ICR_GPI_SDP0 0x00000800 /* General Purpose, SDP0 pin */ | ||
5677 | +#define E1000_ICR_GPI_SDP1 0x00001000 /* General Purpose, SDP1 pin */ | ||
5678 | +#define E1000_ICR_GPI_SDP2 0x00002000 /* General Purpose, SDP2 pin */ | ||
5679 | +#define E1000_ICR_GPI_SDP3 0x00004000 /* General Purpose, SDP3 pin */ | ||
5680 | +#define E1000_ICR_PTRAP 0x00008000 /* Probe Trap */ | ||
5681 | +#define E1000_ICR_MNG 0x00040000 /* Management Event */ | ||
5682 | +#define E1000_ICR_OMED 0x00100000 /* Other Media Energy Detected */ | ||
5683 | +#define E1000_ICR_FER 0x00400000 /* Fatal Error */ | ||
5684 | +#define E1000_ICR_NFER 0x00800000 /* Non Fatal Error */ | ||
5685 | +#define E1000_ICR_CSRTO 0x01000000 /* CSR access Time Out Indication */ | ||
5686 | +#define E1000_ICR_SCE 0x02000000 /* Storm Control Event */ | ||
5687 | +#define E1000_ICR_SW_WD 0x04000000 /* Software Watchdog */ | ||
5688 | + | ||
5689 | +/* Extended Interrupts */ | ||
5690 | + | ||
5691 | +#define E1000_EICR_MSIX_MASK 0x01FFFFFF /* Bits used in MSI-X mode */ | ||
5692 | +#define E1000_EICR_LEGACY_MASK 0x4000FFFF /* Bits used in non MSI-X mode */ | ||
5693 | + | ||
5694 | +/* Mirror VF Control (only RST bit); RW */ | ||
5695 | +#define E1000_PVTCTRL(_n) (0x10000 + (_n) * 0x100) | ||
5696 | + | ||
5697 | +/* Mirror Good Packets Received Count; RO */ | ||
5698 | +#define E1000_PVFGPRC(_n) (0x10010 + (_n) * 0x100) | ||
5699 | + | ||
5700 | +/* Mirror Good Packets Transmitted Count; RO */ | ||
5701 | +#define E1000_PVFGPTC(_n) (0x10014 + (_n) * 0x100) | ||
5702 | + | ||
5703 | +/* Mirror Good Octets Received Count; RO */ | ||
5704 | +#define E1000_PVFGORC(_n) (0x10018 + (_n) * 0x100) | ||
5705 | + | ||
5706 | +/* Mirror Extended Interrupt Cause Set; WO */ | ||
5707 | +#define E1000_PVTEICS(_n) (0x10020 + (_n) * 0x100) | ||
5708 | + | ||
5709 | +/* Mirror Extended Interrupt Mask Set/Read; RW */ | ||
5710 | +#define E1000_PVTEIMS(_n) (0x10024 + (_n) * 0x100) | ||
5711 | + | ||
5712 | +/* Mirror Extended Interrupt Mask Clear; WO */ | ||
5713 | +#define E1000_PVTEIMC(_n) (0x10028 + (_n) * 0x100) | ||
5714 | + | ||
5715 | +/* Mirror Extended Interrupt Auto Clear; RW */ | ||
5716 | +#define E1000_PVTEIAC(_n) (0x1002C + (_n) * 0x100) | ||
5717 | + | ||
5718 | +/* Mirror Extended Interrupt Auto Mask Enable; RW */ | ||
5719 | +#define E1000_PVTEIAM(_n) (0x10030 + (_n) * 0x100) | ||
5720 | + | ||
5721 | +/* Mirror Good Octets Transmitted Count; RO */ | ||
5722 | +#define E1000_PVFGOTC(_n) (0x10034 + (_n) * 0x100) | ||
5723 | + | ||
5724 | +/* Mirror Multicast Packets Received Count; RO */ | ||
5725 | +#define E1000_PVFMPRC(_n) (0x1003C + (_n) * 0x100) | ||
5726 | + | ||
5727 | +/* Mirror Good RX Packets loopback Count; RO */ | ||
5728 | +#define E1000_PVFGPRLBC(_n) (0x10040 + (_n) * 0x100) | ||
5729 | + | ||
5730 | +/* Mirror Good TX packets loopback Count; RO */ | ||
5731 | +#define E1000_PVFGPTLBC(_n) (0x10044 + (_n) * 0x100) | ||
5732 | + | ||
5733 | +/* Mirror Good RX Octets loopback Count; RO */ | ||
5734 | +#define E1000_PVFGORLBC(_n) (0x10048 + (_n) * 0x100) | ||
5735 | + | ||
5736 | +/* Mirror Good TX Octets loopback Count; RO */ | ||
5737 | +#define E1000_PVFGOTLBC(_n) (0x10050 + (_n) * 0x100) | ||
5738 | + | ||
5739 | +/* Mirror Extended Interrupt Cause Set; RC/W1C */ | ||
5740 | +#define E1000_PVTEICR(_n) (0x10080 + (_n) * 0x100) | ||
5741 | + | ||
5742 | +/* | ||
5743 | + * These are fake addresses that, according to the specification, the device | ||
5744 | + * is not using. They are used to distinguish between the PF and the VFs | ||
5745 | + * accessing their VTIVAR register (which is the same address, 0x1700) | ||
5746 | + */ | ||
5747 | +#define E1000_VTIVAR 0x11700 | ||
5748 | +#define E1000_VTIVAR_MISC 0x11720 | ||
5749 | + | ||
5750 | +#define E1000_RSS_QUEUE(reta, hash) (E1000_RETA_VAL(reta, hash) & 0x0F) | ||
5751 | + | ||
5752 | +#define E1000_STATUS_IOV_MODE 0x00040000 | ||
5753 | + | ||
5754 | +#define E1000_STATUS_NUM_VFS_SHIFT 14 | ||
5755 | + | ||
5756 | +static inline uint8_t igb_ivar_entry_rx(uint8_t i) | ||
5757 | +{ | ||
5758 | + return i < 8 ? i * 4 : (i - 8) * 4 + 2; | ||
5759 | +} | ||
5760 | + | ||
5761 | +static inline uint8_t igb_ivar_entry_tx(uint8_t i) | ||
5762 | +{ | ||
5763 | + return i < 8 ? i * 4 + 1 : (i - 8) * 4 + 3; | ||
5764 | +} | ||
5765 | + | ||
5766 | +#endif | ||
5767 | diff --git a/hw/net/igbvf.c b/hw/net/igbvf.c | ||
5768 | new file mode 100644 | ||
5769 | index XXXXXXX..XXXXXXX | ||
5770 | --- /dev/null | ||
5771 | +++ b/hw/net/igbvf.c | ||
5772 | @@ -XXX,XX +XXX,XX @@ | ||
5773 | +/* | ||
5774 | + * QEMU Intel 82576 SR/IOV Ethernet Controller Emulation | ||
5775 | + * | ||
5776 | + * Datasheet: | ||
5777 | + * https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82576eg-gbe-datasheet.pdf | ||
5778 | + * | ||
5779 | + * Copyright (c) 2020-2023 Red Hat, Inc. | ||
5780 | + * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) | ||
5781 | + * Developed by Daynix Computing LTD (http://www.daynix.com) | ||
5782 | + * | ||
5783 | + * Authors: | ||
5784 | + * Akihiko Odaki <akihiko.odaki@daynix.com> | ||
5785 | + * Gal Hammmer <gal.hammer@sap.com> | ||
5786 | + * Marcel Apfelbaum <marcel.apfelbaum@gmail.com> | ||
5787 | + * Dmitry Fleytman <dmitry@daynix.com> | ||
5788 | + * Leonid Bloch <leonid@daynix.com> | ||
5789 | + * Yan Vugenfirer <yan@daynix.com> | ||
5790 | + * | ||
5791 | + * Based on work done by: | ||
5792 | + * Nir Peleg, Tutis Systems Ltd. for Qumranet Inc. | ||
5793 | + * Copyright (c) 2008 Qumranet | ||
5794 | + * Based on work done by: | ||
5795 | + * Copyright (c) 2007 Dan Aloni | ||
5796 | + * Copyright (c) 2004 Antony T Curtis | ||
5797 | + * | ||
5798 | + * This library is free software; you can redistribute it and/or | ||
5799 | + * modify it under the terms of the GNU Lesser General Public | ||
5800 | + * License as published by the Free Software Foundation; either | ||
5801 | + * version 2.1 of the License, or (at your option) any later version. | ||
5802 | + * | ||
5803 | + * This library is distributed in the hope that it will be useful, | ||
5804 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
5805 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
5806 | + * Lesser General Public License for more details. | ||
5807 | + * | ||
5808 | + * You should have received a copy of the GNU Lesser General Public | ||
5809 | + * License along with this library; if not, see <http://www.gnu.org/licenses/>. | ||
5810 | + */ | ||
5811 | + | ||
5812 | +#include "qemu/osdep.h" | ||
5813 | +#include "hw/hw.h" | ||
5814 | +#include "hw/net/mii.h" | ||
5815 | +#include "hw/pci/pci_device.h" | ||
5816 | +#include "hw/pci/pcie.h" | ||
5817 | +#include "hw/pci/msix.h" | ||
5818 | +#include "net/eth.h" | ||
5819 | +#include "net/net.h" | ||
5820 | +#include "igb_common.h" | ||
5821 | +#include "igb_core.h" | ||
5822 | +#include "trace.h" | ||
5823 | +#include "qapi/error.h" | ||
5824 | + | ||
5825 | +#define TYPE_IGBVF "igbvf" | ||
5826 | +OBJECT_DECLARE_SIMPLE_TYPE(IgbVfState, IGBVF) | ||
5827 | + | ||
5828 | +#define IGBVF_MMIO_BAR_IDX (0) | ||
5829 | +#define IGBVF_MSIX_BAR_IDX (3) | ||
5830 | + | ||
5831 | +#define IGBVF_MMIO_SIZE (16 * 1024) | ||
5832 | +#define IGBVF_MSIX_SIZE (16 * 1024) | ||
5833 | + | ||
5834 | +struct IgbVfState { | ||
5835 | + PCIDevice parent_obj; | ||
5836 | + | ||
5837 | + MemoryRegion mmio; | ||
5838 | + MemoryRegion msix; | ||
5839 | +}; | ||
5840 | + | ||
5841 | +static hwaddr vf_to_pf_addr(hwaddr addr, uint16_t vfn, bool write) | ||
5842 | +{ | ||
5843 | + switch (addr) { | ||
5844 | + case E1000_CTRL: | ||
5845 | + case E1000_CTRL_DUP: | ||
5846 | + return E1000_PVTCTRL(vfn); | ||
5847 | + case E1000_EICS: | ||
5848 | + return E1000_PVTEICS(vfn); | ||
5849 | + case E1000_EIMS: | ||
5850 | + return E1000_PVTEIMS(vfn); | ||
5851 | + case E1000_EIMC: | ||
5852 | + return E1000_PVTEIMC(vfn); | ||
5853 | + case E1000_EIAC: | ||
5854 | + return E1000_PVTEIAC(vfn); | ||
5855 | + case E1000_EIAM: | ||
5856 | + return E1000_PVTEIAM(vfn); | ||
5857 | + case E1000_EICR: | ||
5858 | + return E1000_PVTEICR(vfn); | ||
5859 | + case E1000_EITR(0): | ||
5860 | + case E1000_EITR(1): | ||
5861 | + case E1000_EITR(2): | ||
5862 | + return E1000_EITR(22) + (addr - E1000_EITR(0)) - vfn * 0xC; | ||
5863 | + case E1000_IVAR0: | ||
5864 | + return E1000_VTIVAR + vfn * 4; | ||
5865 | + case E1000_IVAR_MISC: | ||
5866 | + return E1000_VTIVAR_MISC + vfn * 4; | ||
5867 | + case 0x0F04: /* PBACL */ | ||
5868 | + return E1000_PBACLR; | ||
5869 | + case 0x0F0C: /* PSRTYPE */ | ||
5870 | + return E1000_PSRTYPE(vfn); | ||
5871 | + case E1000_V2PMAILBOX(0): | ||
5872 | + return E1000_V2PMAILBOX(vfn); | ||
5873 | + case E1000_VMBMEM(0) ... E1000_VMBMEM(0) + 0x3F: | ||
5874 | + return addr + vfn * 0x40; | ||
5875 | + case E1000_RDBAL_A(0): | ||
5876 | + return E1000_RDBAL(vfn); | ||
5877 | + case E1000_RDBAL_A(1): | ||
5878 | + return E1000_RDBAL(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5879 | + case E1000_RDBAH_A(0): | ||
5880 | + return E1000_RDBAH(vfn); | ||
5881 | + case E1000_RDBAH_A(1): | ||
5882 | + return E1000_RDBAH(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5883 | + case E1000_RDLEN_A(0): | ||
5884 | + return E1000_RDLEN(vfn); | ||
5885 | + case E1000_RDLEN_A(1): | ||
5886 | + return E1000_RDLEN(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5887 | + case E1000_SRRCTL_A(0): | ||
5888 | + return E1000_SRRCTL(vfn); | ||
5889 | + case E1000_SRRCTL_A(1): | ||
5890 | + return E1000_SRRCTL(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5891 | + case E1000_RDH_A(0): | ||
5892 | + return E1000_RDH(vfn); | ||
5893 | + case E1000_RDH_A(1): | ||
5894 | + return E1000_RDH(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5895 | + case E1000_RXCTL_A(0): | ||
5896 | + return E1000_RXCTL(vfn); | ||
5897 | + case E1000_RXCTL_A(1): | ||
5898 | + return E1000_RXCTL(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5899 | + case E1000_RDT_A(0): | ||
5900 | + return E1000_RDT(vfn); | ||
5901 | + case E1000_RDT_A(1): | ||
5902 | + return E1000_RDT(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5903 | + case E1000_RXDCTL_A(0): | ||
5904 | + return E1000_RXDCTL(vfn); | ||
5905 | + case E1000_RXDCTL_A(1): | ||
5906 | + return E1000_RXDCTL(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5907 | + case E1000_RQDPC_A(0): | ||
5908 | + return E1000_RQDPC(vfn); | ||
5909 | + case E1000_RQDPC_A(1): | ||
5910 | + return E1000_RQDPC(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5911 | + case E1000_TDBAL_A(0): | ||
5912 | + return E1000_TDBAL(vfn); | ||
5913 | + case E1000_TDBAL_A(1): | ||
5914 | + return E1000_TDBAL(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5915 | + case E1000_TDBAH_A(0): | ||
5916 | + return E1000_TDBAH(vfn); | ||
5917 | + case E1000_TDBAH_A(1): | ||
5918 | + return E1000_TDBAH(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5919 | + case E1000_TDLEN_A(0): | ||
5920 | + return E1000_TDLEN(vfn); | ||
5921 | + case E1000_TDLEN_A(1): | ||
5922 | + return E1000_TDLEN(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5923 | + case E1000_TDH_A(0): | ||
5924 | + return E1000_TDH(vfn); | ||
5925 | + case E1000_TDH_A(1): | ||
5926 | + return E1000_TDH(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5927 | + case E1000_TXCTL_A(0): | ||
5928 | + return E1000_TXCTL(vfn); | ||
5929 | + case E1000_TXCTL_A(1): | ||
5930 | + return E1000_TXCTL(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5931 | + case E1000_TDT_A(0): | ||
5932 | + return E1000_TDT(vfn); | ||
5933 | + case E1000_TDT_A(1): | ||
5934 | + return E1000_TDT(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5935 | + case E1000_TXDCTL_A(0): | ||
5936 | + return E1000_TXDCTL(vfn); | ||
5937 | + case E1000_TXDCTL_A(1): | ||
5938 | + return E1000_TXDCTL(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5939 | + case E1000_TDWBAL_A(0): | ||
5940 | + return E1000_TDWBAL(vfn); | ||
5941 | + case E1000_TDWBAL_A(1): | ||
5942 | + return E1000_TDWBAL(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5943 | + case E1000_TDWBAH_A(0): | ||
5944 | + return E1000_TDWBAH(vfn); | ||
5945 | + case E1000_TDWBAH_A(1): | ||
5946 | + return E1000_TDWBAH(vfn + IGB_MAX_VF_FUNCTIONS); | ||
5947 | + case E1000_VFGPRC: | ||
5948 | + return E1000_PVFGPRC(vfn); | ||
5949 | + case E1000_VFGPTC: | ||
5950 | + return E1000_PVFGPTC(vfn); | ||
5951 | + case E1000_VFGORC: | ||
5952 | + return E1000_PVFGORC(vfn); | ||
5953 | + case E1000_VFGOTC: | ||
5954 | + return E1000_PVFGOTC(vfn); | ||
5955 | + case E1000_VFMPRC: | ||
5956 | + return E1000_PVFMPRC(vfn); | ||
5957 | + case E1000_VFGPRLBC: | ||
5958 | + return E1000_PVFGPRLBC(vfn); | ||
5959 | + case E1000_VFGPTLBC: | ||
5960 | + return E1000_PVFGPTLBC(vfn); | ||
5961 | + case E1000_VFGORLBC: | ||
5962 | + return E1000_PVFGORLBC(vfn); | ||
5963 | + case E1000_VFGOTLBC: | ||
5964 | + return E1000_PVFGOTLBC(vfn); | ||
5965 | + case E1000_STATUS: | ||
5966 | + case E1000_FRTIMER: | ||
5967 | + if (write) { | ||
5968 | + return HWADDR_MAX; | ||
5969 | + } | ||
5970 | + /* fallthrough */ | ||
5971 | + case 0x34E8: /* PBTWAC */ | ||
5972 | + case 0x24E8: /* PBRWAC */ | ||
5973 | + return addr; | ||
5974 | + } | ||
5975 | + | ||
5976 | + trace_igbvf_wrn_io_addr_unknown(addr); | ||
5977 | + | ||
5978 | + return HWADDR_MAX; | ||
5979 | +} | ||
5980 | + | ||
5981 | +static void igbvf_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, | ||
5982 | + int len) | ||
5983 | +{ | ||
5984 | + trace_igbvf_write_config(addr, val, len); | ||
5985 | + pci_default_write_config(dev, addr, val, len); | ||
5986 | +} | ||
5987 | + | ||
5988 | +static uint64_t igbvf_mmio_read(void *opaque, hwaddr addr, unsigned size) | ||
5989 | +{ | ||
5990 | + PCIDevice *vf = PCI_DEVICE(opaque); | ||
5991 | + PCIDevice *pf = pcie_sriov_get_pf(vf); | ||
5992 | + | ||
5993 | + addr = vf_to_pf_addr(addr, pcie_sriov_vf_number(vf), false); | ||
5994 | + return addr == HWADDR_MAX ? 0 : igb_mmio_read(pf, addr, size); | ||
5995 | +} | ||
5996 | + | ||
5997 | +static void igbvf_mmio_write(void *opaque, hwaddr addr, uint64_t val, | ||
5998 | + unsigned size) | ||
5999 | +{ | ||
6000 | + PCIDevice *vf = PCI_DEVICE(opaque); | ||
6001 | + PCIDevice *pf = pcie_sriov_get_pf(vf); | ||
6002 | + | ||
6003 | + addr = vf_to_pf_addr(addr, pcie_sriov_vf_number(vf), true); | ||
6004 | + if (addr != HWADDR_MAX) { | ||
6005 | + igb_mmio_write(pf, addr, val, size); | ||
6006 | + } | ||
6007 | +} | ||
6008 | + | ||
6009 | +static const MemoryRegionOps mmio_ops = { | ||
6010 | + .read = igbvf_mmio_read, | ||
6011 | + .write = igbvf_mmio_write, | ||
6012 | + .endianness = DEVICE_LITTLE_ENDIAN, | ||
6013 | + .impl = { | ||
6014 | + .min_access_size = 4, | ||
6015 | + .max_access_size = 4, | ||
6016 | + }, | ||
6017 | +}; | ||
6018 | + | ||
6019 | +static void igbvf_pci_realize(PCIDevice *dev, Error **errp) | ||
6020 | +{ | ||
6021 | + IgbVfState *s = IGBVF(dev); | ||
6022 | + int ret; | ||
6023 | + int i; | ||
6024 | + | ||
6025 | + dev->config_write = igbvf_write_config; | ||
6026 | + | ||
6027 | + memory_region_init_io(&s->mmio, OBJECT(dev), &mmio_ops, s, "igbvf-mmio", | ||
6028 | + IGBVF_MMIO_SIZE); | ||
6029 | + pcie_sriov_vf_register_bar(dev, IGBVF_MMIO_BAR_IDX, &s->mmio); | ||
6030 | + | ||
6031 | + memory_region_init(&s->msix, OBJECT(dev), "igbvf-msix", IGBVF_MSIX_SIZE); | ||
6032 | + pcie_sriov_vf_register_bar(dev, IGBVF_MSIX_BAR_IDX, &s->msix); | ||
6033 | + | ||
6034 | + ret = msix_init(dev, IGBVF_MSIX_VEC_NUM, &s->msix, IGBVF_MSIX_BAR_IDX, 0, | ||
6035 | + &s->msix, IGBVF_MSIX_BAR_IDX, 0x2000, 0x70, errp); | ||
6036 | + if (ret) { | ||
6037 | + return; | ||
6038 | + } | ||
6039 | + | ||
6040 | + for (i = 0; i < IGBVF_MSIX_VEC_NUM; i++) { | ||
6041 | + msix_vector_use(dev, i); | ||
6042 | + } | ||
6043 | + | ||
6044 | + if (pcie_endpoint_cap_init(dev, 0xa0) < 0) { | ||
6045 | + hw_error("Failed to initialize PCIe capability"); | ||
6046 | + } | ||
6047 | + | ||
6048 | + if (pcie_aer_init(dev, 1, 0x100, 0x40, errp) < 0) { | ||
6049 | + hw_error("Failed to initialize AER capability"); | ||
6050 | + } | ||
6051 | + | ||
6052 | + pcie_ari_init(dev, 0x150, 1); | ||
6053 | +} | ||
6054 | + | ||
6055 | +static void igbvf_pci_uninit(PCIDevice *dev) | ||
6056 | +{ | ||
6057 | + IgbVfState *s = IGBVF(dev); | ||
6058 | + | ||
6059 | + pcie_aer_exit(dev); | ||
6060 | + pcie_cap_exit(dev); | ||
6061 | + msix_unuse_all_vectors(dev); | ||
6062 | + msix_uninit(dev, &s->msix, &s->msix); | ||
6063 | +} | ||
6064 | + | ||
6065 | +static void igbvf_class_init(ObjectClass *class, void *data) | ||
6066 | +{ | ||
6067 | + DeviceClass *dc = DEVICE_CLASS(class); | ||
6068 | + PCIDeviceClass *c = PCI_DEVICE_CLASS(class); | ||
6069 | + | ||
6070 | + c->realize = igbvf_pci_realize; | ||
6071 | + c->exit = igbvf_pci_uninit; | ||
6072 | + c->vendor_id = PCI_VENDOR_ID_INTEL; | ||
6073 | + c->device_id = E1000_DEV_ID_82576_VF; | ||
6074 | + c->revision = 1; | ||
6075 | + c->class_id = PCI_CLASS_NETWORK_ETHERNET; | ||
6076 | + | ||
6077 | + dc->desc = "Intel 82576 Virtual Function"; | ||
6078 | + dc->user_creatable = false; | ||
6079 | + | ||
6080 | + set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); | ||
6081 | +} | ||
6082 | + | ||
6083 | +static const TypeInfo igbvf_info = { | ||
6084 | + .name = TYPE_IGBVF, | ||
6085 | + .parent = TYPE_PCI_DEVICE, | ||
6086 | + .instance_size = sizeof(IgbVfState), | ||
6087 | + .class_init = igbvf_class_init, | ||
6088 | + .interfaces = (InterfaceInfo[]) { | ||
6089 | + { INTERFACE_PCIE_DEVICE }, | ||
6090 | + { } | ||
6091 | + }, | ||
6092 | +}; | ||
6093 | + | ||
6094 | +static void igb_register_types(void) | ||
6095 | +{ | ||
6096 | + type_register_static(&igbvf_info); | ||
6097 | +} | ||
6098 | + | ||
6099 | +type_init(igb_register_types) | ||
6100 | diff --git a/hw/net/meson.build b/hw/net/meson.build | ||
6101 | index XXXXXXX..XXXXXXX 100644 | ||
6102 | --- a/hw/net/meson.build | ||
6103 | +++ b/hw/net/meson.build | ||
6104 | @@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_PCNET_COMMON', if_true: files('pcnet.c')) | ||
6105 | softmmu_ss.add(when: 'CONFIG_E1000_PCI', if_true: files('e1000.c', 'e1000x_common.c')) | ||
6106 | softmmu_ss.add(when: 'CONFIG_E1000E_PCI_EXPRESS', if_true: files('net_tx_pkt.c', 'net_rx_pkt.c')) | ||
6107 | softmmu_ss.add(when: 'CONFIG_E1000E_PCI_EXPRESS', if_true: files('e1000e.c', 'e1000e_core.c', 'e1000x_common.c')) | ||
6108 | +softmmu_ss.add(when: 'CONFIG_IGB_PCI_EXPRESS', if_true: files('net_tx_pkt.c', 'net_rx_pkt.c')) | ||
6109 | +softmmu_ss.add(when: 'CONFIG_IGB_PCI_EXPRESS', if_true: files('igb.c', 'igbvf.c', 'igb_core.c')) | ||
6110 | softmmu_ss.add(when: 'CONFIG_RTL8139_PCI', if_true: files('rtl8139.c')) | ||
6111 | softmmu_ss.add(when: 'CONFIG_TULIP', if_true: files('tulip.c')) | ||
6112 | softmmu_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('net_tx_pkt.c', 'net_rx_pkt.c')) | ||
6113 | diff --git a/hw/net/trace-events b/hw/net/trace-events | ||
6114 | index XXXXXXX..XXXXXXX 100644 | ||
6115 | --- a/hw/net/trace-events | ||
6116 | +++ b/hw/net/trace-events | ||
6117 | @@ -XXX,XX +XXX,XX @@ e1000e_msix_use_vector_fail(uint32_t vec, int32_t res) "Failed to use MSI-X vect | ||
6118 | 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" | ||
6119 | e1000e_cfg_support_virtio(bool support) "Virtio header supported: %d" | ||
6120 | |||
6121 | +# igb.c | ||
6122 | +igb_write_config(uint32_t address, uint32_t val, int len) "CONFIG write 0x%"PRIx32", value: 0x%"PRIx32", len: %"PRId32 | ||
6123 | +igbvf_write_config(uint32_t address, uint32_t val, int len) "CONFIG write 0x%"PRIx32", value: 0x%"PRIx32", len: %"PRId32 | ||
6124 | + | ||
6125 | +# igb_core.c | ||
6126 | +igb_core_mdic_read(uint32_t addr, uint32_t data) "MDIC READ: PHY[%u] = 0x%x" | ||
6127 | +igb_core_mdic_read_unhandled(uint32_t addr) "MDIC READ: PHY[%u] UNHANDLED" | ||
6128 | +igb_core_mdic_write(uint32_t addr, uint32_t data) "MDIC WRITE: PHY[%u] = 0x%x" | ||
6129 | +igb_core_mdic_write_unhandled(uint32_t addr) "MDIC WRITE: PHY[%u] UNHANDLED" | ||
6130 | + | ||
6131 | +igb_rx_desc_buff_size(uint32_t b) "buffer size: %u" | ||
6132 | +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" | ||
6133 | + | ||
6134 | +igb_rx_metadata_rss(uint32_t rss) "RSS data: 0x%X" | ||
6135 | + | ||
6136 | +igb_irq_icr_clear_gpie_nsicr(void) "Clearing ICR on read due to GPIE.NSICR enabled" | ||
6137 | +igb_irq_icr_write(uint32_t bits, uint32_t old_icr, uint32_t new_icr) "Clearing ICR bits 0x%x: 0x%x --> 0x%x" | ||
6138 | +igb_irq_set_iam(uint32_t icr) "Update IAM: 0x%x" | ||
6139 | +igb_irq_read_iam(uint32_t icr) "Current IAM: 0x%x" | ||
6140 | +igb_irq_write_eics(uint32_t val, bool msix) "Update EICS: 0x%x MSI-X: %d" | ||
6141 | +igb_irq_write_eims(uint32_t val, bool msix) "Update EIMS: 0x%x MSI-X: %d" | ||
6142 | +igb_irq_write_eimc(uint32_t val, uint32_t eims, bool msix) "Update EIMC: 0x%x EIMS: 0x%x MSI-X: %d" | ||
6143 | +igb_irq_write_eiac(uint32_t val) "Update EIAC: 0x%x" | ||
6144 | +igb_irq_write_eiam(uint32_t val, bool msix) "Update EIAM: 0x%x MSI-X: %d" | ||
6145 | +igb_irq_write_eicr(uint32_t val, bool msix) "Update EICR: 0x%x MSI-X: %d" | ||
6146 | +igb_irq_eitr_set(uint32_t eitr_num, uint32_t val) "EITR[%u] = 0x%x" | ||
6147 | +igb_set_pfmailbox(uint32_t vf_num, uint32_t val) "PFMailbox[%d]: 0x%x" | ||
6148 | +igb_set_vfmailbox(uint32_t vf_num, uint32_t val) "VFMailbox[%d]: 0x%x" | ||
6149 | + | ||
6150 | +# igbvf.c | ||
6151 | +igbvf_wrn_io_addr_unknown(uint64_t addr) "IO unknown register 0x%"PRIx64 | ||
6152 | + | ||
6153 | # spapr_llan.c | ||
6154 | spapr_vlan_get_rx_bd_from_pool_found(int pool, int32_t count, uint32_t rx_bufs) "pool=%d count=%"PRId32" rxbufs=%"PRIu32 | ||
6155 | spapr_vlan_get_rx_bd_from_page(int buf_ptr, uint64_t bd) "use_buf_ptr=%d bd=0x%016"PRIx64 | ||
6156 | -- | ||
6157 | 2.7.4 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
3 | This change is derived from qtest for e1000e device. | ||
4 | |||
5 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
6 | Acked-by: Thomas Huth <thuth@redhat.com> | ||
7 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
8 | --- | ||
9 | MAINTAINERS | 2 + | ||
10 | tests/qtest/fuzz/generic_fuzz_configs.h | 5 + | ||
11 | tests/qtest/igb-test.c | 243 ++++++++++++++++++++++++++++++++ | ||
12 | tests/qtest/libqos/igb.c | 185 ++++++++++++++++++++++++ | ||
13 | tests/qtest/libqos/meson.build | 1 + | ||
14 | tests/qtest/meson.build | 1 + | ||
15 | 6 files changed, 437 insertions(+) | ||
16 | create mode 100644 tests/qtest/igb-test.c | ||
17 | create mode 100644 tests/qtest/libqos/igb.c | ||
18 | |||
19 | diff --git a/MAINTAINERS b/MAINTAINERS | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/MAINTAINERS | ||
22 | +++ b/MAINTAINERS | ||
23 | @@ -XXX,XX +XXX,XX @@ igb | ||
24 | M: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
25 | S: Maintained | ||
26 | F: hw/net/igb* | ||
27 | +F: tests/qtest/igb-test.c | ||
28 | +F: tests/qtest/libqos/igb.c | ||
29 | |||
30 | eepro100 | ||
31 | M: Stefan Weil <sw@weilnetz.de> | ||
32 | diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/tests/qtest/fuzz/generic_fuzz_configs.h | ||
35 | +++ b/tests/qtest/fuzz/generic_fuzz_configs.h | ||
36 | @@ -XXX,XX +XXX,XX @@ const generic_fuzz_config predefined_configs[] = { | ||
37 | "-device e1000e,netdev=net0 -netdev user,id=net0", | ||
38 | .objects = "e1000e", | ||
39 | },{ | ||
40 | + .name = "igb", | ||
41 | + .args = "-M q35 -nodefaults " | ||
42 | + "-device igb,netdev=net0 -netdev user,id=net0", | ||
43 | + .objects = "igb", | ||
44 | + },{ | ||
45 | .name = "cirrus-vga", | ||
46 | .args = "-machine q35 -nodefaults -device cirrus-vga", | ||
47 | .objects = "cirrus*", | ||
48 | diff --git a/tests/qtest/igb-test.c b/tests/qtest/igb-test.c | ||
49 | new file mode 100644 | ||
50 | index XXXXXXX..XXXXXXX | ||
51 | --- /dev/null | ||
52 | +++ b/tests/qtest/igb-test.c | ||
53 | @@ -XXX,XX +XXX,XX @@ | ||
54 | +/* | ||
55 | + * QTest testcase for igb NIC | ||
56 | + * | ||
57 | + * Copyright (c) 2022-2023 Red Hat, Inc. | ||
58 | + * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com) | ||
59 | + * Developed by Daynix Computing LTD (http://www.daynix.com) | ||
60 | + * | ||
61 | + * Authors: | ||
62 | + * Akihiko Odaki <akihiko.odaki@daynix.com> | ||
63 | + * Dmitry Fleytman <dmitry@daynix.com> | ||
64 | + * Leonid Bloch <leonid@daynix.com> | ||
65 | + * Yan Vugenfirer <yan@daynix.com> | ||
66 | + * | ||
67 | + * This library is free software; you can redistribute it and/or | ||
68 | + * modify it under the terms of the GNU Lesser General Public | ||
69 | + * License as published by the Free Software Foundation; either | ||
70 | + * version 2.1 of the License, or (at your option) any later version. | ||
71 | + * | ||
72 | + * This library is distributed in the hope that it will be useful, | ||
73 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
74 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
75 | + * Lesser General Public License for more details. | ||
76 | + * | ||
77 | + * You should have received a copy of the GNU Lesser General Public | ||
78 | + * License along with this library; if not, see <http://www.gnu.org/licenses/>. | ||
79 | + */ | ||
80 | + | ||
81 | + | ||
82 | +#include "qemu/osdep.h" | ||
83 | +#include "libqtest-single.h" | ||
84 | +#include "libqos/pci-pc.h" | ||
85 | +#include "net/eth.h" | ||
86 | +#include "qemu/sockets.h" | ||
87 | +#include "qemu/iov.h" | ||
88 | +#include "qemu/module.h" | ||
89 | +#include "qemu/bitops.h" | ||
90 | +#include "libqos/libqos-malloc.h" | ||
91 | +#include "libqos/e1000e.h" | ||
92 | +#include "hw/net/igb_regs.h" | ||
93 | + | ||
94 | +static const struct eth_header packet = { | ||
95 | + .h_dest = E1000E_ADDRESS, | ||
96 | + .h_source = E1000E_ADDRESS, | ||
97 | +}; | ||
98 | + | ||
99 | +static void igb_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc) | ||
100 | +{ | ||
101 | + union e1000_adv_tx_desc descr; | ||
102 | + char buffer[64]; | ||
103 | + int ret; | ||
104 | + uint32_t recv_len; | ||
105 | + | ||
106 | + /* Prepare test data buffer */ | ||
107 | + uint64_t data = guest_alloc(alloc, sizeof(buffer)); | ||
108 | + memwrite(data, &packet, sizeof(packet)); | ||
109 | + | ||
110 | + /* Prepare TX descriptor */ | ||
111 | + memset(&descr, 0, sizeof(descr)); | ||
112 | + descr.read.buffer_addr = cpu_to_le64(data); | ||
113 | + descr.read.cmd_type_len = cpu_to_le32(E1000_TXD_CMD_RS | | ||
114 | + E1000_TXD_CMD_EOP | | ||
115 | + E1000_TXD_DTYP_D | | ||
116 | + sizeof(buffer)); | ||
117 | + | ||
118 | + /* Put descriptor to the ring */ | ||
119 | + e1000e_tx_ring_push(d, &descr); | ||
120 | + | ||
121 | + /* Wait for TX WB interrupt */ | ||
122 | + e1000e_wait_isr(d, E1000E_TX0_MSG_ID); | ||
123 | + | ||
124 | + /* Check DD bit */ | ||
125 | + g_assert_cmphex(le32_to_cpu(descr.wb.status) & E1000_TXD_STAT_DD, ==, | ||
126 | + E1000_TXD_STAT_DD); | ||
127 | + | ||
128 | + /* Check data sent to the backend */ | ||
129 | + ret = recv(test_sockets[0], &recv_len, sizeof(recv_len), 0); | ||
130 | + g_assert_cmpint(ret, == , sizeof(recv_len)); | ||
131 | + ret = recv(test_sockets[0], buffer, sizeof(buffer), 0); | ||
132 | + g_assert_cmpint(ret, ==, sizeof(buffer)); | ||
133 | + g_assert_false(memcmp(buffer, &packet, sizeof(packet))); | ||
134 | + | ||
135 | + /* Free test data buffer */ | ||
136 | + guest_free(alloc, data); | ||
137 | +} | ||
138 | + | ||
139 | +static void igb_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc) | ||
140 | +{ | ||
141 | + union e1000_adv_rx_desc descr; | ||
142 | + | ||
143 | + struct eth_header test_iov = packet; | ||
144 | + int len = htonl(sizeof(packet)); | ||
145 | + struct iovec iov[] = { | ||
146 | + { | ||
147 | + .iov_base = &len, | ||
148 | + .iov_len = sizeof(len), | ||
149 | + },{ | ||
150 | + .iov_base = &test_iov, | ||
151 | + .iov_len = sizeof(packet), | ||
152 | + }, | ||
153 | + }; | ||
154 | + | ||
155 | + char buffer[64]; | ||
156 | + int ret; | ||
157 | + | ||
158 | + /* Send a dummy packet to device's socket*/ | ||
159 | + ret = iov_send(test_sockets[0], iov, 2, 0, sizeof(len) + sizeof(packet)); | ||
160 | + g_assert_cmpint(ret, == , sizeof(packet) + sizeof(len)); | ||
161 | + | ||
162 | + /* Prepare test data buffer */ | ||
163 | + uint64_t data = guest_alloc(alloc, sizeof(buffer)); | ||
164 | + | ||
165 | + /* Prepare RX descriptor */ | ||
166 | + memset(&descr, 0, sizeof(descr)); | ||
167 | + descr.read.pkt_addr = cpu_to_le64(data); | ||
168 | + | ||
169 | + /* Put descriptor to the ring */ | ||
170 | + e1000e_rx_ring_push(d, &descr); | ||
171 | + | ||
172 | + /* Wait for TX WB interrupt */ | ||
173 | + e1000e_wait_isr(d, E1000E_RX0_MSG_ID); | ||
174 | + | ||
175 | + /* Check DD bit */ | ||
176 | + g_assert_cmphex(le32_to_cpu(descr.wb.upper.status_error) & | ||
177 | + E1000_RXD_STAT_DD, ==, E1000_RXD_STAT_DD); | ||
178 | + | ||
179 | + /* Check data sent to the backend */ | ||
180 | + memread(data, buffer, sizeof(buffer)); | ||
181 | + g_assert_false(memcmp(buffer, &packet, sizeof(packet))); | ||
182 | + | ||
183 | + /* Free test data buffer */ | ||
184 | + guest_free(alloc, data); | ||
185 | +} | ||
186 | + | ||
187 | +static void test_e1000e_init(void *obj, void *data, QGuestAllocator * alloc) | ||
188 | +{ | ||
189 | + /* init does nothing */ | ||
190 | +} | ||
191 | + | ||
192 | +static void test_igb_tx(void *obj, void *data, QGuestAllocator * alloc) | ||
193 | +{ | ||
194 | + QE1000E_PCI *e1000e = obj; | ||
195 | + QE1000E *d = &e1000e->e1000e; | ||
196 | + QOSGraphObject *e_object = obj; | ||
197 | + QPCIDevice *dev = e_object->get_driver(e_object, "pci-device"); | ||
198 | + | ||
199 | + /* FIXME: add spapr support */ | ||
200 | + if (qpci_check_buggy_msi(dev)) { | ||
201 | + return; | ||
202 | + } | ||
203 | + | ||
204 | + igb_send_verify(d, data, alloc); | ||
205 | +} | ||
206 | + | ||
207 | +static void test_igb_rx(void *obj, void *data, QGuestAllocator * alloc) | ||
208 | +{ | ||
209 | + QE1000E_PCI *e1000e = obj; | ||
210 | + QE1000E *d = &e1000e->e1000e; | ||
211 | + QOSGraphObject *e_object = obj; | ||
212 | + QPCIDevice *dev = e_object->get_driver(e_object, "pci-device"); | ||
213 | + | ||
214 | + /* FIXME: add spapr support */ | ||
215 | + if (qpci_check_buggy_msi(dev)) { | ||
216 | + return; | ||
217 | + } | ||
218 | + | ||
219 | + igb_receive_verify(d, data, alloc); | ||
220 | +} | ||
221 | + | ||
222 | +static void test_igb_multiple_transfers(void *obj, void *data, | ||
223 | + QGuestAllocator *alloc) | ||
224 | +{ | ||
225 | + static const long iterations = 4 * 1024; | ||
226 | + long i; | ||
227 | + | ||
228 | + QE1000E_PCI *e1000e = obj; | ||
229 | + QE1000E *d = &e1000e->e1000e; | ||
230 | + QOSGraphObject *e_object = obj; | ||
231 | + QPCIDevice *dev = e_object->get_driver(e_object, "pci-device"); | ||
232 | + | ||
233 | + /* FIXME: add spapr support */ | ||
234 | + if (qpci_check_buggy_msi(dev)) { | ||
235 | + return; | ||
236 | + } | ||
237 | + | ||
238 | + for (i = 0; i < iterations; i++) { | ||
239 | + igb_send_verify(d, data, alloc); | ||
240 | + igb_receive_verify(d, data, alloc); | ||
241 | + } | ||
242 | + | ||
243 | +} | ||
244 | + | ||
245 | +static void test_igb_hotplug(void *obj, void *data, QGuestAllocator * alloc) | ||
246 | +{ | ||
247 | + QTestState *qts = global_qtest; /* TODO: get rid of global_qtest here */ | ||
248 | + QE1000E_PCI *dev = obj; | ||
249 | + | ||
250 | + if (dev->pci_dev.bus->not_hotpluggable) { | ||
251 | + g_test_skip("pci bus does not support hotplug"); | ||
252 | + return; | ||
253 | + } | ||
254 | + | ||
255 | + qtest_qmp_device_add(qts, "igb", "igb_net", "{'addr': '0x06'}"); | ||
256 | + qpci_unplug_acpi_device_test(qts, "igb_net", 0x06); | ||
257 | +} | ||
258 | + | ||
259 | +static void data_test_clear(void *sockets) | ||
260 | +{ | ||
261 | + int *test_sockets = sockets; | ||
262 | + | ||
263 | + close(test_sockets[0]); | ||
264 | + qos_invalidate_command_line(); | ||
265 | + close(test_sockets[1]); | ||
266 | + g_free(test_sockets); | ||
267 | +} | ||
268 | + | ||
269 | +static void *data_test_init(GString *cmd_line, void *arg) | ||
270 | +{ | ||
271 | + int *test_sockets = g_new(int, 2); | ||
272 | + int ret = socketpair(PF_UNIX, SOCK_STREAM, 0, test_sockets); | ||
273 | + g_assert_cmpint(ret, != , -1); | ||
274 | + | ||
275 | + g_string_append_printf(cmd_line, " -netdev socket,fd=%d,id=hs0 ", | ||
276 | + test_sockets[1]); | ||
277 | + | ||
278 | + g_test_queue_destroy(data_test_clear, test_sockets); | ||
279 | + return test_sockets; | ||
280 | +} | ||
281 | + | ||
282 | +static void register_igb_test(void) | ||
283 | +{ | ||
284 | + QOSGraphTestOptions opts = { | ||
285 | + .before = data_test_init, | ||
286 | + }; | ||
287 | + | ||
288 | + qos_add_test("init", "igb", test_e1000e_init, &opts); | ||
289 | + qos_add_test("tx", "igb", test_igb_tx, &opts); | ||
290 | + qos_add_test("rx", "igb", test_igb_rx, &opts); | ||
291 | + qos_add_test("multiple_transfers", "igb", | ||
292 | + test_igb_multiple_transfers, &opts); | ||
293 | + qos_add_test("hotplug", "igb", test_igb_hotplug, &opts); | ||
294 | +} | ||
295 | + | ||
296 | +libqos_init(register_igb_test); | ||
297 | diff --git a/tests/qtest/libqos/igb.c b/tests/qtest/libqos/igb.c | ||
298 | new file mode 100644 | ||
299 | index XXXXXXX..XXXXXXX | ||
300 | --- /dev/null | ||
301 | +++ b/tests/qtest/libqos/igb.c | ||
302 | @@ -XXX,XX +XXX,XX @@ | ||
303 | +/* | ||
304 | + * libqos driver framework | ||
305 | + * | ||
306 | + * Copyright (c) 2022-2023 Red Hat, Inc. | ||
307 | + * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com> | ||
308 | + * | ||
309 | + * This library is free software; you can redistribute it and/or | ||
310 | + * modify it under the terms of the GNU Lesser General Public | ||
311 | + * License version 2.1 as published by the Free Software Foundation. | ||
312 | + * | ||
313 | + * This library is distributed in the hope that it will be useful, | ||
314 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
315 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
316 | + * Lesser General Public License for more details. | ||
317 | + * | ||
318 | + * You should have received a copy of the GNU Lesser General Public | ||
319 | + * License along with this library; if not, see <http://www.gnu.org/licenses/> | ||
320 | + */ | ||
321 | + | ||
322 | +#include "qemu/osdep.h" | ||
323 | +#include "hw/net/igb_regs.h" | ||
324 | +#include "hw/net/mii.h" | ||
325 | +#include "hw/pci/pci_ids.h" | ||
326 | +#include "../libqtest.h" | ||
327 | +#include "pci-pc.h" | ||
328 | +#include "qemu/sockets.h" | ||
329 | +#include "qemu/iov.h" | ||
330 | +#include "qemu/module.h" | ||
331 | +#include "qemu/bitops.h" | ||
332 | +#include "libqos-malloc.h" | ||
333 | +#include "qgraph.h" | ||
334 | +#include "e1000e.h" | ||
335 | + | ||
336 | +#define IGB_IVAR_TEST_CFG \ | ||
337 | + ((E1000E_RX0_MSG_ID | E1000_IVAR_VALID) << (igb_ivar_entry_rx(0) * 8) | \ | ||
338 | + ((E1000E_TX0_MSG_ID | E1000_IVAR_VALID) << (igb_ivar_entry_tx(0) * 8))) | ||
339 | + | ||
340 | +#define E1000E_RING_LEN (0x1000) | ||
341 | + | ||
342 | +static void e1000e_foreach_callback(QPCIDevice *dev, int devfn, void *data) | ||
343 | +{ | ||
344 | + QPCIDevice *res = data; | ||
345 | + memcpy(res, dev, sizeof(QPCIDevice)); | ||
346 | + g_free(dev); | ||
347 | +} | ||
348 | + | ||
349 | +static void e1000e_pci_destructor(QOSGraphObject *obj) | ||
350 | +{ | ||
351 | + QE1000E_PCI *epci = (QE1000E_PCI *) obj; | ||
352 | + qpci_iounmap(&epci->pci_dev, epci->mac_regs); | ||
353 | + qpci_msix_disable(&epci->pci_dev); | ||
354 | +} | ||
355 | + | ||
356 | +static void igb_pci_start_hw(QOSGraphObject *obj) | ||
357 | +{ | ||
358 | + static const uint8_t address[] = E1000E_ADDRESS; | ||
359 | + QE1000E_PCI *d = (QE1000E_PCI *) obj; | ||
360 | + uint32_t val; | ||
361 | + | ||
362 | + /* Enable the device */ | ||
363 | + qpci_device_enable(&d->pci_dev); | ||
364 | + | ||
365 | + /* Reset the device */ | ||
366 | + val = e1000e_macreg_read(&d->e1000e, E1000_CTRL); | ||
367 | + e1000e_macreg_write(&d->e1000e, E1000_CTRL, val | E1000_CTRL_RST | E1000_CTRL_SLU); | ||
368 | + | ||
369 | + /* Setup link */ | ||
370 | + e1000e_macreg_write(&d->e1000e, E1000_MDIC, | ||
371 | + MII_BMCR_AUTOEN | MII_BMCR_ANRESTART | | ||
372 | + (MII_BMCR << E1000_MDIC_REG_SHIFT) | | ||
373 | + (1 << E1000_MDIC_PHY_SHIFT) | | ||
374 | + E1000_MDIC_OP_WRITE); | ||
375 | + | ||
376 | + qtest_clock_step(d->pci_dev.bus->qts, 900000000); | ||
377 | + | ||
378 | + /* Enable and configure MSI-X */ | ||
379 | + qpci_msix_enable(&d->pci_dev); | ||
380 | + e1000e_macreg_write(&d->e1000e, E1000_IVAR0, IGB_IVAR_TEST_CFG); | ||
381 | + | ||
382 | + /* Check the device link status */ | ||
383 | + val = e1000e_macreg_read(&d->e1000e, E1000_STATUS); | ||
384 | + g_assert_cmphex(val & E1000_STATUS_LU, ==, E1000_STATUS_LU); | ||
385 | + | ||
386 | + /* Initialize TX/RX logic */ | ||
387 | + e1000e_macreg_write(&d->e1000e, E1000_RCTL, 0); | ||
388 | + e1000e_macreg_write(&d->e1000e, E1000_TCTL, 0); | ||
389 | + | ||
390 | + e1000e_macreg_write(&d->e1000e, E1000_TDBAL(0), | ||
391 | + (uint32_t) d->e1000e.tx_ring); | ||
392 | + e1000e_macreg_write(&d->e1000e, E1000_TDBAH(0), | ||
393 | + (uint32_t) (d->e1000e.tx_ring >> 32)); | ||
394 | + e1000e_macreg_write(&d->e1000e, E1000_TDLEN(0), E1000E_RING_LEN); | ||
395 | + e1000e_macreg_write(&d->e1000e, E1000_TDT(0), 0); | ||
396 | + e1000e_macreg_write(&d->e1000e, E1000_TDH(0), 0); | ||
397 | + | ||
398 | + /* Enable transmit */ | ||
399 | + e1000e_macreg_write(&d->e1000e, E1000_TCTL, E1000_TCTL_EN); | ||
400 | + | ||
401 | + e1000e_macreg_write(&d->e1000e, E1000_RDBAL(0), | ||
402 | + (uint32_t)d->e1000e.rx_ring); | ||
403 | + e1000e_macreg_write(&d->e1000e, E1000_RDBAH(0), | ||
404 | + (uint32_t)(d->e1000e.rx_ring >> 32)); | ||
405 | + e1000e_macreg_write(&d->e1000e, E1000_RDLEN(0), E1000E_RING_LEN); | ||
406 | + e1000e_macreg_write(&d->e1000e, E1000_RDT(0), 0); | ||
407 | + e1000e_macreg_write(&d->e1000e, E1000_RDH(0), 0); | ||
408 | + e1000e_macreg_write(&d->e1000e, E1000_RA, | ||
409 | + le32_to_cpu(*(uint32_t *)address)); | ||
410 | + e1000e_macreg_write(&d->e1000e, E1000_RA + 4, | ||
411 | + E1000_RAH_AV | E1000_RAH_POOL_1 | | ||
412 | + le16_to_cpu(*(uint16_t *)(address + 4))); | ||
413 | + | ||
414 | + /* Enable receive */ | ||
415 | + e1000e_macreg_write(&d->e1000e, E1000_RFCTL, E1000_RFCTL_EXTEN); | ||
416 | + e1000e_macreg_write(&d->e1000e, E1000_RCTL, E1000_RCTL_EN); | ||
417 | + | ||
418 | + /* Enable all interrupts */ | ||
419 | + e1000e_macreg_write(&d->e1000e, E1000_IMS, 0xFFFFFFFF); | ||
420 | + e1000e_macreg_write(&d->e1000e, E1000_EIMS, 0xFFFFFFFF); | ||
421 | + | ||
422 | +} | ||
423 | + | ||
424 | +static void *igb_pci_get_driver(void *obj, const char *interface) | ||
425 | +{ | ||
426 | + QE1000E_PCI *epci = obj; | ||
427 | + if (!g_strcmp0(interface, "igb-if")) { | ||
428 | + return &epci->e1000e; | ||
429 | + } | ||
430 | + | ||
431 | + /* implicit contains */ | ||
432 | + if (!g_strcmp0(interface, "pci-device")) { | ||
433 | + return &epci->pci_dev; | ||
434 | + } | ||
435 | + | ||
436 | + fprintf(stderr, "%s not present in igb\n", interface); | ||
437 | + g_assert_not_reached(); | ||
438 | +} | ||
439 | + | ||
440 | +static void *igb_pci_create(void *pci_bus, QGuestAllocator *alloc, void *addr) | ||
441 | +{ | ||
442 | + QE1000E_PCI *d = g_new0(QE1000E_PCI, 1); | ||
443 | + QPCIBus *bus = pci_bus; | ||
444 | + QPCIAddress *address = addr; | ||
445 | + | ||
446 | + qpci_device_foreach(bus, address->vendor_id, address->device_id, | ||
447 | + e1000e_foreach_callback, &d->pci_dev); | ||
448 | + | ||
449 | + /* Map BAR0 (mac registers) */ | ||
450 | + d->mac_regs = qpci_iomap(&d->pci_dev, 0, NULL); | ||
451 | + | ||
452 | + /* Allocate and setup TX ring */ | ||
453 | + d->e1000e.tx_ring = guest_alloc(alloc, E1000E_RING_LEN); | ||
454 | + g_assert(d->e1000e.tx_ring != 0); | ||
455 | + | ||
456 | + /* Allocate and setup RX ring */ | ||
457 | + d->e1000e.rx_ring = guest_alloc(alloc, E1000E_RING_LEN); | ||
458 | + g_assert(d->e1000e.rx_ring != 0); | ||
459 | + | ||
460 | + d->obj.get_driver = igb_pci_get_driver; | ||
461 | + d->obj.start_hw = igb_pci_start_hw; | ||
462 | + d->obj.destructor = e1000e_pci_destructor; | ||
463 | + | ||
464 | + return &d->obj; | ||
465 | +} | ||
466 | + | ||
467 | +static void igb_register_nodes(void) | ||
468 | +{ | ||
469 | + QPCIAddress addr = { | ||
470 | + .vendor_id = PCI_VENDOR_ID_INTEL, | ||
471 | + .device_id = E1000_DEV_ID_82576, | ||
472 | + }; | ||
473 | + | ||
474 | + /* | ||
475 | + * FIXME: every test using this node needs to setup a -netdev socket,id=hs0 | ||
476 | + * otherwise QEMU is not going to start | ||
477 | + */ | ||
478 | + QOSGraphEdgeOptions opts = { | ||
479 | + .extra_device_opts = "netdev=hs0", | ||
480 | + }; | ||
481 | + add_qpci_address(&opts, &addr); | ||
482 | + | ||
483 | + qos_node_create_driver("igb", igb_pci_create); | ||
484 | + qos_node_consumes("igb", "pci-bus", &opts); | ||
485 | +} | ||
486 | + | ||
487 | +libqos_init(igb_register_nodes); | ||
488 | diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build | ||
489 | index XXXXXXX..XXXXXXX 100644 | ||
490 | --- a/tests/qtest/libqos/meson.build | ||
491 | +++ b/tests/qtest/libqos/meson.build | ||
492 | @@ -XXX,XX +XXX,XX @@ libqos_srcs = files( | ||
493 | 'i2c.c', | ||
494 | 'i2c-imx.c', | ||
495 | 'i2c-omap.c', | ||
496 | + 'igb.c', | ||
497 | 'sdhci.c', | ||
498 | 'tpci200.c', | ||
499 | 'virtio.c', | ||
500 | diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build | ||
501 | index XXXXXXX..XXXXXXX 100644 | ||
502 | --- a/tests/qtest/meson.build | ||
503 | +++ b/tests/qtest/meson.build | ||
504 | @@ -XXX,XX +XXX,XX @@ qos_test_ss.add( | ||
505 | 'virtio-scsi-test.c', | ||
506 | 'virtio-iommu-test.c', | ||
507 | 'vmxnet3-test.c', | ||
508 | + 'igb-test.c', | ||
509 | ) | ||
510 | |||
511 | if config_all_devices.has_key('CONFIG_VIRTIO_SERIAL') | ||
512 | -- | ||
513 | 2.7.4 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
3 | This automates ethtool tests for igb registers, interrupts, etc. | ||
4 | |||
5 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
6 | Reviewed-by: Cédric Le Goater <clg@redhat.com> | ||
7 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
8 | --- | ||
9 | MAINTAINERS | 1 + | ||
10 | scripts/ci/org.centos/stream/8/x86_64/test-avocado | 1 + | ||
11 | tests/avocado/igb.py | 38 ++++++++++++++++++++++ | ||
12 | 3 files changed, 40 insertions(+) | ||
13 | create mode 100644 tests/avocado/igb.py | ||
14 | |||
15 | diff --git a/MAINTAINERS b/MAINTAINERS | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/MAINTAINERS | ||
18 | +++ b/MAINTAINERS | ||
19 | @@ -XXX,XX +XXX,XX @@ igb | ||
20 | M: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
21 | S: Maintained | ||
22 | F: hw/net/igb* | ||
23 | +F: tests/avocado/igb.py | ||
24 | F: tests/qtest/igb-test.c | ||
25 | F: tests/qtest/libqos/igb.c | ||
26 | |||
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 | ||
28 | index XXXXXXX..XXXXXXX 100755 | ||
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 | + | ||
48 | +from avocado_qemu import LinuxTest | ||
49 | + | ||
50 | +class IGB(LinuxTest): | ||
51 | + """ | ||
52 | + :avocado: tags=accel:kvm | ||
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 | -- | ||
84 | 2.7.4 | ||
85 | |||
86 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
1 | 2 | ||
3 | Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
4 | Reviewed-by: Cédric Le Goater <clg@redhat.com> | ||
5 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
6 | --- | ||
7 | MAINTAINERS | 1 + | ||
8 | docs/system/device-emulation.rst | 1 + | ||
9 | docs/system/devices/igb.rst | 71 ++++++++++++++++++++++++++++++++++++++++ | ||
10 | 3 files changed, 73 insertions(+) | ||
11 | create mode 100644 docs/system/devices/igb.rst | ||
12 | |||
13 | diff --git a/MAINTAINERS b/MAINTAINERS | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/MAINTAINERS | ||
16 | +++ b/MAINTAINERS | ||
17 | @@ -XXX,XX +XXX,XX @@ F: tests/qtest/libqos/e1000e.* | ||
18 | igb | ||
19 | M: Akihiko Odaki <akihiko.odaki@daynix.com> | ||
20 | S: Maintained | ||
21 | +F: docs/system/devices/igb.rst | ||
22 | F: hw/net/igb* | ||
23 | F: tests/avocado/igb.py | ||
24 | F: tests/qtest/igb-test.c | ||
25 | diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulation.rst | ||
26 | index XXXXXXX..XXXXXXX 100644 | ||
27 | --- a/docs/system/device-emulation.rst | ||
28 | +++ b/docs/system/device-emulation.rst | ||
29 | @@ -XXX,XX +XXX,XX @@ Emulated Devices | ||
30 | devices/virtio-pmem.rst | ||
31 | devices/vhost-user-rng.rst | ||
32 | devices/canokey.rst | ||
33 | + devices/igb.rst | ||
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 | + | ||
43 | +igb | ||
44 | +--- | ||
45 | + | ||
46 | +igb is a family of Intel's gigabit ethernet controllers. In QEMU, 82576 | ||
47 | +emulation is implemented in particular. Its datasheet is available at [1]_. | ||
48 | + | ||
49 | +This implementation is expected to be useful to test SR-IOV networking without | ||
50 | +requiring physical hardware. | ||
51 | + | ||
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 | -- | ||
112 | 2.7.4 | ||
113 | |||
114 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Shreesh Adiga <16567adigashreesh@gmail.com> | ||
1 | 2 | ||
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 |
New patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
1 | 2 | ||
3 | If pci_add_capability() ever fail, the EEPRO100 device is broken, | ||
4 | which is a bug. No need to report that to the user, abort instead. | ||
5 | |||
6 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
7 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
8 | --- | ||
9 | hw/net/eepro100.c | 9 ++------- | ||
10 | 1 file changed, 2 insertions(+), 7 deletions(-) | ||
11 | |||
12 | diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/hw/net/eepro100.c | ||
15 | +++ b/hw/net/eepro100.c | ||
16 | @@ -XXX,XX +XXX,XX @@ static void e100_pci_reset(EEPRO100State *s, Error **errp) | ||
17 | if (info->power_management) { | ||
18 | /* Power Management Capabilities */ | ||
19 | int cfg_offset = 0xdc; | ||
20 | - int r = pci_add_capability(&s->dev, PCI_CAP_ID_PM, | ||
21 | - cfg_offset, PCI_PM_SIZEOF, | ||
22 | - errp); | ||
23 | - if (r < 0) { | ||
24 | - return; | ||
25 | - } | ||
26 | - | ||
27 | + pci_add_capability(&s->dev, PCI_CAP_ID_PM, cfg_offset, PCI_PM_SIZEOF, | ||
28 | + &error_abort); | ||
29 | pci_set_word(pci_conf + cfg_offset + PCI_PM_PMC, 0x7e21); | ||
30 | #if 0 /* TODO: replace dummy code for power management emulation. */ | ||
31 | /* TODO: Power Management Control / Status. */ | ||
32 | -- | ||
33 | 2.7.4 | ||
34 | |||
35 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
1 | 2 | ||
3 | Have all the EEPRO100-based devices share a common (abstract) | ||
4 | QOM parent. | ||
5 | |||
6 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
7 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
8 | --- | ||
9 | hw/net/eepro100.c | 60 ++++++++++++++++++++++++++++++++++++++----------------- | ||
10 | 1 file changed, 42 insertions(+), 18 deletions(-) | ||
11 | |||
12 | diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/hw/net/eepro100.c | ||
15 | +++ b/hw/net/eepro100.c | ||
16 | @@ -XXX,XX +XXX,XX @@ typedef enum { | ||
17 | ru_ready = 4 | ||
18 | } ru_state_t; | ||
19 | |||
20 | -typedef struct { | ||
21 | +#define TYPE_EEPRO100 "eepro100" | ||
22 | +OBJECT_DECLARE_TYPE(EEPRO100State, EEPRO100Class, EEPRO100) | ||
23 | + | ||
24 | +struct EEPRO100Class { | ||
25 | + /*< private >*/ | ||
26 | + PCIDeviceClass parent_class; | ||
27 | + /*< public >*/ | ||
28 | +}; | ||
29 | + | ||
30 | +struct EEPRO100State { | ||
31 | + /*< private >*/ | ||
32 | PCIDevice dev; | ||
33 | + /*< public >*/ | ||
34 | + | ||
35 | /* Hash register (multicast mask array, multiple individual addresses). */ | ||
36 | uint8_t mult[8]; | ||
37 | MemoryRegion mmio_bar; | ||
38 | @@ -XXX,XX +XXX,XX @@ typedef struct { | ||
39 | /* Quasi static device properties (no need to save them). */ | ||
40 | uint16_t stats_size; | ||
41 | bool has_extended_tcb_support; | ||
42 | -} EEPRO100State; | ||
43 | +}; | ||
44 | |||
45 | /* Word indices in EEPROM. */ | ||
46 | typedef enum { | ||
47 | @@ -XXX,XX +XXX,XX @@ static Property e100_properties[] = { | ||
48 | DEFINE_PROP_END_OF_LIST(), | ||
49 | }; | ||
50 | |||
51 | -static void eepro100_class_init(ObjectClass *klass, void *data) | ||
52 | +static void eepro100_base_class_init(ObjectClass *klass, void *data) | ||
53 | { | ||
54 | DeviceClass *dc = DEVICE_CLASS(klass); | ||
55 | PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); | ||
56 | E100PCIDeviceInfo *info; | ||
57 | |||
58 | - info = eepro100_get_class_by_name(object_class_get_name(klass)); | ||
59 | |||
60 | set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); | ||
61 | device_class_set_props(dc, e100_properties); | ||
62 | - dc->desc = info->desc; | ||
63 | k->vendor_id = PCI_VENDOR_ID_INTEL; | ||
64 | k->class_id = PCI_CLASS_NETWORK_ETHERNET; | ||
65 | k->romfile = "pxe-eepro100.rom"; | ||
66 | k->realize = e100_nic_realize; | ||
67 | k->exit = pci_nic_uninit; | ||
68 | + | ||
69 | + info = eepro100_get_class_by_name(object_class_get_name(klass)); | ||
70 | + if (!info) { | ||
71 | + /* base class */ | ||
72 | + return; | ||
73 | + } | ||
74 | + dc->desc = info->desc; | ||
75 | k->device_id = info->device_id; | ||
76 | k->revision = info->revision; | ||
77 | k->subsystem_vendor_id = info->subsystem_vendor_id; | ||
78 | k->subsystem_id = info->subsystem_id; | ||
79 | } | ||
80 | |||
81 | +static const TypeInfo eepro100_base_info = { | ||
82 | + .name = TYPE_EEPRO100, | ||
83 | + .parent = TYPE_PCI_DEVICE, | ||
84 | + .abstract = true, | ||
85 | + .class_init = eepro100_base_class_init, | ||
86 | + .class_size = sizeof(EEPRO100Class), | ||
87 | + .instance_size = sizeof(EEPRO100State), | ||
88 | + .instance_init = eepro100_instance_init, | ||
89 | + .interfaces = (InterfaceInfo[]) { | ||
90 | + { INTERFACE_CONVENTIONAL_PCI_DEVICE }, | ||
91 | + { }, | ||
92 | + }, | ||
93 | +}; | ||
94 | + | ||
95 | static void eepro100_register_types(void) | ||
96 | { | ||
97 | - size_t i; | ||
98 | - for (i = 0; i < ARRAY_SIZE(e100_devices); i++) { | ||
99 | - TypeInfo type_info = {}; | ||
100 | - E100PCIDeviceInfo *info = &e100_devices[i]; | ||
101 | - | ||
102 | - type_info.name = info->name; | ||
103 | - type_info.parent = TYPE_PCI_DEVICE; | ||
104 | - type_info.class_init = eepro100_class_init; | ||
105 | - type_info.instance_size = sizeof(EEPRO100State); | ||
106 | - type_info.instance_init = eepro100_instance_init; | ||
107 | - type_info.interfaces = (InterfaceInfo[]) { | ||
108 | - { INTERFACE_CONVENTIONAL_PCI_DEVICE }, | ||
109 | - { }, | ||
110 | + type_register_static(&eepro100_base_info); | ||
111 | + | ||
112 | + for (size_t i = 0; i < ARRAY_SIZE(e100_devices); i++) { | ||
113 | + TypeInfo type_info = { | ||
114 | + .name = e100_devices[i].name, | ||
115 | + .parent = TYPE_EEPRO100, | ||
116 | }; | ||
117 | |||
118 | type_register(&type_info); | ||
119 | -- | ||
120 | 2.7.4 | ||
121 | |||
122 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
1 | 2 | ||
3 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
4 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
5 | --- | ||
6 | hw/net/eepro100.c | 11 +++-------- | ||
7 | 1 file changed, 3 insertions(+), 8 deletions(-) | ||
8 | |||
9 | diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c | ||
10 | index XXXXXXX..XXXXXXX 100644 | ||
11 | --- a/hw/net/eepro100.c | ||
12 | +++ b/hw/net/eepro100.c | ||
13 | @@ -XXX,XX +XXX,XX @@ static void eepro100_fcp_interrupt(EEPRO100State * s) | ||
14 | } | ||
15 | #endif | ||
16 | |||
17 | -static void e100_pci_reset(EEPRO100State *s, Error **errp) | ||
18 | +static void e100_pci_reset(DeviceState *dev) | ||
19 | { | ||
20 | + EEPRO100State *s = EEPRO100(dev); | ||
21 | E100PCIDeviceInfo *info = eepro100_get_class(s); | ||
22 | uint32_t device = s->device; | ||
23 | uint8_t *pci_conf = s->dev.config; | ||
24 | @@ -XXX,XX +XXX,XX @@ static void e100_nic_realize(PCIDevice *pci_dev, Error **errp) | ||
25 | { | ||
26 | EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); | ||
27 | E100PCIDeviceInfo *info = eepro100_get_class(s); | ||
28 | - Error *local_err = NULL; | ||
29 | |||
30 | TRACE(OTHER, logout("\n")); | ||
31 | |||
32 | s->device = info->device; | ||
33 | |||
34 | - e100_pci_reset(s, &local_err); | ||
35 | - if (local_err) { | ||
36 | - error_propagate(errp, local_err); | ||
37 | - return; | ||
38 | - } | ||
39 | - | ||
40 | /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM, | ||
41 | * i82559 and later support 64 or 256 word EEPROM. */ | ||
42 | s->eeprom = eeprom93xx_new(&pci_dev->qdev, EEPROM_SIZE); | ||
43 | @@ -XXX,XX +XXX,XX @@ static void eepro100_base_class_init(ObjectClass *klass, void *data) | ||
44 | |||
45 | set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); | ||
46 | device_class_set_props(dc, e100_properties); | ||
47 | + dc->reset = e100_pci_reset; | ||
48 | k->vendor_id = PCI_VENDOR_ID_INTEL; | ||
49 | k->class_id = PCI_CLASS_NETWORK_ETHERNET; | ||
50 | k->romfile = "pxe-eepro100.rom"; | ||
51 | -- | ||
52 | 2.7.4 | ||
53 | |||
54 | diff view generated by jsdifflib |
1 | From: Prasad J Pandit <pjp@fedoraproject.org> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | Move repeating error handling sequence in parse_acl_file routine | 3 | QOM already provides the TypeInfo::class_data to set |
4 | to an 'err' label. | 4 | class-specific data. Use it instead of reinventing the |
5 | wheel with eepro100_get_class_by_name(). This finishes | ||
6 | the QDev conversion started 12 years ago in commit | ||
7 | 40021f0888 ("pci: convert to QEMU Object Model"). | ||
5 | 8 | ||
6 | Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> | 9 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
7 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
8 | Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> | ||
9 | Reviewed-by: Li Qiang <liq3ea@gmail.com> | ||
10 | Signed-off-by: Jason Wang <jasowang@redhat.com> | 10 | Signed-off-by: Jason Wang <jasowang@redhat.com> |
11 | --- | 11 | --- |
12 | qemu-bridge-helper.c | 19 +++++++++---------- | 12 | hw/net/eepro100.c | 63 ++++++++++++++++++------------------------------------- |
13 | 1 file changed, 9 insertions(+), 10 deletions(-) | 13 | 1 file changed, 20 insertions(+), 43 deletions(-) |
14 | 14 | ||
15 | diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c | 15 | diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c |
16 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/qemu-bridge-helper.c | 17 | --- a/hw/net/eepro100.c |
18 | +++ b/qemu-bridge-helper.c | 18 | +++ b/hw/net/eepro100.c |
19 | @@ -XXX,XX +XXX,XX @@ static int parse_acl_file(const char *filename, ACLList *acl_list) | 19 | @@ -XXX,XX +XXX,XX @@ struct EEPRO100Class { |
20 | 20 | /*< private >*/ | |
21 | if (arg == NULL) { | 21 | PCIDeviceClass parent_class; |
22 | fprintf(stderr, "Invalid config line:\n %s\n", line); | 22 | /*< public >*/ |
23 | - fclose(f); | 23 | + |
24 | - errno = EINVAL; | 24 | + const E100PCIDeviceInfo *info; |
25 | - return -1; | 25 | }; |
26 | + goto err; | 26 | |
27 | } | 27 | struct EEPRO100State { |
28 | 28 | @@ -XXX,XX +XXX,XX @@ static const uint16_t eepro100_mdi_mask[] = { | |
29 | *arg = 0; | 29 | 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
30 | @@ -XXX,XX +XXX,XX @@ static int parse_acl_file(const char *filename, ACLList *acl_list) | 30 | }; |
31 | 31 | ||
32 | if (!g_str_equal(cmd, "include") && strlen(arg) >= IFNAMSIZ) { | 32 | -static E100PCIDeviceInfo *eepro100_get_class(EEPRO100State *s); |
33 | fprintf(stderr, "name `%s' too long: %zu\n", arg, strlen(arg)); | 33 | - |
34 | - fclose(f); | 34 | /* Read a 16 bit control/status (CSR) register. */ |
35 | - errno = EINVAL; | 35 | static uint16_t e100_read_reg2(EEPRO100State *s, E100RegisterOffset addr) |
36 | - return -1; | 36 | { |
37 | + goto err; | 37 | @@ -XXX,XX +XXX,XX @@ static void eepro100_fcp_interrupt(EEPRO100State * s) |
38 | } | 38 | static void e100_pci_reset(DeviceState *dev) |
39 | 39 | { | |
40 | if (strcmp(cmd, "deny") == 0) { | 40 | EEPRO100State *s = EEPRO100(dev); |
41 | @@ -XXX,XX +XXX,XX @@ static int parse_acl_file(const char *filename, ACLList *acl_list) | 41 | - E100PCIDeviceInfo *info = eepro100_get_class(s); |
42 | parse_acl_file(arg, acl_list); | 42 | - uint32_t device = s->device; |
43 | } else { | 43 | + EEPRO100Class *ek = EEPRO100_GET_CLASS(s); |
44 | fprintf(stderr, "Unknown command `%s'\n", cmd); | 44 | + const E100PCIDeviceInfo *info = ek->info; |
45 | - fclose(f); | 45 | + uint32_t device = info->device; |
46 | - errno = EINVAL; | 46 | uint8_t *pci_conf = s->dev.config; |
47 | - return -1; | 47 | |
48 | + goto err; | 48 | TRACE(OTHER, logout("%p\n", s)); |
49 | } | 49 | @@ -XXX,XX +XXX,XX @@ static NetClientInfo net_eepro100_info = { |
50 | static void e100_nic_realize(PCIDevice *pci_dev, Error **errp) | ||
51 | { | ||
52 | EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); | ||
53 | - E100PCIDeviceInfo *info = eepro100_get_class(s); | ||
54 | + EEPRO100Class *ek = EEPRO100_GET_CLASS(s); | ||
55 | |||
56 | TRACE(OTHER, logout("\n")); | ||
57 | |||
58 | - s->device = info->device; | ||
59 | + s->device = ek->info->device; | ||
60 | |||
61 | /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM, | ||
62 | * i82559 and later support 64 or 256 word EEPROM. */ | ||
63 | @@ -XXX,XX +XXX,XX @@ static E100PCIDeviceInfo e100_devices[] = { | ||
50 | } | 64 | } |
51 | 65 | }; | |
52 | fclose(f); | 66 | |
67 | -static E100PCIDeviceInfo *eepro100_get_class_by_name(const char *typename) | ||
68 | +static void eepro100_class_init(ObjectClass *klass, void *data) | ||
69 | { | ||
70 | - E100PCIDeviceInfo *info = NULL; | ||
71 | - int i; | ||
53 | - | 72 | - |
54 | return 0; | 73 | - /* This is admittedly awkward but also temporary. QOM allows for |
55 | + | 74 | - * parameterized typing and for subclassing both of which would suitable |
56 | +err: | 75 | - * handle what's going on here. But class_data is already being used as |
57 | + fclose(f); | 76 | - * a stop-gap hack to allow incremental qdev conversion so we cannot use it |
58 | + errno = EINVAL; | 77 | - * right now. Once we merge the final QOM series, we can come back here and |
59 | + return -1; | 78 | - * do this in a much more elegant fashion. |
60 | + | 79 | - */ |
80 | - for (i = 0; i < ARRAY_SIZE(e100_devices); i++) { | ||
81 | - if (strcmp(e100_devices[i].name, typename) == 0) { | ||
82 | - info = &e100_devices[i]; | ||
83 | - break; | ||
84 | - } | ||
85 | - } | ||
86 | - assert(info != NULL); | ||
87 | - | ||
88 | - return info; | ||
89 | -} | ||
90 | + DeviceClass *dc = DEVICE_CLASS(klass); | ||
91 | + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); | ||
92 | + EEPRO100Class *ek = EEPRO100_CLASS(klass); | ||
93 | + const E100PCIDeviceInfo *info = data; | ||
94 | |||
95 | -static E100PCIDeviceInfo *eepro100_get_class(EEPRO100State *s) | ||
96 | -{ | ||
97 | - return eepro100_get_class_by_name(object_get_typename(OBJECT(s))); | ||
98 | + dc->desc = info->desc; | ||
99 | + k->device_id = info->device_id; | ||
100 | + k->revision = info->revision; | ||
101 | + k->subsystem_vendor_id = info->subsystem_vendor_id; | ||
102 | + k->subsystem_id = info->subsystem_id; | ||
103 | + ek->info = info; | ||
61 | } | 104 | } |
62 | 105 | ||
63 | static bool has_vnet_hdr(int fd) | 106 | static Property e100_properties[] = { |
107 | @@ -XXX,XX +XXX,XX @@ static void eepro100_base_class_init(ObjectClass *klass, void *data) | ||
108 | { | ||
109 | DeviceClass *dc = DEVICE_CLASS(klass); | ||
110 | PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); | ||
111 | - E100PCIDeviceInfo *info; | ||
112 | - | ||
113 | |||
114 | set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); | ||
115 | device_class_set_props(dc, e100_properties); | ||
116 | @@ -XXX,XX +XXX,XX @@ static void eepro100_base_class_init(ObjectClass *klass, void *data) | ||
117 | k->romfile = "pxe-eepro100.rom"; | ||
118 | k->realize = e100_nic_realize; | ||
119 | k->exit = pci_nic_uninit; | ||
120 | - | ||
121 | - info = eepro100_get_class_by_name(object_class_get_name(klass)); | ||
122 | - if (!info) { | ||
123 | - /* base class */ | ||
124 | - return; | ||
125 | - } | ||
126 | - dc->desc = info->desc; | ||
127 | - k->device_id = info->device_id; | ||
128 | - k->revision = info->revision; | ||
129 | - k->subsystem_vendor_id = info->subsystem_vendor_id; | ||
130 | - k->subsystem_id = info->subsystem_id; | ||
131 | } | ||
132 | |||
133 | static const TypeInfo eepro100_base_info = { | ||
134 | @@ -XXX,XX +XXX,XX @@ static void eepro100_register_types(void) | ||
135 | TypeInfo type_info = { | ||
136 | .name = e100_devices[i].name, | ||
137 | .parent = TYPE_EEPRO100, | ||
138 | + .class_init = eepro100_class_init, | ||
139 | + .class_data = (void *)&e100_devices[i], | ||
140 | }; | ||
141 | |||
142 | type_register(&type_info); | ||
64 | -- | 143 | -- |
65 | 2.5.0 | 144 | 2.7.4 |
66 | 145 | ||
67 | 146 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
1 | 2 | ||
3 | 'has_extended_tcb_support' is accessed read-only and is present | ||
4 | in the class definition. No need to duplicate it in the instance | ||
5 | state. Directly access the class field. | ||
6 | |||
7 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
8 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
9 | --- | ||
10 | hw/net/eepro100.c | 6 +++--- | ||
11 | 1 file changed, 3 insertions(+), 3 deletions(-) | ||
12 | |||
13 | diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/hw/net/eepro100.c | ||
16 | +++ b/hw/net/eepro100.c | ||
17 | @@ -XXX,XX +XXX,XX @@ struct EEPRO100State { | ||
18 | |||
19 | /* Quasi static device properties (no need to save them). */ | ||
20 | uint16_t stats_size; | ||
21 | - bool has_extended_tcb_support; | ||
22 | }; | ||
23 | |||
24 | /* Word indices in EEPROM. */ | ||
25 | @@ -XXX,XX +XXX,XX @@ static void e100_pci_reset(DeviceState *dev) | ||
26 | pci_set_byte(pci_conf + PCI_MAX_LAT, 0x18); | ||
27 | |||
28 | s->stats_size = info->stats_size; | ||
29 | - s->has_extended_tcb_support = info->has_extended_tcb_support; | ||
30 | |||
31 | switch (device) { | ||
32 | case i82550: | ||
33 | @@ -XXX,XX +XXX,XX @@ static void read_cb(EEPRO100State *s) | ||
34 | |||
35 | static void tx_command(EEPRO100State *s) | ||
36 | { | ||
37 | + EEPRO100Class *ek = EEPRO100_GET_CLASS(s); | ||
38 | + const E100PCIDeviceInfo *info = ek->info; | ||
39 | const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; | ||
40 | uint32_t tbd_array = s->tx.tbd_array_addr; | ||
41 | uint16_t tcb_bytes = s->tx.tcb_bytes & 0x3fff; | ||
42 | @@ -XXX,XX +XXX,XX @@ static void tx_command(EEPRO100State *s) | ||
43 | uint16_t tx_buffer_size; | ||
44 | uint16_t tx_buffer_el; | ||
45 | |||
46 | - if (s->has_extended_tcb_support && !(s->configuration[6] & BIT(4))) { | ||
47 | + if (info->has_extended_tcb_support && !(s->configuration[6] & BIT(4))) { | ||
48 | /* Extended Flexible TCB. */ | ||
49 | for (; tbd_count < 2; tbd_count++) { | ||
50 | ldl_le_pci_dma(&s->dev, tbd_address, &tx_buffer_address, attrs); | ||
51 | -- | ||
52 | 2.7.4 | ||
53 | |||
54 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
1 | 2 | ||
3 | 'device' is accessed read-only and is present in the class | ||
4 | definition. No need to duplicate it in the instance state. | ||
5 | Directly access the class field. | ||
6 | |||
7 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
8 | Signed-off-by: Jason Wang <jasowang@redhat.com> | ||
9 | --- | ||
10 | hw/net/eepro100.c | 12 ++++++------ | ||
11 | 1 file changed, 6 insertions(+), 6 deletions(-) | ||
12 | |||
13 | diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/hw/net/eepro100.c | ||
16 | +++ b/hw/net/eepro100.c | ||
17 | @@ -XXX,XX +XXX,XX @@ struct EEPRO100State { | ||
18 | /* region must not be saved by nic_save. */ | ||
19 | uint16_t mdimem[32]; | ||
20 | eeprom_t *eeprom; | ||
21 | - uint32_t device; /* device variant */ | ||
22 | /* (cu_base + cu_offset) address the next command block in the command block list. */ | ||
23 | uint32_t cu_base; /* CU base address */ | ||
24 | uint32_t cu_offset; /* CU address offset */ | ||
25 | @@ -XXX,XX +XXX,XX @@ static void e100_pci_reset(DeviceState *dev) | ||
26 | |||
27 | static void nic_selective_reset(EEPRO100State * s) | ||
28 | { | ||
29 | + EEPRO100Class *ek = EEPRO100_GET_CLASS(s); | ||
30 | + const E100PCIDeviceInfo *info = ek->info; | ||
31 | + | ||
32 | size_t i; | ||
33 | uint16_t *eeprom_contents = eeprom93xx_data(s->eeprom); | ||
34 | #if 0 | ||
35 | @@ -XXX,XX +XXX,XX @@ static void nic_selective_reset(EEPRO100State * s) | ||
36 | #endif | ||
37 | memcpy(eeprom_contents, s->conf.macaddr.a, 6); | ||
38 | eeprom_contents[EEPROM_ID] = EEPROM_ID_VALID; | ||
39 | - if (s->device == i82557B || s->device == i82557C) | ||
40 | + if (info->device == i82557B || info->device == i82557C) { | ||
41 | eeprom_contents[5] = 0x0100; | ||
42 | + } | ||
43 | eeprom_contents[EEPROM_PHY_ID] = 1; | ||
44 | uint16_t sum = 0; | ||
45 | for (i = 0; i < EEPROM_SIZE - 1; i++) { | ||
46 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_eepro100 = { | ||
47 | VMSTATE_UNUSED(19*4), | ||
48 | VMSTATE_UINT16_ARRAY(mdimem, EEPRO100State, 32), | ||
49 | /* The eeprom should be saved and restored by its own routines. */ | ||
50 | - VMSTATE_UINT32(device, EEPRO100State), | ||
51 | + VMSTATE_UNUSED(sizeof(uint32_t)), /* was device variant */ | ||
52 | /* TODO check device. */ | ||
53 | VMSTATE_UINT32(cu_base, EEPRO100State), | ||
54 | VMSTATE_UINT32(cu_offset, EEPRO100State), | ||
55 | @@ -XXX,XX +XXX,XX @@ static NetClientInfo net_eepro100_info = { | ||
56 | static void e100_nic_realize(PCIDevice *pci_dev, Error **errp) | ||
57 | { | ||
58 | EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); | ||
59 | - EEPRO100Class *ek = EEPRO100_GET_CLASS(s); | ||
60 | |||
61 | TRACE(OTHER, logout("\n")); | ||
62 | |||
63 | - s->device = ek->info->device; | ||
64 | - | ||
65 | /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM, | ||
66 | * i82559 and later support 64 or 256 word EEPROM. */ | ||
67 | s->eeprom = eeprom93xx_new(&pci_dev->qdev, EEPROM_SIZE); | ||
68 | -- | ||
69 | 2.7.4 | ||
70 | |||
71 | diff view generated by jsdifflib |
1 | From: Prasad J Pandit <pjp@fedoraproject.org> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | The network interface name in Linux is defined to be of size | 3 | Use the EEPRO100() QOM type-checking macro to avoid DO_UPCAST(). |
4 | IFNAMSIZ(=16), including the terminating null('\0') byte. | ||
5 | The same is applied to interface names read from 'bridge.conf' | ||
6 | file to form ACL rules. If user supplied '--br=bridge' name | ||
7 | is not restricted to the same length, it could lead to ACL bypass | ||
8 | issue. Restrict interface name to IFNAMSIZ, including null byte. | ||
9 | 4 | ||
10 | Reported-by: Riccardo Schirone <rschiron@redhat.com> | 5 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
11 | Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> | ||
12 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | ||
13 | Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> | ||
14 | Reviewed-by: Li Qiang <liq3ea@gmail.com> | ||
15 | Signed-off-by: Jason Wang <jasowang@redhat.com> | 6 | Signed-off-by: Jason Wang <jasowang@redhat.com> |
16 | --- | 7 | --- |
17 | qemu-bridge-helper.c | 11 +++++++++++ | 8 | hw/net/eepro100.c | 6 +++--- |
18 | 1 file changed, 11 insertions(+) | 9 | 1 file changed, 3 insertions(+), 3 deletions(-) |
19 | 10 | ||
20 | diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c | 11 | diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c |
21 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
22 | --- a/qemu-bridge-helper.c | 13 | --- a/hw/net/eepro100.c |
23 | +++ b/qemu-bridge-helper.c | 14 | +++ b/hw/net/eepro100.c |
24 | @@ -XXX,XX +XXX,XX @@ static int parse_acl_file(const char *filename, ACLList *acl_list) | 15 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_eepro100 = { |
25 | } | 16 | |
26 | *argend = 0; | 17 | static void pci_nic_uninit(PCIDevice *pci_dev) |
27 | 18 | { | |
28 | + if (!g_str_equal(cmd, "include") && strlen(arg) >= IFNAMSIZ) { | 19 | - EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); |
29 | + fprintf(stderr, "name `%s' too long: %zu\n", arg, strlen(arg)); | 20 | + EEPRO100State *s = EEPRO100(pci_dev); |
30 | + fclose(f); | 21 | |
31 | + errno = EINVAL; | 22 | vmstate_unregister(VMSTATE_IF(&pci_dev->qdev), s->vmstate, s); |
32 | + return -1; | 23 | g_free(s->vmstate); |
33 | + } | 24 | @@ -XXX,XX +XXX,XX @@ static NetClientInfo net_eepro100_info = { |
34 | + | 25 | |
35 | if (strcmp(cmd, "deny") == 0) { | 26 | static void e100_nic_realize(PCIDevice *pci_dev, Error **errp) |
36 | acl_rule = g_malloc(sizeof(*acl_rule)); | 27 | { |
37 | if (strcmp(arg, "all") == 0) { | 28 | - EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev); |
38 | @@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv) | 29 | + EEPRO100State *s = EEPRO100(pci_dev); |
39 | usage(); | 30 | |
40 | return EXIT_FAILURE; | 31 | TRACE(OTHER, logout("\n")); |
41 | } | 32 | |
42 | + if (strlen(bridge) >= IFNAMSIZ) { | 33 | @@ -XXX,XX +XXX,XX @@ static void e100_nic_realize(PCIDevice *pci_dev, Error **errp) |
43 | + fprintf(stderr, "name `%s' too long: %zu\n", bridge, strlen(bridge)); | 34 | |
44 | + return EXIT_FAILURE; | 35 | static void eepro100_instance_init(Object *obj) |
45 | + } | 36 | { |
46 | 37 | - EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, PCI_DEVICE(obj)); | |
47 | /* parse default acl file */ | 38 | + EEPRO100State *s = EEPRO100(obj); |
48 | QSIMPLEQ_INIT(&acl_list); | 39 | device_add_bootindex_property(obj, &s->conf.bootindex, |
40 | "bootindex", "/ethernet-phy@0", | ||
41 | DEVICE(s)); | ||
49 | -- | 42 | -- |
50 | 2.5.0 | 43 | 2.7.4 |
51 | 44 | ||
52 | 45 | diff view generated by jsdifflib |