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"
17 /* Comment this out if you don't want register debug on stderr */
18 //#define DM9000_DEBUG
20 /* Comment this out if you don't want a packet dump */
21 //#define DM9000_DUMP_FILENAME "/tmp/dm9k_dump"
24 #define DM9000_DBF(X...) fprintf(stderr, X)
26 #define DM9000_DBF(X...) if(0) fprintf(stderr, X)
29 #define DM9000_REG_NCR 0x00
30 #define DM9000_NCR_RESET (1 << 0)
32 #define DM9000_NCR_EXT_PHY (1<<7)
33 #define DM9000_NCR_WAKEEN (1<<6)
34 #define DM9000_NCR_FCOL (1<<4)
35 #define DM9000_NCR_FDX (1<<3)
36 #define DM9000_NCR_LBK (3<<1)
38 #define DM9000_NCR_RESETPROTECT (DM9000_NCR_EXT_PHY | DM9000_NCR_WAKEEN)
40 #define DM9000_REG_NSR 0x01
42 #define DM9000_NSR_SPEED (1<<7)
43 #define DM9000_NSR_LINKST (1<<6)
44 #define DM9000_NSR_WAKEST (1<<5)
45 #define DM9000_NSR_TX2END (1<<3)
46 #define DM9000_NSR_TX1END (1<<2)
47 #define DM9000_NSR_RXOV (1<<1)
49 #define DM9000_NSR_RESETPROTECT (DM9000_NSR_WAKEST)
50 #define DM9000_NSR_READONLY (DM9000_NSR_SPEED|DM9000_NSR_LINKST|(1<<4)|DM9000_NSR_RXOV|(1<<0))
52 #define DM9000_REG_TCR 0x02
53 #define DM9000_TCR_TXREQ (1 << 0)
55 #define DM9000_REG_TSR1 0x03
56 #define DM9000_REG_TSR2 0x04
57 #define DM9000_REG_RCR 0x05
58 #define DM9000_RCR_DIS_LONG (1 << 5) /* RX Discard long frames (>1522) */
59 #define DM9000_RCR_DIS_CRC (1 << 4) /* RX Discard bad CRC */
60 #define DM9000_RCR_ALL (1 << 3) /* RX Pass All Multicast */
61 #define DM9000_RCR_RUNT (1 << 2) /* RX Pass Runt Frames (frame < 64 bytes) */
62 #define DM9000_RCR_PRMSC (1 << 1) /* RX Promiscuous Mode */
63 #define DM9000_RCR_RXEN (1 << 0) /* RX Enabled */
65 #define DM9000_REG_RSR 0x06
66 #define DM9000_RSR_RF (1 << 7) /* RX Runt Frame (frame < 64 bytes) */
67 #define DM9000_RSR_MF (1 << 6) /* RX Multicast Frame */
68 #define DM9000_RSR_FOE (1 << 0) /* RX FIFO overflow */
70 #define DM9000_REG_ROCR 0x07
71 #define DM9000_REG_BPTR 0x08
72 #define DM9000_REG_FCTR 0x09
73 #define DM9000_REG_FCR 0x0A
74 #define DM9000_FCR_TXP0 (1 << 7) /* TX Pause Packet (when empty) */
75 #define DM9000_FCR_TXPF (1 << 6) /* TX Pause Packet (when full) */
76 #define DM9000_FCR_TXPEN (1 << 5) /* Force pause/unpause packets */
77 #define DM9000_FCR_BKPA (1 << 4)
78 #define DM9000_FCR_BKPM (1 << 3)
79 #define DM9000_FCR_RXPS (1 << 2) /* RX Pause Packet Status, latch and read to clear */
80 #define DM9000_FCR_RXPCS (1 << 1) /* RX Pause Packet Current Status */
81 #define DM9000_FCR_FLCE (1 << 0) /* Flow Control Enable */
83 #define DM9000_REG_EPCR 0x0B
84 #define DM9000_REG_EPAR 0x0C
85 #define DM9000_REG_EPDRL 0x0D
86 #define DM9000_REG_EPDRH 0x0E
87 #define DM9000_REG_WCR 0x0F
88 #define DM9000_REG_PAR0 0x10
89 #define DM9000_REG_PAR1 0x11
90 #define DM9000_REG_PAR2 0x12
91 #define DM9000_REG_PAR3 0x13
92 #define DM9000_REG_PAR4 0x14
93 #define DM9000_REG_PAR5 0x15
94 #define DM9000_REG_MAR0 0x16
95 #define DM9000_REG_MAR1 0x17
96 #define DM9000_REG_MAR2 0x18
97 #define DM9000_REG_MAR3 0x19
98 #define DM9000_REG_MAR4 0x1A
99 #define DM9000_REG_MAR5 0x1B
100 #define DM9000_REG_MAR6 0x1C
101 #define DM9000_REG_MAR7 0x1D
102 #define DM9000_REG_GPCR 0x1E
103 #define DM9000_REG_GPR 0x1F
104 #define DM9000_REG_TRPAL 0x22
105 #define DM9000_REG_TRPAH 0x23
106 #define DM9000_REG_RWPAL 0x24
107 #define DM9000_REG_RWPAH 0x25
108 #define DM9000_REG_VIDL 0x28
109 #define DM9000_REG_VIDH 0x29
110 #define DM9000_REG_PIDL 0x2A
111 #define DM9000_REG_PIDH 0x2B
112 #define DM9000_REG_CHIPR 0x2C
113 #define DM9000_REG_SMCR 0x2F
114 #define DM9000_REG_MRCMDX 0xF0
115 #define DM9000_REG_MRCMD 0xF2
116 #define DM9000_REG_MRRL 0xF4
117 #define DM9000_REG_MRRH 0xF5
118 #define DM9000_REG_MWCMDX 0xF6
119 #define DM9000_REG_MWCMD 0xF8
120 #define DM9000_REG_MWRL 0xFA
121 #define DM9000_REG_MWRH 0xFB
122 #define DM9000_REG_TXPLL 0xFC
123 #define DM9000_REG_TXPLH 0xFD
124 #define DM9000_REG_ISR 0xFE
125 #define DM9000_ISR_ROOS (1<<3)
126 #define DM9000_ISR_ROS (1<<2)
127 #define DM9000_ISR_PTS (1<<1)
128 #define DM9000_ISR_PRS (1<<0)
129 #define DM9000_ISR_CLR_STATUS (ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS)
131 #define DM9000_REG_IMR 0xFF
132 #define DM9000_IMR_AUTOWRAP 0x80
135 #define DM9000_MII_READ 0x0C
136 #define DM9000_MII_WRITE 0x0A
138 #define DM9000_MII_REG_BMCR 0x00
139 #define DM9000_MII_REG_STATUS 0x01
140 #define DM9000_MII_REG_PHYID1 0x02
141 #define DM9000_MII_REG_PHYID2 0x03
142 #define DM9000_MII_REG_ANAR 0x04
143 #define DM9000_MII_REG_ANLPAR 0x05
144 #define DM9000_MII_REG_ANER 0x06
145 #define DM9000_MII_REG_DSCR 0x10
146 #define DM9000_MII_REG_DSCSR 0x11
147 #define DM9000_MII_REG_10BTCSR 0x12
150 DM9K_TX_FIFO_START
= 0,
151 DM9K_TX_FIFO_SIZE
= (3 * 1024),
153 DM9K_RX_FIFO_START
= DM9K_TX_FIFO_SIZE
,
154 DM9K_RX_FIFO_SIZE
= (13 * 1024),
156 DM9K_FIFO_SIZE
= (DM9K_TX_FIFO_SIZE
+ DM9K_RX_FIFO_SIZE
)
159 #define DM9K_WRAP_TX_INDEX(_v) ((_v >= DM9K_TX_FIFO_SIZE) ? (_v) - DM9K_TX_FIFO_SIZE : (_v))
160 #define DM9K_WRAP_RX_INDEX(_v) ((_v >= DM9K_FIFO_SIZE) ? (_v) - DM9K_RX_FIFO_SIZE : (_v))
161 /* DM9KNOTE: Assumes 16bit wiring */
162 #define DM9K_CLIP_TX_INDEX(_v) ((_v) & 1 ? DM9K_WRAP_TX_INDEX((_v)+1) : (_v))
163 #define DM9K_CLIP_RX_INDEX(_v) ((_v) & 1 ? DM9K_WRAP_RX_INDEX((_v)+1) : (_v))
166 uint32_t addr
; /* address port */
167 uint32_t data
; /* data port */
173 uint8_t address
; /* The internal magical address */
176 * Transmit buffer is the first 3KB,
177 * followed by the receive buffer
179 uint8_t packet_buffer
[DM9K_FIFO_SIZE
];
182 uint16_t dm9k_rwpa
; /* TX Read ptr address, RX write ptr address */
185 uint16_t fc_high_mark
;
186 uint16_t fc_low_mark
;
189 uint16_t dm9k_mwr
; /* Read and write address registers */
190 uint16_t dm9k_txpl
; /* TX packet length */
192 uint8_t dm9k_imr
, dm9k_isr
; /* Interrupt mask register and status register*/
193 uint8_t dm9k_ncr
, dm9k_nsr
; /* Network control register, network status register */
194 uint8_t dm9k_rcr
; /* RX Control Register */
195 uint8_t dm9k_rsr
; /* RX Status Register */
196 uint8_t dm9k_wcr
; /* Wakeup control */
197 uint8_t dm9k_tcr
; /* Transmission control register */
198 uint8_t packet_copy_buffer
[3 * 1024]; /* packet copy buffer */
199 unsigned int packet_index
:1; /* 0 == packet I, 1 == packet II */
201 /* Internal MII PHY state */
202 uint8_t dm9k_epcr
; /* EEPROM/PHY control register */
203 uint8_t dm9k_epar
; /* EEPROM/PHY address register */
204 uint16_t dm9k_epdr
; /* EEPROM/PHY data register */
206 uint16_t dm9k_mii_bmcr
;
207 uint16_t dm9k_mii_anar
;
208 uint16_t dm9k_mii_dscr
;
213 #ifdef DM9000_DUMP_FILENAME
214 #include <arpa/inet.h>
215 static uint8_t pcap_header
[24] = {
216 0xA1, 0xB2, 0xC3, 0xD4, /* TCPDUMP Magic */
217 0x00, 0x02, 0x00, 0x04, /* Major 2, Minor 4 */
218 0x00, 0x00, 0x00, 0x00, /* Timezone offset */
219 0x00, 0x00, 0x00, 0x01, /* Accuracy of timestamps */
220 0x00, 0x00, 0x0C, 0x00, /* Snaplen 3KiB */
221 0x00, 0x00, 0x00, 0x01, /* Ethernet frames */
223 static uint8_t nulls
[8] = {0, 0, 0, 0, 0, 0, 0, 0};
224 static void dm9k_dump_packet(uint8_t *buf
, uint32_t size
)
226 FILE* dm9k_fileh
= fopen(DM9000_DUMP_FILENAME
, "ab+");
227 unsigned long bsize
= htonl(size
);
228 DM9000_DBF("Dumping packet at %08x (%d bytes)\n", buf
, size
);
229 fseek(dm9k_fileh
, 0, SEEK_END
);
230 if(ftell(dm9k_fileh
)==0) fwrite(pcap_header
, 1, 24, dm9k_fileh
);
231 fwrite(nulls
, 1, 8, dm9k_fileh
);
232 fwrite(&bsize
, 1, 4, dm9k_fileh
);
233 fwrite(&bsize
, 1, 4, dm9k_fileh
);
234 fwrite(buf
, 1, size
, dm9k_fileh
);
238 #define dm9k_dump_packet(X...) do { } while(0)
241 static void hexdump(const void* address
, uint32_t len
)
243 const unsigned char* p
= address
;
246 for (i
= 0; i
< len
; i
+= 16) {
247 for (j
= 0; j
< 16 && i
+ j
< len
; j
++)
248 fprintf(stderr
, "%02x ", p
[i
+ j
]);
250 fprintf(stderr
, " ");
251 fprintf(stderr
, " ");
252 for (j
= 0; j
< 16 && i
+ j
< len
; j
++)
253 fprintf(stderr
, "%c", (p
[i
+ j
] < ' ' || p
[i
+ j
] > 0x7f) ? '.' : p
[i
+ j
]);
254 fprintf(stderr
, "\n");
258 static void dm9000_raise_irq(dm9000_state
*s
)
260 int level
= ((s
->dm9k_isr
& s
->dm9k_imr
) & 0x0f) != 0;
261 //DM9000_DBF("DM9000: Set IRQ level %d (isr = %02x imr %02x\n", level, s->dm9k_isr, s->dm9k_imr);
262 qemu_set_irq(s
->irq
, level
);
265 static void dm9000_soft_reset_mii(dm9000_state
*s
)
267 s
->dm9k_mii_bmcr
= 0x3100; /* 100Mbps, AUTONEG, FULL DUPLEX */
268 s
->dm9k_mii_anar
= 0x01E1;
269 s
->dm9k_mii_dscr
= 0x0410;
272 static void dm9000_soft_reset(dm9000_state
*s
)
274 DM9000_DBF("DM9000: Soft Reset\n");
276 s
->dm9k_mwr
= s
->dm9k_trpa
= DM9K_TX_FIFO_START
;
277 s
->dm9k_mrr
= s
->dm9k_rwpa
= DM9K_RX_FIFO_START
;
279 s
->dm9k_isr
= 0; /* 16 bit mode, no interrupts asserted */
284 s
->fctr
= (3 << 4) | (8 << 0); // flow control high/low marks
285 s
->fc_high_mark
= 3 * 1024;
286 s
->fc_low_mark
= 8 * 1024;
289 memset(s
->packet_buffer
, 0, sizeof(s
->packet_buffer
));
290 memset(s
->packet_copy_buffer
, 0, sizeof(s
->packet_copy_buffer
));
291 /* These registers have some bits "unaffected by software reset" */
292 /* Clear the reset bits */
293 s
->dm9k_ncr
&= DM9000_NCR_RESETPROTECT
;
294 s
->dm9k_nsr
&= DM9000_NSR_RESETPROTECT
;
295 /* Claim full duplex */
296 s
->dm9k_ncr
|= DM9000_NCR_FDX
;
297 /* Set link status to 1 */
298 s
->dm9k_nsr
|= DM9000_NSR_LINKST
;
299 /* dm9k_wcr is unaffected or reserved, never reset */
300 /* MII control regs */
304 dm9000_soft_reset_mii(s
);
305 dm9000_raise_irq(s
); /* Clear any potentially pending IRQ */
308 static void dm9000_hard_reset(dm9000_state
*s
)
313 dm9000_soft_reset(s
);
316 static void dm9000_do_transmit(dm9000_state
*s
) {
317 uint16_t idx
, cnt
, tptr
;
321 if (cnt
> DM9K_TX_FIFO_SIZE
)
322 cnt
= DM9K_TX_FIFO_SIZE
; /* HARD CAP AT 3KiB */
326 s
->packet_copy_buffer
[tptr
++] = s
->packet_buffer
[idx
];
327 idx
= DM9K_WRAP_TX_INDEX(idx
+1);
332 uint8_t *buf
= &s
->packet_copy_buffer
[6];
333 DM9000_DBF("TX_Packet: %02x:%02x:%02x:%02x:%02x:%02x %d bytes from %04x\n",
334 buf
[0],buf
[1],buf
[2],buf
[3],buf
[4],buf
[5],
336 // hexdump(s->packet_copy_buffer, tptr);
340 s
->dm9k_trpa
= DM9K_CLIP_TX_INDEX(idx
);
341 dm9k_dump_packet(s
->packet_copy_buffer
, s
->dm9k_txpl
);
342 /* We have the copy buffer, now we do the transmit */
343 qemu_send_packet(s
->vc
, s
->packet_copy_buffer
, s
->dm9k_txpl
);
345 /* Clear the "please xmit" bit */
346 s
->dm9k_tcr
&= ~DM9000_TCR_TXREQ
;
347 /* Set the TXEND bit */
348 s
->dm9k_nsr
|= 1 << (2 + s
->packet_index
);
349 DM9000_DBF("TX: NSR=%02x PI=%d\n", s
->dm9k_nsr
, s
->packet_index
);
350 /* Claim a TX complete IRQ */
351 s
->dm9k_isr
|= DM9000_ISR_PTS
; /* Packet transmitted latch */
352 /* And flip the next-packet bit */
358 static void dm9000_mii_read(dm9000_state
*s
)
360 int mii_reg
= (s
->dm9k_epar
) & 0x3f;
363 case DM9000_MII_REG_BMCR
:
364 ret
= s
->dm9k_mii_bmcr
;
366 case DM9000_MII_REG_STATUS
:
367 ret
= 0x782D; /* No 100/T4, Can 100/FD, Can 100/HD, Can 10/FD, Can 10/HD,
368 * No Preamble suppression, Autoneg complete, No remote fault,
369 * Can autoneg, link up, no jabber, extended capability */
371 case DM9000_MII_REG_PHYID1
:
374 case DM9000_MII_REG_PHYID2
:
377 case DM9000_MII_REG_ANAR
:
378 ret
= s
->dm9k_mii_anar
;
380 case DM9000_MII_REG_ANLPAR
:
383 case DM9000_MII_REG_ANER
:
386 case DM9000_MII_REG_DSCR
:
387 ret
= s
->dm9k_mii_dscr
;
389 case DM9000_MII_REG_DSCSR
:
392 case DM9000_MII_REG_10BTCSR
:
395 printf("%s: Bad register 0x%lx\n", __FUNCTION__
, (unsigned long)mii_reg
);
398 // DM9000_DBF("DM9000:MIIPHY: Read of MII reg %d gives %04x\n", mii_reg, s->dm9k_epdr);
401 static void dm9000_mii_write(dm9000_state
*s
)
403 int mii_reg
= (s
->dm9k_epar
) & 0x3f;
404 DM9000_DBF("DM9000:MIIPHY: Write of MII reg %d value %04x\n", mii_reg
, s
->dm9k_epdr
);
406 case DM9000_MII_REG_BMCR
:
407 s
->dm9k_mii_bmcr
= (s
->dm9k_epdr
&~0x8000);
408 if( s
->dm9k_epdr
& 0x8000 ) dm9000_soft_reset_mii(s
);
410 case DM9000_MII_REG_ANAR
:
411 s
->dm9k_mii_anar
= s
->dm9k_epdr
;
413 case DM9000_MII_REG_DSCR
:
414 s
->dm9k_mii_dscr
= s
->dm9k_epdr
& ~0x0008;
417 printf("%s: Bad register 0x%lx=%4x\n", __FUNCTION__
, (unsigned long)mii_reg
, s
->dm9k_epdr
);
421 static void dm9000_write(void *opaque
, target_phys_addr_t address
,
424 dm9000_state
*s
= (dm9000_state
*)opaque
;
426 int suppress_debug
= 0;
429 if (address
== s
->addr
) {
430 // if( (value != DM9000_REG_MRCMD) && (value != DM9000_REG_MWCMD) )
431 // DM9000_DBF("DM9000: Address set to 0x%02x\n", value);
438 DM9000_DBF("DM9000_REG_NCR: %02x=%04x\n", s
->address
, value
);
439 s
->dm9k_ncr
= value
| DM9000_NCR_FDX
;
440 if (s
->dm9k_ncr
& DM9000_NCR_RESET
)
441 dm9000_soft_reset(s
);
444 s
->dm9k_nsr
&= ~(value
& ~DM9000_NSR_READONLY
);
447 s
->dm9k_tcr
= value
& 0xFF;
448 if ( value
& DM9000_TCR_TXREQ
)
449 dm9000_do_transmit(s
);
451 case DM9000_REG_EPCR
:
452 s
->dm9k_epcr
= value
& 0xFF;
453 if( value
& DM9000_MII_READ
)
455 else if( value
& DM9000_MII_WRITE
)
459 s
->dm9k_rcr
= value
& 0xFF;
462 case DM9000_REG_BPTR
: /* can be ignored */
465 case DM9000_REG_FCTR
: {/* 0x09 Flow Control Threshold Register */
466 s
->fc_high_mark
= ((value
>> 4) & 0xf) * 1024; // emit a pause packet time=0xffff
467 s
->fc_low_mark
= ((value
) & 0xf) * 1024; // emit an unpause packet time=0x0000
471 case DM9000_REG_FCR
: /* 0x0a Flow Control Register */
475 case DM9000_REG_EPAR
:
476 s
->dm9k_epar
= value
& 0xFF;
478 case DM9000_REG_EPDRL
:
479 s
->dm9k_epdr
&= 0xFF00;
480 s
->dm9k_epdr
|= value
& 0xFF;
482 case DM9000_REG_EPDRH
:
483 s
->dm9k_epdr
&= 0xFF;
484 s
->dm9k_epdr
|= (value
& 0xFF) << 8;
486 case DM9000_REG_PAR0
... DM9000_REG_PAR5
:
487 /* MAC address is set by the QEMU Nic */
488 s
->macaddr
[s
->address
- DM9000_REG_PAR0
] = value
;
490 case DM9000_REG_MAR0
... DM9000_REG_MAR7
:
491 /* Multicast address is ignored */
492 s
->mult
[s
->address
- DM9000_REG_MAR0
] = value
;
494 case DM9000_REG_GPCR
:
495 case DM9000_REG_GPR
: /* General purpose reg (GPIOs, LED?) */
497 case DM9000_REG_SMCR
:
499 printf("%s: something playing with special mode ? 0x%lx=%x\n", __FUNCTION__
, (unsigned long)s
->address
, value
);
501 case DM9000_REG_MRRL
:
502 s
->dm9k_mrr
&= 0xFF00;
503 s
->dm9k_mrr
|= value
& 0xFF;
505 case DM9000_REG_MRRH
:
507 s
->dm9k_mrr
|= (value
& 0xFF) << 8;
509 case DM9000_REG_MWCMDX
:
510 case DM9000_REG_MWCMD
:
511 /* DM9KNOTE: This assumes a 16bit wide wiring */
512 s
->packet_buffer
[s
->dm9k_mwr
] = value
& 0xFF;
513 s
->packet_buffer
[s
->dm9k_mwr
+ 1] = (value
>> 8) & 0xFF;
514 if (s
->address
== DM9000_REG_MWCMD
) {
515 if (s
->dm9k_imr
& DM9000_IMR_AUTOWRAP
)
516 s
->dm9k_mwr
= DM9K_WRAP_TX_INDEX(s
->dm9k_mwr
+ 2);
517 else if (s
->dm9k_mwr
+ 2 < DM9K_TX_FIFO_SIZE
) // clip it
524 case DM9000_REG_MWRL
:
525 s
->dm9k_mwr
&= 0xFF00;
526 s
->dm9k_mwr
|= value
& 0xFF;
528 case DM9000_REG_MWRH
:
530 s
->dm9k_mwr
|= (value
& 0xFF) << 8;
532 case DM9000_REG_TXPLL
:
533 s
->dm9k_txpl
&= 0xFF00;
534 s
->dm9k_txpl
|= value
& 0xFF;
536 case DM9000_REG_TXPLH
:
537 s
->dm9k_txpl
&= 0xFF;
538 s
->dm9k_txpl
|= (value
& 0xFF) << 8;
541 s
->dm9k_isr
&= ~(value
& 0x0F);
545 if( !(s
->dm9k_imr
& DM9000_IMR_AUTOWRAP
) && (value
& DM9000_IMR_AUTOWRAP
) )
546 s
->dm9k_mrr
= 0x0C00 | (s
->dm9k_mrr
& 0xFF);
547 s
->dm9k_imr
= value
& 0xFF;
551 printf("%s: Bad register 0x%lx=%x\n", __FUNCTION__
, (unsigned long)s
->address
, value
);
553 #if 0 // def DM9000_DEBUG
554 if(!suppress_debug
) DM9000_DBF("DM9000: Write value %02x=%04x\n", s
->address
, value
);
558 static uint32_t dm9000_read(void *opaque
, target_phys_addr_t address
)
560 dm9000_state
*s
= (dm9000_state
*)opaque
;
563 int suppress_debug
= 0;
566 if (address
== s
->addr
)
574 /* Note, TX1END and TX2END are *CLEAR ON READ* */
575 s
->dm9k_nsr
&= ~(DM9000_NSR_TX1END
| DM9000_NSR_TX2END
);
580 case DM9000_REG_TSR1
:
581 case DM9000_REG_TSR2
:
582 ret
= 0x00; /* No error, yay! */
584 case DM9000_REG_EPCR
:
593 case DM9000_REG_EPAR
:
596 case DM9000_REG_EPDRL
:
597 ret
= s
->dm9k_epdr
& 0xFF;
599 case DM9000_REG_EPDRH
:
600 ret
= (s
->dm9k_epdr
>> 8) & 0xFF;
602 case DM9000_REG_PAR0
...DM9000_REG_PAR5
:
603 ret
= s
->macaddr
[s
->address
- DM9000_REG_PAR0
];
605 case DM9000_REG_MAR0
...DM9000_REG_MAR7
:
606 /* Multicast address is ignored */
608 case DM9000_REG_TRPAL
:
609 ret
= s
->dm9k_trpa
& 0xFF;
611 case DM9000_REG_TRPAH
:
612 ret
= s
->dm9k_trpa
>> 8;
614 case DM9000_REG_RWPAL
:
615 ret
= s
->dm9k_rwpa
& 0xFF;
617 case DM9000_REG_RWPAH
:
618 ret
= s
->dm9k_rwpa
>> 8;
620 case DM9000_REG_VIDL
:
623 case DM9000_REG_VIDH
:
626 case DM9000_REG_PIDL
:
629 case DM9000_REG_PIDH
:
632 case DM9000_REG_CHIPR
:
635 case DM9000_REG_MRCMDX
:
636 case DM9000_REG_MRCMD
:
637 /* DM9KNOTE: This assumes a 16bit wide wiring */
638 ret
= s
->packet_buffer
[s
->dm9k_mrr
];
639 ret
|= s
->packet_buffer
[s
->dm9k_mrr
+ 1] << 8;
641 if (s
->dm9k_mrr
== s
->dm9k_rwpa
)
642 printf("(%04x=%04x) ", s
->dm9k_mrr
, ret
);
644 printf("[%04x=%04x] ", s
->dm9k_mrr
, ret
);
647 if( s
->address
== DM9000_REG_MRCMD
) {
648 if( s
->dm9k_imr
& DM9000_IMR_AUTOWRAP
)
649 s
->dm9k_mrr
= DM9K_WRAP_RX_INDEX(s
->dm9k_mrr
+ 2);
650 else if (s
->dm9k_mrr
+ 2 < DM9K_FIFO_SIZE
) // clip it
653 // drive read the fifo looking for a 0x01 to indicate a packet is there, so we just return
654 // it a zero if there is nothing to read
655 if (s
->dm9k_mrr
== s
->dm9k_rwpa
)
659 if (s
->address
==DM9000_REG_MRCMD
)
663 case DM9000_REG_MRRL
:
664 ret
= s
->dm9k_mrr
& 0xFF;
666 case DM9000_REG_MRRH
:
667 ret
= s
->dm9k_mrr
>> 8;
669 case DM9000_REG_MWRL
:
670 ret
= s
->dm9k_mwr
& 0xFF;
672 case DM9000_REG_MWRH
:
673 ret
= s
->dm9k_mwr
>> 8;
675 case DM9000_REG_TXPLL
:
676 ret
= s
->dm9k_txpl
& 0xFF;
678 case DM9000_REG_TXPLH
:
679 ret
= s
->dm9k_txpl
>> 8;
691 #if 0 // def DM9000_DEBUG
692 if(!suppress_debug
) DM9000_DBF("DM9000: Read gives: %04x\n", ret
);
699 static int dm9000_can_receive(void *opaque
)
701 dm9000_state
*s
= (dm9000_state
*)opaque
;
703 if( s
->dm9k_rwpa
< s
->dm9k_mrr
)
704 rx_space
= s
->dm9k_mrr
- s
->dm9k_rwpa
;
706 rx_space
= DM9K_RX_FIFO_SIZE
- (s
->dm9k_rwpa
- s
->dm9k_mrr
);
707 DM9000_DBF("DM9000:RX_Packet: Asked about RX, rwpa=%d mrr=%d => space is %d bytes\n",
708 s
->dm9k_rwpa
, s
->dm9k_mrr
, rx_space
);
709 if (rx_space
> 2048) return 1;
713 #define POLYNOMIAL 0x04c11db6
717 static int compute_mcast_idx(const uint8_t *ep
)
724 for (i
= 0; i
< 6; i
++) {
726 for (j
= 0; j
< 8; j
++) {
727 carry
= ((crc
& 0x80000000L
) ? 1 : 0) ^ (b
& 0x01);
731 crc
= ((crc
^ POLYNOMIAL
) | carry
);
737 static void dm9000_receive(void *opaque
, const uint8_t *buf
, int size
)
739 dm9000_state
*s
= (dm9000_state
*)opaque
;
740 uint16_t rxptr
= s
->dm9k_rwpa
, idx
;
741 unsigned int mcast_idx
= 0;
744 if (!(s
->dm9k_rcr
& DM9000_RCR_RXEN
))
748 if (!(s
->dm9k_rcr
& DM9000_RCR_PRMSC
)) {
750 /* multi/broadcast */
751 if (!(s
->dm9k_rcr
& DM9000_RCR_ALL
)) {
752 mcast_idx
= compute_mcast_idx(buf
);
753 if (!(s
->mult
[mcast_idx
>> 3] & (1 << (mcast_idx
& 7))))
755 s
->dm9k_rsr
|= DM9000_RSR_MF
;
757 } else if (!memcmp(buf
, s
->macaddr
, 6)) {
762 if (size
< 64 && !(s
->dm9k_rcr
& DM9000_RCR_RUNT
)) {
763 // printf("rcr %02x RUNT %d\n", s->dm9k_rcr, size);
764 s
->dm9k_rsr
|= DM9000_RSR_RF
;
767 if (size
> 1522 && (s
->dm9k_rcr
& DM9000_RCR_DIS_LONG
))
771 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",
772 buf
[0],buf
[1],buf
[2],buf
[3],buf
[4],buf
[5],
773 buf
[6],buf
[7],buf
[8],buf
[9],buf
[10],buf
[11],
774 size
, rxptr
, s
->dm9k_rcr
);
775 dm9k_dump_packet(buf
, size
);
778 * apparently even runt frames are padded to 64
783 rxptr
= DM9K_CLIP_RX_INDEX(rxptr
);
785 s
->packet_buffer
[rxptr
] = 0x01; /* Packet read */
786 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
787 s
->packet_buffer
[rxptr
] = 0x00; /* Status OK */
788 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
789 s
->packet_buffer
[rxptr
] = (size
+pad
) & 0xFF; /* Size LOW */
790 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
791 s
->packet_buffer
[rxptr
] = ((size
+pad
) >> 8) & 0xff; /* Size HIGH */
792 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
794 for (idx
= 0; idx
< size
; idx
++) {
795 s
->packet_buffer
[rxptr
] = *buf
++;
796 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
799 s
->packet_buffer
[rxptr
] = 0;
800 rxptr
= DM9K_WRAP_RX_INDEX(rxptr
+1);
803 s
->dm9k_rwpa
= DM9K_CLIP_RX_INDEX(rxptr
);
804 s
->dm9k_isr
|= DM9000_ISR_PRS
; /* RX interrupt, yay */
809 static CPUReadMemoryFunc
*dm9000_readfn
[] = {
815 static CPUWriteMemoryFunc
*dm9000_writefn
[] = {
821 /* initialises a dm9000 ethernet controller
822 * The dm9k has a single 16bit wide address and data port through which all
823 * operations are multiplexed, there is a single IRQ
825 void dm9000_init(NICInfo
*nd
, target_phys_addr_t base_addr
,
826 uint32_t addr_offset
, uint32_t data_offset
,
832 s
= (dm9000_state
*)qemu_mallocz(sizeof(dm9000_state
));
833 iomemtype
= cpu_register_io_memory(0, dm9000_readfn
,
835 cpu_register_physical_memory(base_addr
, MAX(addr_offset
, data_offset
) + 4, iomemtype
);
836 s
->addr
= addr_offset
;
837 s
->data
= data_offset
;
839 memcpy(s
->macaddr
, nd
->macaddr
, 6);
840 memset(s
->mult
, 0xff, 8);
843 uint8_t * buf
= s
->macaddr
;
844 printf("DM9000: INIT QEMU MAC : %02x:%02x:%02x:%02x:%02x:%02x\n",
845 buf
[0],buf
[1],buf
[2],buf
[3],buf
[4],buf
[5]);
848 dm9000_hard_reset(s
);
850 s
->vc
= qemu_new_vlan_client(nd
->vlan
, nd
->model
, nd
->name
,
851 dm9000_receive
, dm9000_can_receive
, s
);
852 qemu_format_nic_info_str(s
->vc
, s
->macaddr
);