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