]> Git Repo - qemu.git/blob - hw/lan9118.c
Merge remote-tracking branch 'agraf/xen-next' into staging
[qemu.git] / hw / lan9118.c
1 /*
2  * SMSC LAN9118 Ethernet interface emulation
3  *
4  * Copyright (c) 2009 CodeSourcery, LLC.
5  * Written by Paul Brook
6  *
7  * This code is licenced under the GNU GPL v2
8  */
9
10 #include "sysbus.h"
11 #include "net.h"
12 #include "devices.h"
13 #include "sysemu.h"
14 /* For crc32 */
15 #include <zlib.h>
16
17 //#define DEBUG_LAN9118
18
19 #ifdef DEBUG_LAN9118
20 #define DPRINTF(fmt, ...) \
21 do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
22 #define BADF(fmt, ...) \
23 do { hw_error("lan9118: error: " fmt , ## __VA_ARGS__);} while (0)
24 #else
25 #define DPRINTF(fmt, ...) do {} while(0)
26 #define BADF(fmt, ...) \
27 do { fprintf(stderr, "lan9118: error: " fmt , ## __VA_ARGS__);} while (0)
28 #endif
29
30 #define CSR_ID_REV      0x50
31 #define CSR_IRQ_CFG     0x54
32 #define CSR_INT_STS     0x58
33 #define CSR_INT_EN      0x5c
34 #define CSR_BYTE_TEST   0x64
35 #define CSR_FIFO_INT    0x68
36 #define CSR_RX_CFG      0x6c
37 #define CSR_TX_CFG      0x70
38 #define CSR_HW_CFG      0x74
39 #define CSR_RX_DP_CTRL  0x78
40 #define CSR_RX_FIFO_INF 0x7c
41 #define CSR_TX_FIFO_INF 0x80
42 #define CSR_PMT_CTRL    0x84
43 #define CSR_GPIO_CFG    0x88
44 #define CSR_GPT_CFG     0x8c
45 #define CSR_GPT_CNT     0x90
46 #define CSR_WORD_SWAP   0x98
47 #define CSR_FREE_RUN    0x9c
48 #define CSR_RX_DROP     0xa0
49 #define CSR_MAC_CSR_CMD 0xa4
50 #define CSR_MAC_CSR_DATA 0xa8
51 #define CSR_AFC_CFG     0xac
52 #define CSR_E2P_CMD     0xb0
53 #define CSR_E2P_DATA    0xb4
54
55 /* IRQ_CFG */
56 #define IRQ_INT         0x00001000
57 #define IRQ_EN          0x00000100
58 #define IRQ_POL         0x00000010
59 #define IRQ_TYPE        0x00000001
60
61 /* INT_STS/INT_EN */
62 #define SW_INT          0x80000000
63 #define TXSTOP_INT      0x02000000
64 #define RXSTOP_INT      0x01000000
65 #define RXDFH_INT       0x00800000
66 #define TX_IOC_INT      0x00200000
67 #define RXD_INT         0x00100000
68 #define GPT_INT         0x00080000
69 #define PHY_INT         0x00040000
70 #define PME_INT         0x00020000
71 #define TXSO_INT        0x00010000
72 #define RWT_INT         0x00008000
73 #define RXE_INT         0x00004000
74 #define TXE_INT         0x00002000
75 #define TDFU_INT        0x00000800
76 #define TDFO_INT        0x00000400
77 #define TDFA_INT        0x00000200
78 #define TSFF_INT        0x00000100
79 #define TSFL_INT        0x00000080
80 #define RXDF_INT        0x00000040
81 #define RDFL_INT        0x00000020
82 #define RSFF_INT        0x00000010
83 #define RSFL_INT        0x00000008
84 #define GPIO2_INT       0x00000004
85 #define GPIO1_INT       0x00000002
86 #define GPIO0_INT       0x00000001
87 #define RESERVED_INT    0x7c001000
88
89 #define MAC_CR          1
90 #define MAC_ADDRH       2
91 #define MAC_ADDRL       3
92 #define MAC_HASHH       4
93 #define MAC_HASHL       5
94 #define MAC_MII_ACC     6
95 #define MAC_MII_DATA    7
96 #define MAC_FLOW        8
97 #define MAC_VLAN1       9 /* TODO */
98 #define MAC_VLAN2       10 /* TODO */
99 #define MAC_WUFF        11 /* TODO */
100 #define MAC_WUCSR       12 /* TODO */
101
102 #define MAC_CR_RXALL    0x80000000
103 #define MAC_CR_RCVOWN   0x00800000
104 #define MAC_CR_LOOPBK   0x00200000
105 #define MAC_CR_FDPX     0x00100000
106 #define MAC_CR_MCPAS    0x00080000
107 #define MAC_CR_PRMS     0x00040000
108 #define MAC_CR_INVFILT  0x00020000
109 #define MAC_CR_PASSBAD  0x00010000
110 #define MAC_CR_HO       0x00008000
111 #define MAC_CR_HPFILT   0x00002000
112 #define MAC_CR_LCOLL    0x00001000
113 #define MAC_CR_BCAST    0x00000800
114 #define MAC_CR_DISRTY   0x00000400
115 #define MAC_CR_PADSTR   0x00000100
116 #define MAC_CR_BOLMT    0x000000c0
117 #define MAC_CR_DFCHK    0x00000020
118 #define MAC_CR_TXEN     0x00000008
119 #define MAC_CR_RXEN     0x00000004
120 #define MAC_CR_RESERVED 0x7f404213
121
122 #define PHY_INT_ENERGYON            0x80
123 #define PHY_INT_AUTONEG_COMPLETE    0x40
124 #define PHY_INT_FAULT               0x20
125 #define PHY_INT_DOWN                0x10
126 #define PHY_INT_AUTONEG_LP          0x08
127 #define PHY_INT_PARFAULT            0x04
128 #define PHY_INT_AUTONEG_PAGE        0x02
129
130 #define GPT_TIMER_EN    0x20000000
131
132 enum tx_state {
133     TX_IDLE,
134     TX_B,
135     TX_DATA
136 };
137
138 typedef struct {
139     enum tx_state state;
140     uint32_t cmd_a;
141     uint32_t cmd_b;
142     int buffer_size;
143     int offset;
144     int pad;
145     int fifo_used;
146     int len;
147     uint8_t data[2048];
148 } LAN9118Packet;
149
150 typedef struct {
151     SysBusDevice busdev;
152     NICState *nic;
153     NICConf conf;
154     qemu_irq irq;
155     int mmio_index;
156     ptimer_state *timer;
157
158     uint32_t irq_cfg;
159     uint32_t int_sts;
160     uint32_t int_en;
161     uint32_t fifo_int;
162     uint32_t rx_cfg;
163     uint32_t tx_cfg;
164     uint32_t hw_cfg;
165     uint32_t pmt_ctrl;
166     uint32_t gpio_cfg;
167     uint32_t gpt_cfg;
168     uint32_t word_swap;
169     uint32_t free_timer_start;
170     uint32_t mac_cmd;
171     uint32_t mac_data;
172     uint32_t afc_cfg;
173     uint32_t e2p_cmd;
174     uint32_t e2p_data;
175
176     uint32_t mac_cr;
177     uint32_t mac_hashh;
178     uint32_t mac_hashl;
179     uint32_t mac_mii_acc;
180     uint32_t mac_mii_data;
181     uint32_t mac_flow;
182
183     uint32_t phy_status;
184     uint32_t phy_control;
185     uint32_t phy_advertise;
186     uint32_t phy_int;
187     uint32_t phy_int_mask;
188
189     int eeprom_writable;
190     uint8_t eeprom[128];
191
192     int tx_fifo_size;
193     LAN9118Packet *txp;
194     LAN9118Packet tx_packet;
195
196     int tx_status_fifo_used;
197     int tx_status_fifo_head;
198     uint32_t tx_status_fifo[512];
199
200     int rx_status_fifo_size;
201     int rx_status_fifo_used;
202     int rx_status_fifo_head;
203     uint32_t rx_status_fifo[896];
204     int rx_fifo_size;
205     int rx_fifo_used;
206     int rx_fifo_head;
207     uint32_t rx_fifo[3360];
208     int rx_packet_size_head;
209     int rx_packet_size_tail;
210     int rx_packet_size[1024];
211
212     int rxp_offset;
213     int rxp_size;
214     int rxp_pad;
215 } lan9118_state;
216
217 static void lan9118_update(lan9118_state *s)
218 {
219     int level;
220
221     /* TODO: Implement FIFO level IRQs.  */
222     level = (s->int_sts & s->int_en) != 0;
223     if (level) {
224         s->irq_cfg |= IRQ_INT;
225     } else {
226         s->irq_cfg &= ~IRQ_INT;
227     }
228     if ((s->irq_cfg & IRQ_EN) == 0) {
229         level = 0;
230     }
231     if ((s->irq_cfg & (IRQ_TYPE | IRQ_POL)) != (IRQ_TYPE | IRQ_POL)) {
232         /* Interrupt is active low unless we're configured as
233          * active-high polarity, push-pull type.
234          */
235         level = !level;
236     }
237     qemu_set_irq(s->irq, level);
238 }
239
240 static void lan9118_mac_changed(lan9118_state *s)
241 {
242     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
243 }
244
245 static void lan9118_reload_eeprom(lan9118_state *s)
246 {
247     int i;
248     if (s->eeprom[0] != 0xa5) {
249         s->e2p_cmd &= ~0x10;
250         DPRINTF("MACADDR load failed\n");
251         return;
252     }
253     for (i = 0; i < 6; i++) {
254         s->conf.macaddr.a[i] = s->eeprom[i + 1];
255     }
256     s->e2p_cmd |= 0x10;
257     DPRINTF("MACADDR loaded from eeprom\n");
258     lan9118_mac_changed(s);
259 }
260
261 static void phy_update_irq(lan9118_state *s)
262 {
263     if (s->phy_int & s->phy_int_mask) {
264         s->int_sts |= PHY_INT;
265     } else {
266         s->int_sts &= ~PHY_INT;
267     }
268     lan9118_update(s);
269 }
270
271 static void phy_update_link(lan9118_state *s)
272 {
273     /* Autonegotiation status mirrors link status.  */
274     if (s->nic->nc.link_down) {
275         s->phy_status &= ~0x0024;
276         s->phy_int |= PHY_INT_DOWN;
277     } else {
278         s->phy_status |= 0x0024;
279         s->phy_int |= PHY_INT_ENERGYON;
280         s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
281     }
282     phy_update_irq(s);
283 }
284
285 static void lan9118_set_link(VLANClientState *nc)
286 {
287     phy_update_link(DO_UPCAST(NICState, nc, nc)->opaque);
288 }
289
290 static void phy_reset(lan9118_state *s)
291 {
292     s->phy_status = 0x7809;
293     s->phy_control = 0x3000;
294     s->phy_advertise = 0x01e1;
295     s->phy_int_mask = 0;
296     s->phy_int = 0;
297     phy_update_link(s);
298 }
299
300 static void lan9118_reset(DeviceState *d)
301 {
302     lan9118_state *s = FROM_SYSBUS(lan9118_state, sysbus_from_qdev(d));
303     s->irq_cfg &= (IRQ_TYPE | IRQ_POL);
304     s->int_sts = 0;
305     s->int_en = 0;
306     s->fifo_int = 0x48000000;
307     s->rx_cfg = 0;
308     s->tx_cfg = 0;
309     s->hw_cfg = 0x00050000;
310     s->pmt_ctrl &= 0x45;
311     s->gpio_cfg = 0;
312     s->txp->fifo_used = 0;
313     s->txp->state = TX_IDLE;
314     s->txp->cmd_a = 0xffffffffu;
315     s->txp->cmd_b = 0xffffffffu;
316     s->txp->len = 0;
317     s->txp->fifo_used = 0;
318     s->tx_fifo_size = 4608;
319     s->tx_status_fifo_used = 0;
320     s->rx_status_fifo_size = 704;
321     s->rx_fifo_size = 2640;
322     s->rx_fifo_used = 0;
323     s->rx_status_fifo_size = 176;
324     s->rx_status_fifo_used = 0;
325     s->rxp_offset = 0;
326     s->rxp_size = 0;
327     s->rxp_pad = 0;
328     s->rx_packet_size_tail = s->rx_packet_size_head;
329     s->rx_packet_size[s->rx_packet_size_head] = 0;
330     s->mac_cmd = 0;
331     s->mac_data = 0;
332     s->afc_cfg = 0;
333     s->e2p_cmd = 0;
334     s->e2p_data = 0;
335     s->free_timer_start = qemu_get_clock_ns(vm_clock) / 40;
336
337     ptimer_stop(s->timer);
338     ptimer_set_count(s->timer, 0xffff);
339     s->gpt_cfg = 0xffff;
340
341     s->mac_cr = MAC_CR_PRMS;
342     s->mac_hashh = 0;
343     s->mac_hashl = 0;
344     s->mac_mii_acc = 0;
345     s->mac_mii_data = 0;
346     s->mac_flow = 0;
347
348     phy_reset(s);
349
350     s->eeprom_writable = 0;
351     lan9118_reload_eeprom(s);
352 }
353
354 static int lan9118_can_receive(VLANClientState *nc)
355 {
356     return 1;
357 }
358
359 static void rx_fifo_push(lan9118_state *s, uint32_t val)
360 {
361     int fifo_pos;
362     fifo_pos = s->rx_fifo_head + s->rx_fifo_used;
363     if (fifo_pos >= s->rx_fifo_size)
364       fifo_pos -= s->rx_fifo_size;
365     s->rx_fifo[fifo_pos] = val;
366     s->rx_fifo_used++;
367 }
368
369 /* Return nonzero if the packet is accepted by the filter.  */
370 static int lan9118_filter(lan9118_state *s, const uint8_t *addr)
371 {
372     int multicast;
373     uint32_t hash;
374
375     if (s->mac_cr & MAC_CR_PRMS) {
376         return 1;
377     }
378     if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
379         addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
380         return (s->mac_cr & MAC_CR_BCAST) == 0;
381     }
382
383     multicast = addr[0] & 1;
384     if (multicast &&s->mac_cr & MAC_CR_MCPAS) {
385         return 1;
386     }
387     if (multicast ? (s->mac_cr & MAC_CR_HPFILT) == 0
388                   : (s->mac_cr & MAC_CR_HO) == 0) {
389         /* Exact matching.  */
390         hash = memcmp(addr, s->conf.macaddr.a, 6);
391         if (s->mac_cr & MAC_CR_INVFILT) {
392             return hash != 0;
393         } else {
394             return hash == 0;
395         }
396     } else {
397         /* Hash matching  */
398         hash = (crc32(~0, addr, 6) >> 26);
399         if (hash & 0x20) {
400             return (s->mac_hashh >> (hash & 0x1f)) & 1;
401         } else {
402             return (s->mac_hashl >> (hash & 0x1f)) & 1;
403         }
404     }
405 }
406
407 static ssize_t lan9118_receive(VLANClientState *nc, const uint8_t *buf,
408                                size_t size)
409 {
410     lan9118_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
411     int fifo_len;
412     int offset;
413     int src_pos;
414     int n;
415     int filter;
416     uint32_t val;
417     uint32_t crc;
418     uint32_t status;
419
420     if ((s->mac_cr & MAC_CR_RXEN) == 0) {
421         return -1;
422     }
423
424     if (size >= 2048 || size < 14) {
425         return -1;
426     }
427
428     /* TODO: Implement FIFO overflow notification.  */
429     if (s->rx_status_fifo_used == s->rx_status_fifo_size) {
430         return -1;
431     }
432
433     filter = lan9118_filter(s, buf);
434     if (!filter && (s->mac_cr & MAC_CR_RXALL) == 0) {
435         return size;
436     }
437
438     offset = (s->rx_cfg >> 8) & 0x1f;
439     n = offset & 3;
440     fifo_len = (size + n + 3) >> 2;
441     /* Add a word for the CRC.  */
442     fifo_len++;
443     if (s->rx_fifo_size - s->rx_fifo_used < fifo_len) {
444         return -1;
445     }
446
447     DPRINTF("Got packet len:%d fifo:%d filter:%s\n",
448             (int)size, fifo_len, filter ? "pass" : "fail");
449     val = 0;
450     crc = bswap32(crc32(~0, buf, size));
451     for (src_pos = 0; src_pos < size; src_pos++) {
452         val = (val >> 8) | ((uint32_t)buf[src_pos] << 24);
453         n++;
454         if (n == 4) {
455             n = 0;
456             rx_fifo_push(s, val);
457             val = 0;
458         }
459     }
460     if (n) {
461         val >>= ((4 - n) * 8);
462         val |= crc << (n * 8);
463         rx_fifo_push(s, val);
464         val = crc >> ((4 - n) * 8);
465         rx_fifo_push(s, val);
466     } else {
467         rx_fifo_push(s, crc);
468     }
469     n = s->rx_status_fifo_head + s->rx_status_fifo_used;
470     if (n >= s->rx_status_fifo_size) {
471         n -= s->rx_status_fifo_size;
472     }
473     s->rx_packet_size[s->rx_packet_size_tail] = fifo_len;
474     s->rx_packet_size_tail = (s->rx_packet_size_tail + 1023) & 1023;
475     s->rx_status_fifo_used++;
476
477     status = (size + 4) << 16;
478     if (buf[0] == 0xff && buf[1] == 0xff && buf[2] == 0xff &&
479         buf[3] == 0xff && buf[4] == 0xff && buf[5] == 0xff) {
480         status |= 0x00002000;
481     } else if (buf[0] & 1) {
482         status |= 0x00000400;
483     }
484     if (!filter) {
485         status |= 0x40000000;
486     }
487     s->rx_status_fifo[n] = status;
488
489     if (s->rx_status_fifo_used > (s->fifo_int & 0xff)) {
490         s->int_sts |= RSFL_INT;
491     }
492     lan9118_update(s);
493
494     return size;
495 }
496
497 static uint32_t rx_fifo_pop(lan9118_state *s)
498 {
499     int n;
500     uint32_t val;
501
502     if (s->rxp_size == 0 && s->rxp_pad == 0) {
503         s->rxp_size = s->rx_packet_size[s->rx_packet_size_head];
504         s->rx_packet_size[s->rx_packet_size_head] = 0;
505         if (s->rxp_size != 0) {
506             s->rx_packet_size_head = (s->rx_packet_size_head + 1023) & 1023;
507             s->rxp_offset = (s->rx_cfg >> 10) & 7;
508             n = s->rxp_offset + s->rxp_size;
509             switch (s->rx_cfg >> 30) {
510             case 1:
511                 n = (-n) & 3;
512                 break;
513             case 2:
514                 n = (-n) & 7;
515                 break;
516             default:
517                 n = 0;
518                 break;
519             }
520             s->rxp_pad = n;
521             DPRINTF("Pop packet size:%d offset:%d pad: %d\n",
522                     s->rxp_size, s->rxp_offset, s->rxp_pad);
523         }
524     }
525     if (s->rxp_offset > 0) {
526         s->rxp_offset--;
527         val = 0;
528     } else if (s->rxp_size > 0) {
529         s->rxp_size--;
530         val = s->rx_fifo[s->rx_fifo_head++];
531         if (s->rx_fifo_head >= s->rx_fifo_size) {
532             s->rx_fifo_head -= s->rx_fifo_size;
533         }
534         s->rx_fifo_used--;
535     } else if (s->rxp_pad > 0) {
536         s->rxp_pad--;
537         val =  0;
538     } else {
539         DPRINTF("RX underflow\n");
540         s->int_sts |= RXE_INT;
541         val =  0;
542     }
543     lan9118_update(s);
544     return val;
545 }
546
547 static void do_tx_packet(lan9118_state *s)
548 {
549     int n;
550     uint32_t status;
551
552     /* FIXME: Honor TX disable, and allow queueing of packets.  */
553     if (s->phy_control & 0x4000)  {
554         /* This assumes the receive routine doesn't touch the VLANClient.  */
555         lan9118_receive(&s->nic->nc, s->txp->data, s->txp->len);
556     } else {
557         qemu_send_packet(&s->nic->nc, s->txp->data, s->txp->len);
558     }
559     s->txp->fifo_used = 0;
560
561     if (s->tx_status_fifo_used == 512) {
562         /* Status FIFO full */
563         return;
564     }
565     /* Add entry to status FIFO.  */
566     status = s->txp->cmd_b & 0xffff0000u;
567     DPRINTF("Sent packet tag:%04x len %d\n", status >> 16, s->txp->len);
568     n = (s->tx_status_fifo_head + s->tx_status_fifo_used) & 511;
569     s->tx_status_fifo[n] = status;
570     s->tx_status_fifo_used++;
571     if (s->tx_status_fifo_used == 512) {
572         s->int_sts |= TSFF_INT;
573         /* TODO: Stop transmission.  */
574     }
575 }
576
577 static uint32_t rx_status_fifo_pop(lan9118_state *s)
578 {
579     uint32_t val;
580
581     val = s->rx_status_fifo[s->rx_status_fifo_head];
582     if (s->rx_status_fifo_used != 0) {
583         s->rx_status_fifo_used--;
584         s->rx_status_fifo_head++;
585         if (s->rx_status_fifo_head >= s->rx_status_fifo_size) {
586             s->rx_status_fifo_head -= s->rx_status_fifo_size;
587         }
588         /* ??? What value should be returned when the FIFO is empty?  */
589         DPRINTF("RX status pop 0x%08x\n", val);
590     }
591     return val;
592 }
593
594 static uint32_t tx_status_fifo_pop(lan9118_state *s)
595 {
596     uint32_t val;
597
598     val = s->tx_status_fifo[s->tx_status_fifo_head];
599     if (s->tx_status_fifo_used != 0) {
600         s->tx_status_fifo_used--;
601         s->tx_status_fifo_head = (s->tx_status_fifo_head + 1) & 511;
602         /* ??? What value should be returned when the FIFO is empty?  */
603     }
604     return val;
605 }
606
607 static void tx_fifo_push(lan9118_state *s, uint32_t val)
608 {
609     int n;
610
611     if (s->txp->fifo_used == s->tx_fifo_size) {
612         s->int_sts |= TDFO_INT;
613         return;
614     }
615     switch (s->txp->state) {
616     case TX_IDLE:
617         s->txp->cmd_a = val & 0x831f37ff;
618         s->txp->fifo_used++;
619         s->txp->state = TX_B;
620         break;
621     case TX_B:
622         if (s->txp->cmd_a & 0x2000) {
623             /* First segment */
624             s->txp->cmd_b = val;
625             s->txp->fifo_used++;
626             s->txp->buffer_size = s->txp->cmd_a & 0x7ff;
627             s->txp->offset = (s->txp->cmd_a >> 16) & 0x1f;
628             /* End alignment does not include command words.  */
629             n = (s->txp->buffer_size + s->txp->offset + 3) >> 2;
630             switch ((n >> 24) & 3) {
631             case 1:
632                 n = (-n) & 3;
633                 break;
634             case 2:
635                 n = (-n) & 7;
636                 break;
637             default:
638                 n = 0;
639             }
640             s->txp->pad = n;
641             s->txp->len = 0;
642         }
643         DPRINTF("Block len:%d offset:%d pad:%d cmd %08x\n",
644                 s->txp->buffer_size, s->txp->offset, s->txp->pad,
645                 s->txp->cmd_a);
646         s->txp->state = TX_DATA;
647         break;
648     case TX_DATA:
649         if (s->txp->offset >= 4) {
650             s->txp->offset -= 4;
651             break;
652         }
653         if (s->txp->buffer_size <= 0 && s->txp->pad != 0) {
654             s->txp->pad--;
655         } else {
656             n = 4;
657             while (s->txp->offset) {
658                 val >>= 8;
659                 n--;
660                 s->txp->offset--;
661             }
662             /* Documentation is somewhat unclear on the ordering of bytes
663                in FIFO words.  Empirical results show it to be little-endian.
664                */
665             /* TODO: FIFO overflow checking.  */
666             while (n--) {
667                 s->txp->data[s->txp->len] = val & 0xff;
668                 s->txp->len++;
669                 val >>= 8;
670                 s->txp->buffer_size--;
671             }
672             s->txp->fifo_used++;
673         }
674         if (s->txp->buffer_size <= 0 && s->txp->pad == 0) {
675             if (s->txp->cmd_a & 0x1000) {
676                 do_tx_packet(s);
677             }
678             if (s->txp->cmd_a & 0x80000000) {
679                 s->int_sts |= TX_IOC_INT;
680             }
681             s->txp->state = TX_IDLE;
682         }
683         break;
684     }
685 }
686
687 static uint32_t do_phy_read(lan9118_state *s, int reg)
688 {
689     uint32_t val;
690
691     switch (reg) {
692     case 0: /* Basic Control */
693         return s->phy_control;
694     case 1: /* Basic Status */
695         return s->phy_status;
696     case 2: /* ID1 */
697         return 0x0007;
698     case 3: /* ID2 */
699         return 0xc0d1;
700     case 4: /* Auto-neg advertisment */
701         return s->phy_advertise;
702     case 5: /* Auto-neg Link Partner Ability */
703         return 0x0f71;
704     case 6: /* Auto-neg Expansion */
705         return 1;
706         /* TODO 17, 18, 27, 29, 30, 31 */
707     case 29: /* Interrupt source.  */
708         val = s->phy_int;
709         s->phy_int = 0;
710         phy_update_irq(s);
711         return val;
712     case 30: /* Interrupt mask */
713         return s->phy_int_mask;
714     default:
715         BADF("PHY read reg %d\n", reg);
716         return 0;
717     }
718 }
719
720 static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
721 {
722     switch (reg) {
723     case 0: /* Basic Control */
724         if (val & 0x8000) {
725             phy_reset(s);
726             break;
727         }
728         s->phy_control = val & 0x7980;
729         /* Complete autonegotiation immediately.  */
730         if (val & 0x1000) {
731             s->phy_status |= 0x0020;
732         }
733         break;
734     case 4: /* Auto-neg advertisment */
735         s->phy_advertise = (val & 0x2d7f) | 0x80;
736         break;
737         /* TODO 17, 18, 27, 31 */
738     case 30: /* Interrupt mask */
739         s->phy_int_mask = val & 0xff;
740         phy_update_irq(s);
741         break;
742     default:
743         BADF("PHY write reg %d = 0x%04x\n", reg, val);
744     }
745 }
746
747 static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
748 {
749     switch (reg) {
750     case MAC_CR:
751         if ((s->mac_cr & MAC_CR_RXEN) != 0 && (val & MAC_CR_RXEN) == 0) {
752             s->int_sts |= RXSTOP_INT;
753         }
754         s->mac_cr = val & ~MAC_CR_RESERVED;
755         DPRINTF("MAC_CR: %08x\n", val);
756         break;
757     case MAC_ADDRH:
758         s->conf.macaddr.a[4] = val & 0xff;
759         s->conf.macaddr.a[5] = (val >> 8) & 0xff;
760         lan9118_mac_changed(s);
761         break;
762     case MAC_ADDRL:
763         s->conf.macaddr.a[0] = val & 0xff;
764         s->conf.macaddr.a[1] = (val >> 8) & 0xff;
765         s->conf.macaddr.a[2] = (val >> 16) & 0xff;
766         s->conf.macaddr.a[3] = (val >> 24) & 0xff;
767         lan9118_mac_changed(s);
768         break;
769     case MAC_HASHH:
770         s->mac_hashh = val;
771         break;
772     case MAC_HASHL:
773         s->mac_hashl = val;
774         break;
775     case MAC_MII_ACC:
776         s->mac_mii_acc = val & 0xffc2;
777         if (val & 2) {
778             DPRINTF("PHY write %d = 0x%04x\n",
779                     (val >> 6) & 0x1f, s->mac_mii_data);
780             do_phy_write(s, (val >> 6) & 0x1f, s->mac_mii_data);
781         } else {
782             s->mac_mii_data = do_phy_read(s, (val >> 6) & 0x1f);
783             DPRINTF("PHY read %d = 0x%04x\n",
784                     (val >> 6) & 0x1f, s->mac_mii_data);
785         }
786         break;
787     case MAC_MII_DATA:
788         s->mac_mii_data = val & 0xffff;
789         break;
790     case MAC_FLOW:
791         s->mac_flow = val & 0xffff0000;
792         break;
793     case MAC_VLAN1:
794         /* Writing to this register changes a condition for
795          * FrameTooLong bit in rx_status.  Since we do not set
796          * FrameTooLong anyway, just ignore write to this.
797          */
798         break;
799     default:
800         hw_error("lan9118: Unimplemented MAC register write: %d = 0x%x\n",
801                  s->mac_cmd & 0xf, val);
802     }
803 }
804
805 static uint32_t do_mac_read(lan9118_state *s, int reg)
806 {
807     switch (reg) {
808     case MAC_CR:
809         return s->mac_cr;
810     case MAC_ADDRH:
811         return s->conf.macaddr.a[4] | (s->conf.macaddr.a[5] << 8);
812     case MAC_ADDRL:
813         return s->conf.macaddr.a[0] | (s->conf.macaddr.a[1] << 8)
814                | (s->conf.macaddr.a[2] << 16) | (s->conf.macaddr.a[3] << 24);
815     case MAC_HASHH:
816         return s->mac_hashh;
817         break;
818     case MAC_HASHL:
819         return s->mac_hashl;
820         break;
821     case MAC_MII_ACC:
822         return s->mac_mii_acc;
823     case MAC_MII_DATA:
824         return s->mac_mii_data;
825     case MAC_FLOW:
826         return s->mac_flow;
827     default:
828         hw_error("lan9118: Unimplemented MAC register read: %d\n",
829                  s->mac_cmd & 0xf);
830     }
831 }
832
833 static void lan9118_eeprom_cmd(lan9118_state *s, int cmd, int addr)
834 {
835     s->e2p_cmd = (s->e2p_cmd & 0x10) | (cmd << 28) | addr;
836     switch (cmd) {
837     case 0:
838         s->e2p_data = s->eeprom[addr];
839         DPRINTF("EEPROM Read %d = 0x%02x\n", addr, s->e2p_data);
840         break;
841     case 1:
842         s->eeprom_writable = 0;
843         DPRINTF("EEPROM Write Disable\n");
844         break;
845     case 2: /* EWEN */
846         s->eeprom_writable = 1;
847         DPRINTF("EEPROM Write Enable\n");
848         break;
849     case 3: /* WRITE */
850         if (s->eeprom_writable) {
851             s->eeprom[addr] &= s->e2p_data;
852             DPRINTF("EEPROM Write %d = 0x%02x\n", addr, s->e2p_data);
853         } else {
854             DPRINTF("EEPROM Write %d (ignored)\n", addr);
855         }
856         break;
857     case 4: /* WRAL */
858         if (s->eeprom_writable) {
859             for (addr = 0; addr < 128; addr++) {
860                 s->eeprom[addr] &= s->e2p_data;
861             }
862             DPRINTF("EEPROM Write All 0x%02x\n", s->e2p_data);
863         } else {
864             DPRINTF("EEPROM Write All (ignored)\n");
865         }
866     case 5: /* ERASE */
867         if (s->eeprom_writable) {
868             s->eeprom[addr] = 0xff;
869             DPRINTF("EEPROM Erase %d\n", addr);
870         } else {
871             DPRINTF("EEPROM Erase %d (ignored)\n", addr);
872         }
873         break;
874     case 6: /* ERAL */
875         if (s->eeprom_writable) {
876             memset(s->eeprom, 0xff, 128);
877             DPRINTF("EEPROM Erase All\n");
878         } else {
879             DPRINTF("EEPROM Erase All (ignored)\n");
880         }
881         break;
882     case 7: /* RELOAD */
883         lan9118_reload_eeprom(s);
884         break;
885     }
886 }
887
888 static void lan9118_tick(void *opaque)
889 {
890     lan9118_state *s = (lan9118_state *)opaque;
891     if (s->int_en & GPT_INT) {
892         s->int_sts |= GPT_INT;
893     }
894     lan9118_update(s);
895 }
896
897 static void lan9118_writel(void *opaque, target_phys_addr_t offset,
898                            uint32_t val)
899 {
900     lan9118_state *s = (lan9118_state *)opaque;
901     offset &= 0xff;
902     
903     //DPRINTF("Write reg 0x%02x = 0x%08x\n", (int)offset, val);
904     if (offset >= 0x20 && offset < 0x40) {
905         /* TX FIFO */
906         tx_fifo_push(s, val);
907         return;
908     }
909     switch (offset) {
910     case CSR_IRQ_CFG:
911         /* TODO: Implement interrupt deassertion intervals.  */
912         val &= (IRQ_EN | IRQ_POL | IRQ_TYPE);
913         s->irq_cfg = (s->irq_cfg & IRQ_INT) | val;
914         break;
915     case CSR_INT_STS:
916         s->int_sts &= ~val;
917         break;
918     case CSR_INT_EN:
919         s->int_en = val & ~RESERVED_INT;
920         s->int_sts |= val & SW_INT;
921         break;
922     case CSR_FIFO_INT:
923         DPRINTF("FIFO INT levels %08x\n", val);
924         s->fifo_int = val;
925         break;
926     case CSR_RX_CFG:
927         if (val & 0x8000) {
928             /* RX_DUMP */
929             s->rx_fifo_used = 0;
930             s->rx_status_fifo_used = 0;
931             s->rx_packet_size_tail = s->rx_packet_size_head;
932             s->rx_packet_size[s->rx_packet_size_head] = 0;
933         }
934         s->rx_cfg = val & 0xcfff1ff0;
935         break;
936     case CSR_TX_CFG:
937         if (val & 0x8000) {
938             s->tx_status_fifo_used = 0;
939         }
940         if (val & 0x4000) {
941             s->txp->state = TX_IDLE;
942             s->txp->fifo_used = 0;
943             s->txp->cmd_a = 0xffffffff;
944         }
945         s->tx_cfg = val & 6;
946         break;
947     case CSR_HW_CFG:
948         if (val & 1) {
949             /* SRST */
950             lan9118_reset(&s->busdev.qdev);
951         } else {
952             s->hw_cfg = val & 0x003f300;
953         }
954         break;
955     case CSR_RX_DP_CTRL:
956         if (val & 0x80000000) {
957             /* Skip forward to next packet.  */
958             s->rxp_pad = 0;
959             s->rxp_offset = 0;
960             if (s->rxp_size == 0) {
961                 /* Pop a word to start the next packet.  */
962                 rx_fifo_pop(s);
963                 s->rxp_pad = 0;
964                 s->rxp_offset = 0;
965             }
966             s->rx_fifo_head += s->rxp_size;
967             if (s->rx_fifo_head >= s->rx_fifo_size) {
968                 s->rx_fifo_head -= s->rx_fifo_size;
969             }
970         }
971         break;
972     case CSR_PMT_CTRL:
973         if (val & 0x400) {
974             phy_reset(s);
975         }
976         s->pmt_ctrl &= ~0x34e;
977         s->pmt_ctrl |= (val & 0x34e);
978         break;
979     case CSR_GPIO_CFG:
980         /* Probably just enabling LEDs.  */
981         s->gpio_cfg = val & 0x7777071f;
982         break;
983     case CSR_GPT_CFG:
984         if ((s->gpt_cfg ^ val) & GPT_TIMER_EN) {
985             if (val & GPT_TIMER_EN) {
986                 ptimer_set_count(s->timer, val & 0xffff);
987                 ptimer_run(s->timer, 0);
988             } else {
989                 ptimer_stop(s->timer);
990                 ptimer_set_count(s->timer, 0xffff);
991             }
992         }
993         s->gpt_cfg = val & (GPT_TIMER_EN | 0xffff);
994         break;
995     case CSR_WORD_SWAP:
996         /* Ignored because we're in 32-bit mode.  */
997         s->word_swap = val;
998         break;
999     case CSR_MAC_CSR_CMD:
1000         s->mac_cmd = val & 0x4000000f;
1001         if (val & 0x80000000) {
1002             if (val & 0x40000000) {
1003                 s->mac_data = do_mac_read(s, val & 0xf);
1004                 DPRINTF("MAC read %d = 0x%08x\n", val & 0xf, s->mac_data);
1005             } else {
1006                 DPRINTF("MAC write %d = 0x%08x\n", val & 0xf, s->mac_data);
1007                 do_mac_write(s, val & 0xf, s->mac_data);
1008             }
1009         }
1010         break;
1011     case CSR_MAC_CSR_DATA:
1012         s->mac_data = val;
1013         break;
1014     case CSR_AFC_CFG:
1015         s->afc_cfg = val & 0x00ffffff;
1016         break;
1017     case CSR_E2P_CMD:
1018         lan9118_eeprom_cmd(s, (val >> 28) & 7, val & 0x7f);
1019         break;
1020     case CSR_E2P_DATA:
1021         s->e2p_data = val & 0xff;
1022         break;
1023
1024     default:
1025         hw_error("lan9118_write: Bad reg 0x%x = %x\n", (int)offset, val);
1026         break;
1027     }
1028     lan9118_update(s);
1029 }
1030
1031 static uint32_t lan9118_readl(void *opaque, target_phys_addr_t offset)
1032 {
1033     lan9118_state *s = (lan9118_state *)opaque;
1034
1035     //DPRINTF("Read reg 0x%02x\n", (int)offset);
1036     if (offset < 0x20) {
1037         /* RX FIFO */
1038         return rx_fifo_pop(s);
1039     }
1040     switch (offset) {
1041     case 0x40:
1042         return rx_status_fifo_pop(s);
1043     case 0x44:
1044         return s->rx_status_fifo[s->tx_status_fifo_head];
1045     case 0x48:
1046         return tx_status_fifo_pop(s);
1047     case 0x4c:
1048         return s->tx_status_fifo[s->tx_status_fifo_head];
1049     case CSR_ID_REV:
1050         return 0x01180001;
1051     case CSR_IRQ_CFG:
1052         return s->irq_cfg;
1053     case CSR_INT_STS:
1054         return s->int_sts;
1055     case CSR_INT_EN:
1056         return s->int_en;
1057     case CSR_BYTE_TEST:
1058         return 0x87654321;
1059     case CSR_FIFO_INT:
1060         return s->fifo_int;
1061     case CSR_RX_CFG:
1062         return s->rx_cfg;
1063     case CSR_TX_CFG:
1064         return s->tx_cfg;
1065     case CSR_HW_CFG:
1066         return s->hw_cfg | 0x4;
1067     case CSR_RX_DP_CTRL:
1068         return 0;
1069     case CSR_RX_FIFO_INF:
1070         return (s->rx_status_fifo_used << 16) | (s->rx_fifo_used << 2);
1071     case CSR_TX_FIFO_INF:
1072         return (s->tx_status_fifo_used << 16)
1073                | (s->tx_fifo_size - s->txp->fifo_used);
1074     case CSR_PMT_CTRL:
1075         return s->pmt_ctrl;
1076     case CSR_GPIO_CFG:
1077         return s->gpio_cfg;
1078     case CSR_GPT_CFG:
1079         return s->gpt_cfg;
1080     case CSR_GPT_CNT:
1081         return ptimer_get_count(s->timer);
1082     case CSR_WORD_SWAP:
1083         return s->word_swap;
1084     case CSR_FREE_RUN:
1085         return (qemu_get_clock_ns(vm_clock) / 40) - s->free_timer_start;
1086     case CSR_RX_DROP:
1087         /* TODO: Implement dropped frames counter.  */
1088         return 0;
1089     case CSR_MAC_CSR_CMD:
1090         return s->mac_cmd;
1091     case CSR_MAC_CSR_DATA:
1092         return s->mac_data;
1093     case CSR_AFC_CFG:
1094         return s->afc_cfg;
1095     case CSR_E2P_CMD:
1096         return s->e2p_cmd;
1097     case CSR_E2P_DATA:
1098         return s->e2p_data;
1099     }
1100     hw_error("lan9118_read: Bad reg 0x%x\n", (int)offset);
1101     return 0;
1102 }
1103
1104 static CPUReadMemoryFunc * const lan9118_readfn[] = {
1105     lan9118_readl,
1106     lan9118_readl,
1107     lan9118_readl
1108 };
1109
1110 static CPUWriteMemoryFunc * const lan9118_writefn[] = {
1111     lan9118_writel,
1112     lan9118_writel,
1113     lan9118_writel
1114 };
1115
1116 static void lan9118_cleanup(VLANClientState *nc)
1117 {
1118     lan9118_state *s = DO_UPCAST(NICState, nc, nc)->opaque;
1119
1120     s->nic = NULL;
1121 }
1122
1123 static NetClientInfo net_lan9118_info = {
1124     .type = NET_CLIENT_TYPE_NIC,
1125     .size = sizeof(NICState),
1126     .can_receive = lan9118_can_receive,
1127     .receive = lan9118_receive,
1128     .cleanup = lan9118_cleanup,
1129     .link_status_changed = lan9118_set_link,
1130 };
1131
1132 static int lan9118_init1(SysBusDevice *dev)
1133 {
1134     lan9118_state *s = FROM_SYSBUS(lan9118_state, dev);
1135     QEMUBH *bh;
1136     int i;
1137
1138     s->mmio_index = cpu_register_io_memory(lan9118_readfn,
1139                                            lan9118_writefn, s,
1140                                            DEVICE_NATIVE_ENDIAN);
1141     sysbus_init_mmio(dev, 0x100, s->mmio_index);
1142     sysbus_init_irq(dev, &s->irq);
1143     qemu_macaddr_default_if_unset(&s->conf.macaddr);
1144
1145     s->nic = qemu_new_nic(&net_lan9118_info, &s->conf,
1146                           dev->qdev.info->name, dev->qdev.id, s);
1147     qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
1148     s->eeprom[0] = 0xa5;
1149     for (i = 0; i < 6; i++) {
1150         s->eeprom[i + 1] = s->conf.macaddr.a[i];
1151     }
1152     s->pmt_ctrl = 1;
1153     s->txp = &s->tx_packet;
1154
1155     bh = qemu_bh_new(lan9118_tick, s);
1156     s->timer = ptimer_init(bh);
1157     ptimer_set_freq(s->timer, 10000);
1158     ptimer_set_limit(s->timer, 0xffff, 1);
1159
1160     /* ??? Save/restore.  */
1161     return 0;
1162 }
1163
1164 static SysBusDeviceInfo lan9118_info = {
1165     .init = lan9118_init1,
1166     .qdev.name  = "lan9118",
1167     .qdev.size  = sizeof(lan9118_state),
1168     .qdev.reset = lan9118_reset,
1169     .qdev.props = (Property[]) {
1170         DEFINE_NIC_PROPERTIES(lan9118_state, conf),
1171         DEFINE_PROP_END_OF_LIST(),
1172     }
1173 };
1174
1175 static void lan9118_register_devices(void)
1176 {
1177     sysbus_register_withprop(&lan9118_info);
1178 }
1179
1180 /* Legacy helper function.  Should go away when machine config files are
1181    implemented.  */
1182 void lan9118_init(NICInfo *nd, uint32_t base, qemu_irq irq)
1183 {
1184     DeviceState *dev;
1185     SysBusDevice *s;
1186
1187     qemu_check_nic_model(nd, "lan9118");
1188     dev = qdev_create(NULL, "lan9118");
1189     qdev_set_nic_properties(dev, nd);
1190     qdev_init_nofail(dev);
1191     s = sysbus_from_qdev(dev);
1192     sysbus_mmio_map(s, 0, base);
1193     sysbus_connect_irq(s, 0, irq);
1194 }
1195
1196 device_init(lan9118_register_devices)
This page took 0.093021 seconds and 4 git commands to generate.