3 * DM9000 Ethernet interface
5 * Copyright Daniel Silverstone and Vincent Sanders
6 * Copyright Michel Pollet <buserror@gmail.com>
8 * This file is under the terms of the GNU General Public
13 #include "qemu-common.h"
19 /* Comment this out if you don't want register debug on stderr */
20 //#define DM9000_DEBUG
22 /* Comment this out if you don't want a packet dump */
23 //#define DM9000_DUMP_FILENAME "/tmp/dm9k_dump"
26 #define DM9000_DBF(X...) fprintf(stderr, X)
28 #define DM9000_DBF(X...) if(0) fprintf(stderr, X)
31 #define DM9000_REG_NCR 0x00
32 #define DM9000_NCR_RESET (1 << 0)
34 #define DM9000_NCR_EXT_PHY (1<<7)
35 #define DM9000_NCR_WAKEEN (1<<6)
36 #define DM9000_NCR_FCOL (1<<4)
37 #define DM9000_NCR_FDX (1<<3)
38 #define DM9000_NCR_LBK (3<<1)
40 #define DM9000_NCR_RESETPROTECT (DM9000_NCR_EXT_PHY | DM9000_NCR_WAKEEN)
42 #define DM9000_REG_NSR 0x01
44 #define DM9000_NSR_SPEED (1<<7)
45 #define DM9000_NSR_LINKST (1<<6)
46 #define DM9000_NSR_WAKEST (1<<5)
47 #define DM9000_NSR_TX2END (1<<3)
48 #define DM9000_NSR_TX1END (1<<2)
49 #define DM9000_NSR_RXOV (1<<1)
51 #define DM9000_NSR_RESETPROTECT (DM9000_NSR_WAKEST)
52 #define DM9000_NSR_READONLY (DM9000_NSR_SPEED|DM9000_NSR_LINKST|(1<<4)|DM9000_NSR_RXOV|(1<<0))
54 #define DM9000_REG_TCR 0x02
55 #define DM9000_TCR_TXREQ (1 << 0)
57 #define DM9000_REG_TSR1 0x03
58 #define DM9000_REG_TSR2 0x04
59 #define DM9000_REG_RCR 0x05
60 #define DM9000_RCR_DIS_LONG (1 << 5) /* RX Discard long frames (>1522) */
61 #define DM9000_RCR_DIS_CRC (1 << 4) /* RX Discard bad CRC */
62 #define DM9000_RCR_ALL (1 << 3) /* RX Pass All Multicast */
63 #define DM9000_RCR_RUNT (1 << 2) /* RX Pass Runt Frames (frame < 64 bytes) */
64 #define DM9000_RCR_PRMSC (1 << 1) /* RX Promiscuous Mode */
65 #define DM9000_RCR_RXEN (1 << 0) /* RX Enabled */
67 #define DM9000_REG_RSR 0x06
68 #define DM9000_RSR_RF (1 << 7) /* RX Runt Frame (frame < 64 bytes) */
69 #define DM9000_RSR_MF (1 << 6) /* RX Multicast Frame */
70 #define DM9000_RSR_FOE (1 << 0) /* RX FIFO overflow */
72 #define DM9000_REG_ROCR 0x07
73 #define DM9000_REG_BPTR 0x08
74 #define DM9000_REG_FCTR 0x09
75 #define DM9000_REG_FCR 0x0A
76 #define DM9000_FCR_TXP0 (1 << 7) /* TX Pause Packet (when empty) */
77 #define DM9000_FCR_TXPF (1 << 6) /* TX Pause Packet (when full) */
78 #define DM9000_FCR_TXPEN (1 << 5) /* Force pause/unpause packets */
79 #define DM9000_FCR_BKPA (1 << 4)
80 #define DM9000_FCR_BKPM (1 << 3)
81 #define DM9000_FCR_RXPS (1 << 2) /* RX Pause Packet Status, latch and read to clear */
82 #define DM9000_FCR_RXPCS (1 << 1) /* RX Pause Packet Current Status */
83 #define DM9000_FCR_FLCE (1 << 0) /* Flow Control Enable */
85 #define DM9000_REG_EPCR 0x0B
86 #define DM9000_REG_EPAR 0x0C
87 #define DM9000_REG_EPDRL 0x0D
88 #define DM9000_REG_EPDRH 0x0E
89 #define DM9000_REG_WCR 0x0F
90 #define DM9000_REG_PAR0 0x10
91 #define DM9000_REG_PAR1 0x11
92 #define DM9000_REG_PAR2 0x12
93 #define DM9000_REG_PAR3 0x13
94 #define DM9000_REG_PAR4 0x14
95 #define DM9000_REG_PAR5 0x15
96 #define DM9000_REG_MAR0 0x16
97 #define DM9000_REG_MAR1 0x17
98 #define DM9000_REG_MAR2 0x18
99 #define DM9000_REG_MAR3 0x19
100 #define DM9000_REG_MAR4 0x1A
101 #define DM9000_REG_MAR5 0x1B
102 #define DM9000_REG_MAR6 0x1C
103 #define DM9000_REG_MAR7 0x1D
104 #define DM9000_REG_GPCR 0x1E
105 #define DM9000_REG_GPR 0x1F
106 #define DM9000_REG_TRPAL 0x22
107 #define DM9000_REG_TRPAH 0x23
108 #define DM9000_REG_RWPAL 0x24
109 #define DM9000_REG_RWPAH 0x25
110 #define DM9000_REG_VIDL 0x28
111 #define DM9000_REG_VIDH 0x29
112 #define DM9000_REG_PIDL 0x2A
113 #define DM9000_REG_PIDH 0x2B
114 #define DM9000_REG_CHIPR 0x2C
115 #define DM9000_REG_SMCR 0x2F
116 #define DM9000_REG_MRCMDX 0xF0
117 #define DM9000_REG_MRCMD 0xF2
118 #define DM9000_REG_MRRL 0xF4
119 #define DM9000_REG_MRRH 0xF5
120 #define DM9000_REG_MWCMDX 0xF6
121 #define DM9000_REG_MWCMD 0xF8
122 #define DM9000_REG_MWRL 0xFA
123 #define DM9000_REG_MWRH 0xFB
124 #define DM9000_REG_TXPLL 0xFC
125 #define DM9000_REG_TXPLH 0xFD
126 #define DM9000_REG_ISR 0xFE
127 #define DM9000_ISR_ROOS (1<<3)
128 #define DM9000_ISR_ROS (1<<2)
129 #define DM9000_ISR_PTS (1<<1)
130 #define DM9000_ISR_PRS (1<<0)
131 #define DM9000_ISR_CLR_STATUS (ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS)
133 #define DM9000_REG_IMR 0xFF
134 #define DM9000_IMR_AUTOWRAP 0x80
137 #define DM9000_MII_READ 0x0C
138 #define DM9000_MII_WRITE 0x0A
140 #define DM9000_MII_REG_BMCR 0x00
141 #define DM9000_MII_REG_STATUS 0x01
142 #define DM9000_MII_REG_PHYID1 0x02
143 #define DM9000_MII_REG_PHYID2 0x03
144 #define DM9000_MII_REG_ANAR 0x04
145 #define DM9000_MII_REG_ANLPAR 0x05
146 #define DM9000_MII_REG_ANER 0x06
147 #define DM9000_MII_REG_DSCR 0x10
148 #define DM9000_MII_REG_DSCSR 0x11
149 #define DM9000_MII_REG_10BTCSR 0x12
152 DM9K_TX_FIFO_START
= 0,
153 DM9K_TX_FIFO_SIZE
= (3 * 1024),
155 DM9K_RX_FIFO_START
= DM9K_TX_FIFO_SIZE
,
156 DM9K_RX_FIFO_SIZE
= (13 * 1024),
158 DM9K_FIFO_SIZE
= (DM9K_TX_FIFO_SIZE
+ DM9K_RX_FIFO_SIZE
)
161 #define DM9K_WRAP_TX_INDEX(_v) ((_v >= DM9K_TX_FIFO_SIZE) ? (_v) - DM9K_TX_FIFO_SIZE : (_v))
162 #define DM9K_WRAP_RX_INDEX(_v) ((_v >= DM9K_FIFO_SIZE) ? (_v) - DM9K_RX_FIFO_SIZE : (_v))
163 /* DM9KNOTE: Assumes 16bit wiring */
164 #define DM9K_CLIP_TX_INDEX(_v) ((_v) & 1 ? DM9K_WRAP_TX_INDEX((_v)+1) : (_v))
165 #define DM9K_CLIP_RX_INDEX(_v) ((_v) & 1 ? DM9K_WRAP_RX_INDEX((_v)+1) : (_v))
168 uint32_t addr
; /* address port */
169 uint32_t data
; /* data port */
172 uint8_t macaddr
[6]; /* MAC address -- default to qemu, can/will be overridden by guest driver */
173 uint8_t mult
[8]; /* multicast filtering fields */
175 uint8_t address
; /* The internal magical register address */
178 * Transmit buffer is the first 3KB,
179 * followed by the receive buffer
181 uint8_t packet_buffer
[DM9K_FIFO_SIZE
];
184 uint16_t dm9k_rwpa
; /* TX Read ptr address, RX write ptr address */
187 uint16_t fc_high_mark
;
188 uint16_t fc_low_mark
;
191 uint16_t dm9k_mwr
; /* Read and write address registers */
192 uint16_t dm9k_txpl
; /* TX packet length */
194 uint8_t dm9k_imr
, dm9k_isr
; /* Interrupt mask register and status register*/
195 uint8_t dm9k_ncr
, dm9k_nsr
; /* Network control register, network status register */
196 uint8_t dm9k_rcr
; /* RX Control Register */
197 uint8_t dm9k_rsr
; /* RX Status Register */
198 uint8_t dm9k_wcr
; /* Wakeup control */
199 uint8_t dm9k_tcr
; /* Transmission control register */
200 uint8_t packet_copy_buffer
[DM9K_TX_FIFO_SIZE
]; /* realigned packet copy buffer */
201 unsigned int packet_index
:1; /* 0 == packet I, 1 == packet II */
203 /* Internal MII PHY state */
204 uint8_t dm9k_epcr
; /* EEPROM/PHY control register */
205 uint8_t dm9k_epar
; /* EEPROM/PHY address register */
206 uint16_t dm9k_epdr
; /* EEPROM/PHY data register */
208 uint16_t dm9k_mii_bmcr
;
209 uint16_t dm9k_mii_anar
;
210 uint16_t dm9k_mii_dscr
;
214 static void dm9000_save(QEMUFile
*f
, void *opaque
)
216 dm9000_state
*s
= (dm9000_state
*)opaque
;
218 qemu_put_be32s(f
, &s
->addr
);
219 qemu_put_be32s(f
, &s
->data
);
220 qemu_put_8s(f
, &s
->address
);
221 qemu_put_buffer(f
, s
->macaddr
, sizeof(s
->macaddr
));
222 qemu_put_buffer(f
, s
->mult
, sizeof(s
->mult
));
223 qemu_put_buffer(f
, s
->packet_buffer
, sizeof(s
->packet_buffer
));
224 qemu_put_buffer(f
, s
->packet_copy_buffer
, sizeof(s
->packet_copy_buffer
));
225 qemu_put_be16s(f
, &s
->dm9k_trpa
);
226 qemu_put_be16s(f
, &s
->dm9k_rwpa
);
227 qemu_put_8s(f
, &s
->fctr
);
228 qemu_put_8s(f
, &s
->fcr
);
229 qemu_put_be16s(f
, &s
->fc_high_mark
);
230 qemu_put_be16s(f
, &s
->fc_low_mark
);
231 qemu_put_be16s(f
, &s
->dm9k_mrr
);
232 qemu_put_be16s(f
, &s
->dm9k_mwr
);
233 qemu_put_be16s(f
, &s
->dm9k_txpl
);
234 qemu_put_8s(f
, &s
->dm9k_imr
);
235 qemu_put_8s(f
, &s
->dm9k_isr
);
236 qemu_put_8s(f
, &s
->dm9k_ncr
);
237 qemu_put_8s(f
, &s
->dm9k_nsr
);
238 qemu_put_8s(f
, &s
->dm9k_rcr
);
239 qemu_put_8s(f
, &s
->dm9k_rsr
);
240 qemu_put_8s(f
, &s
->dm9k_wcr
);
241 qemu_put_8s(f
, &s
->dm9k_tcr
);
242 qemu_put_8s(f
, &s
->dm9k_epcr
);
243 qemu_put_8s(f
, &s
->dm9k_epar
);
244 qemu_put_be16s(f
, &s
->dm9k_epdr
);
245 qemu_put_be16s(f
, &s
->dm9k_mii_bmcr
);
246 qemu_put_be16s(f
, &s
->dm9k_mii_anar
);
247 qemu_put_be16s(f
, &s
->dm9k_mii_dscr
);
250 static int dm9000_load(QEMUFile
*f
, void *opaque
, int version_id
)
252 dm9000_state
*s
= (dm9000_state
*)opaque
;
253 qemu_get_be32s(f
, &s
->addr
);
254 qemu_get_be32s(f
, &s
->data
);
255 qemu_get_8s(f
, &s
->address
);
256 qemu_get_buffer(f
, s
->macaddr
, sizeof(s
->macaddr
));
257 qemu_get_buffer(f
, s
->mult
, sizeof(s
->mult
));
258 qemu_get_buffer(f
, s
->packet_buffer
, sizeof(s
->packet_buffer
));
259 qemu_get_buffer(f
, s
->packet_copy_buffer
, sizeof(s
->packet_copy_buffer
));
260 qemu_get_be16s(f
, &s
->dm9k_trpa
);
261 qemu_get_be16s(f
, &s
->dm9k_rwpa
);
262 qemu_get_8s(f
, &s
->fctr
);
263 qemu_get_8s(f
, &s
->fcr
);
264 qemu_get_be16s(f
, &s
->fc_high_mark
);
265 qemu_get_be16s(f
, &s
->fc_low_mark
);
266 qemu_get_be16s(f
, &s
->dm9k_mrr
);
267 qemu_get_be16s(f
, &s
->dm9k_mwr
);
268 qemu_get_be16s(f
, &s
->dm9k_txpl
);
269 qemu_get_8s(f
, &s
->dm9k_imr
);
270 qemu_get_8s(f
, &s
->dm9k_isr
);
271 qemu_get_8s(f
, &s
->dm9k_ncr
);
272 qemu_get_8s(f
, &s
->dm9k_nsr
);
273 qemu_get_8s(f
, &s
->dm9k_rcr
);
274 qemu_get_8s(f
, &s
->dm9k_rsr
);
275 qemu_get_8s(f
, &s
->dm9k_wcr
);
276 qemu_get_8s(f
, &s
->dm9k_tcr
);
277 qemu_get_8s(f
, &s
->dm9k_epcr
);
278 qemu_get_8s(f
, &s
->dm9k_epar
);
279 qemu_get_be16s(f
, &s
->dm9k_epdr
);
280 qemu_get_be16s(f
, &s
->dm9k_mii_bmcr
);
281 qemu_get_be16s(f
, &s
->dm9k_mii_anar
);
282 qemu_get_be16s(f
, &s
->dm9k_mii_dscr
);
287 #ifdef DM9000_DUMP_FILENAME
288 #include <arpa/inet.h>
289 static uint8_t pcap_header
[24] = {
290 0xA1, 0xB2, 0xC3, 0xD4, /* TCPDUMP Magic */
291 0x00, 0x02, 0x00, 0x04, /* Major 2, Minor 4 */
292 0x00, 0x00, 0x00, 0x00, /* Timezone offset */
293 0x00, 0x00, 0x00, 0x01, /* Accuracy of timestamps */
294 0x00, 0x00, 0x0C, 0x00, /* Snaplen 3KiB */
295 0x00, 0x00, 0x00, 0x01, /* Ethernet frames */
297 static uint8_t nulls
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
298 static void dm9k_dump_packet(uint8_t *buf
, uint32_t size
)
300 FILE* dm9k_fileh
= fopen(DM9000_DUMP_FILENAME
, "ab+");
301 unsigned long bsize
= htonl(size
);
302 DM9000_DBF("Dumping packet at %08x (%d bytes)\n", buf
, size
);
303 fseek(dm9k_fileh
, 0, SEEK_END
);
304 if(ftell(dm9k_fileh
)==0) fwrite(pcap_header
, 1, 24, dm9k_fileh
);
305 fwrite(nulls
, 1, 8, dm9k_fileh
);
306 fwrite(&bsize
, 1, 4, dm9k_fileh
);
307 fwrite(&bsize
, 1, 4, dm9k_fileh
);
308 fwrite(buf
, 1, size
, dm9k_fileh
);
312 #define dm9k_dump_packet(X...) do { } while(0)
316 static void dm9000_raise_irq(dm9000_state
*s
)
318 int level
= ((s
->dm9k_isr
& s
->dm9k_imr
) & 0x0f) != 0;
319 //DM9000_DBF("DM9000: Set IRQ level %d (isr = %02x imr %02x\n", level, s->dm9k_isr, s->dm9k_imr);
320 qemu_set_irq(s
->irq
, level
);
323 static void dm9000_soft_reset_mii(dm9000_state
*s
)
325 s
->dm9k_mii_bmcr
= 0x3100; /* 100Mbps, AUTONEG, FULL DUPLEX */
326 s
->dm9k_mii_anar
= 0x01E1;
327 s
->dm9k_mii_dscr
= 0x0410;
330 static void dm9000_soft_reset(dm9000_state
*s
)
332 DM9000_DBF("DM9000: Soft Reset\n");
334 s
->dm9k_mwr
= s
->dm9k_trpa
= DM9K_TX_FIFO_START
;
335 s
->dm9k_mrr
= s
->dm9k_rwpa
= DM9K_RX_FIFO_START
;
337 s
->dm9k_isr
= 0; /* 16 bit mode, no interrupts asserted */
342 s
->fctr
= (3 << 4) | (8 << 0); // flow control high/low marks
343 s
->fc_high_mark
= 3 * 1024;
344 s
->fc_low_mark
= 8 * 1024;
347 memset(s
->packet_buffer
, 0, sizeof(s
->packet_buffer
));
348 memset(s
->packet_copy_buffer
, 0, sizeof(s
->packet_copy_buffer
));
349 /* These registers have some bits "unaffected by software reset" */
350 /* Clear the reset bits */
351 s
->dm9k_ncr
&= DM9000_NCR_RESETPROTECT
;
352 s
->dm9k_nsr
&= DM9000_NSR_RESETPROTECT
;
353 /* Claim full duplex */
354 s
->dm9k_ncr
|= DM9000_NCR_FDX
;
355 /* Set link status to 1 */
356 s
->dm9k_nsr
|= DM9000_NSR_LINKST
;
357 /* dm9k_wcr is unaffected or reserved, never reset */
358 /* MII control regs */
362 dm9000_soft_reset_mii(s
);
363 dm9000_raise_irq(s
); /* Clear any potentially pending IRQ */
366 static void dm9000_hard_reset(dm9000_state
*s
)
371 dm9000_soft_reset(s
);
374 static uint16_t dm9000_get_rx_fifo_fill_state(dm9000_state
*s
)
377 if (s
->dm9k_mrr
> s
->dm9k_rwpa
)
378 res
= (DM9K_FIFO_SIZE
-s
->dm9k_rwpa
) + (s
->dm9k_mrr
-DM9K_RX_FIFO_START
);
380 res
= s
->dm9k_rwpa
- s
->dm9k_mrr
;
384 static void dm9000_do_transmit(dm9000_state
*s
) {
385 uint16_t idx
, cnt
, tptr
;
389 if (cnt
> DM9K_TX_FIFO_SIZE
)
390 cnt
= DM9K_TX_FIFO_SIZE
; /* HARD CAP AT 3KiB */
394 s
->packet_copy_buffer
[tptr
++] = s
->packet_buffer
[idx
];
395 idx
= DM9K_WRAP_TX_INDEX(idx
+1);
400 uint8_t *buf
= &s
->packet_copy_buffer
[6];
401 DM9000_DBF("TX_Packet: %02x:%02x:%02x:%02x:%02x:%02x %d bytes from %04x\n",
402 buf
[0],buf
[1],buf
[2],buf
[3],buf
[4],buf
[5],
404 // hexdump(s->packet_copy_buffer, tptr);
408 s
->dm9k_trpa
= DM9K_CLIP_TX_INDEX(idx
);
409 dm9k_dump_packet(s
->packet_copy_buffer
, s
->dm9k_txpl
);
410 /* We have the copy buffer, now we do the transmit */
411 qemu_send_packet(s
->vc
, s
->packet_copy_buffer
, s
->dm9k_txpl
);
413 /* Clear the "please xmit" bit */
414 s
->dm9k_tcr
&= ~DM9000_TCR_TXREQ
;
415 /* Set the TXEND bit */
416 s
->dm9k_nsr
|= 1 << (2 + s
->packet_index
);
417 DM9000_DBF("TX: NSR=%02x PI=%d\n", s
->dm9k_nsr
, s
->packet_index
);
418 /* Claim a TX complete IRQ */
419 s
->dm9k_isr
|= DM9000_ISR_PTS
; /* Packet transmitted latch */
420 /* And flip the next-packet bit */
426 static void dm9000_mii_read(dm9000_state
*s
)
428 int mii_reg
= (s
->dm9k_epar
) & 0x3f;
431 case DM9000_MII_REG_BMCR
:
432 ret
= s
->dm9k_mii_bmcr
;
434 case DM9000_MII_REG_STATUS
:
435 ret
= 0x782D; /* No 100/T4, Can 100/FD, Can 100/HD, Can 10/FD, Can 10/HD,
436 * No Preamble suppression, Autoneg complete, No remote fault,
437 * Can autoneg, link up, no jabber, extended capability */
439 case DM9000_MII_REG_PHYID1
:
442 case DM9000_MII_REG_PHYID2
:
445 case DM9000_MII_REG_ANAR
:
446 ret
= s
->dm9k_mii_anar
;
448 case DM9000_MII_REG_ANLPAR
:
451 case DM9000_MII_REG_ANER
:
454 case DM9000_MII_REG_DSCR
:
455 ret
= s
->dm9k_mii_dscr
;
457 case DM9000_MII_REG_DSCSR
:
460 case DM9000_MII_REG_10BTCSR
:
463 printf("%s: Bad register 0x%lx\n", __FUNCTION__
, (unsigned long)mii_reg
);
466 // DM9000_DBF("DM9000:MIIPHY: Read of MII reg %d gives %04x\n", mii_reg, s->dm9k_epdr);
469 static void dm9000_mii_write(dm9000_state
*s
)
471 int mii_reg
= (s
->dm9k_epar
) & 0x3f;
472 DM9000_DBF("DM9000:MIIPHY: Write of MII reg %d value %04x\n", mii_reg
, s
->dm9k_epdr
);
474 case DM9000_MII_REG_BMCR
:
475 s
->dm9k_mii_bmcr
= (s
->dm9k_epdr
&~0x8000);
476 if( s
->dm9k_epdr
& 0x8000 ) dm9000_soft_reset_mii(s
);
478 case DM9000_MII_REG_ANAR
:
479 s
->dm9k_mii_anar
= s
->dm9k_epdr
;
481 case DM9000_MII_REG_DSCR
:
482 s
->dm9k_mii_dscr
= s
->dm9k_epdr
& ~0x0008;
485 printf("%s: Bad register 0x%lx=%4x\n", __FUNCTION__
, (unsigned long)mii_reg
, s
->dm9k_epdr
);
489 static void dm9000_write(void *opaque
, target_phys_addr_t address
,
492 dm9000_state
*s
= (dm9000_state
*)opaque
;
494 int suppress_debug
= 0;
497 if (address
== s
->addr
) {
498 // if( (value != DM9000_REG_MRCMD) && (value != DM9000_REG_MWCMD) )
499 // DM9000_DBF("DM9000: Address set to 0x%02x\n", value);
506 DM9000_DBF("DM9000_REG_NCR: %02x=%04x\n", s
->address
, value
);
507 s
->dm9k_ncr
= value
| DM9000_NCR_FDX
;
508 if (s
->dm9k_ncr
& DM9000_NCR_RESET
)
509 dm9000_soft_reset(s
);
512 s
->dm9k_nsr
&= ~(value
& ~DM9000_NSR_READONLY
);
515 s
->dm9k_tcr
= value
& 0xFF;
516 if ( value
& DM9000_TCR_TXREQ
)
517 dm9000_do_transmit(s
);
519 case DM9000_REG_EPCR
:
520 s
->dm9k_epcr
= value
& 0xFF;
521 if( value
& DM9000_MII_READ
)
523 else if( value
& DM9000_MII_WRITE
)
527 s
->dm9k_rcr
= value
& 0xFF;
530 case DM9000_REG_BPTR
: /* can be ignored */
533 case DM9000_REG_FCTR
: {/* 0x09 Flow Control Threshold Register */
534 s
->fc_high_mark
= ((value
>> 4) & 0xf) * 1024; // emit a pause packet time=0xffff
535 s
->fc_low_mark
= ((value
) & 0xf) * 1024; // emit an unpause packet time=0x0000
539 case DM9000_REG_FCR
: /* 0x0a Flow Control Register */
543 case DM9000_REG_EPAR
:
544 s
->dm9k_epar
= value
& 0xFF;
546 case DM9000_REG_EPDRL
:
547 s
->dm9k_epdr
&= 0xFF00;
548 s
->dm9k_epdr
|= value
& 0xFF;
550 case DM9000_REG_EPDRH
:
551 s
->dm9k_epdr
&= 0xFF;
552 s
->dm9k_epdr
|= (value
& 0xFF) << 8;
554 case DM9000_REG_PAR0
... DM9000_REG_PAR5
:
555 /* MAC address is set by the QEMU Nic */
556 s
->macaddr
[s
->address
- DM9000_REG_PAR0
] = value
;
558 case DM9000_REG_MAR0
... DM9000_REG_MAR7
:
559 /* Multicast address is ignored */
560 s
->mult
[s
->address
- DM9000_REG_MAR0
] = value
;
562 case DM9000_REG_GPCR
:
563 case DM9000_REG_GPR
: /* General purpose reg (GPIOs, LED?) */
565 case DM9000_REG_SMCR
:
567 printf("%s: something playing with special mode ? 0x%lx=%x\n", __FUNCTION__
, (unsigned long)s
->address
, value
);
569 case DM9000_REG_MRRL
:
570 s
->dm9k_mrr
&= 0xFF00;
571 s
->dm9k_mrr
|= value
& 0xFF;
573 case DM9000_REG_MRRH
:
575 s
->dm9k_mrr
|= (value
& 0xFF) << 8;
577 case DM9000_REG_MWCMDX
:
578 case DM9000_REG_MWCMD
:
579 /* DM9KNOTE: This assumes a 16bit wide wiring */
580 s
->packet_buffer
[s
->dm9k_mwr
] = value
& 0xFF;
581 s
->packet_buffer
[s
->dm9k_mwr
+ 1] = (value
>> 8) & 0xFF;
582 if (s
->address
== DM9000_REG_MWCMD
) {
583 if (s
->dm9k_imr
& DM9000_IMR_AUTOWRAP
)
584 s
->dm9k_mwr
= DM9K_WRAP_TX_INDEX(s
->dm9k_mwr
+ 2);
585 else if (s
->dm9k_mwr
+ 2 < DM9K_TX_FIFO_SIZE
) // clip it
592 case DM9000_REG_MWRL
:
593 s
->dm9k_mwr
&= 0xFF00;
594 s
->dm9k_mwr
|= value
& 0xFF;
596 case DM9000_REG_MWRH
:
598 s
->dm9k_mwr
|= (value
& 0xFF) << 8;
600 case DM9000_REG_TXPLL
:
601 s
->dm9k_txpl
&= 0xFF00;
602 s
->dm9k_txpl
|= value
& 0xFF;
604 case DM9000_REG_TXPLH
:
605 s
->dm9k_txpl
&= 0xFF;
606 s
->dm9k_txpl
|= (value
& 0xFF) << 8;
609 s
->dm9k_isr
&= ~(value
& 0x0F);
613 if( !(s
->dm9k_imr
& DM9000_IMR_AUTOWRAP
) && (value
& DM9000_IMR_AUTOWRAP
) )
614 s
->dm9k_mrr
= 0x0C00 | (s
->dm9k_mrr
& 0xFF);
615 s
->dm9k_imr
= value
& 0xFF;
619 printf("%s: Bad register 0x%lx=%x\n", __FUNCTION__
, (unsigned long)s
->address
, value
);
621 #if 0 // def DM9000_DEBUG
622 if(!suppress_debug
) DM9000_DBF("DM9000: Write value %02x=%04x\n", s
->address
, value
);
626 static uint32_t dm9000_read(void *opaque
, target_phys_addr_t address
)
628 dm9000_state
*s
= (dm9000_state
*)opaque
;
631 int suppress_debug
= 0;
634 if (address
== s
->addr
)
642 /* Note, TX1END and TX2END are *CLEAR ON READ* */
643 s
->dm9k_nsr
&= ~(DM9000_NSR_TX1END
| DM9000_NSR_TX2END
);
648 case DM9000_REG_TSR1
:
649 case DM9000_REG_TSR2
:
650 ret
= 0x00; /* No error, yay! */
652 case DM9000_REG_EPCR
:
661 case DM9000_REG_EPAR
:
664 case DM9000_REG_EPDRL
:
665 ret
= s
->dm9k_epdr
& 0xFF;
667 case DM9000_REG_EPDRH
:
668 ret
= (s
->dm9k_epdr
>> 8) & 0xFF;
670 case DM9000_REG_PAR0
...DM9000_REG_PAR5
:
671 ret
= s
->macaddr
[s
->address
- DM9000_REG_PAR0
];
673 case DM9000_REG_MAR0
...DM9000_REG_MAR7
:
674 ret
= s
->mult
[s
->address
- DM9000_REG_MAR0
];
676 case DM9000_REG_TRPAL
:
677 ret
= s
->dm9k_trpa
& 0xFF;
679 case DM9000_REG_TRPAH
:
680 ret
= s
->dm9k_trpa
>> 8;
682 case DM9000_REG_RWPAL
:
683 ret
= s
->dm9k_rwpa
& 0xFF;
685 case DM9000_REG_RWPAH
:
686 ret
= s
->dm9k_rwpa
>> 8;
688 case DM9000_REG_VIDL
:
691 case DM9000_REG_VIDH
:
694 case DM9000_REG_PIDL
:
697 case DM9000_REG_PIDH
:
700 case DM9000_REG_CHIPR
:
703 case DM9000_REG_MRCMDX
:
704 case DM9000_REG_MRCMD
:
705 // drivers read the fifo looking for a 0x01 to indicate a packet is there,
706 // so we just return it a zero if there is nothing to read
707 if (s
->dm9k_mrr
== s
->dm9k_rwpa
)
710 /* DM9KNOTE: This assumes a 16bit wide wiring */
711 ret
= s
->packet_buffer
[s
->dm9k_mrr
];
712 ret
|= s
->packet_buffer
[s
->dm9k_mrr
+ 1] << 8;
713 if( s
->address
== DM9000_REG_MRCMD
) {
714 if( s
->dm9k_imr
& DM9000_IMR_AUTOWRAP
)
715 s
->dm9k_mrr
= DM9K_WRAP_RX_INDEX(s
->dm9k_mrr
+ 2);
716 else if (s
->dm9k_mrr
+ 2 < DM9K_FIFO_SIZE
) // clip it
721 if (s
->address
==DM9000_REG_MRCMD
)
725 case DM9000_REG_MRRL
:
726 ret
= s
->dm9k_mrr
& 0xFF;
728 case DM9000_REG_MRRH
:
729 ret
= s
->dm9k_mrr
>> 8;
731 case DM9000_REG_MWRL
:
732 ret
= s
->dm9k_mwr
& 0xFF;
734 case DM9000_REG_MWRH
:
735 ret
= s
->dm9k_mwr
>> 8;
737 case DM9000_REG_TXPLL
:
738 ret
= s
->dm9k_txpl
& 0xFF;
740 case DM9000_REG_TXPLH
:
741 ret
= s
->dm9k_txpl
>> 8;
753 #if 0 // def DM9000_DEBUG
754 if(!suppress_debug
) DM9000_DBF("DM9000: Read gives: %04x\n", ret
);
760 static int dm9000_can_receive(void *opaque
)
762 dm9000_state
*s
= (dm9000_state
*)opaque
;
763 uint16_t rx_space
= dm9000_get_rx_fifo_fill_state(s
);
764 DM9000_DBF("DM9000:RX_Packet: Asked about RX, rwpa=%d mrr=%d => space is %d bytes\n",
765 s
->dm9k_rwpa
, s
->dm9k_mrr
, rx_space
);
766 return rx_space
> 1522;
769 #define POLYNOMINAL 0x04c11db6
773 static int compute_mcast_idx(const uint8_t *ep
)
780 for (i
= 0; i
< 6; i
++) {
782 for (j
= 0; j
< 8; j
++) {
783 carry
= ((crc
& 0x80000000L
) ? 1 : 0) ^ (b
& 0x01);
787 crc
= ((crc
^ POLYNOMINAL
) | carry
);
793 static void dm9000_receive(void *opaque
, const uint8_t *buf
, int size
)
795 dm9000_state
*s
= (dm9000_state
*)opaque
;
796 uint16_t rxptr
= s
->dm9k_rwpa
;
797 unsigned int mcast_idx
= 0;
800 if (!(s
->dm9k_rcr
& DM9000_RCR_RXEN
))
804 if (!(s
->dm9k_rcr
& DM9000_RCR_PRMSC
)) {
806 /* multi/broadcast */
807 if (!(s
->dm9k_rcr
& DM9000_RCR_ALL
)) {
808 mcast_idx
= compute_mcast_idx(buf
);
809 if (!(s
->mult
[mcast_idx
>> 3] & (1 << (mcast_idx
& 7))))
811 s
->dm9k_rsr
|= DM9000_RSR_MF
;
813 } else if (!memcmp(buf
, s
->macaddr
, 6)) {
818 if (size
< 64 && !(s
->dm9k_rcr
& DM9000_RCR_RUNT
)) {
819 // printf("rcr %02x RUNT %d\n", s->dm9k_rcr, size);
820 s
->dm9k_rsr
|= DM9000_RSR_RF
;
823 if (size
> 1522 && (s
->dm9k_rcr
& DM9000_RCR_DIS_LONG
))
827 DM9000_DBF("DM9000:RX_Packet: %02x:%02x:%02x:%02x:%02x:%02x -> %02x:%02x:%02x:%02x:%02x:%02x : %d bytes into buffer at %04x [RCR %02x]\n",
828 buf
[0],buf
[1],buf
[2],buf
[3],buf
[4],buf
[5],
829 buf
[6],buf
[7],buf
[8],buf
[9],buf
[10],buf
[11],
830 size
, rxptr
, s
->dm9k_rcr
);
831 dm9k_dump_packet(buf
, size
);
834 * apparently even runt frames are padded to 64
839 rxptr
= DM9K_CLIP_RX_INDEX(rxptr
);
841 s
->packet_buffer
[rxptr
] = 0x01; /* Packet read */
842 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
843 s
->packet_buffer
[rxptr
] = 0x00; /* Status OK */
844 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
845 s
->packet_buffer
[rxptr
] = (size
+pad
) & 0xFF; /* Size LOW */
846 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
847 s
->packet_buffer
[rxptr
] = ((size
+pad
) >> 8) & 0xff; /* Size HIGH */
848 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
850 if (DM9K_FIFO_SIZE
- rxptr
> size
) {
851 memcpy(s
->packet_buffer
+ rxptr
, buf
, size
);
854 int p1
= DM9K_FIFO_SIZE
- rxptr
;
855 memcpy(s
->packet_buffer
+ rxptr
, buf
, p1
);
857 rxptr
= DM9K_RX_FIFO_START
; /* wrap */
858 p1
= size
- p1
; /* remaining */
859 memcpy(s
->packet_buffer
+ rxptr
, buf
, p1
);
862 /* obligatory padding */
864 s
->packet_buffer
[rxptr
] = 0;
865 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
868 s
->dm9k_rwpa
= DM9K_CLIP_RX_INDEX(rxptr
);
869 s
->dm9k_isr
|= DM9000_ISR_PRS
; /* RX interrupt, yay */
874 static CPUReadMemoryFunc
*dm9000_readfn
[] = {
880 static CPUWriteMemoryFunc
*dm9000_writefn
[] = {
886 /* initialises a dm9000 ethernet controller
887 * The dm9k has a single 16bit wide address and data port through which all
888 * operations are multiplexed, there is a single IRQ
890 void dm9000_init(NICInfo
*nd
, target_phys_addr_t base_addr
,
891 uint32_t addr_offset
, uint32_t data_offset
,
897 s
= (dm9000_state
*)qemu_mallocz(sizeof(dm9000_state
));
898 iomemtype
= cpu_register_io_memory(0, dm9000_readfn
,
900 cpu_register_physical_memory(base_addr
, MAX(addr_offset
, data_offset
) + 4, iomemtype
);
901 s
->addr
= addr_offset
;
902 s
->data
= data_offset
;
904 memcpy(s
->macaddr
, nd
->macaddr
, 6);
905 memset(s
->mult
, 0xff, 8);
908 uint8_t * buf
= s
->macaddr
;
909 printf("DM9000: INIT QEMU MAC : %02x:%02x:%02x:%02x:%02x:%02x\n",
910 buf
[0],buf
[1],buf
[2],buf
[3],buf
[4],buf
[5]);
913 register_savevm("dm9000", 0, 0, dm9000_save
, dm9000_load
, s
);
915 dm9000_hard_reset(s
);
917 s
->vc
= qemu_new_vlan_client(nd
->vlan
, nd
->model
, nd
->name
,
918 dm9000_receive
, dm9000_can_receive
, s
);
919 qemu_format_nic_info_str(s
->vc
, s
->macaddr
);