3 * DM9000 Ethernet interface
5 * Copyright Daniel Silverstone and Vincent Sanders
7 * This file is under the terms of the GNU General Public
12 #include "qemu-common.h"
18 /* Comment this out if you don't want register debug on stderr */
19 //#define DM9000_DEBUG
21 /* Comment this out if you don't want a packet dump */
22 //#define DM9000_DUMP_FILENAME "/tmp/dm9k_dump"
25 #define DM9000_DBF(X...) fprintf(stderr, X)
27 #define DM9000_DBF(X...) if(0) fprintf(stderr, X)
30 #define DM9000_REG_NCR 0x00
31 #define DM9000_NCR_RESET (1 << 0)
33 #define DM9000_NCR_EXT_PHY (1<<7)
34 #define DM9000_NCR_WAKEEN (1<<6)
35 #define DM9000_NCR_FCOL (1<<4)
36 #define DM9000_NCR_FDX (1<<3)
37 #define DM9000_NCR_LBK (3<<1)
39 #define DM9000_NCR_RESETPROTECT (DM9000_NCR_EXT_PHY | DM9000_NCR_WAKEEN)
41 #define DM9000_REG_NSR 0x01
43 #define DM9000_NSR_SPEED (1<<7)
44 #define DM9000_NSR_LINKST (1<<6)
45 #define DM9000_NSR_WAKEST (1<<5)
46 #define DM9000_NSR_TX2END (1<<3)
47 #define DM9000_NSR_TX1END (1<<2)
48 #define DM9000_NSR_RXOV (1<<1)
50 #define DM9000_NSR_RESETPROTECT (DM9000_NSR_WAKEST)
51 #define DM9000_NSR_READONLY (DM9000_NSR_SPEED|DM9000_NSR_LINKST|(1<<4)|DM9000_NSR_RXOV|(1<<0))
53 #define DM9000_REG_TCR 0x02
54 #define DM9000_TCR_TXREQ (1 << 0)
56 #define DM9000_REG_TSR1 0x03
57 #define DM9000_REG_TSR2 0x04
58 #define DM9000_REG_RCR 0x05
59 #define DM9000_RCR_DIS_LONG (1 << 5) /* RX Discard long frames (>1522) */
60 #define DM9000_RCR_DIS_CRC (1 << 4) /* RX Discard bad CRC */
61 #define DM9000_RCR_ALL (1 << 3) /* RX Pass All Multicast */
62 #define DM9000_RCR_RUNT (1 << 2) /* RX Pass Runt Frames (frame < 64 bytes) */
63 #define DM9000_RCR_PRMSC (1 << 1) /* RX Promiscuous Mode */
64 #define DM9000_RCR_RXEN (1 << 0) /* RX Enabled */
66 #define DM9000_REG_RSR 0x06
67 #define DM9000_RSR_RF (1 << 7) /* RX Runt Frame (frame < 64 bytes) */
68 #define DM9000_RSR_MF (1 << 6) /* RX Multicast Frame */
69 #define DM9000_RSR_FOE (1 << 0) /* RX FIFO overflow */
71 #define DM9000_REG_ROCR 0x07
72 #define DM9000_REG_BPTR 0x08
73 #define DM9000_REG_FCTR 0x09
74 #define DM9000_REG_FCR 0x0A
75 #define DM9000_FCR_TXP0 (1 << 7) /* TX Pause Packet (when empty) */
76 #define DM9000_FCR_TXPF (1 << 6) /* TX Pause Packet (when full) */
77 #define DM9000_FCR_TXPEN (1 << 5) /* Force pause/unpause packets */
78 #define DM9000_FCR_BKPA (1 << 4)
79 #define DM9000_FCR_BKPM (1 << 3)
80 #define DM9000_FCR_RXPS (1 << 2) /* RX Pause Packet Status, latch and read to clear */
81 #define DM9000_FCR_RXPCS (1 << 1) /* RX Pause Packet Current Status */
82 #define DM9000_FCR_FLCE (1 << 0) /* Flow Control Enable */
84 #define DM9000_REG_EPCR 0x0B
85 #define DM9000_REG_EPAR 0x0C
86 #define DM9000_REG_EPDRL 0x0D
87 #define DM9000_REG_EPDRH 0x0E
88 #define DM9000_REG_WCR 0x0F
89 #define DM9000_REG_PAR0 0x10
90 #define DM9000_REG_PAR1 0x11
91 #define DM9000_REG_PAR2 0x12
92 #define DM9000_REG_PAR3 0x13
93 #define DM9000_REG_PAR4 0x14
94 #define DM9000_REG_PAR5 0x15
95 #define DM9000_REG_MAR0 0x16
96 #define DM9000_REG_MAR1 0x17
97 #define DM9000_REG_MAR2 0x18
98 #define DM9000_REG_MAR3 0x19
99 #define DM9000_REG_MAR4 0x1A
100 #define DM9000_REG_MAR5 0x1B
101 #define DM9000_REG_MAR6 0x1C
102 #define DM9000_REG_MAR7 0x1D
103 #define DM9000_REG_GPCR 0x1E
104 #define DM9000_REG_GPR 0x1F
105 #define DM9000_REG_TRPAL 0x22
106 #define DM9000_REG_TRPAH 0x23
107 #define DM9000_REG_RWPAL 0x24
108 #define DM9000_REG_RWPAH 0x25
109 #define DM9000_REG_VIDL 0x28
110 #define DM9000_REG_VIDH 0x29
111 #define DM9000_REG_PIDL 0x2A
112 #define DM9000_REG_PIDH 0x2B
113 #define DM9000_REG_CHIPR 0x2C
114 #define DM9000_REG_SMCR 0x2F
115 #define DM9000_REG_MRCMDX 0xF0
116 #define DM9000_REG_MRCMD 0xF2
117 #define DM9000_REG_MRRL 0xF4
118 #define DM9000_REG_MRRH 0xF5
119 #define DM9000_REG_MWCMDX 0xF6
120 #define DM9000_REG_MWCMD 0xF8
121 #define DM9000_REG_MWRL 0xFA
122 #define DM9000_REG_MWRH 0xFB
123 #define DM9000_REG_TXPLL 0xFC
124 #define DM9000_REG_TXPLH 0xFD
125 #define DM9000_REG_ISR 0xFE
126 #define DM9000_ISR_ROOS (1<<3)
127 #define DM9000_ISR_ROS (1<<2)
128 #define DM9000_ISR_PTS (1<<1)
129 #define DM9000_ISR_PRS (1<<0)
130 #define DM9000_ISR_CLR_STATUS (ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS)
132 #define DM9000_REG_IMR 0xFF
133 #define DM9000_IMR_AUTOWRAP 0x80
136 #define DM9000_MII_READ 0x0C
137 #define DM9000_MII_WRITE 0x0A
139 #define DM9000_MII_REG_BMCR 0x00
140 #define DM9000_MII_REG_STATUS 0x01
141 #define DM9000_MII_REG_PHYID1 0x02
142 #define DM9000_MII_REG_PHYID2 0x03
143 #define DM9000_MII_REG_ANAR 0x04
144 #define DM9000_MII_REG_ANLPAR 0x05
145 #define DM9000_MII_REG_ANER 0x06
146 #define DM9000_MII_REG_DSCR 0x10
147 #define DM9000_MII_REG_DSCSR 0x11
148 #define DM9000_MII_REG_10BTCSR 0x12
151 DM9K_TX_FIFO_START
= 0,
152 DM9K_TX_FIFO_SIZE
= (3 * 1024),
154 DM9K_RX_FIFO_START
= DM9K_TX_FIFO_SIZE
,
155 DM9K_RX_FIFO_SIZE
= (13 * 1024),
157 DM9K_FIFO_SIZE
= (DM9K_TX_FIFO_SIZE
+ DM9K_RX_FIFO_SIZE
)
160 #define DM9K_WRAP_TX_INDEX(_v) ((_v >= DM9K_TX_FIFO_SIZE) ? (_v) - DM9K_TX_FIFO_SIZE : (_v))
161 #define DM9K_WRAP_RX_INDEX(_v) ((_v >= DM9K_FIFO_SIZE) ? (_v) - DM9K_RX_FIFO_SIZE : (_v))
162 /* DM9KNOTE: Assumes 16bit wiring */
163 #define DM9K_CLIP_TX_INDEX(_v) ((_v) & 1 ? DM9K_WRAP_TX_INDEX((_v)+1) : (_v))
164 #define DM9K_CLIP_RX_INDEX(_v) ((_v) & 1 ? DM9K_WRAP_RX_INDEX((_v)+1) : (_v))
167 uint32_t addr
; /* address port */
168 uint32_t data
; /* data port */
171 uint8_t macaddr
[6]; /* MAC address -- default to qemu, can/will be overridden by guest driver */
172 uint8_t mult
[8]; /* multicast filtering fields */
174 uint8_t address
; /* The internal magical register address */
177 * Transmit buffer is the first 3KB,
178 * followed by the receive buffer
180 uint8_t packet_buffer
[DM9K_FIFO_SIZE
];
183 uint16_t dm9k_rwpa
; /* TX Read ptr address, RX write ptr address */
186 uint16_t fc_high_mark
;
187 uint16_t fc_low_mark
;
190 uint16_t dm9k_mwr
; /* Read and write address registers */
191 uint16_t dm9k_txpl
; /* TX packet length */
193 uint8_t dm9k_imr
, dm9k_isr
; /* Interrupt mask register and status register*/
194 uint8_t dm9k_ncr
, dm9k_nsr
; /* Network control register, network status register */
195 uint8_t dm9k_rcr
; /* RX Control Register */
196 uint8_t dm9k_rsr
; /* RX Status Register */
197 uint8_t dm9k_wcr
; /* Wakeup control */
198 uint8_t dm9k_tcr
; /* Transmission control register */
199 uint8_t packet_copy_buffer
[DM9K_TX_FIFO_SIZE
]; /* realigned packet copy buffer */
200 unsigned int packet_index
:1; /* 0 == packet I, 1 == packet II */
202 /* Internal MII PHY state */
203 uint8_t dm9k_epcr
; /* EEPROM/PHY control register */
204 uint8_t dm9k_epar
; /* EEPROM/PHY address register */
205 uint16_t dm9k_epdr
; /* EEPROM/PHY data register */
207 uint16_t dm9k_mii_bmcr
;
208 uint16_t dm9k_mii_anar
;
209 uint16_t dm9k_mii_dscr
;
213 static void dm9000_save(QEMUFile
*f
, void *opaque
)
215 dm9000_state
*s
= (dm9000_state
*)opaque
;
217 qemu_put_be32s(f
, &s
->addr
);
218 qemu_put_be32s(f
, &s
->data
);
219 qemu_put_8s(f
, &s
->address
);
220 qemu_put_buffer(f
, s
->macaddr
, sizeof(s
->macaddr
));
221 qemu_put_buffer(f
, s
->mult
, sizeof(s
->mult
));
222 qemu_put_buffer(f
, s
->packet_buffer
, sizeof(s
->packet_buffer
));
223 qemu_put_buffer(f
, s
->packet_copy_buffer
, sizeof(s
->packet_copy_buffer
));
224 qemu_put_be16s(f
, &s
->dm9k_trpa
);
225 qemu_put_be16s(f
, &s
->dm9k_rwpa
);
226 qemu_put_8s(f
, &s
->fctr
);
227 qemu_put_8s(f
, &s
->fcr
);
228 qemu_put_be16s(f
, &s
->fc_high_mark
);
229 qemu_put_be16s(f
, &s
->fc_low_mark
);
230 qemu_put_be16s(f
, &s
->dm9k_mrr
);
231 qemu_put_be16s(f
, &s
->dm9k_mwr
);
232 qemu_put_be16s(f
, &s
->dm9k_txpl
);
233 qemu_put_8s(f
, &s
->dm9k_imr
);
234 qemu_put_8s(f
, &s
->dm9k_isr
);
235 qemu_put_8s(f
, &s
->dm9k_ncr
);
236 qemu_put_8s(f
, &s
->dm9k_nsr
);
237 qemu_put_8s(f
, &s
->dm9k_rcr
);
238 qemu_put_8s(f
, &s
->dm9k_rsr
);
239 qemu_put_8s(f
, &s
->dm9k_wcr
);
240 qemu_put_8s(f
, &s
->dm9k_tcr
);
241 qemu_put_8s(f
, &s
->dm9k_epcr
);
242 qemu_put_8s(f
, &s
->dm9k_epar
);
243 qemu_put_be16s(f
, &s
->dm9k_epdr
);
244 qemu_put_be16s(f
, &s
->dm9k_mii_bmcr
);
245 qemu_put_be16s(f
, &s
->dm9k_mii_anar
);
246 qemu_put_be16s(f
, &s
->dm9k_mii_dscr
);
249 static int dm9000_load(QEMUFile
*f
, void *opaque
, int version_id
)
251 dm9000_state
*s
= (dm9000_state
*)opaque
;
252 qemu_get_be32s(f
, &s
->addr
);
253 qemu_get_be32s(f
, &s
->data
);
254 qemu_get_8s(f
, &s
->address
);
255 qemu_get_buffer(f
, s
->macaddr
, sizeof(s
->macaddr
));
256 qemu_get_buffer(f
, s
->mult
, sizeof(s
->mult
));
257 qemu_get_buffer(f
, s
->packet_buffer
, sizeof(s
->packet_buffer
));
258 qemu_get_buffer(f
, s
->packet_copy_buffer
, sizeof(s
->packet_copy_buffer
));
259 qemu_get_be16s(f
, &s
->dm9k_trpa
);
260 qemu_get_be16s(f
, &s
->dm9k_rwpa
);
261 qemu_get_8s(f
, &s
->fctr
);
262 qemu_get_8s(f
, &s
->fcr
);
263 qemu_get_be16s(f
, &s
->fc_high_mark
);
264 qemu_get_be16s(f
, &s
->fc_low_mark
);
265 qemu_get_be16s(f
, &s
->dm9k_mrr
);
266 qemu_get_be16s(f
, &s
->dm9k_mwr
);
267 qemu_get_be16s(f
, &s
->dm9k_txpl
);
268 qemu_get_8s(f
, &s
->dm9k_imr
);
269 qemu_get_8s(f
, &s
->dm9k_isr
);
270 qemu_get_8s(f
, &s
->dm9k_ncr
);
271 qemu_get_8s(f
, &s
->dm9k_nsr
);
272 qemu_get_8s(f
, &s
->dm9k_rcr
);
273 qemu_get_8s(f
, &s
->dm9k_rsr
);
274 qemu_get_8s(f
, &s
->dm9k_wcr
);
275 qemu_get_8s(f
, &s
->dm9k_tcr
);
276 qemu_get_8s(f
, &s
->dm9k_epcr
);
277 qemu_get_8s(f
, &s
->dm9k_epar
);
278 qemu_get_be16s(f
, &s
->dm9k_epdr
);
279 qemu_get_be16s(f
, &s
->dm9k_mii_bmcr
);
280 qemu_get_be16s(f
, &s
->dm9k_mii_anar
);
281 qemu_get_be16s(f
, &s
->dm9k_mii_dscr
);
286 #ifdef DM9000_DUMP_FILENAME
287 #include <arpa/inet.h>
288 static uint8_t pcap_header
[24] = {
289 0xA1, 0xB2, 0xC3, 0xD4, /* TCPDUMP Magic */
290 0x00, 0x02, 0x00, 0x04, /* Major 2, Minor 4 */
291 0x00, 0x00, 0x00, 0x00, /* Timezone offset */
292 0x00, 0x00, 0x00, 0x01, /* Accuracy of timestamps */
293 0x00, 0x00, 0x0C, 0x00, /* Snaplen 3KiB */
294 0x00, 0x00, 0x00, 0x01, /* Ethernet frames */
296 static uint8_t nulls
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
297 static void dm9k_dump_packet(uint8_t *buf
, uint32_t size
)
299 FILE* dm9k_fileh
= fopen(DM9000_DUMP_FILENAME
, "ab+");
300 unsigned long bsize
= htonl(size
);
301 DM9000_DBF("Dumping packet at %08x (%d bytes)\n", buf
, size
);
302 fseek(dm9k_fileh
, 0, SEEK_END
);
303 if(ftell(dm9k_fileh
)==0) fwrite(pcap_header
, 1, 24, dm9k_fileh
);
304 fwrite(nulls
, 1, 8, dm9k_fileh
);
305 fwrite(&bsize
, 1, 4, dm9k_fileh
);
306 fwrite(&bsize
, 1, 4, dm9k_fileh
);
307 fwrite(buf
, 1, size
, dm9k_fileh
);
311 #define dm9k_dump_packet(X...) do { } while(0)
315 static void dm9000_raise_irq(dm9000_state
*s
)
317 int level
= ((s
->dm9k_isr
& s
->dm9k_imr
) & 0x0f) != 0;
318 //DM9000_DBF("DM9000: Set IRQ level %d (isr = %02x imr %02x\n", level, s->dm9k_isr, s->dm9k_imr);
319 qemu_set_irq(s
->irq
, level
);
322 static void dm9000_soft_reset_mii(dm9000_state
*s
)
324 s
->dm9k_mii_bmcr
= 0x3100; /* 100Mbps, AUTONEG, FULL DUPLEX */
325 s
->dm9k_mii_anar
= 0x01E1;
326 s
->dm9k_mii_dscr
= 0x0410;
329 static void dm9000_soft_reset(dm9000_state
*s
)
331 DM9000_DBF("DM9000: Soft Reset\n");
333 s
->dm9k_mwr
= s
->dm9k_trpa
= DM9K_TX_FIFO_START
;
334 s
->dm9k_mrr
= s
->dm9k_rwpa
= DM9K_RX_FIFO_START
;
336 s
->dm9k_isr
= 0; /* 16 bit mode, no interrupts asserted */
341 s
->fctr
= (3 << 4) | (8 << 0); // flow control high/low marks
342 s
->fc_high_mark
= 3 * 1024;
343 s
->fc_low_mark
= 8 * 1024;
346 memset(s
->packet_buffer
, 0, sizeof(s
->packet_buffer
));
347 memset(s
->packet_copy_buffer
, 0, sizeof(s
->packet_copy_buffer
));
348 /* These registers have some bits "unaffected by software reset" */
349 /* Clear the reset bits */
350 s
->dm9k_ncr
&= DM9000_NCR_RESETPROTECT
;
351 s
->dm9k_nsr
&= DM9000_NSR_RESETPROTECT
;
352 /* Claim full duplex */
353 s
->dm9k_ncr
|= DM9000_NCR_FDX
;
354 /* Set link status to 1 */
355 s
->dm9k_nsr
|= DM9000_NSR_LINKST
;
356 /* dm9k_wcr is unaffected or reserved, never reset */
357 /* MII control regs */
361 dm9000_soft_reset_mii(s
);
362 dm9000_raise_irq(s
); /* Clear any potentially pending IRQ */
365 static void dm9000_hard_reset(dm9000_state
*s
)
370 dm9000_soft_reset(s
);
373 static uint16_t dm9000_get_rx_fifo_fill_state(dm9000_state
*s
)
376 if (s
->dm9k_mrr
> s
->dm9k_rwpa
)
377 res
= (DM9K_FIFO_SIZE
-s
->dm9k_rwpa
) + (s
->dm9k_mrr
-DM9K_RX_FIFO_START
);
379 res
= s
->dm9k_rwpa
- s
->dm9k_mrr
;
383 static void dm9000_do_transmit(dm9000_state
*s
) {
384 uint16_t idx
, cnt
, tptr
;
388 if (cnt
> DM9K_TX_FIFO_SIZE
)
389 cnt
= DM9K_TX_FIFO_SIZE
; /* HARD CAP AT 3KiB */
393 s
->packet_copy_buffer
[tptr
++] = s
->packet_buffer
[idx
];
394 idx
= DM9K_WRAP_TX_INDEX(idx
+1);
399 uint8_t *buf
= &s
->packet_copy_buffer
[6];
400 DM9000_DBF("TX_Packet: %02x:%02x:%02x:%02x:%02x:%02x %d bytes from %04x\n",
401 buf
[0],buf
[1],buf
[2],buf
[3],buf
[4],buf
[5],
403 // hexdump(s->packet_copy_buffer, tptr);
407 s
->dm9k_trpa
= DM9K_CLIP_TX_INDEX(idx
);
408 dm9k_dump_packet(s
->packet_copy_buffer
, s
->dm9k_txpl
);
409 /* We have the copy buffer, now we do the transmit */
410 qemu_send_packet(s
->vc
, s
->packet_copy_buffer
, s
->dm9k_txpl
);
412 /* Clear the "please xmit" bit */
413 s
->dm9k_tcr
&= ~DM9000_TCR_TXREQ
;
414 /* Set the TXEND bit */
415 s
->dm9k_nsr
|= 1 << (2 + s
->packet_index
);
416 DM9000_DBF("TX: NSR=%02x PI=%d\n", s
->dm9k_nsr
, s
->packet_index
);
417 /* Claim a TX complete IRQ */
418 s
->dm9k_isr
|= DM9000_ISR_PTS
; /* Packet transmitted latch */
419 /* And flip the next-packet bit */
425 static void dm9000_mii_read(dm9000_state
*s
)
427 int mii_reg
= (s
->dm9k_epar
) & 0x3f;
430 case DM9000_MII_REG_BMCR
:
431 ret
= s
->dm9k_mii_bmcr
;
433 case DM9000_MII_REG_STATUS
:
434 ret
= 0x782D; /* No 100/T4, Can 100/FD, Can 100/HD, Can 10/FD, Can 10/HD,
435 * No Preamble suppression, Autoneg complete, No remote fault,
436 * Can autoneg, link up, no jabber, extended capability */
438 case DM9000_MII_REG_PHYID1
:
441 case DM9000_MII_REG_PHYID2
:
444 case DM9000_MII_REG_ANAR
:
445 ret
= s
->dm9k_mii_anar
;
447 case DM9000_MII_REG_ANLPAR
:
450 case DM9000_MII_REG_ANER
:
453 case DM9000_MII_REG_DSCR
:
454 ret
= s
->dm9k_mii_dscr
;
456 case DM9000_MII_REG_DSCSR
:
459 case DM9000_MII_REG_10BTCSR
:
462 printf("%s: Bad register 0x%lx\n", __FUNCTION__
, (unsigned long)mii_reg
);
465 // DM9000_DBF("DM9000:MIIPHY: Read of MII reg %d gives %04x\n", mii_reg, s->dm9k_epdr);
468 static void dm9000_mii_write(dm9000_state
*s
)
470 int mii_reg
= (s
->dm9k_epar
) & 0x3f;
471 DM9000_DBF("DM9000:MIIPHY: Write of MII reg %d value %04x\n", mii_reg
, s
->dm9k_epdr
);
473 case DM9000_MII_REG_BMCR
:
474 s
->dm9k_mii_bmcr
= (s
->dm9k_epdr
&~0x8000);
475 if( s
->dm9k_epdr
& 0x8000 ) dm9000_soft_reset_mii(s
);
477 case DM9000_MII_REG_ANAR
:
478 s
->dm9k_mii_anar
= s
->dm9k_epdr
;
480 case DM9000_MII_REG_DSCR
:
481 s
->dm9k_mii_dscr
= s
->dm9k_epdr
& ~0x0008;
484 printf("%s: Bad register 0x%lx=%4x\n", __FUNCTION__
, (unsigned long)mii_reg
, s
->dm9k_epdr
);
488 static void dm9000_write(void *opaque
, target_phys_addr_t address
,
491 dm9000_state
*s
= (dm9000_state
*)opaque
;
493 int suppress_debug
= 0;
496 if (address
== s
->addr
) {
497 // if( (value != DM9000_REG_MRCMD) && (value != DM9000_REG_MWCMD) )
498 // DM9000_DBF("DM9000: Address set to 0x%02x\n", value);
505 DM9000_DBF("DM9000_REG_NCR: %02x=%04x\n", s
->address
, value
);
506 s
->dm9k_ncr
= value
| DM9000_NCR_FDX
;
507 if (s
->dm9k_ncr
& DM9000_NCR_RESET
)
508 dm9000_soft_reset(s
);
511 s
->dm9k_nsr
&= ~(value
& ~DM9000_NSR_READONLY
);
514 s
->dm9k_tcr
= value
& 0xFF;
515 if ( value
& DM9000_TCR_TXREQ
)
516 dm9000_do_transmit(s
);
518 case DM9000_REG_EPCR
:
519 s
->dm9k_epcr
= value
& 0xFF;
520 if( value
& DM9000_MII_READ
)
522 else if( value
& DM9000_MII_WRITE
)
526 s
->dm9k_rcr
= value
& 0xFF;
529 case DM9000_REG_BPTR
: /* can be ignored */
532 case DM9000_REG_FCTR
: {/* 0x09 Flow Control Threshold Register */
533 s
->fc_high_mark
= ((value
>> 4) & 0xf) * 1024; // emit a pause packet time=0xffff
534 s
->fc_low_mark
= ((value
) & 0xf) * 1024; // emit an unpause packet time=0x0000
538 case DM9000_REG_FCR
: /* 0x0a Flow Control Register */
542 case DM9000_REG_EPAR
:
543 s
->dm9k_epar
= value
& 0xFF;
545 case DM9000_REG_EPDRL
:
546 s
->dm9k_epdr
&= 0xFF00;
547 s
->dm9k_epdr
|= value
& 0xFF;
549 case DM9000_REG_EPDRH
:
550 s
->dm9k_epdr
&= 0xFF;
551 s
->dm9k_epdr
|= (value
& 0xFF) << 8;
553 case DM9000_REG_PAR0
... DM9000_REG_PAR5
:
554 /* MAC address is set by the QEMU Nic */
555 s
->macaddr
[s
->address
- DM9000_REG_PAR0
] = value
;
557 case DM9000_REG_MAR0
... DM9000_REG_MAR7
:
558 /* Multicast address is ignored */
559 s
->mult
[s
->address
- DM9000_REG_MAR0
] = value
;
561 case DM9000_REG_GPCR
:
562 case DM9000_REG_GPR
: /* General purpose reg (GPIOs, LED?) */
564 case DM9000_REG_SMCR
:
566 printf("%s: something playing with special mode ? 0x%lx=%x\n", __FUNCTION__
, (unsigned long)s
->address
, value
);
568 case DM9000_REG_MRRL
:
569 s
->dm9k_mrr
&= 0xFF00;
570 s
->dm9k_mrr
|= value
& 0xFF;
572 case DM9000_REG_MRRH
:
574 s
->dm9k_mrr
|= (value
& 0xFF) << 8;
576 case DM9000_REG_MWCMDX
:
577 case DM9000_REG_MWCMD
:
578 /* DM9KNOTE: This assumes a 16bit wide wiring */
579 s
->packet_buffer
[s
->dm9k_mwr
] = value
& 0xFF;
580 s
->packet_buffer
[s
->dm9k_mwr
+ 1] = (value
>> 8) & 0xFF;
581 if (s
->address
== DM9000_REG_MWCMD
) {
582 if (s
->dm9k_imr
& DM9000_IMR_AUTOWRAP
)
583 s
->dm9k_mwr
= DM9K_WRAP_TX_INDEX(s
->dm9k_mwr
+ 2);
584 else if (s
->dm9k_mwr
+ 2 < DM9K_TX_FIFO_SIZE
) // clip it
591 case DM9000_REG_MWRL
:
592 s
->dm9k_mwr
&= 0xFF00;
593 s
->dm9k_mwr
|= value
& 0xFF;
595 case DM9000_REG_MWRH
:
597 s
->dm9k_mwr
|= (value
& 0xFF) << 8;
599 case DM9000_REG_TXPLL
:
600 s
->dm9k_txpl
&= 0xFF00;
601 s
->dm9k_txpl
|= value
& 0xFF;
603 case DM9000_REG_TXPLH
:
604 s
->dm9k_txpl
&= 0xFF;
605 s
->dm9k_txpl
|= (value
& 0xFF) << 8;
608 s
->dm9k_isr
&= ~(value
& 0x0F);
612 if( !(s
->dm9k_imr
& DM9000_IMR_AUTOWRAP
) && (value
& DM9000_IMR_AUTOWRAP
) )
613 s
->dm9k_mrr
= 0x0C00 | (s
->dm9k_mrr
& 0xFF);
614 s
->dm9k_imr
= value
& 0xFF;
618 printf("%s: Bad register 0x%lx=%x\n", __FUNCTION__
, (unsigned long)s
->address
, value
);
620 #if 0 // def DM9000_DEBUG
621 if(!suppress_debug
) DM9000_DBF("DM9000: Write value %02x=%04x\n", s
->address
, value
);
625 static uint32_t dm9000_read(void *opaque
, target_phys_addr_t address
)
627 dm9000_state
*s
= (dm9000_state
*)opaque
;
630 int suppress_debug
= 0;
633 if (address
== s
->addr
)
641 /* Note, TX1END and TX2END are *CLEAR ON READ* */
642 s
->dm9k_nsr
&= ~(DM9000_NSR_TX1END
| DM9000_NSR_TX2END
);
647 case DM9000_REG_TSR1
:
648 case DM9000_REG_TSR2
:
649 ret
= 0x00; /* No error, yay! */
651 case DM9000_REG_EPCR
:
660 case DM9000_REG_EPAR
:
663 case DM9000_REG_EPDRL
:
664 ret
= s
->dm9k_epdr
& 0xFF;
666 case DM9000_REG_EPDRH
:
667 ret
= (s
->dm9k_epdr
>> 8) & 0xFF;
669 case DM9000_REG_PAR0
...DM9000_REG_PAR5
:
670 ret
= s
->macaddr
[s
->address
- DM9000_REG_PAR0
];
672 case DM9000_REG_MAR0
...DM9000_REG_MAR7
:
673 ret
= s
->mult
[s
->address
- DM9000_REG_MAR0
];
675 case DM9000_REG_TRPAL
:
676 ret
= s
->dm9k_trpa
& 0xFF;
678 case DM9000_REG_TRPAH
:
679 ret
= s
->dm9k_trpa
>> 8;
681 case DM9000_REG_RWPAL
:
682 ret
= s
->dm9k_rwpa
& 0xFF;
684 case DM9000_REG_RWPAH
:
685 ret
= s
->dm9k_rwpa
>> 8;
687 case DM9000_REG_VIDL
:
690 case DM9000_REG_VIDH
:
693 case DM9000_REG_PIDL
:
696 case DM9000_REG_PIDH
:
699 case DM9000_REG_CHIPR
:
702 case DM9000_REG_MRCMDX
:
703 case DM9000_REG_MRCMD
:
704 // drivers read the fifo looking for a 0x01 to indicate a packet is there,
705 // so we just return it a zero if there is nothing to read
706 if (s
->dm9k_mrr
== s
->dm9k_rwpa
)
709 /* DM9KNOTE: This assumes a 16bit wide wiring */
710 ret
= s
->packet_buffer
[s
->dm9k_mrr
];
711 ret
|= s
->packet_buffer
[s
->dm9k_mrr
+ 1] << 8;
712 if( s
->address
== DM9000_REG_MRCMD
) {
713 if( s
->dm9k_imr
& DM9000_IMR_AUTOWRAP
)
714 s
->dm9k_mrr
= DM9K_WRAP_RX_INDEX(s
->dm9k_mrr
+ 2);
715 else if (s
->dm9k_mrr
+ 2 < DM9K_FIFO_SIZE
) // clip it
720 if (s
->address
==DM9000_REG_MRCMD
)
724 case DM9000_REG_MRRL
:
725 ret
= s
->dm9k_mrr
& 0xFF;
727 case DM9000_REG_MRRH
:
728 ret
= s
->dm9k_mrr
>> 8;
730 case DM9000_REG_MWRL
:
731 ret
= s
->dm9k_mwr
& 0xFF;
733 case DM9000_REG_MWRH
:
734 ret
= s
->dm9k_mwr
>> 8;
736 case DM9000_REG_TXPLL
:
737 ret
= s
->dm9k_txpl
& 0xFF;
739 case DM9000_REG_TXPLH
:
740 ret
= s
->dm9k_txpl
>> 8;
752 #if 0 // def DM9000_DEBUG
753 if(!suppress_debug
) DM9000_DBF("DM9000: Read gives: %04x\n", ret
);
759 static int dm9000_can_receive(void *opaque
)
761 dm9000_state
*s
= (dm9000_state
*)opaque
;
762 uint16_t rx_space
= dm9000_get_rx_fifo_fill_state(s
);
763 DM9000_DBF("DM9000:RX_Packet: Asked about RX, rwpa=%d mrr=%d => space is %d bytes\n",
764 s
->dm9k_rwpa
, s
->dm9k_mrr
, rx_space
);
765 return rx_space
> 1522;
768 #define POLYNOMINAL 0x04c11db6
772 static int compute_mcast_idx(const uint8_t *ep
)
779 for (i
= 0; i
< 6; i
++) {
781 for (j
= 0; j
< 8; j
++) {
782 carry
= ((crc
& 0x80000000L
) ? 1 : 0) ^ (b
& 0x01);
786 crc
= ((crc
^ POLYNOMINAL
) | carry
);
792 static void dm9000_receive(void *opaque
, const uint8_t *buf
, int size
)
794 dm9000_state
*s
= (dm9000_state
*)opaque
;
795 uint16_t rxptr
= s
->dm9k_rwpa
;
796 unsigned int mcast_idx
= 0;
799 if (!(s
->dm9k_rcr
& DM9000_RCR_RXEN
))
803 if (!(s
->dm9k_rcr
& DM9000_RCR_PRMSC
)) {
805 /* multi/broadcast */
806 if (!(s
->dm9k_rcr
& DM9000_RCR_ALL
)) {
807 mcast_idx
= compute_mcast_idx(buf
);
808 if (!(s
->mult
[mcast_idx
>> 3] & (1 << (mcast_idx
& 7))))
810 s
->dm9k_rsr
|= DM9000_RSR_MF
;
812 } else if (!memcmp(buf
, s
->macaddr
, 6)) {
817 if (size
< 64 && !(s
->dm9k_rcr
& DM9000_RCR_RUNT
)) {
818 // printf("rcr %02x RUNT %d\n", s->dm9k_rcr, size);
819 s
->dm9k_rsr
|= DM9000_RSR_RF
;
822 if (size
> 1522 && (s
->dm9k_rcr
& DM9000_RCR_DIS_LONG
))
826 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",
827 buf
[0],buf
[1],buf
[2],buf
[3],buf
[4],buf
[5],
828 buf
[6],buf
[7],buf
[8],buf
[9],buf
[10],buf
[11],
829 size
, rxptr
, s
->dm9k_rcr
);
830 dm9k_dump_packet(buf
, size
);
833 * apparently even runt frames are padded to 64
838 rxptr
= DM9K_CLIP_RX_INDEX(rxptr
);
840 s
->packet_buffer
[rxptr
] = 0x01; /* Packet read */
841 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
842 s
->packet_buffer
[rxptr
] = 0x00; /* Status OK */
843 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
844 s
->packet_buffer
[rxptr
] = (size
+pad
) & 0xFF; /* Size LOW */
845 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
846 s
->packet_buffer
[rxptr
] = ((size
+pad
) >> 8) & 0xff; /* Size HIGH */
847 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
849 if (DM9K_FIFO_SIZE
- rxptr
> size
) {
850 memcpy(s
->packet_buffer
+ rxptr
, buf
, size
);
853 int p1
= DM9K_FIFO_SIZE
- rxptr
;
854 memcpy(s
->packet_buffer
+ rxptr
, buf
, p1
);
856 rxptr
= DM9K_RX_FIFO_START
; /* wrap */
857 p1
= size
- p1
; /* remaining */
858 memcpy(s
->packet_buffer
+ rxptr
, buf
, p1
);
861 /* obligatory padding */
863 s
->packet_buffer
[rxptr
] = 0;
864 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
867 s
->dm9k_rwpa
= DM9K_CLIP_RX_INDEX(rxptr
);
868 s
->dm9k_isr
|= DM9000_ISR_PRS
; /* RX interrupt, yay */
873 static CPUReadMemoryFunc
*dm9000_readfn
[] = {
879 static CPUWriteMemoryFunc
*dm9000_writefn
[] = {
885 /* initialises a dm9000 ethernet controller
886 * The dm9k has a single 16bit wide address and data port through which all
887 * operations are multiplexed, there is a single IRQ
889 void dm9000_init(NICInfo
*nd
, target_phys_addr_t base_addr
,
890 uint32_t addr_offset
, uint32_t data_offset
,
896 s
= (dm9000_state
*)qemu_mallocz(sizeof(dm9000_state
));
897 iomemtype
= cpu_register_io_memory(0, dm9000_readfn
,
899 cpu_register_physical_memory(base_addr
, MAX(addr_offset
, data_offset
) + 4, iomemtype
);
900 s
->addr
= addr_offset
;
901 s
->data
= data_offset
;
903 memcpy(s
->macaddr
, nd
->macaddr
, 6);
904 memset(s
->mult
, 0xff, 8);
907 uint8_t * buf
= s
->macaddr
;
908 printf("DM9000: INIT QEMU MAC : %02x:%02x:%02x:%02x:%02x:%02x\n",
909 buf
[0],buf
[1],buf
[2],buf
[3],buf
[4],buf
[5]);
912 register_savevm("dm9000", 0, 0, dm9000_save
, dm9000_load
, s
);
914 dm9000_hard_reset(s
);
916 s
->vc
= qemu_new_vlan_client(nd
->vlan
, nd
->model
, nd
->name
,
917 dm9000_receive
, dm9000_can_receive
, s
);
918 qemu_format_nic_info_str(s
->vc
, s
->macaddr
);