|
|
1.1 root 1: /*
2: * QEMU NE2000 emulation
1.1.1.6 root 3: *
1.1 root 4: * Copyright (c) 2003-2004 Fabrice Bellard
1.1.1.6 root 5: *
1.1 root 6: * Permission is hereby granted, free of charge, to any person obtaining a copy
7: * of this software and associated documentation files (the "Software"), to deal
8: * in the Software without restriction, including without limitation the rights
9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10: * copies of the Software, and to permit persons to whom the Software is
11: * furnished to do so, subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included in
14: * all copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22: * THE SOFTWARE.
23: */
1.1.1.6 root 24: #include "hw.h"
25: #include "pci.h"
26: #include "net.h"
1.1.1.10 root 27: #include "ne2000.h"
28: #include "loader.h"
1.1.1.12 root 29: #include "sysemu.h"
1.1 root 30:
31: /* debug NE2000 card */
32: //#define DEBUG_NE2000
33:
34: #define MAX_ETH_FRAME_SIZE 1514
35:
36: #define E8390_CMD 0x00 /* The command register (for all pages) */
37: /* Page 0 register offsets. */
38: #define EN0_CLDALO 0x01 /* Low byte of current local dma addr RD */
39: #define EN0_STARTPG 0x01 /* Starting page of ring bfr WR */
40: #define EN0_CLDAHI 0x02 /* High byte of current local dma addr RD */
41: #define EN0_STOPPG 0x02 /* Ending page +1 of ring bfr WR */
42: #define EN0_BOUNDARY 0x03 /* Boundary page of ring bfr RD WR */
43: #define EN0_TSR 0x04 /* Transmit status reg RD */
44: #define EN0_TPSR 0x04 /* Transmit starting page WR */
45: #define EN0_NCR 0x05 /* Number of collision reg RD */
46: #define EN0_TCNTLO 0x05 /* Low byte of tx byte count WR */
47: #define EN0_FIFO 0x06 /* FIFO RD */
48: #define EN0_TCNTHI 0x06 /* High byte of tx byte count WR */
49: #define EN0_ISR 0x07 /* Interrupt status reg RD WR */
50: #define EN0_CRDALO 0x08 /* low byte of current remote dma address RD */
51: #define EN0_RSARLO 0x08 /* Remote start address reg 0 */
52: #define EN0_CRDAHI 0x09 /* high byte, current remote dma address RD */
53: #define EN0_RSARHI 0x09 /* Remote start address reg 1 */
54: #define EN0_RCNTLO 0x0a /* Remote byte count reg WR */
1.1.1.2 root 55: #define EN0_RTL8029ID0 0x0a /* Realtek ID byte #1 RD */
1.1 root 56: #define EN0_RCNTHI 0x0b /* Remote byte count reg WR */
1.1.1.2 root 57: #define EN0_RTL8029ID1 0x0b /* Realtek ID byte #2 RD */
1.1 root 58: #define EN0_RSR 0x0c /* rx status reg RD */
59: #define EN0_RXCR 0x0c /* RX configuration reg WR */
60: #define EN0_TXCR 0x0d /* TX configuration reg WR */
61: #define EN0_COUNTER0 0x0d /* Rcv alignment error counter RD */
62: #define EN0_DCFG 0x0e /* Data configuration reg WR */
63: #define EN0_COUNTER1 0x0e /* Rcv CRC error counter RD */
64: #define EN0_IMR 0x0f /* Interrupt mask reg WR */
65: #define EN0_COUNTER2 0x0f /* Rcv missed frame error counter RD */
66:
67: #define EN1_PHYS 0x11
68: #define EN1_CURPAG 0x17
69: #define EN1_MULT 0x18
70:
71: #define EN2_STARTPG 0x21 /* Starting page of ring bfr RD */
72: #define EN2_STOPPG 0x22 /* Ending page +1 of ring bfr RD */
73:
1.1.1.2 root 74: #define EN3_CONFIG0 0x33
75: #define EN3_CONFIG1 0x34
76: #define EN3_CONFIG2 0x35
77: #define EN3_CONFIG3 0x36
78:
1.1 root 79: /* Register accessed at EN_CMD, the 8390 base addr. */
80: #define E8390_STOP 0x01 /* Stop and reset the chip */
81: #define E8390_START 0x02 /* Start the chip, clear reset */
82: #define E8390_TRANS 0x04 /* Transmit a frame */
83: #define E8390_RREAD 0x08 /* Remote read */
84: #define E8390_RWRITE 0x10 /* Remote write */
85: #define E8390_NODMA 0x20 /* Remote DMA */
86: #define E8390_PAGE0 0x00 /* Select page chip registers */
87: #define E8390_PAGE1 0x40 /* using the two high-order bits */
88: #define E8390_PAGE2 0x80 /* Page 3 is invalid. */
89:
90: /* Bits in EN0_ISR - Interrupt status register */
91: #define ENISR_RX 0x01 /* Receiver, no error */
92: #define ENISR_TX 0x02 /* Transmitter, no error */
93: #define ENISR_RX_ERR 0x04 /* Receiver, with error */
94: #define ENISR_TX_ERR 0x08 /* Transmitter, with error */
95: #define ENISR_OVER 0x10 /* Receiver overwrote the ring */
96: #define ENISR_COUNTERS 0x20 /* Counters need emptying */
97: #define ENISR_RDC 0x40 /* remote dma complete */
98: #define ENISR_RESET 0x80 /* Reset completed */
99: #define ENISR_ALL 0x3f /* Interrupts we will enable */
100:
101: /* Bits in received packet status byte and EN0_RSR*/
102: #define ENRSR_RXOK 0x01 /* Received a good packet */
103: #define ENRSR_CRC 0x02 /* CRC error */
104: #define ENRSR_FAE 0x04 /* frame alignment error */
105: #define ENRSR_FO 0x08 /* FIFO overrun */
106: #define ENRSR_MPA 0x10 /* missed pkt */
107: #define ENRSR_PHY 0x20 /* physical/multicast address */
108: #define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */
109: #define ENRSR_DEF 0x80 /* deferring */
110:
111: /* Transmitted packet status, EN0_TSR. */
112: #define ENTSR_PTX 0x01 /* Packet transmitted without error */
113: #define ENTSR_ND 0x02 /* The transmit wasn't deferred. */
114: #define ENTSR_COL 0x04 /* The transmit collided at least once. */
115: #define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */
116: #define ENTSR_CRS 0x10 /* The carrier sense was lost. */
117: #define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */
118: #define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
119: #define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
120:
1.1.1.10 root 121: typedef struct PCINE2000State {
122: PCIDevice dev;
123: NE2000State ne2000;
124: } PCINE2000State;
1.1 root 125:
1.1.1.10 root 126: void ne2000_reset(NE2000State *s)
1.1 root 127: {
128: int i;
129:
130: s->isr = ENISR_RESET;
1.1.1.10 root 131: memcpy(s->mem, &s->c.macaddr, 6);
1.1 root 132: s->mem[14] = 0x57;
133: s->mem[15] = 0x57;
134:
135: /* duplicate prom data */
136: for(i = 15;i >= 0; i--) {
137: s->mem[2 * i] = s->mem[i];
138: s->mem[2 * i + 1] = s->mem[i];
139: }
140: }
141:
142: static void ne2000_update_irq(NE2000State *s)
143: {
144: int isr;
145: isr = (s->isr & s->imr) & 0x7f;
146: #if defined(DEBUG_NE2000)
1.1.1.6 root 147: printf("NE2000: Set IRQ to %d (%02x %02x)\n",
148: isr ? 1 : 0, s->isr, s->imr);
1.1 root 149: #endif
1.1.1.6 root 150: qemu_set_irq(s->irq, (isr != 0));
1.1 root 151: }
152:
1.1.1.3 root 153: static int ne2000_buffer_full(NE2000State *s)
1.1 root 154: {
155: int avail, index, boundary;
1.1.1.3 root 156:
1.1 root 157: index = s->curpag << 8;
158: boundary = s->boundary << 8;
1.1.1.6 root 159: if (index < boundary)
1.1 root 160: avail = boundary - index;
161: else
162: avail = (s->stop - s->start) - (index - boundary);
163: if (avail < (MAX_ETH_FRAME_SIZE + 4))
1.1.1.3 root 164: return 1;
165: return 0;
166: }
167:
1.1.1.10 root 168: int ne2000_can_receive(VLANClientState *nc)
1.1.1.3 root 169: {
1.1.1.10 root 170: NE2000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
1.1.1.6 root 171:
1.1.1.3 root 172: if (s->cmd & E8390_STOP)
173: return 1;
174: return !ne2000_buffer_full(s);
1.1 root 175: }
176:
177: #define MIN_BUF_SIZE 60
178:
1.1.1.10 root 179: ssize_t ne2000_receive(VLANClientState *nc, const uint8_t *buf, size_t size_)
1.1 root 180: {
1.1.1.10 root 181: NE2000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
1.1.1.9 root 182: int size = size_;
1.1 root 183: uint8_t *p;
1.1.1.6 root 184: unsigned int total_len, next, avail, len, index, mcast_idx;
1.1 root 185: uint8_t buf1[60];
1.1.1.6 root 186: static const uint8_t broadcast_macaddr[6] =
1.1.1.2 root 187: { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1.1.1.6 root 188:
1.1 root 189: #if defined(DEBUG_NE2000)
190: printf("NE2000: received len=%d\n", size);
191: #endif
192:
1.1.1.3 root 193: if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
1.1.1.9 root 194: return -1;
1.1.1.6 root 195:
1.1.1.2 root 196: /* XXX: check this */
197: if (s->rxcr & 0x10) {
198: /* promiscuous: receive all */
199: } else {
200: if (!memcmp(buf, broadcast_macaddr, 6)) {
201: /* broadcast address */
202: if (!(s->rxcr & 0x04))
1.1.1.9 root 203: return size;
1.1.1.2 root 204: } else if (buf[0] & 0x01) {
205: /* multicast */
206: if (!(s->rxcr & 0x08))
1.1.1.9 root 207: return size;
1.1.1.2 root 208: mcast_idx = compute_mcast_idx(buf);
209: if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
1.1.1.9 root 210: return size;
1.1.1.2 root 211: } else if (s->mem[0] == buf[0] &&
1.1.1.6 root 212: s->mem[2] == buf[1] &&
213: s->mem[4] == buf[2] &&
214: s->mem[6] == buf[3] &&
215: s->mem[8] == buf[4] &&
1.1.1.2 root 216: s->mem[10] == buf[5]) {
217: /* match */
218: } else {
1.1.1.9 root 219: return size;
1.1.1.2 root 220: }
221: }
222:
223:
1.1 root 224: /* if too small buffer, then expand it */
225: if (size < MIN_BUF_SIZE) {
226: memcpy(buf1, buf, size);
227: memset(buf1 + size, 0, MIN_BUF_SIZE - size);
228: buf = buf1;
229: size = MIN_BUF_SIZE;
230: }
231:
232: index = s->curpag << 8;
233: /* 4 bytes for header */
234: total_len = size + 4;
235: /* address for next packet (4 bytes for CRC) */
236: next = index + ((total_len + 4 + 255) & ~0xff);
237: if (next >= s->stop)
238: next -= (s->stop - s->start);
239: /* prepare packet header */
240: p = s->mem + index;
241: s->rsr = ENRSR_RXOK; /* receive status */
242: /* XXX: check this */
243: if (buf[0] & 0x01)
244: s->rsr |= ENRSR_PHY;
245: p[0] = s->rsr;
246: p[1] = next >> 8;
247: p[2] = total_len;
248: p[3] = total_len >> 8;
249: index += 4;
250:
251: /* write packet data */
252: while (size > 0) {
1.1.1.6 root 253: if (index <= s->stop)
254: avail = s->stop - index;
255: else
256: avail = 0;
1.1 root 257: len = size;
258: if (len > avail)
259: len = avail;
260: memcpy(s->mem + index, buf, len);
261: buf += len;
262: index += len;
263: if (index == s->stop)
264: index = s->start;
265: size -= len;
266: }
267: s->curpag = next >> 8;
268:
1.1.1.5 root 269: /* now we can signal we have received something */
1.1 root 270: s->isr |= ENISR_RX;
271: ne2000_update_irq(s);
1.1.1.9 root 272:
273: return size_;
1.1 root 274: }
275:
1.1.1.14 root 276: static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1.1 root 277: {
278: NE2000State *s = opaque;
279: int offset, page, index;
280:
281: addr &= 0xf;
282: #ifdef DEBUG_NE2000
283: printf("NE2000: write addr=0x%x val=0x%02x\n", addr, val);
284: #endif
285: if (addr == E8390_CMD) {
286: /* control register */
287: s->cmd = val;
288: if (!(val & E8390_STOP)) { /* START bit makes no sense on RTL8029... */
289: s->isr &= ~ENISR_RESET;
1.1.1.6 root 290: /* test specific case: zero length transfer */
1.1 root 291: if ((val & (E8390_RREAD | E8390_RWRITE)) &&
292: s->rcnt == 0) {
293: s->isr |= ENISR_RDC;
294: ne2000_update_irq(s);
295: }
296: if (val & E8390_TRANS) {
297: index = (s->tpsr << 8);
1.1.1.6 root 298: /* XXX: next 2 lines are a hack to make netware 3.11 work */
1.1 root 299: if (index >= NE2000_PMEM_END)
300: index -= NE2000_PMEM_SIZE;
301: /* fail safe: check range on the transmitted length */
302: if (index + s->tcnt <= NE2000_PMEM_END) {
1.1.1.10 root 303: qemu_send_packet(&s->nic->nc, s->mem + index, s->tcnt);
1.1 root 304: }
1.1.1.6 root 305: /* signal end of transfer */
1.1 root 306: s->tsr = ENTSR_PTX;
307: s->isr |= ENISR_TX;
1.1.1.6 root 308: s->cmd &= ~E8390_TRANS;
1.1 root 309: ne2000_update_irq(s);
310: }
311: }
312: } else {
313: page = s->cmd >> 6;
314: offset = addr | (page << 4);
315: switch(offset) {
316: case EN0_STARTPG:
317: s->start = val << 8;
318: break;
319: case EN0_STOPPG:
320: s->stop = val << 8;
321: break;
322: case EN0_BOUNDARY:
323: s->boundary = val;
324: break;
325: case EN0_IMR:
326: s->imr = val;
327: ne2000_update_irq(s);
328: break;
329: case EN0_TPSR:
330: s->tpsr = val;
331: break;
332: case EN0_TCNTLO:
333: s->tcnt = (s->tcnt & 0xff00) | val;
334: break;
335: case EN0_TCNTHI:
336: s->tcnt = (s->tcnt & 0x00ff) | (val << 8);
337: break;
338: case EN0_RSARLO:
339: s->rsar = (s->rsar & 0xff00) | val;
340: break;
341: case EN0_RSARHI:
342: s->rsar = (s->rsar & 0x00ff) | (val << 8);
343: break;
344: case EN0_RCNTLO:
345: s->rcnt = (s->rcnt & 0xff00) | val;
346: break;
347: case EN0_RCNTHI:
348: s->rcnt = (s->rcnt & 0x00ff) | (val << 8);
349: break;
1.1.1.2 root 350: case EN0_RXCR:
351: s->rxcr = val;
352: break;
1.1 root 353: case EN0_DCFG:
354: s->dcfg = val;
355: break;
356: case EN0_ISR:
357: s->isr &= ~(val & 0x7f);
358: ne2000_update_irq(s);
359: break;
360: case EN1_PHYS ... EN1_PHYS + 5:
361: s->phys[offset - EN1_PHYS] = val;
362: break;
363: case EN1_CURPAG:
364: s->curpag = val;
365: break;
366: case EN1_MULT ... EN1_MULT + 7:
367: s->mult[offset - EN1_MULT] = val;
368: break;
369: }
370: }
371: }
372:
1.1.1.14 root 373: static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
1.1 root 374: {
375: NE2000State *s = opaque;
376: int offset, page, ret;
377:
378: addr &= 0xf;
379: if (addr == E8390_CMD) {
380: ret = s->cmd;
381: } else {
382: page = s->cmd >> 6;
383: offset = addr | (page << 4);
384: switch(offset) {
385: case EN0_TSR:
386: ret = s->tsr;
387: break;
388: case EN0_BOUNDARY:
389: ret = s->boundary;
390: break;
391: case EN0_ISR:
392: ret = s->isr;
393: break;
394: case EN0_RSARLO:
395: ret = s->rsar & 0x00ff;
396: break;
397: case EN0_RSARHI:
398: ret = s->rsar >> 8;
399: break;
400: case EN1_PHYS ... EN1_PHYS + 5:
401: ret = s->phys[offset - EN1_PHYS];
402: break;
403: case EN1_CURPAG:
404: ret = s->curpag;
405: break;
406: case EN1_MULT ... EN1_MULT + 7:
407: ret = s->mult[offset - EN1_MULT];
408: break;
409: case EN0_RSR:
410: ret = s->rsr;
411: break;
412: case EN2_STARTPG:
413: ret = s->start >> 8;
414: break;
415: case EN2_STOPPG:
416: ret = s->stop >> 8;
417: break;
1.1.1.2 root 418: case EN0_RTL8029ID0:
419: ret = 0x50;
420: break;
421: case EN0_RTL8029ID1:
422: ret = 0x43;
423: break;
424: case EN3_CONFIG0:
425: ret = 0; /* 10baseT media */
426: break;
427: case EN3_CONFIG2:
428: ret = 0x40; /* 10baseT active */
429: break;
430: case EN3_CONFIG3:
431: ret = 0x40; /* Full duplex */
432: break;
1.1 root 433: default:
434: ret = 0x00;
435: break;
436: }
437: }
438: #ifdef DEBUG_NE2000
439: printf("NE2000: read addr=0x%x val=%02x\n", addr, ret);
440: #endif
441: return ret;
442: }
443:
1.1.1.6 root 444: static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr,
1.1 root 445: uint32_t val)
446: {
1.1.1.6 root 447: if (addr < 32 ||
1.1 root 448: (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
449: s->mem[addr] = val;
450: }
451: }
452:
1.1.1.6 root 453: static inline void ne2000_mem_writew(NE2000State *s, uint32_t addr,
1.1 root 454: uint32_t val)
455: {
456: addr &= ~1; /* XXX: check exact behaviour if not even */
1.1.1.6 root 457: if (addr < 32 ||
1.1 root 458: (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
459: *(uint16_t *)(s->mem + addr) = cpu_to_le16(val);
460: }
461: }
462:
1.1.1.6 root 463: static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr,
1.1 root 464: uint32_t val)
465: {
466: addr &= ~1; /* XXX: check exact behaviour if not even */
1.1.1.6 root 467: if (addr < 32 ||
1.1 root 468: (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
469: cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
470: }
471: }
472:
473: static inline uint32_t ne2000_mem_readb(NE2000State *s, uint32_t addr)
474: {
1.1.1.6 root 475: if (addr < 32 ||
1.1 root 476: (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
477: return s->mem[addr];
478: } else {
479: return 0xff;
480: }
481: }
482:
483: static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr)
484: {
485: addr &= ~1; /* XXX: check exact behaviour if not even */
1.1.1.6 root 486: if (addr < 32 ||
1.1 root 487: (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
488: return le16_to_cpu(*(uint16_t *)(s->mem + addr));
489: } else {
490: return 0xffff;
491: }
492: }
493:
494: static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr)
495: {
496: addr &= ~1; /* XXX: check exact behaviour if not even */
1.1.1.6 root 497: if (addr < 32 ||
1.1 root 498: (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
499: return le32_to_cpupu((uint32_t *)(s->mem + addr));
500: } else {
501: return 0xffffffff;
502: }
503: }
504:
505: static inline void ne2000_dma_update(NE2000State *s, int len)
506: {
507: s->rsar += len;
508: /* wrap */
509: /* XXX: check what to do if rsar > stop */
510: if (s->rsar == s->stop)
511: s->rsar = s->start;
512:
513: if (s->rcnt <= len) {
514: s->rcnt = 0;
1.1.1.6 root 515: /* signal end of transfer */
1.1 root 516: s->isr |= ENISR_RDC;
517: ne2000_update_irq(s);
518: } else {
519: s->rcnt -= len;
520: }
521: }
522:
1.1.1.14 root 523: static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1.1 root 524: {
525: NE2000State *s = opaque;
526:
527: #ifdef DEBUG_NE2000
528: printf("NE2000: asic write val=0x%04x\n", val);
529: #endif
530: if (s->rcnt == 0)
531: return;
532: if (s->dcfg & 0x01) {
533: /* 16 bit access */
534: ne2000_mem_writew(s, s->rsar, val);
535: ne2000_dma_update(s, 2);
536: } else {
537: /* 8 bit access */
538: ne2000_mem_writeb(s, s->rsar, val);
539: ne2000_dma_update(s, 1);
540: }
541: }
542:
1.1.1.14 root 543: static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
1.1 root 544: {
545: NE2000State *s = opaque;
546: int ret;
547:
548: if (s->dcfg & 0x01) {
549: /* 16 bit access */
550: ret = ne2000_mem_readw(s, s->rsar);
551: ne2000_dma_update(s, 2);
552: } else {
553: /* 8 bit access */
554: ret = ne2000_mem_readb(s, s->rsar);
555: ne2000_dma_update(s, 1);
556: }
557: #ifdef DEBUG_NE2000
558: printf("NE2000: asic read val=0x%04x\n", ret);
559: #endif
560: return ret;
561: }
562:
563: static void ne2000_asic_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
564: {
565: NE2000State *s = opaque;
566:
567: #ifdef DEBUG_NE2000
568: printf("NE2000: asic writel val=0x%04x\n", val);
569: #endif
570: if (s->rcnt == 0)
571: return;
572: /* 32 bit access */
573: ne2000_mem_writel(s, s->rsar, val);
574: ne2000_dma_update(s, 4);
575: }
576:
577: static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr)
578: {
579: NE2000State *s = opaque;
580: int ret;
581:
582: /* 32 bit access */
583: ret = ne2000_mem_readl(s, s->rsar);
584: ne2000_dma_update(s, 4);
585: #ifdef DEBUG_NE2000
586: printf("NE2000: asic readl val=0x%04x\n", ret);
587: #endif
588: return ret;
589: }
590:
1.1.1.14 root 591: static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
1.1 root 592: {
593: /* nothing to do (end of reset pulse) */
594: }
595:
1.1.1.14 root 596: static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
1.1 root 597: {
598: NE2000State *s = opaque;
599: ne2000_reset(s);
600: return 0;
601: }
602:
1.1.1.10 root 603: static int ne2000_post_load(void* opaque, int version_id)
1.1 root 604: {
1.1.1.10 root 605: NE2000State* s = opaque;
1.1.1.8 root 606:
1.1.1.10 root 607: if (version_id < 2) {
608: s->rxcr = 0x0c;
609: }
610: return 0;
1.1.1.8 root 611: }
612:
1.1.1.10 root 613: const VMStateDescription vmstate_ne2000 = {
614: .name = "ne2000",
615: .version_id = 2,
616: .minimum_version_id = 0,
617: .minimum_version_id_old = 0,
618: .post_load = ne2000_post_load,
619: .fields = (VMStateField []) {
620: VMSTATE_UINT8_V(rxcr, NE2000State, 2),
621: VMSTATE_UINT8(cmd, NE2000State),
622: VMSTATE_UINT32(start, NE2000State),
623: VMSTATE_UINT32(stop, NE2000State),
624: VMSTATE_UINT8(boundary, NE2000State),
625: VMSTATE_UINT8(tsr, NE2000State),
626: VMSTATE_UINT8(tpsr, NE2000State),
627: VMSTATE_UINT16(tcnt, NE2000State),
628: VMSTATE_UINT16(rcnt, NE2000State),
629: VMSTATE_UINT32(rsar, NE2000State),
630: VMSTATE_UINT8(rsr, NE2000State),
631: VMSTATE_UINT8(isr, NE2000State),
632: VMSTATE_UINT8(dcfg, NE2000State),
633: VMSTATE_UINT8(imr, NE2000State),
634: VMSTATE_BUFFER(phys, NE2000State),
635: VMSTATE_UINT8(curpag, NE2000State),
636: VMSTATE_BUFFER(mult, NE2000State),
637: VMSTATE_UNUSED(4), /* was irq */
638: VMSTATE_BUFFER(mem, NE2000State),
639: VMSTATE_END_OF_LIST()
640: }
641: };
1.1.1.6 root 642:
1.1.1.10 root 643: static const VMStateDescription vmstate_pci_ne2000 = {
644: .name = "ne2000",
645: .version_id = 3,
646: .minimum_version_id = 3,
647: .minimum_version_id_old = 3,
648: .fields = (VMStateField []) {
649: VMSTATE_PCI_DEVICE(dev, PCINE2000State),
650: VMSTATE_STRUCT(ne2000, PCINE2000State, 0, vmstate_ne2000, NE2000State),
651: VMSTATE_END_OF_LIST()
652: }
653: };
1.1 root 654:
1.1.1.14 root 655: static uint64_t ne2000_read(void *opaque, target_phys_addr_t addr,
656: unsigned size)
657: {
658: NE2000State *s = opaque;
659:
660: if (addr < 0x10 && size == 1) {
661: return ne2000_ioport_read(s, addr);
662: } else if (addr == 0x10) {
663: if (size <= 2) {
664: return ne2000_asic_ioport_read(s, addr);
665: } else {
666: return ne2000_asic_ioport_readl(s, addr);
667: }
668: } else if (addr == 0x1f && size == 1) {
669: return ne2000_reset_ioport_read(s, addr);
670: }
671: return ((uint64_t)1 << (size * 8)) - 1;
672: }
1.1 root 673:
1.1.1.14 root 674: static void ne2000_write(void *opaque, target_phys_addr_t addr,
675: uint64_t data, unsigned size)
1.1 root 676: {
1.1.1.14 root 677: NE2000State *s = opaque;
1.1 root 678:
1.1.1.14 root 679: if (addr < 0x10 && size == 1) {
680: return ne2000_ioport_write(s, addr, data);
681: } else if (addr == 0x10) {
682: if (size <= 2) {
683: return ne2000_asic_ioport_write(s, addr, data);
684: } else {
685: return ne2000_asic_ioport_writel(s, addr, data);
686: }
687: } else if (addr == 0x1f && size == 1) {
688: return ne2000_reset_ioport_write(s, addr, data);
689: }
690: }
1.1 root 691:
1.1.1.14 root 692: static const MemoryRegionOps ne2000_ops = {
693: .read = ne2000_read,
694: .write = ne2000_write,
695: .endianness = DEVICE_NATIVE_ENDIAN,
696: };
1.1 root 697:
1.1.1.14 root 698: /***********************************************************/
699: /* PCI NE2000 definitions */
700:
701: void ne2000_setup_io(NE2000State *s, unsigned size)
702: {
703: memory_region_init_io(&s->io, &ne2000_ops, s, "ne2000", size);
1.1 root 704: }
705:
1.1.1.10 root 706: static void ne2000_cleanup(VLANClientState *nc)
1.1.1.8 root 707: {
1.1.1.10 root 708: NE2000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
1.1.1.8 root 709:
1.1.1.10 root 710: s->nic = NULL;
1.1.1.8 root 711: }
712:
1.1.1.10 root 713: static NetClientInfo net_ne2000_info = {
714: .type = NET_CLIENT_TYPE_NIC,
715: .size = sizeof(NICState),
716: .can_receive = ne2000_can_receive,
717: .receive = ne2000_receive,
718: .cleanup = ne2000_cleanup,
719: };
720:
721: static int pci_ne2000_init(PCIDevice *pci_dev)
1.1 root 722: {
1.1.1.10 root 723: PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
1.1 root 724: NE2000State *s;
725: uint8_t *pci_conf;
1.1.1.6 root 726:
1.1 root 727: pci_conf = d->dev.config;
1.1.1.14 root 728: pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin A */
1.1.1.6 root 729:
1.1 root 730: s = &d->ne2000;
1.1.1.14 root 731: ne2000_setup_io(s, 0x100);
732: pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
1.1.1.6 root 733: s->irq = d->dev.irq[0];
1.1.1.10 root 734:
735: qemu_macaddr_default_if_unset(&s->c.macaddr);
1.1 root 736: ne2000_reset(s);
1.1.1.7 root 737:
1.1.1.10 root 738: s->nic = qemu_new_nic(&net_ne2000_info, &s->c,
1.1.1.15! root 739: object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s);
1.1.1.10 root 740: qemu_format_nic_info_str(&s->nic->nc, s->c.macaddr.a);
741:
1.1.1.12 root 742: add_boot_device_path(s->c.bootindex, &pci_dev->qdev, "/ethernet-phy@0");
743:
1.1.1.10 root 744: return 0;
745: }
746:
747: static int pci_ne2000_exit(PCIDevice *pci_dev)
748: {
749: PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
750: NE2000State *s = &d->ne2000;
751:
1.1.1.14 root 752: memory_region_destroy(&s->io);
1.1.1.10 root 753: qemu_del_vlan_client(&s->nic->nc);
754: return 0;
1.1.1.9 root 755: }
1.1.1.6 root 756:
1.1.1.15! root 757: static Property ne2000_properties[] = {
! 758: DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
! 759: DEFINE_PROP_END_OF_LIST(),
! 760: };
! 761:
! 762: static void ne2000_class_init(ObjectClass *klass, void *data)
! 763: {
! 764: DeviceClass *dc = DEVICE_CLASS(klass);
! 765: PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
! 766:
! 767: k->init = pci_ne2000_init;
! 768: k->exit = pci_ne2000_exit;
! 769: k->romfile = "pxe-ne2k_pci.rom",
! 770: k->vendor_id = PCI_VENDOR_ID_REALTEK;
! 771: k->device_id = PCI_DEVICE_ID_REALTEK_8029;
! 772: k->class_id = PCI_CLASS_NETWORK_ETHERNET;
! 773: dc->vmsd = &vmstate_pci_ne2000;
! 774: dc->props = ne2000_properties;
! 775: }
! 776:
! 777: static TypeInfo ne2000_info = {
! 778: .name = "ne2k_pci",
! 779: .parent = TYPE_PCI_DEVICE,
! 780: .instance_size = sizeof(PCINE2000State),
! 781: .class_init = ne2000_class_init,
1.1.1.9 root 782: };
783:
1.1.1.15! root 784: static void ne2000_register_types(void)
1.1.1.9 root 785: {
1.1.1.15! root 786: type_register_static(&ne2000_info);
1.1 root 787: }
1.1.1.9 root 788:
1.1.1.15! root 789: type_init(ne2000_register_types)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.