hw: Remove Marvell 88W8618 devices
The mv88w8618 ethernet and audio devices were used only by the now-removed musicpal machine, so can also be deleted. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Acked-by: Jan Kiszka <jan.kiszka@web.de> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Message-id: 20260819185430.3467629-5-peter.maydell@linaro.org
Peter Maydell committed
Aug 19, 2026 at 19:54 UTC
7d31d00b84ee38d17ffc5c7ce10b899789985e25
6 files changed
-736
hw/arm/Kconfig
-3
@@ -100,9 +100,6 @@ config MUSCA
100
select SPLIT_IRQ
101
select UNIMP
102
103
-config MARVELL_88W8618
104
- bool
105
-
103
config NETDUINO2
104
bool
105
default y
hw/audio/marvell_88w8618.c
deleted
-315
@@ -1,315 +0,0 @@
1
-/*
2
- * Marvell 88w8618 audio emulation extracted from
3
- * Marvell MV88w8618 / Freecom MusicPal emulation.
4
- *
5
- * Copyright (c) 2008 Jan Kiszka
6
- *
7
- * This code is licensed under the GNU GPL v2.
8
- *
9
- * Contributions after 2012-01-13 are licensed under the terms of the
10
- * GNU GPL, version 2 or (at your option) any later version.
11
- */
12
-
13
-#include "qemu/osdep.h"
14
-#include "hw/core/sysbus.h"
15
-#include "exec/cpu-common.h"
16
-#include "migration/vmstate.h"
17
-#include "hw/core/irq.h"
18
-#include "hw/core/qdev-properties.h"
19
-#include "hw/audio/wm8750.h"
20
-#include "qemu/audio.h"
21
-#include "qapi/error.h"
22
-#include "qemu/module.h"
23
-#include "qom/object.h"
24
-#include "system/physmem.h"
25
-
26
-#define MP_AUDIO_SIZE 0x00001000
27
-
28
-/* Audio register offsets */
29
-#define MP_AUDIO_PLAYBACK_MODE 0x00
30
-#define MP_AUDIO_CLOCK_DIV 0x18
31
-#define MP_AUDIO_IRQ_STATUS 0x20
32
-#define MP_AUDIO_IRQ_ENABLE 0x24
33
-#define MP_AUDIO_TX_START_LO 0x28
34
-#define MP_AUDIO_TX_THRESHOLD 0x2C
35
-#define MP_AUDIO_TX_STATUS 0x38
36
-#define MP_AUDIO_TX_START_HI 0x40
37
-
38
-/* Status register and IRQ enable bits */
39
-#define MP_AUDIO_TX_HALF (1 << 6)
40
-#define MP_AUDIO_TX_FULL (1 << 7)
41
-
42
-/* Playback mode bits */
43
-#define MP_AUDIO_16BIT_SAMPLE (1 << 0)
44
-#define MP_AUDIO_PLAYBACK_EN (1 << 7)
45
-#define MP_AUDIO_CLOCK_24MHZ (1 << 9)
46
-#define MP_AUDIO_MONO (1 << 14)
47
-
48
-OBJECT_DECLARE_SIMPLE_TYPE(mv88w8618_audio_state, MV88W8618_AUDIO)
49
-
50
-struct mv88w8618_audio_state {
51
- SysBusDevice parent_obj;
52
-
53
- MemoryRegion iomem;
54
- qemu_irq irq;
55
- uint32_t playback_mode;
56
- uint32_t status;
57
- uint32_t irq_enable;
58
- uint32_t phys_buf;
59
- uint32_t target_buffer;
60
- uint32_t threshold;
61
- uint32_t play_pos;
62
- uint32_t last_free;
63
- uint32_t clock_div;
64
- void *wm;
65
-};
66
-
67
-static void mv88w8618_audio_callback(void *opaque, int free_out, int free_in)
68
-{
69
- mv88w8618_audio_state *s = opaque;
70
- int16_t *codec_buffer;
71
- QEMU_UNINITIALIZED int8_t buf[4096];
72
- int8_t *mem_buffer;
73
- int pos, block_size;
74
-
75
- if (!(s->playback_mode & MP_AUDIO_PLAYBACK_EN)) {
76
- return;
77
- }
78
- if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) {
79
- free_out <<= 1;
80
- }
81
- if (!(s->playback_mode & MP_AUDIO_MONO)) {
82
- free_out <<= 1;
83
- }
84
- block_size = s->threshold / 2;
85
- if (free_out - s->last_free < block_size) {
86
- return;
87
- }
88
- if (block_size > 4096) {
89
- return;
90
- }
91
- physical_memory_read(s->target_buffer + s->play_pos, buf, block_size);
92
- mem_buffer = buf;
93
- if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) {
94
- if (s->playback_mode & MP_AUDIO_MONO) {
95
- codec_buffer = wm8750_dac_buffer(s->wm, block_size >> 1);
96
- for (pos = 0; pos < block_size; pos += 2) {
97
- *codec_buffer++ = *(int16_t *)mem_buffer;
98
- *codec_buffer++ = *(int16_t *)mem_buffer;
99
- mem_buffer += 2;
100
- }
101
- } else {
102
- memcpy(wm8750_dac_buffer(s->wm, block_size >> 2),
103
- (uint32_t *)mem_buffer, block_size);
104
- }
105
- } else {
106
- if (s->playback_mode & MP_AUDIO_MONO) {
107
- codec_buffer = wm8750_dac_buffer(s->wm, block_size);
108
- for (pos = 0; pos < block_size; pos++) {
109
- *codec_buffer++ = cpu_to_le16(256 * *mem_buffer);
110
- *codec_buffer++ = cpu_to_le16(256 * *mem_buffer++);
111
- }
112
- } else {
113
- codec_buffer = wm8750_dac_buffer(s->wm, block_size >> 1);
114
- for (pos = 0; pos < block_size; pos += 2) {
115
- *codec_buffer++ = cpu_to_le16(256 * *mem_buffer++);
116
- *codec_buffer++ = cpu_to_le16(256 * *mem_buffer++);
117
- }
118
- }
119
- }
120
- wm8750_dac_commit(s->wm);
121
-
122
- s->last_free = free_out - block_size;
123
-
124
- if (s->play_pos == 0) {
125
- s->status |= MP_AUDIO_TX_HALF;
126
- s->play_pos = block_size;
127
- } else {
128
- s->status |= MP_AUDIO_TX_FULL;
129
- s->play_pos = 0;
130
- }
131
-
132
- if (s->status & s->irq_enable) {
133
- qemu_irq_raise(s->irq);
134
- }
135
-}
136
-
137
-static void mv88w8618_audio_clock_update(mv88w8618_audio_state *s)
138
-{
139
- int rate;
140
-
141
- if (s->playback_mode & MP_AUDIO_CLOCK_24MHZ) {
142
- rate = 24576000 / 64; /* 24.576MHz */
143
- } else {
144
- rate = 11289600 / 64; /* 11.2896MHz */
145
- }
146
- rate /= ((s->clock_div >> 8) & 0xff) + 1;
147
-
148
- wm8750_set_bclk_in(s->wm, rate);
149
-}
150
-
151
-static uint64_t mv88w8618_audio_read(void *opaque, hwaddr offset,
152
- unsigned size)
153
-{
154
- mv88w8618_audio_state *s = opaque;
155
-
156
- switch (offset) {
157
- case MP_AUDIO_PLAYBACK_MODE:
158
- return s->playback_mode;
159
-
160
- case MP_AUDIO_CLOCK_DIV:
161
- return s->clock_div;
162
-
163
- case MP_AUDIO_IRQ_STATUS:
164
- return s->status;
165
-
166
- case MP_AUDIO_IRQ_ENABLE:
167
- return s->irq_enable;
168
-
169
- case MP_AUDIO_TX_STATUS:
170
- return s->play_pos >> 2;
171
-
172
- default:
173
- return 0;
174
- }
175
-}
176
-
177
-static void mv88w8618_audio_write(void *opaque, hwaddr offset,
178
- uint64_t value, unsigned size)
179
-{
180
- mv88w8618_audio_state *s = opaque;
181
-
182
- switch (offset) {
183
- case MP_AUDIO_PLAYBACK_MODE:
184
- if (value & MP_AUDIO_PLAYBACK_EN &&
185
- !(s->playback_mode & MP_AUDIO_PLAYBACK_EN)) {
186
- s->status = 0;
187
- s->last_free = 0;
188
- s->play_pos = 0;
189
- }
190
- s->playback_mode = value;
191
- mv88w8618_audio_clock_update(s);
192
- break;
193
-
194
- case MP_AUDIO_CLOCK_DIV:
195
- s->clock_div = value;
196
- s->last_free = 0;
197
- s->play_pos = 0;
198
- mv88w8618_audio_clock_update(s);
199
- break;
200
-
201
- case MP_AUDIO_IRQ_STATUS:
202
- s->status &= ~value;
203
- break;
204
-
205
- case MP_AUDIO_IRQ_ENABLE:
206
- s->irq_enable = value;
207
- if (s->status & s->irq_enable) {
208
- qemu_irq_raise(s->irq);
209
- }
210
- break;
211
-
212
- case MP_AUDIO_TX_START_LO:
213
- s->phys_buf = (s->phys_buf & 0xFFFF0000) | (value & 0xFFFF);
214
- s->target_buffer = s->phys_buf;
215
- s->play_pos = 0;
216
- s->last_free = 0;
217
- break;
218
-
219
- case MP_AUDIO_TX_THRESHOLD:
220
- s->threshold = (value + 1) * 4;
221
- break;
222
-
223
- case MP_AUDIO_TX_START_HI:
224
- s->phys_buf = (s->phys_buf & 0xFFFF) | (value << 16);
225
- s->target_buffer = s->phys_buf;
226
- s->play_pos = 0;
227
- s->last_free = 0;
228
- break;
229
- }
230
-}
231
-
232
-static void mv88w8618_audio_reset(DeviceState *d)
233
-{
234
- mv88w8618_audio_state *s = MV88W8618_AUDIO(d);
235
-
236
- s->playback_mode = 0;
237
- s->status = 0;
238
- s->irq_enable = 0;
239
- s->clock_div = 0;
240
- s->threshold = 0;
241
- s->phys_buf = 0;
242
-}
243
-
244
-static const MemoryRegionOps mv88w8618_audio_ops = {
245
- .read = mv88w8618_audio_read,
246
- .write = mv88w8618_audio_write,
247
- .endianness = DEVICE_NATIVE_ENDIAN,
248
-};
249
-
250
-static void mv88w8618_audio_init(Object *obj)
251
-{
252
- SysBusDevice *dev = SYS_BUS_DEVICE(obj);
253
- mv88w8618_audio_state *s = MV88W8618_AUDIO(dev);
254
-
255
- sysbus_init_irq(dev, &s->irq);
256
-
257
- memory_region_init_io(&s->iomem, obj, &mv88w8618_audio_ops, s,
258
- "audio", MP_AUDIO_SIZE);
259
- sysbus_init_mmio(dev, &s->iomem);
260
-
261
- object_property_add_link(OBJECT(dev), "wm8750", TYPE_WM8750,
262
- (Object **) &s->wm,
263
- qdev_prop_allow_set_link_before_realize,
264
- 0);
265
-}
266
-
267
-static void mv88w8618_audio_realize(DeviceState *dev, Error **errp)
268
-{
269
- mv88w8618_audio_state *s = MV88W8618_AUDIO(dev);
270
-
271
- wm8750_data_req_set(s->wm, mv88w8618_audio_callback, s);
272
-}
273
-
274
-static const VMStateDescription mv88w8618_audio_vmsd = {
275
- .name = "mv88w8618_audio",
276
- .version_id = 1,
277
- .minimum_version_id = 1,
278
- .fields = (const VMStateField[]) {
279
- VMSTATE_UINT32(playback_mode, mv88w8618_audio_state),
280
- VMSTATE_UINT32(status, mv88w8618_audio_state),
281
- VMSTATE_UINT32(irq_enable, mv88w8618_audio_state),
282
- VMSTATE_UINT32(phys_buf, mv88w8618_audio_state),
283
- VMSTATE_UINT32(target_buffer, mv88w8618_audio_state),
284
- VMSTATE_UINT32(threshold, mv88w8618_audio_state),
285
- VMSTATE_UINT32(play_pos, mv88w8618_audio_state),
286
- VMSTATE_UINT32(last_free, mv88w8618_audio_state),
287
- VMSTATE_UINT32(clock_div, mv88w8618_audio_state),
288
- VMSTATE_END_OF_LIST()
289
- }
290
-};
291
-
292
-static void mv88w8618_audio_class_init(ObjectClass *klass, const void *data)
293
-{
294
- DeviceClass *dc = DEVICE_CLASS(klass);
295
-
296
- dc->realize = mv88w8618_audio_realize;
297
- device_class_set_legacy_reset(dc, mv88w8618_audio_reset);
298
- dc->vmsd = &mv88w8618_audio_vmsd;
299
- dc->user_creatable = false;
300
-}
301
-
302
-static const TypeInfo mv88w8618_audio_info = {
303
- .name = TYPE_MV88W8618_AUDIO,
304
- .parent = TYPE_SYS_BUS_DEVICE,
305
- .instance_size = sizeof(mv88w8618_audio_state),
306
- .instance_init = mv88w8618_audio_init,
307
- .class_init = mv88w8618_audio_class_init,
308
-};
309
-
310
-static void mv88w8618_register_types(void)
311
-{
312
- type_register_static(&mv88w8618_audio_info);
313
-}
314
-
315
-type_init(mv88w8618_register_types)
hw/audio/meson.build
-1
@@ -7,7 +7,6 @@ system_ss.add(when: 'CONFIG_CS4231A', if_true: files('cs4231a.c'))
7
system_ss.add(when: 'CONFIG_ES1370', if_true: files('es1370.c'))
8
system_ss.add(when: 'CONFIG_GUS', if_true: files('gus.c', 'gusemu_hal.c', 'gusemu_mixer.c'))
9
system_ss.add(when: 'CONFIG_HDA', if_true: files('intel-hda.c', 'hda-codec.c'))
10
-system_ss.add(when: 'CONFIG_MARVELL_88W8618', if_true: files('marvell_88w8618.c'))
10
system_ss.add(when: 'CONFIG_PCSPK', if_true: files('pcspk.c'))
11
system_ss.add(when: 'CONFIG_PL041', if_true: files('pl041.c', 'lm4549.c'))
12
system_ss.add(when: 'CONFIG_SB16', if_true: files('sb16.c'))
hw/net/meson.build
-1
@@ -27,7 +27,6 @@ system_ss.add(when: 'CONFIG_ALLWINNER_EMAC', if_true: files('allwinner_emac.c'))
27
system_ss.add(when: 'CONFIG_ALLWINNER_SUN8I_EMAC', if_true: files('allwinner-sun8i-emac.c'))
28
system_ss.add(when: 'CONFIG_IMX_FEC', if_true: files('imx_fec.c'))
29
system_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-emac.c'))
30
-system_ss.add(when: 'CONFIG_MARVELL_88W8618', if_true: files('mv88w8618_eth.c'))
30
31
system_ss.add(when: 'CONFIG_CADENCE', if_true: files('cadence_gem.c'))
32
system_ss.add(when: 'CONFIG_STELLARIS_ENET', if_true: files('stellaris_enet.c'))
hw/net/mv88w8618_eth.c
deleted
-403
@@ -1,403 +0,0 @@
1
-/* SPDX-License-Identifier: GPL-2.0-or-later */
2
-/*
3
- * Marvell MV88W8618 / Freecom MusicPal emulation.
4
- *
5
- * Copyright (c) 2008 Jan Kiszka
6
- */
7
-
8
-#include "qemu/osdep.h"
9
-#include "qapi/error.h"
10
-#include "hw/core/qdev-properties.h"
11
-#include "hw/core/sysbus.h"
12
-#include "hw/core/irq.h"
13
-#include "hw/net/mv88w8618_eth.h"
14
-#include "migration/vmstate.h"
15
-#include "system/dma.h"
16
-#include "net/net.h"
17
-
18
-#define MP_ETH_SIZE 0x00001000
19
-
20
-/* Ethernet register offsets */
21
-#define MP_ETH_SMIR 0x010
22
-#define MP_ETH_PCXR 0x408
23
-#define MP_ETH_SDCMR 0x448
24
-#define MP_ETH_ICR 0x450
25
-#define MP_ETH_IMR 0x458
26
-#define MP_ETH_FRDP0 0x480
27
-#define MP_ETH_FRDP1 0x484
28
-#define MP_ETH_FRDP2 0x488
29
-#define MP_ETH_FRDP3 0x48C
30
-#define MP_ETH_CRDP0 0x4A0
31
-#define MP_ETH_CRDP1 0x4A4
32
-#define MP_ETH_CRDP2 0x4A8
33
-#define MP_ETH_CRDP3 0x4AC
34
-#define MP_ETH_CTDP0 0x4E0
35
-#define MP_ETH_CTDP1 0x4E4
36
-
37
-/* MII PHY access */
38
-#define MP_ETH_SMIR_DATA 0x0000FFFF
39
-#define MP_ETH_SMIR_ADDR 0x03FF0000
40
-#define MP_ETH_SMIR_OPCODE (1 << 26) /* Read value */
41
-#define MP_ETH_SMIR_RDVALID (1 << 27)
42
-
43
-/* PHY registers */
44
-#define MP_ETH_PHY1_BMSR 0x00210000
45
-#define MP_ETH_PHY1_PHYSID1 0x00410000
46
-#define MP_ETH_PHY1_PHYSID2 0x00610000
47
-
48
-#define MP_PHY_BMSR_LINK 0x0004
49
-#define MP_PHY_BMSR_AUTONEG 0x0008
50
-
51
-#define MP_PHY_88E3015 0x01410E20
52
-
53
-/* TX descriptor status */
54
-#define MP_ETH_TX_OWN (1U << 31)
55
-
56
-/* RX descriptor status */
57
-#define MP_ETH_RX_OWN (1U << 31)
58
-
59
-/* Interrupt cause/mask bits */
60
-#define MP_ETH_IRQ_RX_BIT 0
61
-#define MP_ETH_IRQ_RX (1 << MP_ETH_IRQ_RX_BIT)
62
-#define MP_ETH_IRQ_TXHI_BIT 2
63
-#define MP_ETH_IRQ_TXLO_BIT 3
64
-
65
-/* Port config bits */
66
-#define MP_ETH_PCXR_2BSM_BIT 28 /* 2-byte incoming suffix */
67
-
68
-/* SDMA command bits */
69
-#define MP_ETH_CMD_TXHI (1 << 23)
70
-#define MP_ETH_CMD_TXLO (1 << 22)
71
-
72
-typedef struct mv88w8618_tx_desc {
73
- uint32_t cmdstat;
74
- uint16_t res;
75
- uint16_t bytes;
76
- uint32_t buffer;
77
- uint32_t next;
78
-} mv88w8618_tx_desc;
79
-
80
-typedef struct mv88w8618_rx_desc {
81
- uint32_t cmdstat;
82
- uint16_t bytes;
83
- uint16_t buffer_size;
84
- uint32_t buffer;
85
- uint32_t next;
86
-} mv88w8618_rx_desc;
87
-
88
-OBJECT_DECLARE_SIMPLE_TYPE(mv88w8618_eth_state, MV88W8618_ETH)
89
-
90
-struct mv88w8618_eth_state {
91
- /*< private >*/
92
- SysBusDevice parent_obj;
93
- /*< public >*/
94
-
95
- MemoryRegion iomem;
96
- qemu_irq irq;
97
- MemoryRegion *dma_mr;
98
- AddressSpace dma_as;
99
- uint32_t smir;
100
- uint32_t icr;
101
- uint32_t imr;
102
- int mmio_index;
103
- uint32_t vlan_header;
104
- uint32_t tx_queue[2];
105
- uint32_t rx_queue[4];
106
- uint32_t frx_queue[4];
107
- uint32_t cur_rx[4];
108
- NICState *nic;
109
- NICConf conf;
110
-};
111
-
112
-static void eth_rx_desc_put(AddressSpace *dma_as, uint32_t addr,
113
- mv88w8618_rx_desc *desc)
114
-{
115
- cpu_to_le32s(&desc->cmdstat);
116
- cpu_to_le16s(&desc->bytes);
117
- cpu_to_le16s(&desc->buffer_size);
118
- cpu_to_le32s(&desc->buffer);
119
- cpu_to_le32s(&desc->next);
120
- dma_memory_write(dma_as, addr, desc, sizeof(*desc), MEMTXATTRS_UNSPECIFIED);
121
-}
122
-
123
-static void eth_rx_desc_get(AddressSpace *dma_as, uint32_t addr,
124
- mv88w8618_rx_desc *desc)
125
-{
126
- dma_memory_read(dma_as, addr, desc, sizeof(*desc), MEMTXATTRS_UNSPECIFIED);
127
- le32_to_cpus(&desc->cmdstat);
128
- le16_to_cpus(&desc->bytes);
129
- le16_to_cpus(&desc->buffer_size);
130
- le32_to_cpus(&desc->buffer);
131
- le32_to_cpus(&desc->next);
132
-}
133
-
134
-static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size)
135
-{
136
- mv88w8618_eth_state *s = qemu_get_nic_opaque(nc);
137
- uint32_t desc_addr;
138
- mv88w8618_rx_desc desc;
139
- int i;
140
-
141
- for (i = 0; i < 4; i++) {
142
- desc_addr = s->cur_rx[i];
143
- if (!desc_addr) {
144
- continue;
145
- }
146
- do {
147
- eth_rx_desc_get(&s->dma_as, desc_addr, &desc);
148
- if ((desc.cmdstat & MP_ETH_RX_OWN) && desc.buffer_size >= size) {
149
- dma_memory_write(&s->dma_as, desc.buffer + s->vlan_header,
150
- buf, size, MEMTXATTRS_UNSPECIFIED);
151
- desc.bytes = size + s->vlan_header;
152
- desc.cmdstat &= ~MP_ETH_RX_OWN;
153
- s->cur_rx[i] = desc.next;
154
-
155
- s->icr |= MP_ETH_IRQ_RX;
156
- if (s->icr & s->imr) {
157
- qemu_irq_raise(s->irq);
158
- }
159
- eth_rx_desc_put(&s->dma_as, desc_addr, &desc);
160
- return size;
161
- }
162
- desc_addr = desc.next;
163
- } while (desc_addr != s->rx_queue[i]);
164
- }
165
- return size;
166
-}
167
-
168
-static void eth_tx_desc_put(AddressSpace *dma_as, uint32_t addr,
169
- mv88w8618_tx_desc *desc)
170
-{
171
- cpu_to_le32s(&desc->cmdstat);
172
- cpu_to_le16s(&desc->res);
173
- cpu_to_le16s(&desc->bytes);
174
- cpu_to_le32s(&desc->buffer);
175
- cpu_to_le32s(&desc->next);
176
- dma_memory_write(dma_as, addr, desc, sizeof(*desc), MEMTXATTRS_UNSPECIFIED);
177
-}
178
-
179
-static void eth_tx_desc_get(AddressSpace *dma_as, uint32_t addr,
180
- mv88w8618_tx_desc *desc)
181
-{
182
- dma_memory_read(dma_as, addr, desc, sizeof(*desc), MEMTXATTRS_UNSPECIFIED);
183
- le32_to_cpus(&desc->cmdstat);
184
- le16_to_cpus(&desc->res);
185
- le16_to_cpus(&desc->bytes);
186
- le32_to_cpus(&desc->buffer);
187
- le32_to_cpus(&desc->next);
188
-}
189
-
190
-static void eth_send(mv88w8618_eth_state *s, int queue_index)
191
-{
192
- uint32_t desc_addr = s->tx_queue[queue_index];
193
- mv88w8618_tx_desc desc;
194
- uint32_t next_desc;
195
- uint8_t buf[2048];
196
- int len;
197
-
198
- do {
199
- eth_tx_desc_get(&s->dma_as, desc_addr, &desc);
200
- next_desc = desc.next;
201
- if (desc.cmdstat & MP_ETH_TX_OWN) {
202
- len = desc.bytes;
203
- if (len < 2048) {
204
- dma_memory_read(&s->dma_as, desc.buffer, buf, len,
205
- MEMTXATTRS_UNSPECIFIED);
206
- qemu_send_packet(qemu_get_queue(s->nic), buf, len);
207
- }
208
- desc.cmdstat &= ~MP_ETH_TX_OWN;
209
- s->icr |= 1 << (MP_ETH_IRQ_TXLO_BIT - queue_index);
210
- eth_tx_desc_put(&s->dma_as, desc_addr, &desc);
211
- }
212
- desc_addr = next_desc;
213
- } while (desc_addr != s->tx_queue[queue_index]);
214
-}
215
-
216
-static uint64_t mv88w8618_eth_read(void *opaque, hwaddr offset,
217
- unsigned size)
218
-{
219
- mv88w8618_eth_state *s = opaque;
220
-
221
- switch (offset) {
222
- case MP_ETH_SMIR:
223
- if (s->smir & MP_ETH_SMIR_OPCODE) {
224
- switch (s->smir & MP_ETH_SMIR_ADDR) {
225
- case MP_ETH_PHY1_BMSR:
226
- return MP_PHY_BMSR_LINK | MP_PHY_BMSR_AUTONEG |
227
- MP_ETH_SMIR_RDVALID;
228
- case MP_ETH_PHY1_PHYSID1:
229
- return (MP_PHY_88E3015 >> 16) | MP_ETH_SMIR_RDVALID;
230
- case MP_ETH_PHY1_PHYSID2:
231
- return (MP_PHY_88E3015 & 0xFFFF) | MP_ETH_SMIR_RDVALID;
232
- default:
233
- return MP_ETH_SMIR_RDVALID;
234
- }
235
- }
236
- return 0;
237
-
238
- case MP_ETH_ICR:
239
- return s->icr;
240
-
241
- case MP_ETH_IMR:
242
- return s->imr;
243
-
244
- case MP_ETH_FRDP0 ... MP_ETH_FRDP3:
245
- return s->frx_queue[(offset - MP_ETH_FRDP0) / 4];
246
-
247
- case MP_ETH_CRDP0 ... MP_ETH_CRDP3:
248
- return s->rx_queue[(offset - MP_ETH_CRDP0) / 4];
249
-
250
- case MP_ETH_CTDP0 ... MP_ETH_CTDP1:
251
- return s->tx_queue[(offset - MP_ETH_CTDP0) / 4];
252
-
253
- default:
254
- return 0;
255
- }
256
-}
257
-
258
-static void mv88w8618_eth_write(void *opaque, hwaddr offset,
259
- uint64_t value, unsigned size)
260
-{
261
- mv88w8618_eth_state *s = opaque;
262
-
263
- switch (offset) {
264
- case MP_ETH_SMIR:
265
- s->smir = value;
266
- break;
267
-
268
- case MP_ETH_PCXR:
269
- s->vlan_header = ((value >> MP_ETH_PCXR_2BSM_BIT) & 1) * 2;
270
- break;
271
-
272
- case MP_ETH_SDCMR:
273
- if (value & MP_ETH_CMD_TXHI) {
274
- eth_send(s, 1);
275
- }
276
- if (value & MP_ETH_CMD_TXLO) {
277
- eth_send(s, 0);
278
- }
279
- if (value & (MP_ETH_CMD_TXHI | MP_ETH_CMD_TXLO) && s->icr & s->imr) {
280
- qemu_irq_raise(s->irq);
281
- }
282
- break;
283
-
284
- case MP_ETH_ICR:
285
- s->icr &= value;
286
- break;
287
-
288
- case MP_ETH_IMR:
289
- s->imr = value;
290
- if (s->icr & s->imr) {
291
- qemu_irq_raise(s->irq);
292
- }
293
- break;
294
-
295
- case MP_ETH_FRDP0 ... MP_ETH_FRDP3:
296
- s->frx_queue[(offset - MP_ETH_FRDP0) / 4] = value;
297
- break;
298
-
299
- case MP_ETH_CRDP0 ... MP_ETH_CRDP3:
300
- s->rx_queue[(offset - MP_ETH_CRDP0) / 4] =
301
- s->cur_rx[(offset - MP_ETH_CRDP0) / 4] = value;
302
- break;
303
-
304
- case MP_ETH_CTDP0 ... MP_ETH_CTDP1:
305
- s->tx_queue[(offset - MP_ETH_CTDP0) / 4] = value;
306
- break;
307
- }
308
-}
309
-
310
-static const MemoryRegionOps mv88w8618_eth_ops = {
311
- .read = mv88w8618_eth_read,
312
- .write = mv88w8618_eth_write,
313
- .endianness = DEVICE_NATIVE_ENDIAN,
314
-};
315
-
316
-static void eth_cleanup(NetClientState *nc)
317
-{
318
- mv88w8618_eth_state *s = qemu_get_nic_opaque(nc);
319
-
320
- s->nic = NULL;
321
-}
322
-
323
-static NetClientInfo net_mv88w8618_info = {
324
- .type = NET_CLIENT_DRIVER_NIC,
325
- .size = sizeof(NICState),
326
- .receive = eth_receive,
327
- .cleanup = eth_cleanup,
328
-};
329
-
330
-static void mv88w8618_eth_init(Object *obj)
331
-{
332
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
333
- DeviceState *dev = DEVICE(sbd);
334
- mv88w8618_eth_state *s = MV88W8618_ETH(dev);
335
-
336
- sysbus_init_irq(sbd, &s->irq);
337
- memory_region_init_io(&s->iomem, obj, &mv88w8618_eth_ops, s,
338
- "mv88w8618-eth", MP_ETH_SIZE);
339
- sysbus_init_mmio(sbd, &s->iomem);
340
-}
341
-
342
-static void mv88w8618_eth_realize(DeviceState *dev, Error **errp)
343
-{
344
- mv88w8618_eth_state *s = MV88W8618_ETH(dev);
345
-
346
- if (!s->dma_mr) {
347
- error_setg(errp, TYPE_MV88W8618_ETH " 'dma-memory' link not set");
348
- return;
349
- }
350
-
351
- address_space_init(&s->dma_as, s->dma_mr, "emac-dma");
352
- s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf,
353
- object_get_typename(OBJECT(dev)), dev->id,
354
- &dev->mem_reentrancy_guard, s);
355
-}
356
-
357
-static const VMStateDescription mv88w8618_eth_vmsd = {
358
- .name = "mv88w8618_eth",
359
- .version_id = 1,
360
- .minimum_version_id = 1,
361
- .fields = (const VMStateField[]) {
362
- VMSTATE_UINT32(smir, mv88w8618_eth_state),
363
- VMSTATE_UINT32(icr, mv88w8618_eth_state),
364
- VMSTATE_UINT32(imr, mv88w8618_eth_state),
365
- VMSTATE_UINT32(vlan_header, mv88w8618_eth_state),
366
- VMSTATE_UINT32_ARRAY(tx_queue, mv88w8618_eth_state, 2),
367
- VMSTATE_UINT32_ARRAY(rx_queue, mv88w8618_eth_state, 4),
368
- VMSTATE_UINT32_ARRAY(frx_queue, mv88w8618_eth_state, 4),
369
- VMSTATE_UINT32_ARRAY(cur_rx, mv88w8618_eth_state, 4),
370
- VMSTATE_END_OF_LIST()
371
- }
372
-};
373
-
374
-static const Property mv88w8618_eth_properties[] = {
375
- DEFINE_NIC_PROPERTIES(mv88w8618_eth_state, conf),
376
- DEFINE_PROP_LINK("dma-memory", mv88w8618_eth_state, dma_mr,
377
- TYPE_MEMORY_REGION, MemoryRegion *),
378
-};
379
-
380
-static void mv88w8618_eth_class_init(ObjectClass *klass, const void *data)
381
-{
382
- DeviceClass *dc = DEVICE_CLASS(klass);
383
-
384
- dc->vmsd = &mv88w8618_eth_vmsd;
385
- device_class_set_props(dc, mv88w8618_eth_properties);
386
- dc->realize = mv88w8618_eth_realize;
387
-}
388
-
389
-static const TypeInfo mv88w8618_eth_info = {
390
- .name = TYPE_MV88W8618_ETH,
391
- .parent = TYPE_SYS_BUS_DEVICE,
392
- .instance_size = sizeof(mv88w8618_eth_state),
393
- .instance_init = mv88w8618_eth_init,
394
- .class_init = mv88w8618_eth_class_init,
395
-};
396
-
397
-static void musicpal_register_types(void)
398
-{
399
- type_register_static(&mv88w8618_eth_info);
400
-}
401
-
402
-type_init(musicpal_register_types)
403
-
include/hw/net/mv88w8618_eth.h
deleted
-13
@@ -1,13 +0,0 @@
1
-/* SPDX-License-Identifier: GPL-2.0-or-later */
2
-/*
3
- * Marvell MV88W8618 / Freecom MusicPal emulation.
4
- *
5
- * Copyright (c) 2008-2021 QEMU contributors
6
- */
7
-
8
-#ifndef HW_NET_MV88W8618_ETH_H
9
-#define HW_NET_MV88W8618_ETH_H
10
-
11
-#define TYPE_MV88W8618_ETH "mv88w8618_eth"
12
-
13
-#endif