[24C0X] Added eeprom to Makefile
[qemu/mini2440.git] / hw / dm9000.c
blobefc4a96ebfbae34aad6c68b77bb800dc1882fbda
1 /* hw/dm9000.c
3 * DM9000 Ethernet interface
5 * Copyright Daniel Silverstone and Vincent Sanders
7 * This file is under the terms of the GNU General Public
8 * License Version 2
9 */
11 #include <string.h>
12 #include "qemu-common.h"
13 #include "hw/irq.h"
14 #include "net.h"
15 #include "dm9000.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"
23 #ifdef DM9000_DEBUG
24 #define DM9000_DBF(X...) fprintf(stderr, X)
25 #else
26 #define DM9000_DBF(X...) if(0) fprintf(stderr, X)
27 #endif
29 #define DM9000_REG_NCR 0x00
30 #define DM9000_REG_NSR 0x01
31 #define DM9000_REG_TCR 0x02
32 #define DM9000_REG_TSR1 0x03
33 #define DM9000_REG_TSR2 0x04
34 #define DM9000_REG_RCR 0x05
35 #define DM9000_REG_RSR 0x06
36 #define DM9000_REG_ROCR 0x07
37 #define DM9000_REG_BPTR 0x08
38 #define DM9000_REG_FCTR 0x09
39 #define DM9000_REG_FCR 0x0A
40 #define DM9000_REG_EPCR 0x0B
41 #define DM9000_REG_EPAR 0x0C
42 #define DM9000_REG_EPDRL 0x0D
43 #define DM9000_REG_EPDRH 0x0E
44 #define DM9000_REG_WCR 0x0F
45 #define DM9000_REG_PAR0 0x10
46 #define DM9000_REG_PAR1 0x11
47 #define DM9000_REG_PAR2 0x12
48 #define DM9000_REG_PAR3 0x13
49 #define DM9000_REG_PAR4 0x14
50 #define DM9000_REG_PAR5 0x15
51 #define DM9000_REG_MAR0 0x16
52 #define DM9000_REG_MAR1 0x17
53 #define DM9000_REG_MAR2 0x18
54 #define DM9000_REG_MAR3 0x19
55 #define DM9000_REG_MAR4 0x1A
56 #define DM9000_REG_MAR5 0x1B
57 #define DM9000_REG_MAR6 0x1C
58 #define DM9000_REG_MAR7 0x1D
59 #define DM9000_REG_GPCR 0x1E
60 #define DM9000_REG_GPR 0x1F
61 #define DM9000_REG_TRPAL 0x22
62 #define DM9000_REG_TRPAH 0x23
63 #define DM9000_REG_RWPAL 0x24
64 #define DM9000_REG_RWPAH 0x25
65 #define DM9000_REG_VIDL 0x28
66 #define DM9000_REG_VIDH 0x29
67 #define DM9000_REG_PIDL 0x2A
68 #define DM9000_REG_PIDH 0x2B
69 #define DM9000_REG_CHIPR 0x2C
70 #define DM9000_REG_SMCR 0x2F
71 #define DM9000_REG_MRCMDX 0xF0
72 #define DM9000_REG_MRCMD 0xF2
73 #define DM9000_REG_MRRL 0xF4
74 #define DM9000_REG_MRRH 0xF5
75 #define DM9000_REG_MWCMDX 0xF6
76 #define DM9000_REG_MWCMD 0xF8
77 #define DM9000_REG_MWRL 0xFA
78 #define DM9000_REG_MWRH 0xFB
79 #define DM9000_REG_TXPLL 0xFC
80 #define DM9000_REG_TXPLH 0xFD
81 #define DM9000_REG_ISR 0xFE
82 #define DM9000_REG_IMR 0xFF
84 #define DM9000_NCR_RESET 0x01
85 #define DM9000_NSR_TX1END 0x04
86 #define DM9000_NSR_TX2END 0x08
87 #define DM9000_TCR_TXREQ 0x01
89 #define DM9000_IMR_AUTOWRAP 0x80
91 #define DM9000_MII_READ 0x0C
92 #define DM9000_MII_WRITE 0x0A
94 #define DM9000_MII_REG_BMCR 0x00
95 #define DM9000_MII_REG_STATUS 0x01
96 #define DM9000_MII_REG_PHYID1 0x02
97 #define DM9000_MII_REG_PHYID2 0x03
98 #define DM9000_MII_REG_ANAR 0x04
99 #define DM9000_MII_REG_ANLPAR 0x05
100 #define DM9000_MII_REG_ANER 0x06
101 #define DM9000_MII_REG_DSCR 0x10
102 #define DM9000_MII_REG_DSCSR 0x11
103 #define DM9000_MII_REG_10BTCSR 0x12
106 typedef struct {
107 uint32_t addr; /* address port */
108 uint32_t data; /* data port */
109 VLANClientState *vc;
110 qemu_irq irq;
111 uint8_t macaddr[6];
112 uint8_t address; /* The internal magial address */
113 uint8_t packet_buffer[16 * 1024];
114 uint16_t dm9k_mrr, dm9k_mwr; /* Read and write address registers */
115 uint16_t dm9k_txpl; /* TX packet length */
116 uint16_t dm9k_trpa, dm9k_rwpa; /* TX Read ptr address, RX write ptr address */
117 uint8_t dm9k_imr, dm9k_isr; /* Interrupt mask register and status register*/
118 uint8_t dm9k_ncr, dm9k_nsr; /* Network control register, network status register */
119 uint8_t dm9k_wcr; /* Wakeup control */
120 uint8_t dm9k_tcr; /* Transmission control register */
121 uint8_t packet_copy_buffer[3 * 1024]; /* packet copy buffer */
122 unsigned int packet_index:1; /* 0 == packet I, 1 == packet II */
124 /* Internal MII PHY state */
125 uint8_t dm9k_epcr; /* EEPROM/PHY control register */
126 uint8_t dm9k_epar; /* EEPROM/PHY address register */
127 uint16_t dm9k_epdr; /* EEPROM/PHY data register */
128 /* MII Regs */
129 uint16_t dm9k_mii_bmcr;
130 uint16_t dm9k_mii_anar;
131 uint16_t dm9k_mii_dscr;
133 } dm9000_state;
136 #ifdef DM9000_DUMP_FILENAME
137 #include <arpa/inet.h>
138 static uint8_t pcap_header[24] = {
139 0xA1, 0xB2, 0xC3, 0xD4, /* TCPDUMP Magic */
140 0x00, 0x02, 0x00, 0x04, /* Major 2, Minor 4 */
141 0x00, 0x00, 0x00, 0x00, /* Timezone offset */
142 0x00, 0x00, 0x00, 0x01, /* Accuracy of timestamps */
143 0x00, 0x00, 0x0C, 0x00, /* Snaplen 3KiB */
144 0x00, 0x00, 0x00, 0x01, /* Ethernet frames */
146 static uint8_t nulls[8] = {0, 0, 0, 0, 0, 0, 0, 0};
147 static void dm9k_dump_packet(uint8_t *buf, uint32_t size)
149 FILE* dm9k_fileh = fopen(DM9000_DUMP_FILENAME, "ab+");
150 unsigned long bsize = htonl(size);
151 DM9000_DBF("Dumping packet at %08x (%d bytes)\n", buf, size);
152 fseek(dm9k_fileh, 0, SEEK_END);
153 if(ftell(dm9k_fileh)==0) fwrite(pcap_header, 1, 24, dm9k_fileh);
154 fwrite(nulls, 1, 8, dm9k_fileh);
155 fwrite(&bsize, 1, 4, dm9k_fileh);
156 fwrite(&bsize, 1, 4, dm9k_fileh);
157 fwrite(buf, 1, size, dm9k_fileh);
158 fclose(dm9k_fileh);
160 #else
161 #define dm9k_dump_packet(X...) do { } while(0)
162 #endif
164 static void dm9000_raise_irq(dm9000_state *state)
166 int level = ((state->dm9k_isr & state->dm9k_imr) & 0x03) != 0;
167 DM9000_DBF("DM9000: Set IRQ level %d\n", level);
168 qemu_set_irq(state->irq, level);
171 static void dm9000_soft_reset_mii(dm9000_state *state)
173 state->dm9k_mii_bmcr = 0x3100; /* 100Mbps, AUTONEG, FULL DUPLEX */
174 state->dm9k_mii_anar = 0x01E1;
175 state->dm9k_mii_dscr = 0x0410;
178 static void dm9000_soft_reset(dm9000_state *state)
180 DM9000_DBF("DM9000: Soft Reset\n");
181 state->dm9k_mrr = state->dm9k_mwr = state->dm9k_txpl = state->dm9k_trpa = 0x0000;
182 state->dm9k_rwpa = 0x0C04;
183 state->dm9k_imr = 0;
184 state->dm9k_isr = 0; /* 16 bit mode, no interrupts asserted */
185 state->dm9k_tcr = 0;
186 state->packet_index = 0;
187 memset(state->packet_buffer, 0, 16*1024);
188 memset(state->packet_copy_buffer, 0, 3*1024);
189 /* These registers have some bits "unaffected by software reset" */
190 /* Clear the reset bits */
191 state->dm9k_ncr &= 0xA0;
192 state->dm9k_nsr &= 0xD0;
193 /* Claim full duplex */
194 state->dm9k_ncr |= 1<<3;
195 /* Set link status to 1 */
196 state->dm9k_nsr |= 1<<6;
197 /* dm9k_wcr is unaffected or reserved, never reset */
198 /* MII control regs */
199 state->dm9k_epcr = 0x00;
200 state->dm9k_epar = 0x40;
201 /* reset the MII */
202 dm9000_soft_reset_mii(state);
203 dm9000_raise_irq(state); /* Clear any potentially pending IRQ */
206 static void dm9000_hard_reset(dm9000_state *state)
208 state->dm9k_ncr = 0x00;
209 state->dm9k_nsr = 0x00;
210 state->dm9k_wcr = 0x00;
211 dm9000_soft_reset(state);
214 static void dm9000_do_transmit(dm9000_state *state)
216 uint16_t idx, cnt, tptr;
217 idx = state->dm9k_trpa;
218 cnt = state->dm9k_txpl;
219 tptr = 0;
220 if( cnt > 3*1024 ) cnt = 3*1024; /* HARD CAP AT 3KiB */
221 DM9000_DBF("TX_Packet: %d bytes from %04x\n", cnt, idx);
222 while(cnt--) {
223 state->packet_copy_buffer[tptr++] = state->packet_buffer[idx++];
224 if( idx == 0x0C00 ) idx = 0;
226 /* DM9KNOTE: Assumes 16bit wiring */
227 idx = (idx+1) & ~1; /* Round up to nearest 16bit boundary */
228 if( idx == 0x0C00 ) idx = 0;
229 state->dm9k_trpa = idx;
230 dm9k_dump_packet(state->packet_copy_buffer, state->dm9k_txpl);
231 /* We have the copy buffer, now we do the transmit */
232 qemu_send_packet(state->vc, state->packet_copy_buffer, state->dm9k_txpl);
233 /* Clear the "please xmit" bit */
234 state->dm9k_tcr &= ~DM9000_TCR_TXREQ;
235 /* Set the TXEND bit */
236 state->dm9k_nsr |= 1<<(2+state->packet_index);
237 DM9000_DBF("TX: NSR=%02x PI=%d\n", state->dm9k_nsr, state->packet_index);
238 /* Claim a TX complete IRQ */
239 state->dm9k_isr |= 0x02; /* Packet transmitted latch */
240 /* And flip the next-packet bit */
241 state->packet_index = !state->packet_index;
242 dm9000_raise_irq(state);
245 static void dm9000_mii_read(dm9000_state *state)
247 int mii_reg = (state->dm9k_epar) & 0x3f;
248 uint16_t ret = 0;
249 switch(mii_reg) {
250 case DM9000_MII_REG_BMCR:
251 ret = state->dm9k_mii_bmcr;
252 break;
253 case DM9000_MII_REG_STATUS:
254 ret = 0x782D; /* No 100/T4, Can 100/FD, Can 100/HD, Can 10/FD, Can 10/HD,
255 * No Preamble suppression, Autoneg complete, No remote fault,
256 * Can autoneg, link up, no jabber, extended capability */
257 break;
258 case DM9000_MII_REG_PHYID1:
259 ret = 0x0181;
260 break;
261 case DM9000_MII_REG_PHYID2:
262 ret = 0xB8C0;
263 break;
264 case DM9000_MII_REG_ANAR:
265 ret = state->dm9k_mii_anar;
266 break;
267 case DM9000_MII_REG_ANLPAR:
268 ret = 0x0400;
269 break;
270 case DM9000_MII_REG_ANER:
271 ret = 0x0001;
272 break;
273 case DM9000_MII_REG_DSCR:
274 ret = state->dm9k_mii_dscr;
275 break;
276 case DM9000_MII_REG_DSCSR:
277 ret = 0xF008;
278 break;
279 case DM9000_MII_REG_10BTCSR:
280 ret = 0x7800;
282 state->dm9k_epdr = ret;
283 DM9000_DBF("DM9000:MIIPHY: Read of MII reg %d gives %04x\n", mii_reg, state->dm9k_epdr);
286 static void dm9000_mii_write(dm9000_state *state)
288 int mii_reg = (state->dm9k_epar) & 0x3f;
289 DM9000_DBF("DM9000:MIIPHY: Write of MII reg %d value %04x\n", mii_reg, state->dm9k_epdr);
290 switch(mii_reg) {
291 case DM9000_MII_REG_BMCR:
292 state->dm9k_mii_bmcr = (state->dm9k_epdr &~0x8000);
293 if( state->dm9k_epdr & 0x8000 ) dm9000_soft_reset_mii(state);
294 break;
295 case DM9000_MII_REG_ANAR:
296 state->dm9k_mii_anar = state->dm9k_epdr;
297 break;
298 case DM9000_MII_REG_DSCR:
299 state->dm9k_mii_dscr = state->dm9k_epdr & ~0x0008;
300 break;
304 static void dm9000_write(void *opaque, target_phys_addr_t address,
305 uint32_t value)
307 dm9000_state *state = (dm9000_state *)opaque;
308 #ifdef DM9000_DEBUG
309 int suppress_debug = 0;
310 #endif
312 if (address == state->addr) {
313 if( (value != DM9000_REG_MRCMD) &&
314 (value != DM9000_REG_MWCMD) )
315 DM9000_DBF("DM9000: Address set to 0x%02x\n", value);
316 state->address = value;
317 return;
320 switch(state->address) {
321 case DM9000_REG_NCR:
322 state->dm9k_ncr = value & 0xDF;
323 if (state->dm9k_ncr & DM9000_NCR_RESET)
324 dm9000_soft_reset(state);
325 break;
326 case DM9000_REG_NSR:
327 state->dm9k_nsr &= ~(value & 0x2C);
328 break;
329 case DM9000_REG_TCR:
330 state->dm9k_tcr = value & 0xFF;
331 if( value & DM9000_TCR_TXREQ ) dm9000_do_transmit(state);
332 break;
333 case DM9000_REG_EPCR:
334 state->dm9k_epcr = value & 0xFF;
335 if( value & DM9000_MII_READ )
336 dm9000_mii_read(state);
337 else if( value & DM9000_MII_WRITE )
338 dm9000_mii_write(state);
339 break;
340 case DM9000_REG_EPAR:
341 state->dm9k_epar = value & 0xFF;
342 break;
343 case DM9000_REG_EPDRL:
344 state->dm9k_epdr &= 0xFF00;
345 state->dm9k_epdr |= value & 0xFF;
346 break;
347 case DM9000_REG_EPDRH:
348 state->dm9k_epdr &= 0xFF;
349 state->dm9k_epdr |= (value & 0xFF) << 8;
350 break;
351 case DM9000_REG_PAR0:
352 case DM9000_REG_PAR1:
353 case DM9000_REG_PAR2:
354 case DM9000_REG_PAR3:
355 case DM9000_REG_PAR4:
356 case DM9000_REG_PAR5:
357 state->macaddr[state->address - DM9000_REG_PAR0] = value & 0xFF;
358 break;
359 case DM9000_REG_MRRL:
360 state->dm9k_mrr &= 0xFF00;
361 state->dm9k_mrr |= value & 0xFF;
362 break;
363 case DM9000_REG_MRRH:
364 state->dm9k_mrr &= 0xFF;
365 state->dm9k_mrr |= (value & 0xFF) << 8;
366 break;
367 case DM9000_REG_MWCMDX:
368 case DM9000_REG_MWCMD:
369 /* DM9KNOTE: This assumes a 16bit wide wiring */
370 state->packet_buffer[state->dm9k_mwr] = value & 0xFF;
371 state->packet_buffer[state->dm9k_mwr+1] = (value >> 8) & 0xFF;
372 if( state->address == DM9000_REG_MWCMD ) {
373 state->dm9k_mwr += 2;
374 if( state->dm9k_imr & DM9000_IMR_AUTOWRAP )
375 if( state->dm9k_mwr >= 0x0C00 )
376 state->dm9k_mwr -= 0x0C00;
378 #ifdef DM9000_DEBUG
379 suppress_debug = 1;
380 #endif
381 break;
382 case DM9000_REG_MWRL:
383 state->dm9k_mwr &= 0xFF00;
384 state->dm9k_mwr |= value & 0xFF;
385 break;
386 case DM9000_REG_MWRH:
387 state->dm9k_mwr &= 0xFF;
388 state->dm9k_mwr |= (value & 0xFF) << 8;
389 break;
390 case DM9000_REG_TXPLL:
391 state->dm9k_txpl &= 0xFF00;
392 state->dm9k_txpl |= value & 0xFF;
393 break;
394 case DM9000_REG_TXPLH:
395 state->dm9k_txpl &= 0xFF;
396 state->dm9k_txpl |= (value & 0xFF) << 8;
397 break;
398 case DM9000_REG_ISR:
399 state->dm9k_isr &= ~(value & 0x0F);
400 dm9000_raise_irq(state);
401 break;
402 case DM9000_REG_IMR:
403 if( !(state->dm9k_imr & DM9000_IMR_AUTOWRAP) &&
404 (value & DM9000_IMR_AUTOWRAP) )
405 state->dm9k_mrr = 0x0C00 | (state->dm9k_mrr & 0xFF);
406 state->dm9k_imr = value & 0xFF;
407 dm9000_raise_irq(state);
408 break;
410 #ifdef DM9000_DEBUG
411 if(!suppress_debug) DM9000_DBF("DM9000: Write value %04x\n", value);
412 #endif
415 static uint32_t dm9000_read(void *opaque, target_phys_addr_t address)
417 dm9000_state *state = (dm9000_state *)opaque;
418 uint32_t ret = 0;
419 #ifdef DM9000_DEBUG
420 int suppress_debug = 0;
421 #endif
423 if (address == state->addr)
424 return state->address;
425 switch(state->address) {
426 case DM9000_REG_NCR:
427 ret = state->dm9k_ncr;
428 break;
429 case DM9000_REG_NSR:
430 ret = state->dm9k_nsr;
431 /* Note, TX1END and TX2END are *CLEAR ON READ* */
432 state->dm9k_nsr &= ~(DM9000_NSR_TX1END | DM9000_NSR_TX2END);
433 break;
434 case DM9000_REG_TCR:
435 ret = state->dm9k_tcr;
436 break;
437 case DM9000_REG_TSR1:
438 case DM9000_REG_TSR2:
439 ret = 0x00; /* No error, yay! */
440 break;
441 case DM9000_REG_EPCR:
442 ret = state->dm9k_epcr;
443 break;
444 case DM9000_REG_EPAR:
445 ret = state->dm9k_epar;
446 break;
447 case DM9000_REG_EPDRL:
448 ret = state->dm9k_epdr & 0xFF;
449 break;
450 case DM9000_REG_EPDRH:
451 ret = (state->dm9k_epdr >> 8) & 0xFF;
452 break;
453 case DM9000_REG_PAR0:
454 case DM9000_REG_PAR1:
455 case DM9000_REG_PAR2:
456 case DM9000_REG_PAR3:
457 case DM9000_REG_PAR4:
458 case DM9000_REG_PAR5:
459 ret = state->macaddr[state->address - DM9000_REG_PAR0];
460 break;
461 case DM9000_REG_TRPAL:
462 ret = state->dm9k_trpa & 0xFF;
463 break;
464 case DM9000_REG_TRPAH:
465 ret = state->dm9k_trpa >> 8;
466 break;
467 case DM9000_REG_RWPAL:
468 ret = state->dm9k_rwpa & 0xFF;
469 break;
470 case DM9000_REG_RWPAH:
471 ret = state->dm9k_rwpa >> 8;
472 break;
473 case DM9000_REG_VIDL:
474 ret = 0x46;
475 break;
476 case DM9000_REG_VIDH:
477 ret = 0x0A;
478 break;
479 case DM9000_REG_PIDL:
480 ret = 0x00;
481 break;
482 case DM9000_REG_PIDH:
483 ret = 0x90;
484 break;
485 case DM9000_REG_CHIPR:
486 ret = 0x00;
487 break;
488 case DM9000_REG_MRCMDX:
489 case DM9000_REG_MRCMD:
490 /* DM9KNOTE: This assumes a 16bit wide wiring */
491 ret = state->packet_buffer[state->dm9k_mrr];
492 ret |= state->packet_buffer[state->dm9k_mrr+1] << 8;
493 if( state->address == DM9000_REG_MRCMD ) {
494 state->dm9k_mrr += 2;
495 if( state->dm9k_mrr >= (16*1024) ) state->dm9k_mrr -= (16*1024);
496 if( state->dm9k_imr & DM9000_IMR_AUTOWRAP )
497 if( state->dm9k_mrr < 0x0C00 )
498 state->dm9k_mrr += 0x0C00;
500 #ifdef DM9000_DEBUG
501 if (state->address==DM9000_REG_MRCMD)
502 suppress_debug = 1;
503 #endif
504 break;
505 case DM9000_REG_MRRL:
506 ret = state->dm9k_mrr & 0xFF;
507 break;
508 case DM9000_REG_MRRH:
509 ret = state->dm9k_mrr >> 8;
510 break;
511 case DM9000_REG_MWRL:
512 ret = state->dm9k_mwr & 0xFF;
513 break;
514 case DM9000_REG_MWRH:
515 ret = state->dm9k_mwr >> 8;
516 break;
517 case DM9000_REG_TXPLL:
518 ret = state->dm9k_txpl & 0xFF;
519 break;
520 case DM9000_REG_TXPLH:
521 ret = state->dm9k_txpl >> 8;
522 break;
523 case DM9000_REG_ISR:
524 ret = state->dm9k_isr;
525 break;
526 case DM9000_REG_IMR:
527 ret = state->dm9k_imr;
528 break;
529 default:
530 ret = 0;
533 #ifdef DM9000_DEBUG
534 if(!suppress_debug) DM9000_DBF("DM9000: Read gives: %04x\n", ret);
535 #endif
536 return ret;
541 static int dm9000_can_receive(void *opaque)
543 dm9000_state *state = (dm9000_state *)opaque;
544 uint16_t rx_space;
545 if( state->dm9k_rwpa < state->dm9k_mrr )
546 rx_space = state->dm9k_mrr - state->dm9k_rwpa;
547 else
548 rx_space = (13*1024) - (state->dm9k_rwpa - state->dm9k_mrr);
549 DM9000_DBF("DM9000:RX_Packet: Asked about RX, rwpa=%d mrr=%d => space is %d bytes\n",
550 state->dm9k_rwpa, state->dm9k_mrr, rx_space);
551 if (rx_space > 2048) return 1;
552 return 0;
555 static void dm9000_receive(void *opaque, const uint8_t *buf, int size)
557 dm9000_state *state = (dm9000_state *)opaque;
558 uint16_t rxptr = state->dm9k_rwpa;
559 uint8_t magic_padding = 4;
560 if( size > 2048 ) return; /* La La La, I can't hear you */
561 /* Fill out the magical header structure */
562 DM9000_DBF("DM9000:RX_Packet: %d bytes into buffer at %04x\n", size, rxptr);
563 dm9k_dump_packet(buf, size);
564 if( size < 64 ) magic_padding += (64 - size);
565 DM9000_DBF("DM9000:RX_Packet: Magical padding is %d bytes\n", magic_padding);
566 size += magic_padding; /* The magical CRC bollocks */
567 state->packet_buffer[state->dm9k_rwpa-4] = 0x01; /* Packet read */
568 state->packet_buffer[state->dm9k_rwpa-3] = 0x00; /* Status OK */
569 state->packet_buffer[state->dm9k_rwpa-2] = size & 0xFF; /* Size LOW */
570 state->packet_buffer[state->dm9k_rwpa-1] = (size & 0xFF00)>>8; /* Size HIGH */
571 size += 4; /* The magical next header (which we zero for fun) */
572 while(size--) {
573 if( size > (magic_padding + 3) )
574 state->packet_buffer[rxptr++] = *buf++;
575 else
576 state->packet_buffer[rxptr++] = 0x00; /* Clear to the next header */
577 /* DM9KNOTE: Assumes 16 bit wired config */
578 if (size == 4) rxptr = (rxptr+1) & ~1; /* At end of packet, realign */
579 if( rxptr >= (16*1024) ) rxptr -= (16*1024);
580 if( rxptr < 0x0C00 ) rxptr += 0x0C00;
582 state->dm9k_rwpa = rxptr;
583 state->dm9k_isr |= 0x01; /* RX interrupt, yay */
584 dm9000_raise_irq(state);
588 static CPUReadMemoryFunc *dm9000_readfn[] = {
589 dm9000_read,
590 dm9000_read,
591 dm9000_read
594 static CPUWriteMemoryFunc *dm9000_writefn[] = {
595 dm9000_write,
596 dm9000_write,
597 dm9000_write
600 /* initialises a dm9000 ethernet controller
601 * The dm9k has a single 16bit wide address and data port through which all
602 * operations are multiplexed, there is a single IRQ
604 void dm9000_init(NICInfo *nd, target_phys_addr_t base_addr,
605 uint32_t addr_offset, uint32_t data_offset,
606 qemu_irq irq)
608 dm9000_state *state;
609 int iomemtype;
611 state = (dm9000_state *)qemu_mallocz(sizeof(dm9000_state));
612 iomemtype = cpu_register_io_memory(0, dm9000_readfn,
613 dm9000_writefn, state);
614 cpu_register_physical_memory(base_addr, MAX(addr_offset, data_offset) + 4, iomemtype);
615 state->addr = /*base_addr + */addr_offset;
616 state->data = /*base_addr + */data_offset;
617 state->irq = irq;
618 memcpy(state->macaddr, nd->macaddr, 6);
620 dm9000_hard_reset(state);
622 state->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,
623 dm9000_receive, dm9000_can_receive, state);