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