usb: Fix compilation for Windows
[qemu/ar7.git] / hw / net / dp8381x.c
blobbfcf6bc7750e09b16f3a0968eb23dec7f6612bcf
1 /*
2 * QEMU emulation for National Semiconductor DP83815 / DP83816.
4 * Copyright (C) 2006-2012 Stefan Weil
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * Datasheets are available from National Semiconductor, see
20 * http://www.national.com/pf/DP/DP83815.html
21 * http://www.national.com/pf/DP/DP83816.html
23 * Missing features:
24 * Wake-On-LAN (WOL)
25 * Big-Endian-Mode
26 * many details
28 * Tested features (dp83816):
29 * PXE boot (i386) ok
30 * Linux networking (i386, mipsel) ok
31 * big endian target (mips malta) ok
33 * Untested features:
34 * big endian host cpu
36 * TODO:
37 * Implement save, load VM support.
40 #include "qemu/osdep.h"
41 #include "hw.h"
42 #include "net/net.h"
43 #include "pci/pci.h"
44 #include "eeprom93xx.h"
46 /*****************************************************************************
48 * Common declarations.
50 ****************************************************************************/
52 #define KiB 1024
54 /*****************************************************************************
56 * Declarations for emulation options and debugging.
58 ****************************************************************************/
60 /* Debug DP8381x card. */
61 //~ #define DEBUG_DP8381X
63 #if defined(DEBUG_DP8381X)
64 # define logout(fmt, ...) fprintf(stderr, "DP8381X %-24s" fmt, __func__, ##__VA_ARGS__)
65 #else
66 # define logout(fmt, ...) ((void)0)
67 #endif
69 #define missing(text) assert(!"feature is missing in this emulation: " text)
71 /* Enable or disable logging categories. */
72 #define LOG_EEPROM 0
73 #define LOG_PHY 1
74 #define LOG_RX 1 /* receive messages */
75 #define LOG_TX 1 /* transmit messages */
77 #if defined(DEBUG_DP8381X)
78 # define TRACE(condition, command) ((condition) ? (command) : (void)0)
79 #else
80 # define TRACE(condition, command) ((void)0)
81 #endif
83 /* EEPROM support is optional. */
84 #define CONFIG_EEPROM
85 #define EEPROM_SIZE 16
87 /* Silicon revisions for the different hardware */
88 #define DP83815CVNG 0x00000302
89 #define DP83815DVNG 0x00000403
90 #define DP83816AVNG 0x00000505
92 #define MAX_ETH_FRAME_SIZE 1514
94 #define DP8381X_IO_SIZE 256
95 #define DP8381X_MEM_SIZE 4096
97 /*****************************************************************************
99 * EEPROM emulation.
101 ****************************************************************************/
103 typedef enum {
104 idle,
105 active
106 } RxTxState;
108 typedef struct {
109 PCIDevice dev;
110 MemoryRegion mmio_bar;
111 MemoryRegion io_bar;
112 RxTxState rx_state:8;
113 RxTxState tx_state:8;
115 /* Variables for QEMU interface. */
116 eeprom_t *eeprom;
117 NICState *nic;
118 NICConf conf;
119 uint8_t mem[DP8381X_IO_SIZE];
120 uint8_t filter[1024];
121 uint32_t silicon_revision;
122 } DP8381xState;
124 #if defined(CONFIG_EEPROM)
125 static const uint16_t eeprom_default[16] = {
126 /* Default values for EEPROM. */
127 /* Only 12 words are used. Data is in host byte order. */
128 0xd008,
129 0x0400,
130 0x2cd0,
131 0xcf82,
132 0x0000,
133 0x0000,
134 0x0000,
135 0x0000,
136 0x0000,
137 0x0000,
138 0xa098,
139 0x0055
141 #endif
143 /*****************************************************************************
145 * Register emulation.
147 ****************************************************************************/
149 /* Operational Registers. */
151 typedef enum {
152 /* MAC/BIU Registers */
153 DP8381X_CR = 0x00,
154 DP8381X_CFG = 0x04,
155 DP8381X_MEAR = 0x08,
156 DP8381X_PTSCR = 0x0c,
157 DP8381X_ISR = 0x10,
158 DP8381X_IMR = 0x14,
159 DP8381X_IER = 0x18,
160 DP8381X_IHR = 0x1c,
161 DP8381X_TXDP = 0x20,
162 DP8381X_TXCFG = 0x24,
163 /* DP8381X_R = 0x28, */
164 /* DP8381X_R = 0x2c, */
165 DP8381X_RXDP = 0x30,
166 DP8381X_RXCFG = 0x34,
167 /* DP8381X_R = 0x38, */
168 DP8381X_CCSR = 0x3c,
169 DP8381X_WCSR = 0x40,
170 DP8381X_PCR = 0x44,
171 DP8381X_RFCR = 0x48,
172 DP8381X_RFDR = 0x4c,
173 DP8381X_BRAR = 0x50,
174 DP8381X_BRDR = 0x54,
175 DP8381X_SRR = 0x58,
176 DP8381X_MIBC = 0x5c,
177 DP8381X_MIB0 = 0x60,
178 DP8381X_MIB1 = 0x64,
179 DP8381X_MIB2 = 0x68,
180 DP8381X_MIB3 = 0x6c,
181 DP8381X_MIB4 = 0x70,
182 DP8381X_MIB5 = 0x74,
183 DP8381X_MIB6 = 0x78,
184 /* Internal Phy Registers */
185 DP8381X_BMCR = 0x80, /* Control Register */
186 DP8381X_BMSR = 0x84, /* Status Register */
187 DP8381X_PHYIDR1 = 0x88, /* PHY Identification Register 1 */
188 DP8381X_PHYIDR2 = 0x8c, /* PHY Identification Register 2 */
189 DP8381X_ANAR = 0x90, /* Auto-Negotiation Advertisement Register */
190 DP8381X_ANLPAR = 0x94, /* Auto-Negotiation Link Partner Ability Register */
191 DP8381X_ANER = 0x98, /* Auto-Negotiation Expansion Register */
192 DP8381X_ANPTR = 0x9c,
193 DP8381X_PHYSTS = 0xc0,
194 DP8381X_MICR = 0xc4,
195 DP8381X_MISR = 0xc8,
196 DP8381X_PGSEL = 0xcc,
197 DP8381X_FCSCR = 0xd0,
198 DP8381X_RECR = 0xd4,
199 DP8381X_PCSR = 0xd8,
200 DP8381X_0xdc = 0xdc,
201 DP8381X_PHYCR = 0xe4,
202 DP8381X_TBTSCR = 0xe8,
203 DP8381X_00EC = 0xec,
204 DP8381X_DSPCFG = 0xf4,
205 DP8381X_SDCFG = 0xf8,
206 DP8381X_TSTDAT = 0xfc,
207 } DP8381xRegister;
209 #define BIT(n) (1 << (n))
210 #define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
212 typedef enum {
213 CR_RST = BIT(8),
214 CR_SWI = BIT(7),
215 CR_RXR = BIT(5),
216 CR_TXR = BIT(4),
217 CR_RXD = BIT(3),
218 CR_RXE = BIT(2),
219 CR_TXD = BIT(1),
220 CR_TXE = BIT(0),
221 } CR_Bit;
223 typedef enum {
224 CFG_LNKSTS = BIT(31),
225 CFG_SPEED100 = BIT(30),
226 CFG_FDUP = BIT(29),
227 CFG_POL = BIT(28),
228 CFG_ANEG_DN = BIT(27),
229 CFG_PINT_ACEN = BIT(17),
230 CFG_ANEG_SEL = BITS(15, 13),
231 CFG_EXT_PHY = BIT(12),
232 CFG_BEM = BIT(0),
233 } CFG_Bit;
235 typedef enum {
236 ISR_TXRCMP = BIT(25),
237 ISR_RXRCMP = BIT(24),
238 ISR_PHY = BIT(14),
239 ISR_SWI = BIT(12),
240 ISR_TXIDLE = BIT(9),
241 ISR_TXDESC = BIT(7),
242 ISR_TXOK = BIT(6),
243 ISR_RXORN = BIT(5),
244 ISR_RXIDLE = BIT(4),
245 ISR_RXDESC = BIT(1),
246 ISR_RXOK = BIT(0),
247 /* Special values for dp8381x_interrupt. */
248 ISR_CLEAR = 0,
249 ISR_UPDATE = BITS(31, 0),
250 } ISR_Bit;
252 typedef ISR_Bit IMR_Bit;
254 typedef enum {
255 MEAR_MDC = BIT(6), /* MII Management Clock */
256 MEAR_MDDIR = BIT(5), /* MII Management Direction */
257 MEAR_MDIO = BIT(4), /* MII Management Data */
258 MEAR_EESEL = BIT(3), /* EEPROM Chip Select */
259 MEAR_EECLK = BIT(2), /* EEPROM Serial Clock */
260 MEAR_EEDO = BIT(1), /* EEPROM Data Out */
261 MEAR_EEDI = BIT(0), /* EEPROM Data In */
262 } MEAR_Bit;
264 typedef enum {
265 PTSCR_RBIST_EN = BIT(7),
266 PTSCR_RBIST_DONE = BIT(6),
267 PTSCR_EELOAD_EN = BIT(2),
268 PTSCR_EEBIST_EN = BIT(1),
269 } PTSCR_Bit;
271 typedef enum {
272 RFCR_RFADDR = BITS(9, 0),
273 } RFCR_Bit;
275 typedef enum {
276 MIBC_MIBS = BIT(3),
277 MIBC_ACLR = BIT(2),
278 } MICB_Bit;
280 typedef enum {
281 MICR_INTEN = BIT(1),
282 MICR_TINT = BIT(0),
283 } MICR_Bit;
285 typedef enum {
286 MISR_MINT = BIT(15),
287 } MISR_Bit;
289 static void dp8381x_stl_le_phys(hwaddr addr, uint32_t val)
291 val = cpu_to_le32(val);
292 cpu_physical_memory_write(addr, (const uint8_t *)&val, sizeof(val));
295 static uint32_t op_reg_read(DP8381xState * s, uint32_t addr)
297 assert(addr < 0x80 && !(addr & 3));
298 return le32_to_cpu(*(uint32_t *) (&s->mem[addr]));
301 static void op_reg_write(DP8381xState * s, uint32_t addr, uint32_t value)
303 assert(addr < 0x80 && !(addr & 3));
304 *(uint32_t *) (&s->mem[addr]) = cpu_to_le32(value);
307 static uint16_t phy_reg_read(DP8381xState * s, uint32_t addr)
309 assert(addr >= 0x80 && addr < 0x100 && !(addr & 3));
310 return le16_to_cpu(*(uint16_t *) (&s->mem[addr]));
313 static void phy_reg_write(DP8381xState * s, uint32_t addr, uint32_t value)
315 assert(addr >= 0x80 && addr < 0x100 && !(addr & 3));
316 *(uint16_t *) (&s->mem[addr]) = cpu_to_le16(value);
319 static void init_operational_registers(DP8381xState * s)
321 #define OP_REG(offset, value) op_reg_write(s, offset, value)
322 OP_REG(DP8381X_CR, 0x00000000); /* Command */
323 OP_REG(DP8381X_CFG, 0x00000000); /* Configuration and Media Status */
324 OP_REG(DP8381X_MEAR, 0x00000002); /* EEPROM Access */
325 OP_REG(DP8381X_PTSCR, 0x00000000); /* PCI Test Control */
326 OP_REG(DP8381X_ISR, 0x03008000); /* Interrupt Status */
327 OP_REG(DP8381X_IMR, 0x00000000); /* Interrupt Mask */
328 OP_REG(DP8381X_IER, 0x00000000); /* Interrupt Enable */
329 OP_REG(DP8381X_IHR, 0x00000000); /* Interrupt Holdoff */
330 OP_REG(DP8381X_TXDP, 0x00000000); /* Transmit Descriptor Pointer */
331 #if defined(DP83815)
332 OP_REG(DP8381X_TXCFG, 0x00000102); /* Transmit Configuration */
333 #else
334 OP_REG(DP8381X_TXCFG, 0x00040102); /* Transmit Configuration */
335 #endif
336 OP_REG(DP8381X_RXDP, 0x00000000); /* Receive Descriptor Pointer */
337 OP_REG(DP8381X_RXCFG, 0x00000002); /* Receive Configuration */
338 OP_REG(DP8381X_WCSR, 0x00000000); /* Wake Command/Status */
339 OP_REG(DP8381X_PCR, 0x00000000); /* Pause Control/Status */
340 OP_REG(DP8381X_RFCR, 0x00000000); /* Receive Filter/Match Control */
341 OP_REG(DP8381X_RFDR, 0x00000000); /* Receive Filter Data */
342 /* hard reset only */
343 OP_REG(DP8381X_BRAR, 0xffffffff); /* Boot ROM Address */
344 OP_REG(DP8381X_SRR, s->silicon_revision); /* Silicon Revision */
345 OP_REG(DP8381X_MIBC, 0x00000002); /* Management Information Base Control */
347 #define PHY_REG(offset, value) phy_reg_write(s, offset, value)
348 PHY_REG(DP8381X_BMCR, 0x0000); /* TODO */
349 PHY_REG(DP8381X_BMSR, 0x7849);
350 PHY_REG(DP8381X_PHYIDR1, 0x2000);
351 PHY_REG(DP8381X_PHYIDR2, 0x5c21);
352 PHY_REG(DP8381X_ANAR, 0x05e1);
353 PHY_REG(DP8381X_ANER, 0x0004);
354 PHY_REG(DP8381X_ANPTR, 0x2001);
355 PHY_REG(DP8381X_PCSR, 0x0100);
356 PHY_REG(DP8381X_PHYCR, 0x003f);
357 #if defined(DP83815)
358 PHY_REG(DP8381X_TBTSCR, 0x0004);
359 #else
360 PHY_REG(DP8381X_TBTSCR, 0x0804);
361 #endif
364 static void dp8381x_reset(DP8381xState * s)
366 unsigned i;
367 logout("\n");
368 init_operational_registers(s);
369 s->rx_state = idle;
370 s->tx_state = idle;
371 for (i = 0; i < 6; i++) {
372 s->filter[2 * i] = s->conf.macaddr.a[i];
376 static void dp8381x_interrupt(DP8381xState * s, uint32_t bits)
378 uint32_t isr = op_reg_read(s, DP8381X_ISR);
379 uint32_t imr = op_reg_read(s, DP8381X_IMR);
380 uint32_t ier = op_reg_read(s, DP8381X_IER);
381 if (bits == ISR_CLEAR) {
382 uint32_t cfg = op_reg_read(s, DP8381X_CFG);
383 if (cfg & CFG_PINT_ACEN) {
384 uint16_t misr = phy_reg_read(s, DP8381X_MISR);
385 misr &= ~MISR_MINT;
386 phy_reg_write(s, DP8381X_MISR, misr);
388 isr = 0;
389 } else if (bits != ISR_UPDATE) {
390 isr |= bits;
392 op_reg_write(s, DP8381X_ISR, isr);
393 qemu_set_irq(s->dev.irq[0], (ier && (isr & imr)));
396 #define POLYNOMIAL 0x04c11db6
398 #if 0
399 /* From FreeBSD */
400 /* XXX: optimize */
401 static int compute_mcast_idx(const uint8_t * ep)
403 uint32_t crc;
404 int carry, i, j;
405 uint8_t b;
407 crc = 0xffffffff;
408 for (i = 0; i < 6; i++) {
409 b = *ep++;
410 for (j = 0; j < 8; j++) {
411 carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
412 crc <<= 1;
413 b >>= 1;
414 if (carry)
415 crc = ((crc ^ POLYNOMIAL) | carry);
418 return (crc >> 26);
420 #endif
422 typedef struct {
423 uint32_t link;
424 uint32_t cmdsts;
425 uint32_t bufptr;
426 } descriptor_t;
428 typedef descriptor_t rx_descriptor_t;
429 typedef descriptor_t tx_descriptor_t;
431 static int nic_can_receive(NetClientState *ncs)
433 DP8381xState *s = qemu_get_nic_opaque(ncs);
435 logout("\n");
437 /* TODO: handle queued receive data. */
438 return s->rx_state == active;
441 typedef enum {
442 CMDSTS_OWN = BIT(31),
443 CMDSTS_MORE = BIT(30),
444 CMDSTS_INTR = BIT(29),
445 CMDSTS_SUPCRC = BIT(28),
446 CMDSTS_OK = BIT(27),
447 CMDSTS_SIZE = BITS(11, 0),
448 /* transmit status bits */
449 /* receive status bits */
450 CMDSTS_DEST = BITS(24, 23),
451 CMDSTS_LONG = BIT(22),
452 CMDSTS_RUNT = BIT(21),
453 } cmdsts_bit_t;
455 static ssize_t
456 nic_receive(NetClientState *ncs, const uint8_t *buf, size_t size)
458 static const uint8_t broadcast_macaddr[6] =
459 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
461 DP8381xState *s = qemu_get_nic_opaque(ncs);
462 #if 0
463 uint8_t *p;
464 int total_len, next, avail, len, index, mcast_idx;
465 uint8_t buf1[60];
466 #endif
468 TRACE(LOG_RX, logout("len=%u\n", (unsigned)size));
470 /* TODO: handle queued receive data. */
472 if (s->rx_state != active) {
473 return -1;
475 //~ missing("");
477 /* Filter incoming packet. */
479 if (0 /*PME!!! */ ) {
480 /* Packet filters enabled. */
481 missing("mode only used for wake-on-lan");
482 } else if (!memcmp(buf, s->conf.macaddr.a, 6)) {
483 /* my address */
484 TRACE(LOG_RX, logout("my mac address\n"));
485 } else if (!memcmp(buf, broadcast_macaddr, 6)) {
486 /* broadcast address */
487 TRACE(LOG_RX, logout("broadcast address\n"));
488 } else if (buf[0] & 0x01) {
489 /* multicast */
490 TRACE(LOG_RX, logout("multicast address\n"));
491 } else {
492 /* Frame rejected by filter. */
493 TRACE(LOG_RX, logout("unknown mac address\n"));
494 //~ return -1;
497 rx_descriptor_t rx;
498 uint32_t rxdp = op_reg_read(s, DP8381X_RXDP);
499 cpu_physical_memory_read(rxdp, (uint8_t *) & rx, sizeof(rx));
500 uint32_t rxlink = le32_to_cpu(rx.link);
501 uint32_t cmdsts = le32_to_cpu(rx.cmdsts);
502 uint32_t bufptr = le32_to_cpu(rx.bufptr);
503 uint32_t length = (cmdsts & CMDSTS_SIZE);
504 TRACE(LOG_RX, logout("rxdp 0x%08x, link 0x%08x, cmdsts 0x%08x, "
505 "bufptr 0x%08x, length %u\n",
506 rxdp, rxlink, cmdsts, bufptr, length));
508 /* Linux subtracts 4 bytes for fcs, so we add it here. */
509 size += 4;
511 assert(bufptr != 0);
512 assert(length >= size);
513 if (cmdsts & CMDSTS_OWN) {
514 logout("wrong owner flag for receive buffer\n");
517 cpu_physical_memory_write(bufptr, buf, size);
518 cmdsts &= ~CMDSTS_MORE;
519 cmdsts &= ~CMDSTS_SIZE;
520 cmdsts |= (size & CMDSTS_SIZE);
521 cmdsts |= CMDSTS_OWN;
522 cmdsts |= CMDSTS_OK;
523 dp8381x_stl_le_phys(rxdp + 4, cmdsts);
524 dp8381x_interrupt(s, ISR_RXOK);
525 dp8381x_interrupt(s, ISR_RXDESC);
526 if (rxlink == 0) {
527 s->rx_state = idle;
528 dp8381x_interrupt(s, ISR_RXIDLE);
529 } else {
531 rxdp = rxlink;
532 op_reg_write(s, DP8381X_RXDP, rxdp);
533 //~ dp8381x_interrupt(s, ISR_RXOVR);
534 return size;
537 static void dp8381x_transmit(DP8381xState * s)
539 uint8_t buffer[MAX_ETH_FRAME_SIZE + 4];
540 uint32_t size = 0;
541 tx_descriptor_t tx;
542 uint32_t txdp = op_reg_read(s, DP8381X_TXDP);
543 TRACE(LOG_TX, logout("txdp 0x%08x\n", txdp));
544 while (txdp != 0) {
545 cpu_physical_memory_read(txdp, (uint8_t *) & tx, sizeof(tx));
546 uint32_t txlink = le32_to_cpu(tx.link);
547 uint32_t cmdsts = le32_to_cpu(tx.cmdsts);
548 uint32_t bufptr = le32_to_cpu(tx.bufptr);
549 uint32_t length = (cmdsts & CMDSTS_SIZE);
550 TRACE(LOG_TX, logout("txdp 0x%08x, link 0x%08x, cmdsts 0x%08x, "
551 "bufptr 0x%08x, length %u/%u\n",
552 txdp, txlink, cmdsts, bufptr, length, size));
553 if (!(tx.cmdsts & CMDSTS_OWN)) {
554 s->tx_state = idle;
555 dp8381x_interrupt(s, ISR_TXIDLE);
556 break;
558 assert(size + length < sizeof(buffer));
559 cpu_physical_memory_read(bufptr, buffer + size, length);
560 size += length;
561 if (cmdsts & CMDSTS_INTR) {
562 dp8381x_interrupt(s, ISR_TXDESC);
564 cmdsts &= ~CMDSTS_OWN;
565 if (cmdsts & CMDSTS_MORE) {
566 assert(txlink != 0);
567 txdp = txlink;
568 dp8381x_stl_le_phys(txdp + 4, cmdsts);
569 continue;
571 cmdsts |= CMDSTS_OK;
572 dp8381x_stl_le_phys(txdp + 4, cmdsts);
573 dp8381x_interrupt(s, ISR_TXOK);
574 TRACE(LOG_TX, logout("sending\n"));
575 qemu_send_packet(qemu_get_queue(s->nic), buffer, size);
576 if (txlink == 0) {
577 s->tx_state = idle;
578 dp8381x_interrupt(s, ISR_TXIDLE);
579 break;
581 txdp = txlink;
583 op_reg_write(s, DP8381X_TXDP, txdp);
586 /***********************************************************/
587 /* PCI DP8381X definitions */
589 #if defined(DEBUG_DP8381X)
590 static const char *regnames[] = {
591 /* MAC/BIU Registers */
592 "CR", /* 0x00 */
593 "CFG", /* 0x04 */
594 "MEAR", /* 0x08 */
595 "PTSCR", /* 0x0c */
596 "ISR", /* 0x10 */
597 "IMR", /* 0x14 */
598 "IER", /* 0x18 */
599 "IHR", /* 0x1c */
600 "TXDP", /* 0x20 */
601 "TXCFG", /* 0x24 */
602 "0x28", /* 0x28 */
603 "0x2c", /* 0x2c */
604 "RXDP", /* 0x30 */
605 "RXCFG", /* 0x34 */
606 "0x38", /* 0x38 */
607 "CCSR", /* 0x3c */
608 "WCSR", /* 0x40 */
609 "PCR", /* 0x44 */
610 "RFCR", /* 0x48 */
611 "RFDR", /* 0x4c */
612 "BRAR", /* 0x50 */
613 "BRDR", /* 0x54 */
614 "SRR", /* 0x58 */
615 "MIBC", /* 0x5c */
616 "MIB0", /* 0x60 */
617 "MIB1", /* 0x64 */
618 "MIB2", /* 0x68 */
619 "MIB3", /* 0x6c */
620 "MIB4", /* 0x70 */
621 "MIB5", /* 0x74 */
622 "MIB6", /* 0x78 */
623 "0x7c", /* 0x7c */
624 /* Internal Phy Registers */
625 "BMCR", /* 0x80 */
626 "BMSR", /* 0x84 */
627 "PHYIDR1", /* 0x88 */
628 "PHYIDR2", /* 0x8c */
629 "ANAR", /* 0x90 */
630 "ANLPAR", /* 0x94 */
631 "ANER", /* 0x98 */
632 "ANNPTR", /* 0x9c */
633 "0xa0", /* 0xa0 */
634 "0xa4", /* 0xa4 */
635 "0xa8", /* 0xa8 */
636 "0xac", /* 0xac */
637 "0xb0", /* 0xb0 */
638 "0xb4", /* 0xb4 */
639 "0xb8", /* 0xb8 */
640 "0xbc", /* 0xbc */
641 "PHYSTS", /* 0xc0 */
642 "MICR", /* 0xc4 */
643 "MISR", /* 0xc8 */
644 "PGSEL", /* 0xcc */
645 "FCSCR", /* 0xd0 */
646 "RECR", /* 0xd4 */
647 "PCSR", /* 0xd8 */
648 "0xdc", /* 0xdc */
649 "0xe0", /* 0xe0 */
650 "PHYCR", /* 0xe4 */
651 /* PMDCSR = 0xE4, */
652 "TBTSCR", /* 0xe8 */
653 "0xec", /* 0xec */
654 "0xf0", /* 0xf0 */
655 "DSPCFG", /* 0xf4 */
656 "SDCFG", /* 0xf8 */
657 "TSTDAT", /* 0xfc */
660 #define num_elements(s) (sizeof(s) / sizeof(*s))
662 static const char *dp8381x_regname(unsigned addr)
664 static char name[10];
665 const char *p = name;
666 if (addr < (num_elements(regnames) * 4) && (addr & 3) == 0) {
667 p = regnames[addr / 4];
668 } else {
669 snprintf(name, sizeof(name), "0x%04x", addr);
671 return p;
673 #endif /* DEBUG_DP8381X */
675 static uint16_t anar_read(DP8381xState * s)
677 /* Read operational register 0x90. */
678 uint16_t val = phy_reg_read(s, DP8381X_ANAR);
679 logout("addr=%s val=0x%04x\n", dp8381x_regname(DP8381X_ANAR), val);
680 return val;
683 static uint16_t anlpar_read(DP8381xState * s)
685 /* Read operational register 0x94. */
686 uint16_t val = phy_reg_read(s, DP8381X_ANLPAR);
687 #if 1
688 val |= BIT(14) | BITS(8, 5);
689 #endif
690 logout("addr=%s val=0x%04x\n", dp8381x_regname(DP8381X_ANLPAR), val);
691 return val;
694 static uint16_t bmcr_read(DP8381xState * s)
696 const uint32_t addr = DP8381X_BMCR;
697 uint16_t val = phy_reg_read(s, addr);
698 if (val & BIT(9)) {
699 /* TODO: Restart auto-negotiation. */
700 phy_reg_write(s, addr, val & ~BIT(9));
701 #if 1
702 dp8381x_interrupt(s, ISR_PHY);
703 #endif
705 logout("addr=%s val=0x%04x\n", dp8381x_regname(addr), val);
706 return val;
709 static uint16_t phytst_read(DP8381xState * s)
711 /* TODO: reading RECR clears BIT(13). */
712 /* TODO: BIT(12) duplicates TBTSCR_BIT4. */
713 /* TODO: reading TBTSCR clear BIT(12). */
714 /* TODO: reading FCSCR clears BIT(11). */
715 /* TODO: BIT(8) duplicates ANER_BIT(page received). */
716 /* TODO: reading ANER clears BIT(8). */
717 /* TODO: BIT(0) duplicates BMSR_BIT(link status). */
718 const uint32_t addr = DP8381X_PHYSTS;
719 uint16_t val = phy_reg_read(s, addr);
720 uint16_t newval;
721 /* Auto-negotiation complete, full duplex, valid link. */
722 val |= (BIT(4) | BIT(2) | BIT(0));
723 newval = (val & ~BIT(7));
724 phy_reg_write(s, addr, newval);
725 logout("addr=%s val=0x%04x\n", dp8381x_regname(addr), val);
726 return val;
729 static void micr_write(DP8381xState * s, uint16_t val)
731 const uint32_t addr = DP8381X_MICR;
732 logout("addr=%s val=0x%04x\n", dp8381x_regname(addr), val);
733 if (val & MICR_INTEN) {
734 /* Enable PHY interrupt. In emulation, we immediately raise one. */
735 uint16_t misr = phy_reg_read(s, DP8381X_MISR);
736 misr |= MISR_MINT;
737 phy_reg_write(s, DP8381X_MISR, misr);
738 dp8381x_interrupt(s, ISR_PHY);
740 phy_reg_write(s, addr, val);
743 static uint8_t dp8381x_readb(DP8381xState * s, hwaddr addr)
745 uint8_t val = 0xff;
746 if (0) {
747 } else if (addr == DP8381X_MEAR) { /* 0x08 */
748 /* Needed for Windows. */
749 val = op_reg_read(s, addr);
750 #if defined(CONFIG_EEPROM)
751 val &= ~MEAR_EEDO;
752 if (eeprom93xx_read(s->eeprom)) {
753 val |= MEAR_EEDO;
755 #else
756 val |= MEAR_EEDO;
757 #endif
758 TRACE(LOG_EEPROM,
759 logout("addr=%s val=0x%02x\n", dp8381x_regname(addr), val));
760 } else if (addr == DP8381X_PHYSTS) { /* 0xc0 */
761 /* Needed for Windows. */
762 val = phytst_read(s);
763 //~ logging = 0;
764 } else if (addr >= 256) {
765 logout("??? address too large, addr=%s\n", dp8381x_regname(addr));
766 missing("byte access");
767 } else {
768 val = s->mem[addr];
769 logout("??? addr=%s val=0x%02x\n", dp8381x_regname(addr), val);
770 missing("byte access");
772 return val;
775 static uint16_t dp8381x_readw(DP8381xState * s, hwaddr addr)
777 uint16_t val = 0xffff;
778 int logging = 1;
779 if ((addr & 1) != 0) {
780 logout("??? address not on word boundary, addr=%s\n",
781 dp8381x_regname(addr));
782 logging = 0;
783 } else if (addr == DP8381X_RFDR) { /* 0x4c */
784 uint32_t rfaddr = (op_reg_read(s, DP8381X_RFCR) & RFCR_RFADDR);
785 if (rfaddr & 1) {
786 missing("odd rfaddr");
787 } else {
788 assert(rfaddr < sizeof(s->filter));
789 val = *(uint16_t *) & s->filter[rfaddr];
791 } else if (addr < 0x80) {
792 logout("??? addr=%s val=0x%04x\n", dp8381x_regname(addr), val);
793 logging = 0;
794 } else if (addr >= 256) {
795 logout("??? address too large, addr=%s\n", dp8381x_regname(addr));
796 logging = 0;
797 } else if (addr == DP8381X_BMCR) { /* 0x80 */
798 val = bmcr_read(s);
799 logging = 0;
800 } else if (addr == DP8381X_BMSR) { /* 0x84 */
801 val = phy_reg_read(s, addr);
802 #if 1
803 val |= BIT(5) | BIT(2);
804 #endif
805 } else if (addr == DP8381X_PHYIDR1) { /* 0x88 */
806 val = phy_reg_read(s, addr);
807 } else if (addr == DP8381X_PHYIDR2) { /* 0x8c */
808 val = phy_reg_read(s, addr);
809 } else if (addr == DP8381X_ANAR) { /* 0x90 */
810 val = anar_read(s);
811 logging = 0;
812 } else if (addr == DP8381X_ANLPAR) { /* 0x94 */
813 val = anlpar_read(s);
814 logging = 0;
815 } else if (addr == DP8381X_PHYSTS) { /* 0xc0 */
816 val = phytst_read(s);
817 logging = 0;
818 } else if (addr == DP8381X_MISR) { /* 0xc8 */
819 val = phy_reg_read(s, addr);
820 phy_reg_write(s, addr, val & ~MISR_MINT);
821 } else if (addr == DP8381X_DSPCFG) { /* 0xf4 */
822 val = phy_reg_read(s, addr);
823 } else {
824 val = phy_reg_read(s, addr);
825 logout("??? addr=%s val=0x%04x\n", dp8381x_regname(addr), val);
826 logging = 0;
828 if (logging) {
829 logout("addr=%s val=0x%04x\n", dp8381x_regname(addr), val);
831 return val;
834 static uint32_t dp8381x_readl(DP8381xState * s, hwaddr addr)
836 uint32_t val = 0xffffffffU;
837 int logging = 1;
838 if ((addr & 3) != 0) {
839 logout("??? address not on double word boundary, addr=%s\n",
840 dp8381x_regname(addr));
841 logging = 0;
842 } else if (addr >= 256) {
843 logout("??? address too large, addr=%s\n", dp8381x_regname(addr));
844 } else if (addr == DP8381X_CR) { /* 0x00 */
845 val = op_reg_read(s, addr);
846 } else if (addr == DP8381X_CFG) { /* 0x04 */
847 val = op_reg_read(s, addr);
848 val |= CFG_LNKSTS;
849 if (val & 0x8000) {
850 val |= CFG_SPEED100;
851 val |= CFG_FDUP;
853 #if 1
854 val |= (CFG_SPEED100 | CFG_FDUP | CFG_ANEG_DN);
855 #endif
856 //~ logging = 0;
857 } else if (addr == DP8381X_MEAR) { /* 0x08 */
858 val = op_reg_read(s, addr);
859 #if defined(CONFIG_EEPROM)
860 val &= ~MEAR_EEDO;
861 if (eeprom93xx_read(s->eeprom)) {
862 val |= MEAR_EEDO;
864 #else
865 val |= MEAR_EEDO;
866 #endif
867 logging = LOG_EEPROM;
868 } else if (addr == DP8381X_PTSCR) { /* 0x0c */
869 /* TODO: emulate timing. */
870 uint32_t newval = val = op_reg_read(s, addr);
871 if (val & PTSCR_RBIST_EN) {
872 newval |= PTSCR_RBIST_DONE;
874 if (val & PTSCR_EELOAD_EN) {
875 /* EEPROM load takes 1500 us. */
876 newval &= ~PTSCR_EELOAD_EN;
878 if (val & PTSCR_EEBIST_EN) {
879 newval &= ~PTSCR_EEBIST_EN;
881 op_reg_write(s, addr, newval);
882 //~ logging = 0;
883 } else if (addr == DP8381X_ISR) { /* 0x10 */
884 val = op_reg_read(s, addr);
885 dp8381x_interrupt(s, ISR_CLEAR);
886 } else if (addr == DP8381X_IER) { /* 0x18 */
887 val = op_reg_read(s, addr);
888 } else if (addr == DP8381X_CCSR) { /* 0x3c */
889 val = op_reg_read(s, addr);
890 } else if (addr == DP8381X_WCSR) { /* 0x40 */
891 /* TODO: set bits on arp, unicast, wake-on-lan and other packets */
892 val = op_reg_read(s, addr);
893 //~ logging = 0;
894 } else if (addr == DP8381X_RFCR) { /* 0x48 */
895 val = op_reg_read(s, addr);
896 //~ logging = 0;
897 #if 0
898 } else if (addr == DP8381X_RFDR) { /* 0x4c */
899 val = op_reg_read(s, addr);
900 #endif
901 } else if (addr == DP8381X_SRR) { /* 0x58 */
902 val = op_reg_read(s, addr);
903 } else if (addr >= DP8381X_MIB0 && addr <= DP8381X_MIB6) { /* 0x60 ... 0x78 */
904 /* TODO: statistics counters. */
905 val = op_reg_read(s, addr);
906 /* TODO: check following cases for big endian target. */
907 } else if (addr == DP8381X_BMCR) { /* 0x80 */
908 val = bmcr_read(s);
909 logging = 0;
910 } else if (addr == DP8381X_BMSR) { /* 0x84 */
911 val = dp8381x_readw(s, addr);
912 logging = 0;
913 } else if (addr == DP8381X_ANAR) { /* 0x90 */
914 /* Needed for Windows. */
915 val = anar_read(s);
916 logging = 0;
917 } else if (addr == DP8381X_ANLPAR) { /* 0x94 */
918 /* Needed for Windows. */
919 val = anlpar_read(s);
920 logging = 0;
921 } else if (addr == DP8381X_PHYSTS) { /* 0xc0 */
922 /* Needed for Windows. */
923 val = phytst_read(s);
924 logging = 0;
925 } else {
926 val = op_reg_read(s, addr);
927 logging = 0;
928 logout("??? addr=%s val=0x%08x\n", dp8381x_regname(addr), val);
930 if (logging) {
931 logout("addr=%s val=0x%08x\n", dp8381x_regname(addr), val);
933 return val;
936 static void dp8381x_writeb(DP8381xState * s, hwaddr addr,
937 uint8_t val)
939 if (0) {
940 } else if (addr >= 256) {
941 logout("??? address too large, addr=%s val=0x%08x\n",
942 dp8381x_regname(addr), val);
943 } else {
944 logout("??? addr=%s val=0x%02x\n", dp8381x_regname(addr), val);
946 missing("byte access");
949 static void dp8381x_writew(DP8381xState * s, hwaddr addr,
950 uint16_t val)
952 int logging = 1;
953 if ((addr & 1) != 0) {
954 logout("??? address not on word boundary, addr=%s val=0x%08x\n",
955 dp8381x_regname(addr), val);
956 } else if (addr == DP8381X_RFDR) { /* 0x4c */
957 uint32_t rfaddr = (op_reg_read(s, DP8381X_RFCR) & RFCR_RFADDR);
958 if (rfaddr & 1) {
959 missing("odd rfaddr");
960 } else {
961 assert(rfaddr < sizeof(s->filter));
962 *(uint16_t *) & s->filter[rfaddr] = val;
964 //~ op_reg_write(s, addr, val);
965 } else if (addr < 0x80) {
966 logout("??? addr=%s val=0x%04x\n", dp8381x_regname(addr), val);
967 logging = 0;
968 } else if (addr >= 256) {
969 logout("??? address too large, addr=%s val=0x%08x\n",
970 dp8381x_regname(addr), val);
971 logging = 0;
972 } else if (addr == DP8381X_BMCR) { /* 0x80 */
973 if (val & BIT(15)) {
974 /* Reset PHY. */
975 logout("reset PHY\n");
976 val &= ~BIT(15);
978 phy_reg_write(s, addr, val);
979 logging = 0;
980 } else if (addr == DP8381X_MICR) { /* 0xc4 */
981 micr_write(s, val);
982 logging = 0;
983 } else if (addr == DP8381X_PGSEL) { /* 0xcc */
984 phy_reg_write(s, addr, val);
985 } else if (addr == DP8381X_PHYCR) { /* 0xe4 */
986 phy_reg_write(s, addr, val);
987 } else if (addr == DP8381X_DSPCFG) { /* 0xf4 */
988 phy_reg_write(s, addr, val);
989 } else if (addr == DP8381X_SDCFG) { /* 0xf8 */
990 phy_reg_write(s, addr, val);
991 } else if (addr == DP8381X_TSTDAT) { /* 0xfc */
992 phy_reg_write(s, addr, val);
993 } else {
994 logout("??? addr=%s val=0x%04x\n", dp8381x_regname(addr), val);
995 phy_reg_write(s, addr, val);
996 logging = 0;
998 if (logging) {
999 logout("addr=%s val=0x%08x\n", dp8381x_regname(addr), val);
1003 static void dp8381x_writel(DP8381xState * s, hwaddr addr,
1004 uint32_t val)
1006 int logging = 1;
1007 if ((addr & 3) != 0) {
1008 logout("??? address not on double word boundary, addr=%s val=0x%08x\n",
1009 dp8381x_regname(addr), val);
1010 logging = 0;
1011 } else if (addr >= 256) {
1012 logout("??? address too large, addr=%s val=0x%08x\n",
1013 dp8381x_regname(addr), val);
1014 logging = 0;
1015 } else if (addr == DP8381X_CR) { /* 0x00 */
1016 if (val & CR_RST) {
1017 dp8381x_reset(s);
1018 } else {
1019 if (val & CR_SWI) {
1020 dp8381x_interrupt(s, ISR_SWI);
1022 if (val & CR_RXR) {
1023 s->rx_state = idle;
1025 if (val & CR_TXR) {
1026 s->tx_state = idle;
1028 if (val & CR_RXD) {
1029 val &= ~CR_RXE;
1030 s->rx_state = idle;
1031 } else if (val & CR_RXE) {
1032 s->rx_state = active;
1033 /* TODO: handle queued receive data. */
1035 if (val & CR_TXD) {
1036 val &= ~CR_TXE;
1037 s->tx_state = idle;
1038 } else if (val & CR_TXE) {
1039 s->tx_state = active;
1040 dp8381x_transmit(s);
1042 val &= ~(CR_RXR | CR_TXR | CR_RXD | CR_TXD);
1043 op_reg_write(s, addr, val);
1045 } else if (addr == DP8381X_CFG) { /* 0x04 */
1046 if (val & CFG_BEM) {
1047 missing("big endian mode");
1049 val &= ~(CFG_LNKSTS | CFG_SPEED100 | CFG_FDUP | CFG_POL);
1050 if (val & BIT(13)) {
1051 /* Auto-negotiation enabled. */
1052 val |= CFG_ANEG_DN;
1053 #if 0
1054 dp8381x_interrupt(s, ISR_PHY);
1055 #endif
1057 op_reg_write(s, addr, val);
1058 } else if (addr == DP8381X_MEAR) { /* 0x08 */
1059 #if defined(CONFIG_EEPROM)
1060 int eecs = ((val & MEAR_EESEL) != 0);
1061 int eesk = ((val & MEAR_EECLK) != 0);
1062 int eedi = ((val & MEAR_EEDI) != 0);
1063 eeprom93xx_write(s->eeprom, eecs, eesk, eedi);
1064 #endif
1065 op_reg_write(s, addr, val);
1066 if (val & 0x000000f0) {
1067 missing("MII access");
1069 } else if (addr == DP8381X_PTSCR) { /* 0x0c */
1070 if (val & PTSCR_EELOAD_EN) {
1071 val &= ~PTSCR_EELOAD_EN;
1073 if (val != 0) {
1074 missing("test control");
1076 op_reg_write(s, addr, val);
1077 logging = LOG_EEPROM;
1078 } else if (addr == DP8381X_IMR) { /* 0x14 */
1079 op_reg_write(s, addr, val);
1080 dp8381x_interrupt(s, ISR_UPDATE);
1081 } else if (addr == DP8381X_IER) { /* 0x18 */
1082 op_reg_write(s, addr, val);
1083 dp8381x_interrupt(s, ISR_UPDATE);
1084 } else if (addr == DP8381X_TXDP) { /* 0x20 */
1085 /* Transmit descriptor must be lword aligned. */
1086 assert(!(val & 3));
1087 op_reg_write(s, addr, val);
1088 /* TODO: Clear CTDD. */
1089 //~ s->txdp = val;
1090 } else if (addr == DP8381X_TXCFG) { /* 0x24 */
1091 /* TODO. */
1092 op_reg_write(s, addr, val);
1093 } else if (addr == DP8381X_RXDP) { /* 0x30 */
1094 /* Receive descriptor must be lword aligned. */
1095 assert(!(val & 3));
1096 op_reg_write(s, addr, val);
1097 //~ s->rxdp = val;
1098 } else if (addr == DP8381X_RXCFG) { /* 0x34 */
1099 /* TODO: set flags for receive. */
1100 op_reg_write(s, addr, val);
1101 } else if (addr == DP8381X_CCSR) { /* 0x3c */
1102 /* TODO. */
1103 op_reg_write(s, addr, val);
1104 } else if (addr == DP8381X_WCSR) { /* 0x40 */
1105 op_reg_write(s, addr, val);
1106 if (val != 0) {
1107 missing("wake on lan");
1109 } else if (addr == DP8381X_PCR) { /* 0x44 */
1110 val &= ~BIT(16);
1111 op_reg_write(s, addr, val);
1112 } else if (addr == DP8381X_RFCR) { /* 0x48 */
1113 /* TODO: enable packet filters */
1114 op_reg_write(s, addr, val);
1115 /* RFCR_RFADDR must be even. */
1116 assert(!(val & 1));
1117 } else if (addr == DP8381X_RFDR) { /* 0x4c */
1118 /* TODO. */
1119 uint32_t rfaddr = (op_reg_read(s, DP8381X_RFCR) & RFCR_RFADDR);
1120 if (rfaddr & 1) {
1121 missing("odd rfaddr");
1122 } else {
1123 assert(rfaddr < sizeof(s->filter));
1124 *(uint16_t *) & s->filter[rfaddr] = val;
1126 //~ op_reg_write(s, addr, val);
1127 } else if (addr == DP8381X_MIBC) { /* 0x5c */
1128 if (val & MIBC_MIBS) {
1129 val &= ~MIBC_MIBS;
1130 missing("MIB Counter Stroke");
1132 if (val & MIBC_ACLR) {
1133 /* Clear all counters. */
1134 uint32_t offset;
1135 val &= ~MIBC_ACLR;
1136 for (offset = DP8381X_MIB0; offset <= DP8381X_MIB6; offset += 4) {
1137 op_reg_write(s, offset, 0);
1140 /* TODO: handle MIBC_WRN. */
1141 op_reg_write(s, addr, val);
1142 } else if (addr == DP8381X_MICR) { /* 0xc4 */
1143 /* Needed for Windows. */
1144 micr_write(s, val);
1145 logging = 0;
1146 } else if (addr == DP8381X_MISR) { /* 0xc8 */
1147 /* Needed for Windows. */
1148 phy_reg_write(s, addr, val);
1149 } else if (addr == DP8381X_PGSEL) { /* 0xcc */
1150 /* Needed for Windows. */
1151 phy_reg_write(s, addr, val);
1152 } else if (addr == DP8381X_PHYCR) { /* 0xe4 */
1153 /* Needed for Windows. */
1154 phy_reg_write(s, addr, val);
1155 } else if (addr == DP8381X_00EC) { /* 0xec */
1156 /* Needed for Windows. */
1157 phy_reg_write(s, addr, val);
1158 } else {
1159 op_reg_write(s, addr, val);
1160 logout("??? addr=%s val=0x%08x\n", dp8381x_regname(addr), val);
1161 logging = 0;
1163 if (logging) {
1164 logout("addr=%s val=0x%08x\n", dp8381x_regname(addr), val);
1168 /*****************************************************************************
1170 * I/O interface.
1172 ****************************************************************************/
1174 static uint64_t dp8381x_read(void *opaque, hwaddr addr,
1175 unsigned size)
1177 DP8381xState *s = opaque;
1178 uint64_t val = 0;
1179 switch (size) {
1180 case 1:
1181 val = dp8381x_readb(s, addr);
1182 break;
1183 case 2:
1184 val = dp8381x_readw(s, addr);
1185 break;
1186 case 4:
1187 val = dp8381x_readl(s, addr);
1188 break;
1189 default:
1190 assert(!"bad size");
1192 logout("%u, %s, 0x%08" PRIx64 "\n", size, dp8381x_regname(addr), val);
1193 return val;
1196 static void dp8381x_write(void *opaque, hwaddr addr,
1197 uint64_t val, unsigned size)
1199 DP8381xState *s = opaque;
1200 logout("%u, %s, 0x%08" PRIx64 "\n", size, dp8381x_regname(addr), val);
1201 switch (size) {
1202 case 1:
1203 dp8381x_writeb(s, addr, val);
1204 break;
1205 case 2:
1206 dp8381x_writew(s, addr, val);
1207 break;
1208 case 4:
1209 dp8381x_writel(s, addr, val);
1210 break;
1211 default:
1212 assert(!"bad size");
1216 static const MemoryRegionOps dp8381x_ops = {
1217 .read = dp8381x_read,
1218 .write = dp8381x_write,
1219 //~ .endianness = DEVICE_LITTLE_ENDIAN,
1220 .endianness = DEVICE_NATIVE_ENDIAN,
1223 static void nic_cleanup(NetClientState *ncs)
1225 DP8381xState *s = qemu_get_nic_opaque(ncs);
1227 /* TODO: replace NULL by &dev->qdev. */
1228 unregister_savevm(NULL, "dp8381x", s);
1230 #if 0
1231 timer_del(d->poll_timer);
1232 timer_free(d->poll_timer);
1233 #endif
1236 #if defined(CONFIG_EEPROM)
1237 /* SWAP_BITS is needed for buggy Linux driver. */
1238 #define SWAP_BITS(x) ( (((x) & 0x0001) << 15) | (((x) & 0x0002) << 13) \
1239 | (((x) & 0x0004) << 11) | (((x) & 0x0008) << 9) \
1240 | (((x) & 0x0010) << 7) | (((x) & 0x0020) << 5) \
1241 | (((x) & 0x0040) << 3) | (((x) & 0x0080) << 1) \
1242 | (((x) & 0x0100) >> 1) | (((x) & 0x0200) >> 3) \
1243 | (((x) & 0x0400) >> 5) | (((x) & 0x0800) >> 7) \
1244 | (((x) & 0x1000) >> 9) | (((x) & 0x2000) >> 11) \
1245 | (((x) & 0x4000) >> 13) | (((x) & 0x8000) >> 15) )
1247 static void eeprom_init(DP8381xState * s)
1249 #if 0
1250 uint8_t *pci_conf = s->dev.config;
1251 #endif
1252 uint8_t i;
1253 uint16_t *eeprom_contents = eeprom93xx_data(s->eeprom);
1255 logout("\n");
1257 memcpy(eeprom_contents, eeprom_default, sizeof(eeprom_default));
1259 /* Patch MAC address into EEPROM data. */
1260 eeprom_contents[6] =
1261 (eeprom_contents[6] & 0x7fff) + ((s->conf.macaddr.a[0] & 1) << 15);
1262 eeprom_contents[7] =
1263 (s->conf.macaddr.a[0] >> 1) + (s->conf.macaddr.a[1] << 7) +
1264 ((s->conf.macaddr.a[2] & 1) << 15);
1265 eeprom_contents[8] =
1266 (s->conf.macaddr.a[2] >> 1) + (s->conf.macaddr.a[3] << 7) +
1267 ((s->conf.macaddr.a[4] & 1) << 15);
1268 eeprom_contents[9] =
1269 (s->conf.macaddr.a[4] >> 1) + (s->conf.macaddr.a[5] << 7) +
1270 (eeprom_contents[9] & 0x8000);
1272 /* The Linux driver natsemi.c is buggy because it reads the bits from
1273 * EEPROM in wrong order (low to high). So we must reverse the bit order
1274 * to get the correct mac address. */
1275 for (i = 6; i < 10; i++) {
1276 eeprom_contents[i] = SWAP_BITS(eeprom_contents[i]);
1279 /* Fix EEPROM checksum. */
1280 uint8_t sum = 0;
1281 for (i = 0; i < 11; i++) {
1282 sum += (eeprom_contents[i] & 255);
1283 sum += (eeprom_contents[i] >> 8);
1285 sum += 0x55;
1286 sum = -sum;
1287 eeprom_contents[i] = (sum << 8) + 0x55;
1289 #if 0
1290 // EEPROM Bit 20 NCPEN!!!
1291 pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
1292 PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
1293 // EEPROM Bits 16...31!!!
1294 /* TODO Split using PCI_CONFIG8. */
1295 pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x340b0100); // MNGNT = 11, MXLAT = 52, IPIN = 0
1296 // EEPROM Bits 31...27, 21!!!
1297 pci_set_long(pci_conf + 0x40, 0xff820001); /* Power Management Capabilities */
1298 // EEPROM Bit 8!!!
1299 pci_set_long(pci_conf + 0x44, 0x00000000); /* Power Management Control and Status */
1301 // EEPROM Bits 16, 15-13!!!
1302 OP_REG(DP8381X_CFG, 0x00000000); /* Configuration and Media Status */
1303 #endif
1305 #endif
1307 static NetClientInfo net_info = {
1308 .type = NET_CLIENT_OPTIONS_KIND_NIC,
1309 .size = sizeof(NICState),
1310 .can_receive = nic_can_receive,
1311 .receive = nic_receive,
1312 .cleanup = nic_cleanup,
1315 static int pci_dp8381x_init(PCIDevice *pci_dev, uint32_t silicon_revision)
1317 DP8381xState *s = DO_UPCAST(DP8381xState, dev, pci_dev);
1318 uint8_t *pci_conf = pci_dev->config;
1320 logout("silicon revision = 0x%08x\n", silicon_revision);
1322 pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
1323 PCI_STATUS_FAST_BACK | PCI_STATUS_CAP_LIST);
1324 /* ethernet network controller */
1325 pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
1326 /* Address registers are set by pci_register_bar. */
1327 /* Capabilities Pointer, CLOFS */
1328 pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x00000040);
1329 /* 0x38 reserved, returns 0 */
1330 /* MNGNT = 11, MXLAT = 52, IPIN = 0 */
1331 /* TODO Split using PCI_CONFIG8. */
1332 pci_set_long(pci_conf + PCI_INTERRUPT_LINE, 0x340b0100);
1333 /* Power Management Capabilities */
1334 pci_set_long(pci_conf + 0x40, 0xff820001);
1335 /* Power Management Control and Status */
1336 //~ pci_set_long(pci_conf + 0x44, 0x00000000);
1337 /* 0x48...0xff reserved, returns 0 */
1339 s->silicon_revision = silicon_revision;
1341 /* Handler for memory-mapped I/O */
1342 /* TODO: check size for mmio_bar and io_bar. */
1343 memory_region_init_io(&s->io_bar, &dp8381x_ops, s, "dp8381x_io",
1344 DP8381X_IO_SIZE);
1345 memory_region_init_io(&s->mmio_bar, &dp8381x_ops, s, "dp8381x_mmio",
1346 DP8381X_MEM_SIZE);
1348 pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
1349 pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_bar);
1351 qemu_macaddr_default_if_unset(&s->conf.macaddr);
1352 dp8381x_reset(s);
1354 #if defined(CONFIG_EEPROM)
1355 /* Add EEPROM (16 x 16 bit). */
1356 s->eeprom = eeprom93xx_new(&pci_dev->qdev, EEPROM_SIZE);
1357 eeprom_init(s);
1358 #endif
1360 s->nic = qemu_new_nic(&net_info, &s->conf,
1361 object_get_typename(OBJECT(pci_dev)),
1362 pci_dev->qdev.id, s);
1364 qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
1366 return 0;
1369 static int dp8381x_init(PCIDevice *pci_dev)
1371 logout("\n");
1372 #if defined(DP83815)
1373 return pci_dp8381x_init(pci_dev, DP83815DVNG);
1374 #else
1375 return pci_dp8381x_init(pci_dev, DP83816AVNG);
1376 #endif
1379 static void dp8381x_exit(PCIDevice *pci_dev)
1381 DP8381xState *s = DO_UPCAST(DP8381xState, dev, pci_dev);
1382 memory_region_destroy(&s->mmio_bar);
1383 memory_region_destroy(&s->io_bar);
1384 qemu_del_nic(s->nic);
1387 static void qdev_dp8381x_reset(DeviceState *dev)
1389 DP8381xState *d = DO_UPCAST(DP8381xState, dev.qdev, dev);
1390 dp8381x_reset(d);
1393 static Property dp8381x_properties[] = {
1394 DEFINE_NIC_PROPERTIES(DP8381xState, conf),
1395 DEFINE_PROP_END_OF_LIST(),
1398 static const VMStateDescription vmstate_dp8381x = {
1399 .name = "dp8381x",
1400 .version_id = 20060726,
1401 .minimum_version_id = 20060726,
1402 .minimum_version_id_old = 20060726,
1403 .fields = (VMStateField []) {
1404 VMSTATE_PCI_DEVICE(dev, DP8381xState),
1405 /* TODO: Add missing entries here. */
1406 VMSTATE_END_OF_LIST()
1410 static void dp8381x_class_init(ObjectClass *klass, void *data)
1412 DeviceClass *dc = DEVICE_CLASS(klass);
1413 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1415 #if defined(DP83815)
1416 dc->desc = "National Semiconductor DP83815";
1417 #else
1418 dc->desc = "National Semiconductor DP83816",
1419 #endif
1420 dc->props = dp8381x_properties;
1421 dc->reset = qdev_dp8381x_reset;
1422 dc->vmsd = &vmstate_dp8381x;
1423 k->romfile = "pxe-dp83816.rom";
1424 k->init = dp8381x_init;
1425 k->exit = dp8381x_exit;
1426 /* National Semiconductor DP83815, DP83816 */
1427 k->vendor_id = PCI_VENDOR_ID_NS;
1428 k->class_id = PCI_CLASS_NETWORK_ETHERNET;
1429 k->device_id = PCI_DEVICE_ID_NS_83815;
1430 //~ k->revision = 0x01;
1431 //~ k->subsystem_vendor_id = info->subsystem_vendor_id;
1432 //~ k->subsystem_id = info->subsystem_id;
1435 #if defined(DP83815)
1436 static const TypeInfo dp8381x_info = {
1437 .name = "dp83815",
1438 .parent = TYPE_PCI_DEVICE,
1439 .instance_size = sizeof(DP8381xState),
1440 .class_init = dp8381x_class_init,
1442 #else
1443 static const TypeInfo dp8381x_info = {
1444 .name = "dp83816",
1445 .parent = TYPE_PCI_DEVICE,
1446 .instance_size = sizeof(DP8381xState),
1447 .class_init = dp8381x_class_init,
1449 #endif
1451 static void dp8381x_register_types(void)
1453 type_register_static(&dp8381x_info);
1456 type_init(dp8381x_register_types)
1458 /* eof */