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