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