]> git.proxmox.com Git - mirror_qemu.git/blame - hw/eepro100.c
eepro100: Add diagnose command
[mirror_qemu.git] / hw / eepro100.c
CommitLineData
663e8e51
TS
1/*
2 * QEMU i8255x (PRO100) emulation
3 *
230a167c 4 * Copyright (C) 2006-2010 Stefan Weil
663e8e51
TS
5 *
6 * Portions of the code are copies from grub / etherboot eepro100.c
7 * and linux e100.c.
8 *
230a167c 9 * This program is free software: you can redistribute it and/or modify
663e8e51 10 * it under the terms of the GNU General Public License as published by
230a167c
SW
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) version 3 or any later version.
663e8e51
TS
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
230a167c 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
663e8e51
TS
21 *
22 * Tested features (i82559):
6cded3a4 23 * PXE boot (i386) ok
663e8e51
TS
24 * Linux networking (i386) ok
25 *
26 * Untested:
27 * non-i386 platforms
28 * Windows networking
29 *
30 * References:
31 *
32 * Intel 8255x 10/100 Mbps Ethernet Controller Family
33 * Open Source Software Developer Manual
ba19f2de
SW
34 *
35 * TODO:
36 * * PHY emulation should be separated from nic emulation.
37 * Most nic emulations could share the same phy code.
38 * * i82550 is untested. It is programmed like the i82559.
39 * * i82562 is untested. It is programmed like the i82559.
40 * * Power management (i82558 and later) is not implemented.
41 * * Wake-on-LAN is not implemented.
663e8e51
TS
42 */
43
663e8e51 44#include <stddef.h> /* offsetof */
b84a5c6f 45#include <stdbool.h>
87ecb68b
PB
46#include "hw.h"
47#include "pci.h"
48#include "net.h"
663e8e51
TS
49#include "eeprom93xx.h"
50
51/* Common declarations for all PCI devices. */
52
663e8e51
TS
53#define PCI_CONFIG_8(offset, value) \
54 (pci_conf[offset] = (value))
55#define PCI_CONFIG_16(offset, value) \
56 (*(uint16_t *)&pci_conf[offset] = cpu_to_le16(value))
57#define PCI_CONFIG_32(offset, value) \
58 (*(uint32_t *)&pci_conf[offset] = cpu_to_le32(value))
59
60#define KiB 1024
61
aac443e6 62/* Debug EEPRO100 card. */
ce0e58b3
SW
63#if 0
64# define DEBUG_EEPRO100
65#endif
663e8e51
TS
66
67#ifdef DEBUG_EEPRO100
001faf32 68#define logout(fmt, ...) fprintf(stderr, "EE100\t%-24s" fmt, __func__, ## __VA_ARGS__)
663e8e51 69#else
001faf32 70#define logout(fmt, ...) ((void)0)
663e8e51
TS
71#endif
72
73/* Set flags to 0 to disable debug output. */
aac443e6
SW
74#define INT 1 /* interrupt related actions */
75#define MDI 1 /* mdi related actions */
76#define OTHER 1
77#define RXTX 1
78#define EEPROM 1 /* eeprom related actions */
663e8e51
TS
79
80#define TRACE(flag, command) ((flag) ? (command) : (void)0)
81
7f1e9d4e 82#define missing(text) fprintf(stderr, "eepro100: feature is missing in this emulation: " text "\n")
663e8e51
TS
83
84#define MAX_ETH_FRAME_SIZE 1514
85
86/* This driver supports several different devices which are declared here. */
c4c270e2 87#define i82550 0x82550
663e8e51 88#define i82551 0x82551
c4c270e2 89#define i82557A 0x82557a
663e8e51
TS
90#define i82557B 0x82557b
91#define i82557C 0x82557c
c4c270e2 92#define i82558A 0x82558a
663e8e51 93#define i82558B 0x82558b
c4c270e2
SW
94#define i82559A 0x82559a
95#define i82559B 0x82559b
663e8e51
TS
96#define i82559C 0x82559c
97#define i82559ER 0x82559e
98#define i82562 0x82562
99
aac443e6 100/* Use 64 word EEPROM. TODO: could be a runtime option. */
663e8e51
TS
101#define EEPROM_SIZE 64
102
103#define PCI_MEM_SIZE (4 * KiB)
104#define PCI_IO_SIZE 64
105#define PCI_FLASH_SIZE (128 * KiB)
106
107#define BIT(n) (1 << (n))
108#define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
109
110/* The SCB accepts the following controls for the Tx and Rx units: */
111#define CU_NOP 0x0000 /* No operation. */
112#define CU_START 0x0010 /* CU start. */
113#define CU_RESUME 0x0020 /* CU resume. */
114#define CU_STATSADDR 0x0040 /* Load dump counters address. */
115#define CU_SHOWSTATS 0x0050 /* Dump statistical counters. */
116#define CU_CMD_BASE 0x0060 /* Load CU base address. */
117#define CU_DUMPSTATS 0x0070 /* Dump and reset statistical counters. */
118#define CU_SRESUME 0x00a0 /* CU static resume. */
119
120#define RU_NOP 0x0000
121#define RX_START 0x0001
122#define RX_RESUME 0x0002
e824012b 123#define RU_ABORT 0x0004
663e8e51
TS
124#define RX_ADDR_LOAD 0x0006
125#define RX_RESUMENR 0x0007
126#define INT_MASK 0x0100
127#define DRVR_INT 0x0200 /* Driver generated interrupt. */
128
663e8e51
TS
129/* Offsets to the various registers.
130 All accesses need not be longword aligned. */
131enum speedo_offsets {
0908bba1 132 SCBStatus = 0, /* Status Word. */
663e8e51
TS
133 SCBAck = 1,
134 SCBCmd = 2, /* Rx/Command Unit command and status. */
135 SCBIntmask = 3,
136 SCBPointer = 4, /* General purpose pointer. */
137 SCBPort = 8, /* Misc. commands and operands. */
0908bba1
SW
138 SCBflash = 12, /* Flash memory control. */
139 SCBeeprom = 14, /* EEPROM control. */
663e8e51
TS
140 SCBCtrlMDI = 16, /* MDI interface control. */
141 SCBEarlyRx = 20, /* Early receive byte count. */
0908bba1
SW
142 SCBFlow = 24, /* Flow Control. */
143 SCBpmdr = 27, /* Power Management Driver. */
144 SCBgctrl = 28, /* General Control. */
145 SCBgstat = 29, /* General Status. */
663e8e51
TS
146};
147
148/* A speedo3 transmit buffer descriptor with two buffers... */
149typedef struct {
150 uint16_t status;
151 uint16_t command;
152 uint32_t link; /* void * */
7b8737de 153 uint32_t tbd_array_addr; /* transmit buffer descriptor array address. */
663e8e51
TS
154 uint16_t tcb_bytes; /* transmit command block byte count (in lower 14 bits */
155 uint8_t tx_threshold; /* transmit threshold */
156 uint8_t tbd_count; /* TBD number */
157 //~ /* This constitutes two "TBD" entries: hdr and data */
158 //~ uint32_t tx_buf_addr0; /* void *, header of frame to be transmitted. */
159 //~ int32_t tx_buf_size0; /* Length of Tx hdr. */
160 //~ uint32_t tx_buf_addr1; /* void *, data to be transmitted. */
161 //~ int32_t tx_buf_size1; /* Length of Tx data. */
c227f099 162} eepro100_tx_t;
663e8e51
TS
163
164/* Receive frame descriptor. */
165typedef struct {
166 int16_t status;
167 uint16_t command;
168 uint32_t link; /* struct RxFD * */
169 uint32_t rx_buf_addr; /* void * */
170 uint16_t count;
171 uint16_t size;
172 char packet[MAX_ETH_FRAME_SIZE + 4];
c227f099 173} eepro100_rx_t;
663e8e51 174
ced5296a
SW
175typedef enum {
176 COMMAND_EL = BIT(15),
177 COMMAND_S = BIT(14),
178 COMMAND_I = BIT(13),
179 COMMAND_NC = BIT(4),
180 COMMAND_SF = BIT(3),
181 COMMAND_CMD = BITS(2, 0),
182} scb_command_bit;
183
184typedef enum {
185 STATUS_C = BIT(15),
186 STATUS_OK = BIT(13),
187} scb_status_bit;
188
663e8e51
TS
189typedef struct {
190 uint32_t tx_good_frames, tx_max_collisions, tx_late_collisions,
cc02c66c
SW
191 tx_underruns, tx_lost_crs, tx_deferred, tx_single_collisions,
192 tx_multiple_collisions, tx_total_collisions;
663e8e51 193 uint32_t rx_good_frames, rx_crc_errors, rx_alignment_errors,
cc02c66c
SW
194 rx_resource_errors, rx_overrun_errors, rx_cdt_errors,
195 rx_short_frame_errors;
663e8e51
TS
196 uint32_t fc_xmt_pause, fc_rcv_pause, fc_rcv_unsupported;
197 uint16_t xmt_tco_frames, rcv_tco_frames;
ba42b646
SW
198 /* TODO: i82559 has six reserved statistics but a total of 24 dwords. */
199 uint32_t reserved[4];
c227f099 200} eepro100_stats_t;
663e8e51
TS
201
202typedef enum {
203 cu_idle = 0,
204 cu_suspended = 1,
205 cu_active = 2,
206 cu_lpq_active = 2,
207 cu_hqp_active = 3
c227f099 208} cu_state_t;
663e8e51
TS
209
210typedef enum {
211 ru_idle = 0,
212 ru_suspended = 1,
213 ru_no_resources = 2,
214 ru_ready = 4
c227f099 215} ru_state_t;
663e8e51 216
663e8e51 217typedef struct {
273a2142 218 PCIDevice dev;
663e8e51
TS
219 uint8_t mult[8]; /* multicast mask array */
220 int mmio_index;
e00e365e 221 NICState *nic;
508ef936 222 NICConf conf;
663e8e51
TS
223 uint8_t scb_stat; /* SCB stat/ack byte */
224 uint8_t int_stat; /* PCI interrupt status */
3706c43f 225 /* region must not be saved by nic_save. */
663e8e51 226 uint32_t region[3]; /* PCI region addresses */
663e8e51 227 uint16_t mdimem[32];
c227f099 228 eeprom_t *eeprom;
663e8e51
TS
229 uint32_t device; /* device variant */
230 uint32_t pointer;
231 /* (cu_base + cu_offset) address the next command block in the command block list. */
232 uint32_t cu_base; /* CU base address */
233 uint32_t cu_offset; /* CU address offset */
234 /* (ru_base + ru_offset) address the RFD in the Receive Frame Area. */
235 uint32_t ru_base; /* RU base address */
236 uint32_t ru_offset; /* RU address offset */
c227f099 237 uint32_t statsaddr; /* pointer to eepro100_stats_t */
ba42b646 238
f3a52e50
SW
239 /* Temporary status information (no need to save these values),
240 * used while processing CU commands. */
241 eepro100_tx_t tx; /* transmit buffer descriptor */
242 uint32_t cb_address; /* = cu_base + cu_offset */
243
ba42b646
SW
244 /* Statistical counters. Also used for wake-up packet (i82559). */
245 eepro100_stats_t statistics;
246
663e8e51
TS
247#if 0
248 uint16_t status;
249#endif
250
251 /* Configuration bytes. */
252 uint8_t configuration[22];
253
254 /* Data in mem is always in the byte order of the controller (le). */
255 uint8_t mem[PCI_MEM_SIZE];
151b2986
JQ
256 /* vmstate for each particular nic */
257 VMStateDescription *vmstate;
ba42b646
SW
258
259 /* Quasi static device properties (no need to save them). */
260 uint16_t stats_size;
261 bool has_extended_tcb_support;
663e8e51
TS
262} EEPRO100State;
263
6cded3a4
SW
264/* Word indices in EEPROM. */
265typedef enum {
266 EEPROM_CNFG_MDIX = 0x03,
267 EEPROM_ID = 0x05,
268 EEPROM_PHY_ID = 0x06,
269 EEPROM_VENDOR_ID = 0x0c,
270 EEPROM_CONFIG_ASF = 0x0d,
271 EEPROM_DEVICE_ID = 0x23,
272 EEPROM_SMBUS_ADDR = 0x90,
273} EEPROMOffset;
274
b1e87018
SW
275/* Bit values for EEPROM ID word. */
276typedef enum {
277 EEPROM_ID_MDM = BIT(0), /* Modem */
278 EEPROM_ID_STB = BIT(1), /* Standby Enable */
279 EEPROM_ID_WMR = BIT(2), /* ??? */
280 EEPROM_ID_WOL = BIT(5), /* Wake on LAN */
281 EEPROM_ID_DPD = BIT(6), /* Deep Power Down */
282 EEPROM_ID_ALT = BIT(7), /* */
283 /* BITS(10, 8) device revision */
284 EEPROM_ID_BD = BIT(11), /* boot disable */
285 EEPROM_ID_ID = BIT(13), /* id bit */
286 /* BITS(15, 14) signature */
287 EEPROM_ID_VALID = BIT(14), /* signature for valid eeprom */
288} eeprom_id_bit;
289
663e8e51
TS
290/* Default values for MDI (PHY) registers */
291static const uint16_t eepro100_mdi_default[] = {
292 /* MDI Registers 0 - 6, 7 */
293 0x3000, 0x780d, 0x02a8, 0x0154, 0x05e1, 0x0000, 0x0000, 0x0000,
294 /* MDI Registers 8 - 15 */
295 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
296 /* MDI Registers 16 - 31 */
297 0x0003, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
298 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
299};
300
301/* Readonly mask for MDI (PHY) registers */
302static const uint16_t eepro100_mdi_mask[] = {
303 0x0000, 0xffff, 0xffff, 0xffff, 0xc01f, 0xffff, 0xffff, 0x0000,
304 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
305 0x0fff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
306 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
307};
308
ba42b646
SW
309/* XXX: optimize */
310static void stl_le_phys(target_phys_addr_t addr, uint32_t val)
311{
312 val = cpu_to_le32(val);
313 cpu_physical_memory_write(addr, (const uint8_t *)&val, sizeof(val));
314}
315
663e8e51
TS
316#define POLYNOMIAL 0x04c11db6
317
318/* From FreeBSD */
319/* XXX: optimize */
7b8737de 320static unsigned compute_mcast_idx(const uint8_t * ep)
663e8e51
TS
321{
322 uint32_t crc;
323 int carry, i, j;
324 uint8_t b;
325
326 crc = 0xffffffff;
327 for (i = 0; i < 6; i++) {
328 b = *ep++;
329 for (j = 0; j < 8; j++) {
330 carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
331 crc <<= 1;
332 b >>= 1;
aac443e6 333 if (carry) {
663e8e51 334 crc = ((crc ^ POLYNOMIAL) | carry);
aac443e6 335 }
663e8e51
TS
336 }
337 }
7b8737de 338 return (crc & BITS(7, 2)) >> 2;
663e8e51
TS
339}
340
341#if defined(DEBUG_EEPRO100)
342static const char *nic_dump(const uint8_t * buf, unsigned size)
343{
344 static char dump[3 * 16 + 1];
345 char *p = &dump[0];
aac443e6 346 if (size > 16) {
663e8e51 347 size = 16;
aac443e6 348 }
663e8e51
TS
349 while (size-- > 0) {
350 p += sprintf(p, " %02x", *buf++);
351 }
352 return dump;
353}
354#endif /* DEBUG_EEPRO100 */
355
356enum scb_stat_ack {
357 stat_ack_not_ours = 0x00,
358 stat_ack_sw_gen = 0x04,
359 stat_ack_rnr = 0x10,
360 stat_ack_cu_idle = 0x20,
361 stat_ack_frame_rx = 0x40,
362 stat_ack_cu_cmd_done = 0x80,
363 stat_ack_not_present = 0xFF,
364 stat_ack_rx = (stat_ack_sw_gen | stat_ack_rnr | stat_ack_frame_rx),
365 stat_ack_tx = (stat_ack_cu_idle | stat_ack_cu_cmd_done),
366};
367
368static void disable_interrupt(EEPRO100State * s)
369{
370 if (s->int_stat) {
aac443e6 371 TRACE(INT, logout("interrupt disabled\n"));
273a2142 372 qemu_irq_lower(s->dev.irq[0]);
663e8e51
TS
373 s->int_stat = 0;
374 }
375}
376
377static void enable_interrupt(EEPRO100State * s)
378{
379 if (!s->int_stat) {
aac443e6 380 TRACE(INT, logout("interrupt enabled\n"));
273a2142 381 qemu_irq_raise(s->dev.irq[0]);
663e8e51
TS
382 s->int_stat = 1;
383 }
384}
385
386static void eepro100_acknowledge(EEPRO100State * s)
387{
388 s->scb_stat &= ~s->mem[SCBAck];
389 s->mem[SCBAck] = s->scb_stat;
390 if (s->scb_stat == 0) {
391 disable_interrupt(s);
392 }
393}
394
e715c8e8 395static void eepro100_interrupt(EEPRO100State * s, uint8_t status)
663e8e51
TS
396{
397 uint8_t mask = ~s->mem[SCBIntmask];
e715c8e8
SW
398 s->mem[SCBAck] |= status;
399 status = s->scb_stat = s->mem[SCBAck];
400 status &= (mask | 0x0f);
401 //~ status &= (~s->mem[SCBIntmask] | 0x0xf);
402 if (status && (mask & 0x01)) {
663e8e51
TS
403 /* SCB mask and SCB Bit M do not disable interrupt. */
404 enable_interrupt(s);
405 } else if (s->int_stat) {
406 disable_interrupt(s);
407 }
408}
409
410static void eepro100_cx_interrupt(EEPRO100State * s)
411{
412 /* CU completed action command. */
413 /* Transmit not ok (82557 only, not in emulation). */
414 eepro100_interrupt(s, 0x80);
415}
416
417static void eepro100_cna_interrupt(EEPRO100State * s)
418{
419 /* CU left the active state. */
420 eepro100_interrupt(s, 0x20);
421}
422
423static void eepro100_fr_interrupt(EEPRO100State * s)
424{
425 /* RU received a complete frame. */
426 eepro100_interrupt(s, 0x40);
427}
428
663e8e51
TS
429static void eepro100_rnr_interrupt(EEPRO100State * s)
430{
431 /* RU is not ready. */
432 eepro100_interrupt(s, 0x10);
433}
663e8e51
TS
434
435static void eepro100_mdi_interrupt(EEPRO100State * s)
436{
437 /* MDI completed read or write cycle. */
438 eepro100_interrupt(s, 0x08);
439}
440
441static void eepro100_swi_interrupt(EEPRO100State * s)
442{
443 /* Software has requested an interrupt. */
444 eepro100_interrupt(s, 0x04);
445}
446
447#if 0
448static void eepro100_fcp_interrupt(EEPRO100State * s)
449{
450 /* Flow control pause interrupt (82558 and later). */
451 eepro100_interrupt(s, 0x01);
452}
453#endif
454
455static void pci_reset(EEPRO100State * s)
456{
457 uint32_t device = s->device;
273a2142 458 uint8_t *pci_conf = s->dev.config;
ba42b646 459 bool power_management = 1;
663e8e51 460
aac443e6 461 TRACE(OTHER, logout("%p\n", s));
663e8e51
TS
462
463 /* PCI Vendor ID */
deb54399 464 pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
d6fd1e66 465 /* PCI Device ID depends on device and is set below. */
663e8e51 466 /* PCI Command */
508cc6b4 467 /* TODO: this is the default, do not override. */
663e8e51
TS
468 PCI_CONFIG_16(PCI_COMMAND, 0x0000);
469 /* PCI Status */
508cc6b4 470 /* TODO: Value at RST# should be 0. */
61702408 471 PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM | PCI_STATUS_FAST_BACK);
663e8e51
TS
472 /* PCI Revision ID */
473 PCI_CONFIG_8(PCI_REVISION_ID, 0x08);
508cc6b4 474 /* TODO: this is the default, do not override. */
663e8e51 475 /* PCI Class Code */
508cc6b4 476 PCI_CONFIG_8(PCI_CLASS_PROG, 0x00);
173a543b 477 pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
663e8e51
TS
478 /* PCI Cache Line Size */
479 /* check cache line size!!! */
480 //~ PCI_CONFIG_8(0x0c, 0x00);
481 /* PCI Latency Timer */
508cc6b4 482 PCI_CONFIG_8(PCI_LATENCY_TIMER, 0x20); // latency timer = 32 clocks
663e8e51
TS
483 /* PCI Header Type */
484 /* BIST (built-in self test) */
663e8e51 485 /* Expansion ROM Base Address (depends on boot disable!!!) */
508cc6b4
MT
486 /* TODO: not needed, set when BAR is registered */
487 PCI_CONFIG_32(PCI_ROM_ADDRESS, PCI_BASE_ADDRESS_SPACE_MEMORY);
663e8e51 488 /* Capability Pointer */
508cc6b4
MT
489 /* TODO: revisions with power_management 1 use this but
490 * do not set new capability list bit in status register. */
491 PCI_CONFIG_8(PCI_CAPABILITY_LIST, 0xdc);
aac443e6 492 /* Interrupt Line */
663e8e51 493 /* Interrupt Pin */
508cc6b4
MT
494 /* TODO: RST# value should be 0 */
495 PCI_CONFIG_8(PCI_INTERRUPT_PIN, 1); // interrupt pin 0
663e8e51 496 /* Minimum Grant */
508cc6b4 497 PCI_CONFIG_8(PCI_MIN_GNT, 0x08);
663e8e51 498 /* Maximum Latency */
508cc6b4 499 PCI_CONFIG_8(PCI_MAX_LAT, 0x18);
663e8e51
TS
500
501 switch (device) {
ba42b646
SW
502 case i82550:
503 // TODO: check device id.
504 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
505 /* Revision ID: 0x0c, 0x0d, 0x0e. */
506 PCI_CONFIG_8(PCI_REVISION_ID, 0x0e);
507 // TODO: check size of statistical counters.
508 s->stats_size = 80;
509 // TODO: check extended tcb support.
510 s->has_extended_tcb_support = 1;
511 break;
663e8e51 512 case i82551:
d6fd1e66 513 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
ba42b646 514 /* Revision ID: 0x0f, 0x10. */
663e8e51 515 PCI_CONFIG_8(PCI_REVISION_ID, 0x0f);
ba42b646
SW
516 // TODO: check size of statistical counters.
517 s->stats_size = 80;
518 s->has_extended_tcb_support = 1;
519 break;
520 case i82557A:
521 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
522 PCI_CONFIG_8(PCI_REVISION_ID, 0x01);
508cc6b4 523 PCI_CONFIG_8(PCI_CAPABILITY_LIST, 0x00);
ba42b646 524 power_management = 0;
663e8e51
TS
525 break;
526 case i82557B:
d6fd1e66 527 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
663e8e51 528 PCI_CONFIG_8(PCI_REVISION_ID, 0x02);
508cc6b4 529 PCI_CONFIG_8(PCI_CAPABILITY_LIST, 0x00);
ba42b646 530 power_management = 0;
663e8e51
TS
531 break;
532 case i82557C:
d6fd1e66 533 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
663e8e51 534 PCI_CONFIG_8(PCI_REVISION_ID, 0x03);
508cc6b4 535 PCI_CONFIG_8(PCI_CAPABILITY_LIST, 0x00);
ba42b646
SW
536 power_management = 0;
537 break;
538 case i82558A:
539 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
508cc6b4
MT
540 PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
541 PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
ba42b646
SW
542 PCI_CONFIG_8(PCI_REVISION_ID, 0x04);
543 s->stats_size = 76;
544 s->has_extended_tcb_support = 1;
663e8e51
TS
545 break;
546 case i82558B:
d6fd1e66 547 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
508cc6b4
MT
548 PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
549 PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
663e8e51 550 PCI_CONFIG_8(PCI_REVISION_ID, 0x05);
ba42b646
SW
551 s->stats_size = 76;
552 s->has_extended_tcb_support = 1;
553 break;
554 case i82559A:
555 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
508cc6b4
MT
556 PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
557 PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
ba42b646
SW
558 PCI_CONFIG_8(PCI_REVISION_ID, 0x06);
559 s->stats_size = 80;
560 s->has_extended_tcb_support = 1;
561 break;
562 case i82559B:
563 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
508cc6b4
MT
564 PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
565 PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
ba42b646
SW
566 PCI_CONFIG_8(PCI_REVISION_ID, 0x07);
567 s->stats_size = 80;
568 s->has_extended_tcb_support = 1;
663e8e51
TS
569 break;
570 case i82559C:
d6fd1e66 571 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82557);
508cc6b4
MT
572 PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
573 PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
ba42b646
SW
574 PCI_CONFIG_8(PCI_REVISION_ID, 0x08);
575 // TODO: Windows wants revision id 0x0c.
576 PCI_CONFIG_8(PCI_REVISION_ID, 0x0c);
577#if EEPROM_SIZE > 0
578 PCI_CONFIG_16(PCI_SUBSYSTEM_VENDOR_ID, 0x8086);
579 PCI_CONFIG_16(PCI_SUBSYSTEM_ID, 0x0040);
580#endif
581 s->stats_size = 80;
582 s->has_extended_tcb_support = 1;
663e8e51
TS
583 break;
584 case i82559ER:
d6fd1e66 585 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
508cc6b4
MT
586 PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
587 PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
663e8e51 588 PCI_CONFIG_8(PCI_REVISION_ID, 0x09);
ba42b646
SW
589 s->stats_size = 80;
590 s->has_extended_tcb_support = 1;
591 break;
592 case i82562:
593 // TODO: check device id.
594 pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82551IT);
595 /* TODO: wrong revision id. */
596 PCI_CONFIG_8(PCI_REVISION_ID, 0x0e);
597 s->stats_size = 80;
598 s->has_extended_tcb_support = 1;
663e8e51 599 break;
663e8e51
TS
600 default:
601 logout("Device %X is undefined!\n", device);
602 }
603
ba42b646
SW
604 s->configuration[6] |= BIT(5);
605
606 if (s->stats_size == 80) {
607 /* TODO: check TCO Statistical Counters bit. Documentation not clear. */
608 if (s->configuration[6] & BIT(2)) {
609 /* TCO statistical counters. */
610 assert(s->configuration[6] & BIT(5));
611 } else {
612 if (s->configuration[6] & BIT(5)) {
613 /* No extended statistical counters, i82557 compatible. */
614 s->stats_size = 64;
615 } else {
616 /* i82558 compatible. */
617 s->stats_size = 76;
618 }
619 }
620 } else {
621 if (s->configuration[6] & BIT(5)) {
622 /* No extended statistical counters. */
623 s->stats_size = 64;
624 }
625 }
626 assert(s->stats_size > 0 && s->stats_size <= sizeof(s->statistics));
627
628 if (power_management) {
629 /* Power Management Capabilities */
630 PCI_CONFIG_8(0xdc, 0x01);
631 /* Next Item Pointer */
632 /* Capability ID */
633 PCI_CONFIG_16(0xde, 0x7e21);
634 /* TODO: Power Management Control / Status. */
635 /* TODO: Ethernet Power Consumption Registers (i82559 and later). */
636 }
637
638#if EEPROM_SIZE > 0
663e8e51 639 if (device == i82557C || device == i82558B || device == i82559C) {
ba42b646
SW
640 // TODO: get vendor id from EEPROM for i82557C or later.
641 // TODO: get device id from EEPROM for i82557C or later.
642 // TODO: status bit 4 can be disabled by EEPROM for i82558, i82559.
643 // TODO: header type is determined by EEPROM for i82559.
644 // TODO: get subsystem id from EEPROM for i82557C or later.
645 // TODO: get subsystem vendor id from EEPROM for i82557C or later.
646 // TODO: exp. rom baddr depends on a bit in EEPROM for i82558 or later.
647 // TODO: capability pointer depends on EEPROM for i82558.
663e8e51
TS
648 logout("Get device id and revision from EEPROM!!!\n");
649 }
ba42b646 650#endif /* EEPROM_SIZE > 0 */
663e8e51
TS
651}
652
653static void nic_selective_reset(EEPRO100State * s)
654{
655 size_t i;
656 uint16_t *eeprom_contents = eeprom93xx_data(s->eeprom);
657 //~ eeprom93xx_reset(s->eeprom);
508ef936 658 memcpy(eeprom_contents, s->conf.macaddr.a, 6);
b1e87018 659 eeprom_contents[EEPROM_ID] = EEPROM_ID_VALID;
f4e94dfe
RD
660 if (s->device == i82557B || s->device == i82557C)
661 eeprom_contents[5] = 0x0100;
6cded3a4 662 eeprom_contents[EEPROM_PHY_ID] = 1;
663e8e51
TS
663 uint16_t sum = 0;
664 for (i = 0; i < EEPROM_SIZE - 1; i++) {
665 sum += eeprom_contents[i];
666 }
667 eeprom_contents[EEPROM_SIZE - 1] = 0xbaba - sum;
aac443e6 668 TRACE(EEPROM, logout("checksum=0x%04x\n", eeprom_contents[EEPROM_SIZE - 1]));
663e8e51
TS
669
670 memset(s->mem, 0, sizeof(s->mem));
671 uint32_t val = BIT(21);
672 memcpy(&s->mem[SCBCtrlMDI], &val, sizeof(val));
673
674 assert(sizeof(s->mdimem) == sizeof(eepro100_mdi_default));
675 memcpy(&s->mdimem[0], &eepro100_mdi_default[0], sizeof(s->mdimem));
676}
677
678static void nic_reset(void *opaque)
679{
769cf7a5 680 EEPRO100State *s = opaque;
aac443e6 681 TRACE(OTHER, logout("%p\n", s));
7b8737de
SW
682 /* TODO: Clearing of multicast table for selective reset, too? */
683 memset(&s->mult[0], 0, sizeof(s->mult));
663e8e51
TS
684 nic_selective_reset(s);
685}
686
687#if defined(DEBUG_EEPRO100)
b8f6ba0d 688static const char * const e100_reg[PCI_IO_SIZE / 4] = {
663e8e51
TS
689 "Command/Status",
690 "General Pointer",
691 "Port",
692 "EEPROM/Flash Control",
693 "MDI Control",
694 "Receive DMA Byte Count",
b8f6ba0d 695 "Flow Control",
663e8e51
TS
696 "General Status/Control"
697};
698
699static char *regname(uint32_t addr)
700{
ec169288 701 static char buf[32];
663e8e51 702 if (addr < PCI_IO_SIZE) {
b8f6ba0d 703 const char *r = e100_reg[addr / 4];
663e8e51 704 if (r != 0) {
41cbc23c 705 snprintf(buf, sizeof(buf), "%s+%u", r, addr % 4);
663e8e51 706 } else {
41cbc23c 707 snprintf(buf, sizeof(buf), "0x%02x", addr);
663e8e51
TS
708 }
709 } else {
41cbc23c 710 snprintf(buf, sizeof(buf), "??? 0x%08x", addr);
663e8e51
TS
711 }
712 return buf;
713}
714#endif /* DEBUG_EEPRO100 */
715
716#if 0
717static uint16_t eepro100_read_status(EEPRO100State * s)
718{
719 uint16_t val = s->status;
aac443e6 720 TRACE(OTHER, logout("val=0x%04x\n", val));
663e8e51
TS
721 return val;
722}
723
724static void eepro100_write_status(EEPRO100State * s, uint16_t val)
725{
aac443e6 726 TRACE(OTHER, logout("val=0x%04x\n", val));
663e8e51
TS
727 s->status = val;
728}
729#endif
730
731/*****************************************************************************
732 *
733 * Command emulation.
734 *
735 ****************************************************************************/
736
737#if 0
738static uint16_t eepro100_read_command(EEPRO100State * s)
739{
740 uint16_t val = 0xffff;
aac443e6 741 //~ TRACE(OTHER, logout("val=0x%04x\n", val));
663e8e51
TS
742 return val;
743}
744#endif
745
746/* Commands that can be put in a command list entry. */
747enum commands {
748 CmdNOp = 0,
749 CmdIASetup = 1,
750 CmdConfigure = 2,
751 CmdMulticastList = 3,
752 CmdTx = 4,
753 CmdTDR = 5, /* load microcode */
754 CmdDump = 6,
755 CmdDiagnose = 7,
756
757 /* And some extra flags: */
758 CmdSuspend = 0x4000, /* Suspend after completion. */
759 CmdIntr = 0x2000, /* Interrupt after completion. */
760 CmdTxFlex = 0x0008, /* Use "Flexible mode" for CmdTx command. */
761};
762
c227f099 763static cu_state_t get_cu_state(EEPRO100State * s)
663e8e51 764{
ced5296a 765 return ((s->mem[SCBStatus] & BITS(7, 6)) >> 6);
663e8e51
TS
766}
767
c227f099 768static void set_cu_state(EEPRO100State * s, cu_state_t state)
663e8e51 769{
ced5296a 770 s->mem[SCBStatus] = (s->mem[SCBStatus] & ~BITS(7, 6)) + (state << 6);
663e8e51
TS
771}
772
c227f099 773static ru_state_t get_ru_state(EEPRO100State * s)
663e8e51 774{
ced5296a 775 return ((s->mem[SCBStatus] & BITS(5, 2)) >> 2);
663e8e51
TS
776}
777
c227f099 778static void set_ru_state(EEPRO100State * s, ru_state_t state)
663e8e51 779{
ced5296a 780 s->mem[SCBStatus] = (s->mem[SCBStatus] & ~BITS(5, 2)) + (state << 2);
663e8e51
TS
781}
782
783static void dump_statistics(EEPRO100State * s)
784{
785 /* Dump statistical data. Most data is never changed by the emulation
786 * and always 0, so we first just copy the whole block and then those
787 * values which really matter.
788 * Number of data should check configuration!!!
789 */
ba42b646
SW
790 cpu_physical_memory_write(s->statsaddr,
791 (uint8_t *) & s->statistics, s->stats_size);
792 stl_le_phys(s->statsaddr + 0, s->statistics.tx_good_frames);
793 stl_le_phys(s->statsaddr + 36, s->statistics.rx_good_frames);
794 stl_le_phys(s->statsaddr + 48, s->statistics.rx_resource_errors);
795 stl_le_phys(s->statsaddr + 60, s->statistics.rx_short_frame_errors);
796 //~ stw_le_phys(s->statsaddr + 76, s->statistics.xmt_tco_frames);
797 //~ stw_le_phys(s->statsaddr + 78, s->statistics.rcv_tco_frames);
663e8e51
TS
798 //~ missing("CU dump statistical counters");
799}
800
3d0f4b9b
SW
801static void read_cb(EEPRO100State *s)
802{
803 cpu_physical_memory_read(s->cb_address, (uint8_t *) &s->tx, sizeof(s->tx));
804 s->tx.status = le16_to_cpu(s->tx.status);
805 s->tx.command = le16_to_cpu(s->tx.command);
806 s->tx.link = le32_to_cpu(s->tx.link);
807 s->tx.tbd_array_addr = le32_to_cpu(s->tx.tbd_array_addr);
808 s->tx.tcb_bytes = le16_to_cpu(s->tx.tcb_bytes);
809}
810
f3a52e50
SW
811static void tx_command(EEPRO100State *s)
812{
7b8737de 813 uint32_t tbd_array = le32_to_cpu(s->tx.tbd_array_addr);
f3a52e50
SW
814 uint16_t tcb_bytes = (le16_to_cpu(s->tx.tcb_bytes) & 0x3fff);
815 /* Sends larger than MAX_ETH_FRAME_SIZE are allowed, up to 2600 bytes. */
816 uint8_t buf[2600];
817 uint16_t size = 0;
818 uint32_t tbd_address = s->cb_address + 0x10;
819 TRACE(RXTX, logout
820 ("transmit, TBD array address 0x%08x, TCB byte count 0x%04x, TBD count %u\n",
821 tbd_array, tcb_bytes, s->tx.tbd_count));
822
823 if (tcb_bytes > 2600) {
824 logout("TCB byte count too large, using 2600\n");
825 tcb_bytes = 2600;
826 }
827 if (!((tcb_bytes > 0) || (tbd_array != 0xffffffff))) {
828 logout
829 ("illegal values of TBD array address and TCB byte count!\n");
830 }
831 assert(tcb_bytes <= sizeof(buf));
832 while (size < tcb_bytes) {
833 uint32_t tx_buffer_address = ldl_phys(tbd_address);
834 uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
835 //~ uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
836 tbd_address += 8;
837 TRACE(RXTX, logout
838 ("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",
839 tx_buffer_address, tx_buffer_size));
840 tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
841 cpu_physical_memory_read(tx_buffer_address, &buf[size],
842 tx_buffer_size);
843 size += tx_buffer_size;
844 }
845 if (tbd_array == 0xffffffff) {
846 /* Simplified mode. Was already handled by code above. */
847 } else {
848 /* Flexible mode. */
849 uint8_t tbd_count = 0;
850 if (s->has_extended_tcb_support && !(s->configuration[6] & BIT(4))) {
851 /* Extended Flexible TCB. */
852 for (; tbd_count < 2; tbd_count++) {
853 uint32_t tx_buffer_address = ldl_phys(tbd_address);
854 uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
855 uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
856 tbd_address += 8;
857 TRACE(RXTX, logout
858 ("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n",
859 tx_buffer_address, tx_buffer_size));
860 tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
861 cpu_physical_memory_read(tx_buffer_address, &buf[size],
862 tx_buffer_size);
863 size += tx_buffer_size;
864 if (tx_buffer_el & 1) {
865 break;
866 }
867 }
868 }
869 tbd_address = tbd_array;
870 for (; tbd_count < s->tx.tbd_count; tbd_count++) {
871 uint32_t tx_buffer_address = ldl_phys(tbd_address);
872 uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
873 uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
874 tbd_address += 8;
875 TRACE(RXTX, logout
876 ("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n",
877 tx_buffer_address, tx_buffer_size));
878 tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
879 cpu_physical_memory_read(tx_buffer_address, &buf[size],
880 tx_buffer_size);
881 size += tx_buffer_size;
882 if (tx_buffer_el & 1) {
883 break;
884 }
885 }
886 }
887 TRACE(RXTX, logout("%p sending frame, len=%d,%s\n", s, size, nic_dump(buf, size)));
888 qemu_send_packet(&s->nic->nc, buf, size);
889 s->statistics.tx_good_frames++;
890 /* Transmit with bad status would raise an CX/TNO interrupt.
891 * (82557 only). Emulation never has bad status. */
892 //~ eepro100_cx_interrupt(s);
893}
894
7b8737de
SW
895static void set_multicast_list(EEPRO100State *s)
896{
897 uint16_t multicast_count = s->tx.tbd_array_addr & BITS(13, 0);
898 uint16_t i;
899 memset(&s->mult[0], 0, sizeof(s->mult));
900 TRACE(OTHER, logout("multicast list, multicast count = %u\n", multicast_count));
901 for (i = 0; i < multicast_count; i += 6) {
902 uint8_t multicast_addr[6];
903 cpu_physical_memory_read(s->cb_address + 10 + i, multicast_addr, 6);
904 TRACE(OTHER, logout("multicast entry %s\n", nic_dump(multicast_addr, 6)));
905 unsigned mcast_idx = compute_mcast_idx(multicast_addr);
906 assert(mcast_idx < 64);
907 s->mult[mcast_idx >> 3] |= (1 << (mcast_idx & 7));
908 }
909}
910
5fa9a0ae 911static void action_command(EEPRO100State *s)
663e8e51 912{
5fa9a0ae 913 for (;;) {
3d0f4b9b
SW
914 bool bit_el;
915 bool bit_s;
916 bool bit_i;
917 bool bit_nc;
7f1e9d4e 918 bool success = true;
3d0f4b9b
SW
919 s->cb_address = s->cu_base + s->cu_offset;
920 read_cb(s);
921 bit_el = ((s->tx.command & COMMAND_EL) != 0);
922 bit_s = ((s->tx.command & COMMAND_S) != 0);
923 bit_i = ((s->tx.command & COMMAND_I) != 0);
924 bit_nc = ((s->tx.command & COMMAND_NC) != 0);
925#if 0
926 bool bit_sf = ((s->tx.command & COMMAND_SF) != 0);
927#endif
928 s->cu_offset = s->tx.link;
929 TRACE(OTHER,
930 logout("val=(cu start), status=0x%04x, command=0x%04x, link=0x%08x\n",
931 s->tx.status, s->tx.command, s->tx.link));
932 switch (s->tx.command & COMMAND_CMD) {
663e8e51
TS
933 case CmdNOp:
934 /* Do nothing. */
935 break;
936 case CmdIASetup:
f3a52e50 937 cpu_physical_memory_read(s->cb_address + 8, &s->conf.macaddr.a[0], 6);
ce0e58b3 938 TRACE(OTHER, logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6)));
663e8e51
TS
939 break;
940 case CmdConfigure:
f3a52e50 941 cpu_physical_memory_read(s->cb_address + 8, &s->configuration[0],
663e8e51 942 sizeof(s->configuration));
aac443e6 943 TRACE(OTHER, logout("configuration: %s\n", nic_dump(&s->configuration[0], 16)));
663e8e51
TS
944 break;
945 case CmdMulticastList:
7b8737de 946 set_multicast_list(s);
663e8e51
TS
947 break;
948 case CmdTx:
7f1e9d4e
KW
949 if (bit_nc) {
950 missing("CmdTx: NC = 0");
951 success = false;
952 break;
953 }
f3a52e50 954 tx_command(s);
663e8e51
TS
955 break;
956 case CmdTDR:
aac443e6 957 TRACE(OTHER, logout("load microcode\n"));
663e8e51
TS
958 /* Starting with offset 8, the command contains
959 * 64 dwords microcode which we just ignore here. */
960 break;
f80a7fc3
SW
961 case CmdDiagnose:
962 TRACE(OTHER, logout("diagnose\n"));
963 /* Make sure error flag is not set. */
964 s->tx.status = 0;
965 break;
663e8e51
TS
966 default:
967 missing("undefined command");
7f1e9d4e
KW
968 success = false;
969 break;
663e8e51 970 }
7f1e9d4e 971 /* Write new status. */
ec1d02d8 972 stw_phys(s->cb_address, s->tx.status | STATUS_C | (success ? STATUS_OK : 0));
663e8e51
TS
973 if (bit_i) {
974 /* CU completed action. */
975 eepro100_cx_interrupt(s);
976 }
977 if (bit_el) {
aac443e6 978 /* CU becomes idle. Terminate command loop. */
663e8e51
TS
979 set_cu_state(s, cu_idle);
980 eepro100_cna_interrupt(s);
5fa9a0ae 981 break;
663e8e51 982 } else if (bit_s) {
5fa9a0ae 983 /* CU becomes suspended. Terminate command loop. */
663e8e51
TS
984 set_cu_state(s, cu_suspended);
985 eepro100_cna_interrupt(s);
5fa9a0ae 986 break;
663e8e51
TS
987 } else {
988 /* More entries in list. */
aac443e6 989 TRACE(OTHER, logout("CU list with at least one more entry\n"));
663e8e51 990 }
5fa9a0ae
SW
991 }
992 TRACE(OTHER, logout("CU list empty\n"));
993 /* List is empty. Now CU is idle or suspended. */
994}
995
996static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
997{
cb25a3fb 998 cu_state_t cu_state;
5fa9a0ae
SW
999 switch (val) {
1000 case CU_NOP:
1001 /* No operation. */
1002 break;
1003 case CU_START:
cb25a3fb
SW
1004 cu_state = get_cu_state(s);
1005 if (cu_state != cu_idle && cu_state != cu_suspended) {
1006 /* Intel documentation says that CU must be idle or suspended
1007 * for the CU start command. */
1008 logout("unexpected CU state is %u\n", cu_state);
5fa9a0ae
SW
1009 }
1010 set_cu_state(s, cu_active);
1011 s->cu_offset = s->pointer;
1012 action_command(s);
663e8e51
TS
1013 break;
1014 case CU_RESUME:
1015 if (get_cu_state(s) != cu_suspended) {
1016 logout("bad CU resume from CU state %u\n", get_cu_state(s));
1017 /* Workaround for bad Linux eepro100 driver which resumes
1018 * from idle state. */
1019 //~ missing("cu resume");
1020 set_cu_state(s, cu_suspended);
1021 }
1022 if (get_cu_state(s) == cu_suspended) {
aac443e6 1023 TRACE(OTHER, logout("CU resuming\n"));
663e8e51 1024 set_cu_state(s, cu_active);
5fa9a0ae 1025 action_command(s);
663e8e51
TS
1026 }
1027 break;
1028 case CU_STATSADDR:
1029 /* Load dump counters address. */
1030 s->statsaddr = s->pointer;
aac443e6 1031 TRACE(OTHER, logout("val=0x%02x (status address)\n", val));
663e8e51
TS
1032 break;
1033 case CU_SHOWSTATS:
1034 /* Dump statistical counters. */
aac443e6 1035 TRACE(OTHER, logout("val=0x%02x (dump stats)\n", val));
663e8e51 1036 dump_statistics(s);
ba42b646 1037 stl_le_phys(s->statsaddr + s->stats_size, 0xa005);
663e8e51
TS
1038 break;
1039 case CU_CMD_BASE:
1040 /* Load CU base. */
aac443e6 1041 TRACE(OTHER, logout("val=0x%02x (CU base address)\n", val));
663e8e51
TS
1042 s->cu_base = s->pointer;
1043 break;
1044 case CU_DUMPSTATS:
1045 /* Dump and reset statistical counters. */
aac443e6 1046 TRACE(OTHER, logout("val=0x%02x (dump stats and reset)\n", val));
663e8e51 1047 dump_statistics(s);
ba42b646 1048 stl_le_phys(s->statsaddr + s->stats_size, 0xa007);
663e8e51
TS
1049 memset(&s->statistics, 0, sizeof(s->statistics));
1050 break;
1051 case CU_SRESUME:
1052 /* CU static resume. */
1053 missing("CU static resume");
1054 break;
1055 default:
1056 missing("Undefined CU command");
1057 }
1058}
1059
1060static void eepro100_ru_command(EEPRO100State * s, uint8_t val)
1061{
1062 switch (val) {
1063 case RU_NOP:
1064 /* No operation. */
1065 break;
1066 case RX_START:
1067 /* RU start. */
1068 if (get_ru_state(s) != ru_idle) {
1069 logout("RU state is %u, should be %u\n", get_ru_state(s), ru_idle);
1070 //~ assert(!"wrong RU state");
1071 }
1072 set_ru_state(s, ru_ready);
1073 s->ru_offset = s->pointer;
aac443e6 1074 TRACE(OTHER, logout("val=0x%02x (rx start)\n", val));
663e8e51
TS
1075 break;
1076 case RX_RESUME:
1077 /* Restart RU. */
1078 if (get_ru_state(s) != ru_suspended) {
1079 logout("RU state is %u, should be %u\n", get_ru_state(s),
1080 ru_suspended);
1081 //~ assert(!"wrong RU state");
1082 }
1083 set_ru_state(s, ru_ready);
1084 break;
e824012b
SW
1085 case RU_ABORT:
1086 /* RU abort. */
1087 if (get_ru_state(s) == ru_ready) {
1088 eepro100_rnr_interrupt(s);
1089 }
1090 set_ru_state(s, ru_idle);
1091 break;
663e8e51
TS
1092 case RX_ADDR_LOAD:
1093 /* Load RU base. */
aac443e6 1094 TRACE(OTHER, logout("val=0x%02x (RU base address)\n", val));
663e8e51
TS
1095 s->ru_base = s->pointer;
1096 break;
1097 default:
1098 logout("val=0x%02x (undefined RU command)\n", val);
1099 missing("Undefined SU command");
1100 }
1101}
1102
1103static void eepro100_write_command(EEPRO100State * s, uint8_t val)
1104{
1105 eepro100_ru_command(s, val & 0x0f);
1106 eepro100_cu_command(s, val & 0xf0);
1107 if ((val) == 0) {
aac443e6 1108 TRACE(OTHER, logout("val=0x%02x\n", val));
663e8e51
TS
1109 }
1110 /* Clear command byte after command was accepted. */
1111 s->mem[SCBCmd] = 0;
1112}
1113
1114/*****************************************************************************
1115 *
1116 * EEPROM emulation.
1117 *
1118 ****************************************************************************/
1119
1120#define EEPROM_CS 0x02
1121#define EEPROM_SK 0x01
1122#define EEPROM_DI 0x04
1123#define EEPROM_DO 0x08
1124
1125static uint16_t eepro100_read_eeprom(EEPRO100State * s)
1126{
1127 uint16_t val;
1128 memcpy(&val, &s->mem[SCBeeprom], sizeof(val));
1129 if (eeprom93xx_read(s->eeprom)) {
1130 val |= EEPROM_DO;
1131 } else {
1132 val &= ~EEPROM_DO;
1133 }
aac443e6 1134 TRACE(EEPROM, logout("val=0x%04x\n", val));
663e8e51
TS
1135 return val;
1136}
1137
c227f099 1138static void eepro100_write_eeprom(eeprom_t * eeprom, uint8_t val)
663e8e51 1139{
aac443e6 1140 TRACE(EEPROM, logout("val=0x%02x\n", val));
663e8e51
TS
1141
1142 /* mask unwriteable bits */
1143 //~ val = SET_MASKED(val, 0x31, eeprom->value);
1144
1145 int eecs = ((val & EEPROM_CS) != 0);
1146 int eesk = ((val & EEPROM_SK) != 0);
1147 int eedi = ((val & EEPROM_DI) != 0);
1148 eeprom93xx_write(eeprom, eecs, eesk, eedi);
1149}
1150
1151static void eepro100_write_pointer(EEPRO100State * s, uint32_t val)
1152{
1153 s->pointer = le32_to_cpu(val);
aac443e6 1154 TRACE(OTHER, logout("val=0x%08x\n", val));
663e8e51
TS
1155}
1156
1157/*****************************************************************************
1158 *
1159 * MDI emulation.
1160 *
1161 ****************************************************************************/
1162
1163#if defined(DEBUG_EEPRO100)
6a0b9cc9 1164static const char * const mdi_op_name[] = {
663e8e51
TS
1165 "opcode 0",
1166 "write",
1167 "read",
1168 "opcode 3"
1169};
1170
6a0b9cc9 1171static const char * const mdi_reg_name[] = {
663e8e51
TS
1172 "Control",
1173 "Status",
1174 "PHY Identification (Word 1)",
1175 "PHY Identification (Word 2)",
1176 "Auto-Negotiation Advertisement",
1177 "Auto-Negotiation Link Partner Ability",
1178 "Auto-Negotiation Expansion"
1179};
aac443e6
SW
1180
1181static const char *reg2name(uint8_t reg)
1182{
1183 static char buffer[10];
1184 const char *p = buffer;
1185 if (reg < ARRAY_SIZE(mdi_reg_name)) {
1186 p = mdi_reg_name[reg];
1187 } else {
1188 snprintf(buffer, sizeof(buffer), "reg=0x%02x", reg);
1189 }
1190 return p;
1191}
663e8e51
TS
1192#endif /* DEBUG_EEPRO100 */
1193
1194static uint32_t eepro100_read_mdi(EEPRO100State * s)
1195{
1196 uint32_t val;
1197 memcpy(&val, &s->mem[0x10], sizeof(val));
1198
1199#ifdef DEBUG_EEPRO100
1200 uint8_t raiseint = (val & BIT(29)) >> 29;
1201 uint8_t opcode = (val & BITS(27, 26)) >> 26;
1202 uint8_t phy = (val & BITS(25, 21)) >> 21;
1203 uint8_t reg = (val & BITS(20, 16)) >> 16;
1204 uint16_t data = (val & BITS(15, 0));
1205#endif
1206 /* Emulation takes no time to finish MDI transaction. */
1207 val |= BIT(28);
1208 TRACE(MDI, logout("val=0x%08x (int=%u, %s, phy=%u, %s, data=0x%04x\n",
1209 val, raiseint, mdi_op_name[opcode], phy,
aac443e6 1210 reg2name(reg), data));
663e8e51
TS
1211 return val;
1212}
1213
663e8e51
TS
1214static void eepro100_write_mdi(EEPRO100State * s, uint32_t val)
1215{
1216 uint8_t raiseint = (val & BIT(29)) >> 29;
1217 uint8_t opcode = (val & BITS(27, 26)) >> 26;
1218 uint8_t phy = (val & BITS(25, 21)) >> 21;
1219 uint8_t reg = (val & BITS(20, 16)) >> 16;
1220 uint16_t data = (val & BITS(15, 0));
aac443e6
SW
1221 TRACE(MDI, logout("val=0x%08x (int=%u, %s, phy=%u, %s, data=0x%04x\n",
1222 val, raiseint, mdi_op_name[opcode], phy, reg2name(reg), data));
663e8e51
TS
1223 if (phy != 1) {
1224 /* Unsupported PHY address. */
1225 //~ logout("phy must be 1 but is %u\n", phy);
1226 data = 0;
1227 } else if (opcode != 1 && opcode != 2) {
1228 /* Unsupported opcode. */
1229 logout("opcode must be 1 or 2 but is %u\n", opcode);
1230 data = 0;
1231 } else if (reg > 6) {
1232 /* Unsupported register. */
1233 logout("register must be 0...6 but is %u\n", reg);
1234 data = 0;
1235 } else {
1236 TRACE(MDI, logout("val=0x%08x (int=%u, %s, phy=%u, %s, data=0x%04x\n",
1237 val, raiseint, mdi_op_name[opcode], phy,
aac443e6 1238 reg2name(reg), data));
663e8e51
TS
1239 if (opcode == 1) {
1240 /* MDI write */
1241 switch (reg) {
1242 case 0: /* Control Register */
1243 if (data & 0x8000) {
1244 /* Reset status and control registers to default. */
1245 s->mdimem[0] = eepro100_mdi_default[0];
1246 s->mdimem[1] = eepro100_mdi_default[1];
1247 data = s->mdimem[reg];
1248 } else {
1249 /* Restart Auto Configuration = Normal Operation */
1250 data &= ~0x0200;
1251 }
1252 break;
1253 case 1: /* Status Register */
1254 missing("not writable");
1255 data = s->mdimem[reg];
1256 break;
1257 case 2: /* PHY Identification Register (Word 1) */
1258 case 3: /* PHY Identification Register (Word 2) */
1259 missing("not implemented");
1260 break;
1261 case 4: /* Auto-Negotiation Advertisement Register */
1262 case 5: /* Auto-Negotiation Link Partner Ability Register */
1263 break;
1264 case 6: /* Auto-Negotiation Expansion Register */
1265 default:
1266 missing("not implemented");
1267 }
1268 s->mdimem[reg] = data;
1269 } else if (opcode == 2) {
1270 /* MDI read */
1271 switch (reg) {
1272 case 0: /* Control Register */
1273 if (data & 0x8000) {
1274 /* Reset status and control registers to default. */
1275 s->mdimem[0] = eepro100_mdi_default[0];
1276 s->mdimem[1] = eepro100_mdi_default[1];
1277 }
1278 break;
1279 case 1: /* Status Register */
1280 s->mdimem[reg] |= 0x0020;
1281 break;
1282 case 2: /* PHY Identification Register (Word 1) */
1283 case 3: /* PHY Identification Register (Word 2) */
1284 case 4: /* Auto-Negotiation Advertisement Register */
1285 break;
1286 case 5: /* Auto-Negotiation Link Partner Ability Register */
1287 s->mdimem[reg] = 0x41fe;
1288 break;
1289 case 6: /* Auto-Negotiation Expansion Register */
1290 s->mdimem[reg] = 0x0001;
1291 break;
1292 }
1293 data = s->mdimem[reg];
1294 }
1295 /* Emulation takes no time to finish MDI transaction.
1296 * Set MDI bit in SCB status register. */
1297 s->mem[SCBAck] |= 0x08;
1298 val |= BIT(28);
1299 if (raiseint) {
1300 eepro100_mdi_interrupt(s);
1301 }
1302 }
1303 val = (val & 0xffff0000) + data;
1304 memcpy(&s->mem[0x10], &val, sizeof(val));
1305}
1306
1307/*****************************************************************************
1308 *
1309 * Port emulation.
1310 *
1311 ****************************************************************************/
1312
1313#define PORT_SOFTWARE_RESET 0
1314#define PORT_SELFTEST 1
1315#define PORT_SELECTIVE_RESET 2
1316#define PORT_DUMP 3
1317#define PORT_SELECTION_MASK 3
1318
1319typedef struct {
1320 uint32_t st_sign; /* Self Test Signature */
1321 uint32_t st_result; /* Self Test Results */
c227f099 1322} eepro100_selftest_t;
663e8e51
TS
1323
1324static uint32_t eepro100_read_port(EEPRO100State * s)
1325{
1326 return 0;
1327}
1328
1329static void eepro100_write_port(EEPRO100State * s, uint32_t val)
1330{
1331 val = le32_to_cpu(val);
1332 uint32_t address = (val & ~PORT_SELECTION_MASK);
1333 uint8_t selection = (val & PORT_SELECTION_MASK);
1334 switch (selection) {
1335 case PORT_SOFTWARE_RESET:
1336 nic_reset(s);
1337 break;
1338 case PORT_SELFTEST:
aac443e6 1339 TRACE(OTHER, logout("selftest address=0x%08x\n", address));
c227f099 1340 eepro100_selftest_t data;
663e8e51
TS
1341 cpu_physical_memory_read(address, (uint8_t *) & data, sizeof(data));
1342 data.st_sign = 0xffffffff;
1343 data.st_result = 0;
1344 cpu_physical_memory_write(address, (uint8_t *) & data, sizeof(data));
1345 break;
1346 case PORT_SELECTIVE_RESET:
aac443e6 1347 TRACE(OTHER, logout("selective reset, selftest address=0x%08x\n", address));
663e8e51
TS
1348 nic_selective_reset(s);
1349 break;
1350 default:
1351 logout("val=0x%08x\n", val);
1352 missing("unknown port selection");
1353 }
1354}
1355
1356/*****************************************************************************
1357 *
1358 * General hardware emulation.
1359 *
1360 ****************************************************************************/
1361
1362static uint8_t eepro100_read1(EEPRO100State * s, uint32_t addr)
1363{
1364 uint8_t val;
1365 if (addr <= sizeof(s->mem) - sizeof(val)) {
1366 memcpy(&val, &s->mem[addr], sizeof(val));
1367 }
1368
1369 switch (addr) {
1370 case SCBStatus:
1371 //~ val = eepro100_read_status(s);
aac443e6 1372 TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
663e8e51
TS
1373 break;
1374 case SCBAck:
1375 //~ val = eepro100_read_status(s);
aac443e6 1376 TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
663e8e51
TS
1377 break;
1378 case SCBCmd:
aac443e6 1379 TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
663e8e51
TS
1380 //~ val = eepro100_read_command(s);
1381 break;
1382 case SCBIntmask:
aac443e6 1383 TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
663e8e51
TS
1384 break;
1385 case SCBPort + 3:
aac443e6 1386 TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
663e8e51
TS
1387 break;
1388 case SCBeeprom:
1389 val = eepro100_read_eeprom(s);
1390 break;
0908bba1 1391 case SCBpmdr: /* Power Management Driver Register */
663e8e51 1392 val = 0;
aac443e6 1393 TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
663e8e51 1394 break;
0908bba1 1395 case SCBgstat: /* General Status Register */
663e8e51
TS
1396 /* 100 Mbps full duplex, valid link */
1397 val = 0x07;
aac443e6 1398 TRACE(OTHER, logout("addr=General Status val=%02x\n", val));
663e8e51
TS
1399 break;
1400 default:
1401 logout("addr=%s val=0x%02x\n", regname(addr), val);
1402 missing("unknown byte read");
1403 }
1404 return val;
1405}
1406
1407static uint16_t eepro100_read2(EEPRO100State * s, uint32_t addr)
1408{
1409 uint16_t val;
1410 if (addr <= sizeof(s->mem) - sizeof(val)) {
1411 memcpy(&val, &s->mem[addr], sizeof(val));
1412 }
1413
663e8e51
TS
1414 switch (addr) {
1415 case SCBStatus:
1416 //~ val = eepro100_read_status(s);
dbbaaff6 1417 case SCBCmd:
aac443e6 1418 TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
663e8e51
TS
1419 break;
1420 case SCBeeprom:
1421 val = eepro100_read_eeprom(s);
aac443e6 1422 TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
663e8e51
TS
1423 break;
1424 default:
1425 logout("addr=%s val=0x%04x\n", regname(addr), val);
1426 missing("unknown word read");
1427 }
1428 return val;
1429}
1430
1431static uint32_t eepro100_read4(EEPRO100State * s, uint32_t addr)
1432{
1433 uint32_t val;
1434 if (addr <= sizeof(s->mem) - sizeof(val)) {
1435 memcpy(&val, &s->mem[addr], sizeof(val));
1436 }
1437
1438 switch (addr) {
1439 case SCBStatus:
1440 //~ val = eepro100_read_status(s);
aac443e6 1441 TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
663e8e51
TS
1442 break;
1443 case SCBPointer:
1444 //~ val = eepro100_read_pointer(s);
aac443e6 1445 TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
663e8e51
TS
1446 break;
1447 case SCBPort:
1448 val = eepro100_read_port(s);
aac443e6 1449 TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
663e8e51
TS
1450 break;
1451 case SCBCtrlMDI:
1452 val = eepro100_read_mdi(s);
1453 break;
1454 default:
1455 logout("addr=%s val=0x%08x\n", regname(addr), val);
1456 missing("unknown longword read");
1457 }
1458 return val;
1459}
1460
1461static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val)
1462{
1463 if (addr <= sizeof(s->mem) - sizeof(val)) {
1464 memcpy(&s->mem[addr], &val, sizeof(val));
1465 }
1466
aac443e6 1467 TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
663e8e51
TS
1468
1469 switch (addr) {
1470 case SCBStatus:
1471 //~ eepro100_write_status(s, val);
1472 break;
1473 case SCBAck:
1474 eepro100_acknowledge(s);
1475 break;
1476 case SCBCmd:
1477 eepro100_write_command(s, val);
1478 break;
1479 case SCBIntmask:
1480 if (val & BIT(1)) {
1481 eepro100_swi_interrupt(s);
1482 }
1483 eepro100_interrupt(s, 0);
1484 break;
1485 case SCBPort + 3:
aac443e6 1486 case SCBFlow: /* does not exist on 82557 */
3257d2b6
TS
1487 case SCBFlow + 1:
1488 case SCBFlow + 2:
0908bba1 1489 case SCBpmdr: /* does not exist on 82557 */
aac443e6 1490 TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
663e8e51
TS
1491 break;
1492 case SCBeeprom:
1493 eepro100_write_eeprom(s->eeprom, val);
1494 break;
1495 default:
1496 logout("addr=%s val=0x%02x\n", regname(addr), val);
1497 missing("unknown byte write");
1498 }
1499}
1500
1501static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val)
1502{
1503 if (addr <= sizeof(s->mem) - sizeof(val)) {
1504 memcpy(&s->mem[addr], &val, sizeof(val));
1505 }
1506
aac443e6 1507 TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
663e8e51
TS
1508
1509 switch (addr) {
1510 case SCBStatus:
1511 //~ eepro100_write_status(s, val);
1512 eepro100_acknowledge(s);
1513 break;
1514 case SCBCmd:
1515 eepro100_write_command(s, val);
1516 eepro100_write1(s, SCBIntmask, val >> 8);
1517 break;
1518 case SCBeeprom:
1519 eepro100_write_eeprom(s->eeprom, val);
1520 break;
1521 default:
1522 logout("addr=%s val=0x%04x\n", regname(addr), val);
1523 missing("unknown word write");
1524 }
1525}
1526
1527static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val)
1528{
1529 if (addr <= sizeof(s->mem) - sizeof(val)) {
1530 memcpy(&s->mem[addr], &val, sizeof(val));
1531 }
1532
1533 switch (addr) {
1534 case SCBPointer:
1535 eepro100_write_pointer(s, val);
1536 break;
1537 case SCBPort:
aac443e6 1538 TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
663e8e51
TS
1539 eepro100_write_port(s, val);
1540 break;
1541 case SCBCtrlMDI:
1542 eepro100_write_mdi(s, val);
1543 break;
1544 default:
1545 logout("addr=%s val=0x%08x\n", regname(addr), val);
1546 missing("unknown longword write");
1547 }
1548}
1549
aac443e6
SW
1550/*****************************************************************************
1551 *
1552 * Port mapped I/O.
1553 *
1554 ****************************************************************************/
1555
663e8e51
TS
1556static uint32_t ioport_read1(void *opaque, uint32_t addr)
1557{
1558 EEPRO100State *s = opaque;
1559 //~ logout("addr=%s\n", regname(addr));
1560 return eepro100_read1(s, addr - s->region[1]);
1561}
1562
1563static uint32_t ioport_read2(void *opaque, uint32_t addr)
1564{
1565 EEPRO100State *s = opaque;
1566 return eepro100_read2(s, addr - s->region[1]);
1567}
1568
1569static uint32_t ioport_read4(void *opaque, uint32_t addr)
1570{
1571 EEPRO100State *s = opaque;
1572 return eepro100_read4(s, addr - s->region[1]);
1573}
1574
1575static void ioport_write1(void *opaque, uint32_t addr, uint32_t val)
1576{
1577 EEPRO100State *s = opaque;
1578 //~ logout("addr=%s val=0x%02x\n", regname(addr), val);
1579 eepro100_write1(s, addr - s->region[1], val);
1580}
1581
1582static void ioport_write2(void *opaque, uint32_t addr, uint32_t val)
1583{
1584 EEPRO100State *s = opaque;
1585 eepro100_write2(s, addr - s->region[1], val);
1586}
1587
1588static void ioport_write4(void *opaque, uint32_t addr, uint32_t val)
1589{
1590 EEPRO100State *s = opaque;
1591 eepro100_write4(s, addr - s->region[1], val);
1592}
1593
1594/***********************************************************/
1595/* PCI EEPRO100 definitions */
1596
663e8e51 1597static void pci_map(PCIDevice * pci_dev, int region_num,
6e355d90 1598 pcibus_t addr, pcibus_t size, int type)
663e8e51 1599{
273a2142 1600 EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
663e8e51 1601
89e8b13c
IY
1602 TRACE(OTHER, logout("region %d, addr=0x%08"FMT_PCIBUS", "
1603 "size=0x%08"FMT_PCIBUS", type=%d\n",
aac443e6 1604 region_num, addr, size, type));
663e8e51
TS
1605
1606 assert(region_num == 1);
1607 register_ioport_write(addr, size, 1, ioport_write1, s);
1608 register_ioport_read(addr, size, 1, ioport_read1, s);
1609 register_ioport_write(addr, size, 2, ioport_write2, s);
1610 register_ioport_read(addr, size, 2, ioport_read2, s);
1611 register_ioport_write(addr, size, 4, ioport_write4, s);
1612 register_ioport_read(addr, size, 4, ioport_read4, s);
1613
1614 s->region[region_num] = addr;
1615}
1616
aac443e6
SW
1617/*****************************************************************************
1618 *
1619 * Memory mapped I/O.
1620 *
1621 ****************************************************************************/
1622
c227f099 1623static void pci_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
663e8e51
TS
1624{
1625 EEPRO100State *s = opaque;
663e8e51
TS
1626 //~ logout("addr=%s val=0x%02x\n", regname(addr), val);
1627 eepro100_write1(s, addr, val);
1628}
1629
c227f099 1630static void pci_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
663e8e51
TS
1631{
1632 EEPRO100State *s = opaque;
663e8e51
TS
1633 //~ logout("addr=%s val=0x%02x\n", regname(addr), val);
1634 eepro100_write2(s, addr, val);
1635}
1636
c227f099 1637static void pci_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
663e8e51
TS
1638{
1639 EEPRO100State *s = opaque;
663e8e51
TS
1640 //~ logout("addr=%s val=0x%02x\n", regname(addr), val);
1641 eepro100_write4(s, addr, val);
1642}
1643
c227f099 1644static uint32_t pci_mmio_readb(void *opaque, target_phys_addr_t addr)
663e8e51
TS
1645{
1646 EEPRO100State *s = opaque;
663e8e51
TS
1647 //~ logout("addr=%s\n", regname(addr));
1648 return eepro100_read1(s, addr);
1649}
1650
c227f099 1651static uint32_t pci_mmio_readw(void *opaque, target_phys_addr_t addr)
663e8e51
TS
1652{
1653 EEPRO100State *s = opaque;
663e8e51
TS
1654 //~ logout("addr=%s\n", regname(addr));
1655 return eepro100_read2(s, addr);
1656}
1657
c227f099 1658static uint32_t pci_mmio_readl(void *opaque, target_phys_addr_t addr)
663e8e51
TS
1659{
1660 EEPRO100State *s = opaque;
663e8e51
TS
1661 //~ logout("addr=%s\n", regname(addr));
1662 return eepro100_read4(s, addr);
1663}
1664
d60efc6b 1665static CPUWriteMemoryFunc * const pci_mmio_write[] = {
663e8e51
TS
1666 pci_mmio_writeb,
1667 pci_mmio_writew,
1668 pci_mmio_writel
1669};
1670
d60efc6b 1671static CPUReadMemoryFunc * const pci_mmio_read[] = {
663e8e51
TS
1672 pci_mmio_readb,
1673 pci_mmio_readw,
1674 pci_mmio_readl
1675};
1676
1677static void pci_mmio_map(PCIDevice * pci_dev, int region_num,
6e355d90 1678 pcibus_t addr, pcibus_t size, int type)
663e8e51 1679{
273a2142 1680 EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
663e8e51 1681
89e8b13c
IY
1682 TRACE(OTHER, logout("region %d, addr=0x%08"FMT_PCIBUS", "
1683 "size=0x%08"FMT_PCIBUS", type=%d\n",
aac443e6 1684 region_num, addr, size, type));
663e8e51
TS
1685
1686 if (region_num == 0) {
1687 /* Map control / status registers. */
273a2142
JQ
1688 cpu_register_physical_memory(addr, size, s->mmio_index);
1689 s->region[region_num] = addr;
663e8e51
TS
1690 }
1691}
1692
e00e365e 1693static int nic_can_receive(VLANClientState *nc)
663e8e51 1694{
e00e365e 1695 EEPRO100State *s = DO_UPCAST(NICState, nc, nc)->opaque;
aac443e6 1696 TRACE(RXTX, logout("%p\n", s));
663e8e51
TS
1697 return get_ru_state(s) == ru_ready;
1698 //~ return !eepro100_buffer_full(s);
1699}
1700
e00e365e 1701static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size)
663e8e51
TS
1702{
1703 /* TODO:
1704 * - Magic packets should set bit 30 in power management driver register.
1705 * - Interesting packets should set bit 29 in power management driver register.
1706 */
e00e365e 1707 EEPRO100State *s = DO_UPCAST(NICState, nc, nc)->opaque;
663e8e51
TS
1708 uint16_t rfd_status = 0xa000;
1709 static const uint8_t broadcast_macaddr[6] =
1710 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1711
1712 /* TODO: check multiple IA bit. */
7f1e9d4e
KW
1713 if (s->configuration[20] & BIT(6)) {
1714 missing("Multiple IA bit");
1715 return -1;
1716 }
663e8e51
TS
1717
1718 if (s->configuration[8] & 0x80) {
1719 /* CSMA is disabled. */
1720 logout("%p received while CSMA is disabled\n", s);
4f1c942b 1721 return -1;
ced5296a 1722 } else if (size < 64 && (s->configuration[7] & BIT(0))) {
663e8e51
TS
1723 /* Short frame and configuration byte 7/0 (discard short receive) set:
1724 * Short frame is discarded */
067d01de 1725 logout("%p received short frame (%zu byte)\n", s, size);
663e8e51 1726 s->statistics.rx_short_frame_errors++;
4f1c942b 1727 //~ return -1;
ced5296a 1728 } else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & BIT(3))) {
663e8e51
TS
1729 /* Long frame and configuration byte 18/3 (long receive ok) not set:
1730 * Long frames are discarded. */
067d01de 1731 logout("%p received long frame (%zu byte), ignored\n", s, size);
4f1c942b 1732 return -1;
508ef936 1733 } else if (memcmp(buf, s->conf.macaddr.a, 6) == 0) { // !!!
663e8e51
TS
1734 /* Frame matches individual address. */
1735 /* TODO: check configuration byte 15/4 (ignore U/L). */
067d01de 1736 TRACE(RXTX, logout("%p received frame for me, len=%zu\n", s, size));
663e8e51
TS
1737 } else if (memcmp(buf, broadcast_macaddr, 6) == 0) {
1738 /* Broadcast frame. */
067d01de 1739 TRACE(RXTX, logout("%p received broadcast, len=%zu\n", s, size));
663e8e51 1740 rfd_status |= 0x0002;
7b8737de 1741 } else if (buf[0] & 0x01) {
663e8e51 1742 /* Multicast frame. */
7b8737de 1743 TRACE(RXTX, logout("%p received multicast, len=%zu,%s\n", s, size, nic_dump(buf, size)));
7f1e9d4e 1744 if (s->configuration[21] & BIT(3)) {
7b8737de
SW
1745 /* Multicast all bit is set, receive all multicast frames. */
1746 } else {
1747 unsigned mcast_idx = compute_mcast_idx(buf);
1748 assert(mcast_idx < 64);
1749 if (s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))) {
1750 /* Multicast frame is allowed in hash table. */
ced5296a 1751 } else if (s->configuration[15] & BIT(0)) {
7b8737de
SW
1752 /* Promiscuous: receive all. */
1753 rfd_status |= 0x0004;
1754 } else {
1755 TRACE(RXTX, logout("%p multicast ignored\n", s));
1756 return -1;
1757 }
663e8e51 1758 }
7b8737de 1759 /* TODO: Next not for promiscuous mode? */
663e8e51 1760 rfd_status |= 0x0002;
ced5296a 1761 } else if (s->configuration[15] & BIT(0)) {
663e8e51 1762 /* Promiscuous: receive all. */
067d01de 1763 TRACE(RXTX, logout("%p received frame in promiscuous mode, len=%zu\n", s, size));
663e8e51
TS
1764 rfd_status |= 0x0004;
1765 } else {
067d01de 1766 TRACE(RXTX, logout("%p received frame, ignored, len=%zu,%s\n", s, size,
aac443e6 1767 nic_dump(buf, size)));
4f1c942b 1768 return size;
663e8e51
TS
1769 }
1770
1771 if (get_ru_state(s) != ru_ready) {
aac443e6
SW
1772 /* No resources available. */
1773 logout("no resources, state=%u\n", get_ru_state(s));
e824012b
SW
1774 /* TODO: RNR interrupt only at first failed frame? */
1775 eepro100_rnr_interrupt(s);
663e8e51 1776 s->statistics.rx_resource_errors++;
aac443e6 1777 //~ assert(!"no resources");
4f1c942b 1778 return -1;
663e8e51
TS
1779 }
1780 //~ !!!
1781//~ $3 = {status = 0x0, command = 0xc000, link = 0x2d220, rx_buf_addr = 0x207dc, count = 0x0, size = 0x5f8, packet = {0x0 <repeats 1518 times>}}
c227f099 1782 eepro100_rx_t rx;
663e8e51 1783 cpu_physical_memory_read(s->ru_base + s->ru_offset, (uint8_t *) & rx,
c227f099 1784 offsetof(eepro100_rx_t, packet));
663e8e51
TS
1785 uint16_t rfd_command = le16_to_cpu(rx.command);
1786 uint16_t rfd_size = le16_to_cpu(rx.size);
7f1e9d4e
KW
1787
1788 if (size > rfd_size) {
1789 logout("Receive buffer (%" PRId16 " bytes) too small for data "
1790 "(%zu bytes); data truncated\n", rfd_size, size);
1791 size = rfd_size;
1792 }
663e8e51
TS
1793 if (size < 64) {
1794 rfd_status |= 0x0080;
1795 }
aac443e6
SW
1796 TRACE(OTHER, logout("command 0x%04x, link 0x%08x, addr 0x%08x, size %u\n",
1797 rfd_command, rx.link, rx.rx_buf_addr, rfd_size));
c227f099 1798 stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, status),
663e8e51 1799 rfd_status);
c227f099 1800 stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, count), size);
663e8e51
TS
1801 /* Early receive interrupt not supported. */
1802 //~ eepro100_er_interrupt(s);
1803 /* Receive CRC Transfer not supported. */
ced5296a 1804 if (s->configuration[18] & BIT(2)) {
7f1e9d4e
KW
1805 missing("Receive CRC Transfer");
1806 return -1;
1807 }
663e8e51 1808 /* TODO: check stripping enable bit. */
ced5296a 1809 //~ assert(!(s->configuration[17] & BIT(0)));
663e8e51 1810 cpu_physical_memory_write(s->ru_base + s->ru_offset +
c227f099 1811 offsetof(eepro100_rx_t, packet), buf, size);
663e8e51
TS
1812 s->statistics.rx_good_frames++;
1813 eepro100_fr_interrupt(s);
1814 s->ru_offset = le32_to_cpu(rx.link);
ced5296a 1815 if (rfd_command & COMMAND_EL) {
663e8e51 1816 /* EL bit is set, so this was the last frame. */
7f1e9d4e
KW
1817 logout("receive: Running out of frames\n");
1818 set_ru_state(s, ru_suspended);
663e8e51 1819 }
ced5296a 1820 if (rfd_command & COMMAND_S) {
663e8e51
TS
1821 /* S bit is set. */
1822 set_ru_state(s, ru_suspended);
1823 }
4f1c942b 1824 return size;
663e8e51
TS
1825}
1826
151b2986
JQ
1827static const VMStateDescription vmstate_eepro100 = {
1828 .version_id = 3,
1829 .minimum_version_id = 2,
1830 .minimum_version_id_old = 2,
1831 .fields = (VMStateField []) {
1832 VMSTATE_PCI_DEVICE(dev, EEPRO100State),
1833 VMSTATE_UNUSED(32),
1834 VMSTATE_BUFFER(mult, EEPRO100State),
1835 VMSTATE_BUFFER(mem, EEPRO100State),
1836 /* Save all members of struct between scb_stat and mem. */
1837 VMSTATE_UINT8(scb_stat, EEPRO100State),
1838 VMSTATE_UINT8(int_stat, EEPRO100State),
1839 VMSTATE_UNUSED(3*4),
1840 VMSTATE_MACADDR(conf.macaddr, EEPRO100State),
1841 VMSTATE_UNUSED(19*4),
1842 VMSTATE_UINT16_ARRAY(mdimem, EEPRO100State, 32),
1843 /* The eeprom should be saved and restored by its own routines. */
1844 VMSTATE_UINT32(device, EEPRO100State),
1845 /* TODO check device. */
1846 VMSTATE_UINT32(pointer, EEPRO100State),
1847 VMSTATE_UINT32(cu_base, EEPRO100State),
1848 VMSTATE_UINT32(cu_offset, EEPRO100State),
1849 VMSTATE_UINT32(ru_base, EEPRO100State),
1850 VMSTATE_UINT32(ru_offset, EEPRO100State),
1851 VMSTATE_UINT32(statsaddr, EEPRO100State),
ba42b646 1852 /* Save eepro100_stats_t statistics. */
151b2986
JQ
1853 VMSTATE_UINT32(statistics.tx_good_frames, EEPRO100State),
1854 VMSTATE_UINT32(statistics.tx_max_collisions, EEPRO100State),
1855 VMSTATE_UINT32(statistics.tx_late_collisions, EEPRO100State),
1856 VMSTATE_UINT32(statistics.tx_underruns, EEPRO100State),
1857 VMSTATE_UINT32(statistics.tx_lost_crs, EEPRO100State),
1858 VMSTATE_UINT32(statistics.tx_deferred, EEPRO100State),
1859 VMSTATE_UINT32(statistics.tx_single_collisions, EEPRO100State),
1860 VMSTATE_UINT32(statistics.tx_multiple_collisions, EEPRO100State),
1861 VMSTATE_UINT32(statistics.tx_total_collisions, EEPRO100State),
1862 VMSTATE_UINT32(statistics.rx_good_frames, EEPRO100State),
1863 VMSTATE_UINT32(statistics.rx_crc_errors, EEPRO100State),
1864 VMSTATE_UINT32(statistics.rx_alignment_errors, EEPRO100State),
1865 VMSTATE_UINT32(statistics.rx_resource_errors, EEPRO100State),
1866 VMSTATE_UINT32(statistics.rx_overrun_errors, EEPRO100State),
1867 VMSTATE_UINT32(statistics.rx_cdt_errors, EEPRO100State),
1868 VMSTATE_UINT32(statistics.rx_short_frame_errors, EEPRO100State),
1869 VMSTATE_UINT32(statistics.fc_xmt_pause, EEPRO100State),
1870 VMSTATE_UINT32(statistics.fc_rcv_pause, EEPRO100State),
1871 VMSTATE_UINT32(statistics.fc_rcv_unsupported, EEPRO100State),
1872 VMSTATE_UINT16(statistics.xmt_tco_frames, EEPRO100State),
1873 VMSTATE_UINT16(statistics.rcv_tco_frames, EEPRO100State),
2657c663 1874#if 0
151b2986 1875 VMSTATE_UINT16(status, EEPRO100State),
2657c663 1876#endif
151b2986
JQ
1877 /* Configuration bytes. */
1878 VMSTATE_BUFFER(configuration, EEPRO100State),
1879 VMSTATE_END_OF_LIST()
aac443e6 1880 }
151b2986 1881};
663e8e51 1882
e00e365e 1883static void nic_cleanup(VLANClientState *nc)
b946a153 1884{
e00e365e 1885 EEPRO100State *s = DO_UPCAST(NICState, nc, nc)->opaque;
b946a153 1886
e00e365e 1887 s->nic = NULL;
b946a153
AL
1888}
1889
c4c270e2 1890static int pci_nic_uninit(PCIDevice *pci_dev)
b946a153 1891{
c4c270e2 1892 EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
b946a153
AL
1893
1894 cpu_unregister_io_memory(s->mmio_index);
151b2986 1895 vmstate_unregister(s->vmstate, s);
508ef936 1896 eeprom93xx_free(s->eeprom);
e00e365e 1897 qemu_del_vlan_client(&s->nic->nc);
b946a153
AL
1898 return 0;
1899}
1900
e00e365e
MM
1901static NetClientInfo net_eepro100_info = {
1902 .type = NET_CLIENT_TYPE_NIC,
1903 .size = sizeof(NICState),
1904 .can_receive = nic_can_receive,
1905 .receive = nic_receive,
1906 .cleanup = nic_cleanup,
1907};
1908
81a322d4 1909static int nic_init(PCIDevice *pci_dev, uint32_t device)
663e8e51 1910{
273a2142 1911 EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
663e8e51 1912
aac443e6 1913 TRACE(OTHER, logout("\n"));
663e8e51 1914
663e8e51 1915 s->device = device;
663e8e51
TS
1916
1917 pci_reset(s);
1918
1919 /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,
1920 * i82559 and later support 64 or 256 word EEPROM. */
1921 s->eeprom = eeprom93xx_new(EEPROM_SIZE);
1922
1923 /* Handler for memory-mapped I/O */
273a2142 1924 s->mmio_index =
1eed09cb 1925 cpu_register_io_memory(pci_mmio_read, pci_mmio_write, s);
663e8e51 1926
273a2142 1927 pci_register_bar(&s->dev, 0, PCI_MEM_SIZE,
0392a017
IY
1928 PCI_BASE_ADDRESS_SPACE_MEMORY |
1929 PCI_BASE_ADDRESS_MEM_PREFETCH, pci_mmio_map);
1930 pci_register_bar(&s->dev, 1, PCI_IO_SIZE, PCI_BASE_ADDRESS_SPACE_IO,
663e8e51 1931 pci_map);
0392a017 1932 pci_register_bar(&s->dev, 2, PCI_FLASH_SIZE, PCI_BASE_ADDRESS_SPACE_MEMORY,
663e8e51
TS
1933 pci_mmio_map);
1934
508ef936 1935 qemu_macaddr_default_if_unset(&s->conf.macaddr);
ce0e58b3 1936 logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6));
663e8e51
TS
1937 assert(s->region[1] == 0);
1938
1939 nic_reset(s);
1940
e00e365e
MM
1941 s->nic = qemu_new_nic(&net_eepro100_info, &s->conf,
1942 pci_dev->qdev.info->name, pci_dev->qdev.id, s);
663e8e51 1943
e00e365e
MM
1944 qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
1945 TRACE(OTHER, logout("%s\n", s->nic->nc.info_str));
663e8e51 1946
a08d4367 1947 qemu_register_reset(nic_reset, s);
663e8e51 1948
151b2986
JQ
1949 s->vmstate = qemu_malloc(sizeof(vmstate_eepro100));
1950 memcpy(s->vmstate, &vmstate_eepro100, sizeof(vmstate_eepro100));
e00e365e 1951 s->vmstate->name = s->nic->nc.model;
151b2986 1952 vmstate_register(-1, s->vmstate, s);
4e9df06a 1953
81a322d4 1954 return 0;
663e8e51
TS
1955}
1956
c4c270e2
SW
1957static int pci_i82550_init(PCIDevice *pci_dev)
1958{
1959 return nic_init(pci_dev, i82550);
1960}
1961
1962static int pci_i82551_init(PCIDevice *pci_dev)
1963{
1964 return nic_init(pci_dev, i82551);
1965}
1966
1967static int pci_i82557a_init(PCIDevice *pci_dev)
1968{
1969 return nic_init(pci_dev, i82557A);
1970}
1971
1972static int pci_i82557b_init(PCIDevice *pci_dev)
1973{
1974 return nic_init(pci_dev, i82557B);
1975}
1976
1977static int pci_i82557c_init(PCIDevice *pci_dev)
1978{
1979 return nic_init(pci_dev, i82557C);
1980}
1981
1982static int pci_i82558a_init(PCIDevice *pci_dev)
1983{
1984 return nic_init(pci_dev, i82558A);
1985}
1986
1987static int pci_i82558b_init(PCIDevice *pci_dev)
1988{
1989 return nic_init(pci_dev, i82558B);
1990}
1991
1992static int pci_i82559a_init(PCIDevice *pci_dev)
1993{
1994 return nic_init(pci_dev, i82559A);
1995}
1996
1997static int pci_i82559b_init(PCIDevice *pci_dev)
1998{
1999 return nic_init(pci_dev, i82559B);
2000}
2001
2002static int pci_i82559c_init(PCIDevice *pci_dev)
9d07d757 2003{
c4c270e2 2004 return nic_init(pci_dev, i82559C);
9d07d757
PB
2005}
2006
c4c270e2 2007static int pci_i82559er_init(PCIDevice *pci_dev)
663e8e51 2008{
c4c270e2 2009 return nic_init(pci_dev, i82559ER);
663e8e51
TS
2010}
2011
c4c270e2 2012static int pci_i82562_init(PCIDevice *pci_dev)
663e8e51 2013{
c4c270e2 2014 return nic_init(pci_dev, i82562);
663e8e51
TS
2015}
2016
0aab0d3a
GH
2017static PCIDeviceInfo eepro100_info[] = {
2018 {
c4c270e2 2019 .qdev.name = "i82550",
762401e2 2020 .qdev.desc = "Intel i82550 Ethernet",
c4c270e2
SW
2021 .qdev.size = sizeof(EEPRO100State),
2022 .init = pci_i82550_init,
6a90e308 2023 .exit = pci_nic_uninit,
da51e79b 2024 .romfile = "gpxe-eepro100-80861209.rom",
508ef936
GH
2025 .qdev.props = (Property[]) {
2026 DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
2027 DEFINE_PROP_END_OF_LIST(),
2028 },
c4c270e2 2029 },{
0aab0d3a 2030 .qdev.name = "i82551",
762401e2 2031 .qdev.desc = "Intel i82551 Ethernet",
273a2142 2032 .qdev.size = sizeof(EEPRO100State),
0aab0d3a 2033 .init = pci_i82551_init,
e3936fa5 2034 .exit = pci_nic_uninit,
da51e79b 2035 .romfile = "gpxe-eepro100-80861209.rom",
508ef936
GH
2036 .qdev.props = (Property[]) {
2037 DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
2038 DEFINE_PROP_END_OF_LIST(),
2039 },
c4c270e2
SW
2040 },{
2041 .qdev.name = "i82557a",
762401e2 2042 .qdev.desc = "Intel i82557A Ethernet",
c4c270e2
SW
2043 .qdev.size = sizeof(EEPRO100State),
2044 .init = pci_i82557a_init,
6a90e308 2045 .exit = pci_nic_uninit,
da51e79b 2046 .romfile = "gpxe-eepro100-80861229.rom",
508ef936
GH
2047 .qdev.props = (Property[]) {
2048 DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
2049 DEFINE_PROP_END_OF_LIST(),
2050 },
0aab0d3a
GH
2051 },{
2052 .qdev.name = "i82557b",
762401e2 2053 .qdev.desc = "Intel i82557B Ethernet",
273a2142 2054 .qdev.size = sizeof(EEPRO100State),
0aab0d3a 2055 .init = pci_i82557b_init,
e3936fa5 2056 .exit = pci_nic_uninit,
da51e79b 2057 .romfile = "gpxe-eepro100-80861229.rom",
508ef936
GH
2058 .qdev.props = (Property[]) {
2059 DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
2060 DEFINE_PROP_END_OF_LIST(),
2061 },
c4c270e2
SW
2062 },{
2063 .qdev.name = "i82557c",
762401e2 2064 .qdev.desc = "Intel i82557C Ethernet",
c4c270e2
SW
2065 .qdev.size = sizeof(EEPRO100State),
2066 .init = pci_i82557c_init,
6a90e308 2067 .exit = pci_nic_uninit,
da51e79b 2068 .romfile = "gpxe-eepro100-80861229.rom",
508ef936
GH
2069 .qdev.props = (Property[]) {
2070 DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
2071 DEFINE_PROP_END_OF_LIST(),
2072 },
c4c270e2
SW
2073 },{
2074 .qdev.name = "i82558a",
762401e2 2075 .qdev.desc = "Intel i82558A Ethernet",
c4c270e2
SW
2076 .qdev.size = sizeof(EEPRO100State),
2077 .init = pci_i82558a_init,
6a90e308 2078 .exit = pci_nic_uninit,
da51e79b 2079 .romfile = "gpxe-eepro100-80861229.rom",
508ef936
GH
2080 .qdev.props = (Property[]) {
2081 DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
2082 DEFINE_PROP_END_OF_LIST(),
2083 },
c4c270e2
SW
2084 },{
2085 .qdev.name = "i82558b",
762401e2 2086 .qdev.desc = "Intel i82558B Ethernet",
c4c270e2
SW
2087 .qdev.size = sizeof(EEPRO100State),
2088 .init = pci_i82558b_init,
6a90e308 2089 .exit = pci_nic_uninit,
da51e79b 2090 .romfile = "gpxe-eepro100-80861229.rom",
508ef936
GH
2091 .qdev.props = (Property[]) {
2092 DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
2093 DEFINE_PROP_END_OF_LIST(),
2094 },
c4c270e2
SW
2095 },{
2096 .qdev.name = "i82559a",
762401e2 2097 .qdev.desc = "Intel i82559A Ethernet",
c4c270e2
SW
2098 .qdev.size = sizeof(EEPRO100State),
2099 .init = pci_i82559a_init,
6a90e308 2100 .exit = pci_nic_uninit,
da51e79b 2101 .romfile = "gpxe-eepro100-80861229.rom",
508ef936
GH
2102 .qdev.props = (Property[]) {
2103 DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
2104 DEFINE_PROP_END_OF_LIST(),
2105 },
c4c270e2
SW
2106 },{
2107 .qdev.name = "i82559b",
762401e2 2108 .qdev.desc = "Intel i82559B Ethernet",
c4c270e2
SW
2109 .qdev.size = sizeof(EEPRO100State),
2110 .init = pci_i82559b_init,
6a90e308 2111 .exit = pci_nic_uninit,
da51e79b 2112 .romfile = "gpxe-eepro100-80861229.rom",
508ef936
GH
2113 .qdev.props = (Property[]) {
2114 DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
2115 DEFINE_PROP_END_OF_LIST(),
2116 },
c4c270e2
SW
2117 },{
2118 .qdev.name = "i82559c",
762401e2 2119 .qdev.desc = "Intel i82559C Ethernet",
c4c270e2
SW
2120 .qdev.size = sizeof(EEPRO100State),
2121 .init = pci_i82559c_init,
6a90e308 2122 .exit = pci_nic_uninit,
da51e79b 2123 .romfile = "gpxe-eepro100-80861229.rom",
508ef936
GH
2124 .qdev.props = (Property[]) {
2125 DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
2126 DEFINE_PROP_END_OF_LIST(),
2127 },
0aab0d3a
GH
2128 },{
2129 .qdev.name = "i82559er",
762401e2 2130 .qdev.desc = "Intel i82559ER Ethernet",
273a2142 2131 .qdev.size = sizeof(EEPRO100State),
0aab0d3a 2132 .init = pci_i82559er_init,
e3936fa5 2133 .exit = pci_nic_uninit,
da51e79b 2134 .romfile = "gpxe-eepro100-80861209.rom",
508ef936
GH
2135 .qdev.props = (Property[]) {
2136 DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
2137 DEFINE_PROP_END_OF_LIST(),
2138 },
c4c270e2
SW
2139 },{
2140 .qdev.name = "i82562",
762401e2 2141 .qdev.desc = "Intel i82562 Ethernet",
c4c270e2
SW
2142 .qdev.size = sizeof(EEPRO100State),
2143 .init = pci_i82562_init,
6a90e308 2144 .exit = pci_nic_uninit,
da51e79b 2145 .romfile = "gpxe-eepro100-80861209.rom",
508ef936
GH
2146 .qdev.props = (Property[]) {
2147 DEFINE_NIC_PROPERTIES(EEPRO100State, conf),
2148 DEFINE_PROP_END_OF_LIST(),
2149 },
0aab0d3a
GH
2150 },{
2151 /* end of list */
2152 }
2153};
2154
9d07d757 2155static void eepro100_register_devices(void)
663e8e51 2156{
0aab0d3a 2157 pci_qdev_register_many(eepro100_info);
663e8e51
TS
2158}
2159
9d07d757 2160device_init(eepro100_register_devices)