xref: /openbmc/qemu/hw/net/xgmac.c (revision db725815985654007ade0fd53590d613fd657208)
1 /*
2  * QEMU model of XGMAC Ethernet.
3  *
4  * derived from the Xilinx AXI-Ethernet by Edgar E. Iglesias.
5  *
6  * Copyright (c) 2011 Calxeda, Inc.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  */
26 
27 #include "qemu/osdep.h"
28 #include "hw/irq.h"
29 #include "hw/sysbus.h"
30 #include "migration/vmstate.h"
31 #include "qemu/log.h"
32 #include "qemu/module.h"
33 #include "net/net.h"
34 
35 #ifdef DEBUG_XGMAC
36 #define DEBUGF_BRK(message, args...) do { \
37                                          fprintf(stderr, (message), ## args); \
38                                      } while (0)
39 #else
40 #define DEBUGF_BRK(message, args...) do { } while (0)
41 #endif
42 
43 #define XGMAC_CONTROL           0x00000000   /* MAC Configuration */
44 #define XGMAC_FRAME_FILTER      0x00000001   /* MAC Frame Filter */
45 #define XGMAC_FLOW_CTRL         0x00000006   /* MAC Flow Control */
46 #define XGMAC_VLAN_TAG          0x00000007   /* VLAN Tags */
47 #define XGMAC_VERSION           0x00000008   /* Version */
48 /* VLAN tag for insertion or replacement into tx frames */
49 #define XGMAC_VLAN_INCL         0x00000009
50 #define XGMAC_LPI_CTRL          0x0000000a   /* LPI Control and Status */
51 #define XGMAC_LPI_TIMER         0x0000000b   /* LPI Timers Control */
52 #define XGMAC_TX_PACE           0x0000000c   /* Transmit Pace and Stretch */
53 #define XGMAC_VLAN_HASH         0x0000000d   /* VLAN Hash Table */
54 #define XGMAC_DEBUG             0x0000000e   /* Debug */
55 #define XGMAC_INT_STATUS        0x0000000f   /* Interrupt and Control */
56 /* HASH table registers */
57 #define XGMAC_HASH(n)           ((0x00000300/4) + (n))
58 #define XGMAC_NUM_HASH          16
59 /* Operation Mode */
60 #define XGMAC_OPMODE            (0x00000400/4)
61 /* Remote Wake-Up Frame Filter */
62 #define XGMAC_REMOTE_WAKE       (0x00000700/4)
63 /* PMT Control and Status */
64 #define XGMAC_PMT               (0x00000704/4)
65 
66 #define XGMAC_ADDR_HIGH(reg)    (0x00000010+((reg) * 2))
67 #define XGMAC_ADDR_LOW(reg)     (0x00000011+((reg) * 2))
68 
69 #define DMA_BUS_MODE            0x000003c0   /* Bus Mode */
70 #define DMA_XMT_POLL_DEMAND     0x000003c1   /* Transmit Poll Demand */
71 #define DMA_RCV_POLL_DEMAND     0x000003c2   /* Received Poll Demand */
72 #define DMA_RCV_BASE_ADDR       0x000003c3   /* Receive List Base */
73 #define DMA_TX_BASE_ADDR        0x000003c4   /* Transmit List Base */
74 #define DMA_STATUS              0x000003c5   /* Status Register */
75 #define DMA_CONTROL             0x000003c6   /* Ctrl (Operational Mode) */
76 #define DMA_INTR_ENA            0x000003c7   /* Interrupt Enable */
77 #define DMA_MISSED_FRAME_CTR    0x000003c8   /* Missed Frame Counter */
78 /* Receive Interrupt Watchdog Timer */
79 #define DMA_RI_WATCHDOG_TIMER   0x000003c9
80 #define DMA_AXI_BUS             0x000003ca   /* AXI Bus Mode */
81 #define DMA_AXI_STATUS          0x000003cb   /* AXI Status */
82 #define DMA_CUR_TX_DESC_ADDR    0x000003d2   /* Current Host Tx Descriptor */
83 #define DMA_CUR_RX_DESC_ADDR    0x000003d3   /* Current Host Rx Descriptor */
84 #define DMA_CUR_TX_BUF_ADDR     0x000003d4   /* Current Host Tx Buffer */
85 #define DMA_CUR_RX_BUF_ADDR     0x000003d5   /* Current Host Rx Buffer */
86 #define DMA_HW_FEATURE          0x000003d6   /* Enabled Hardware Features */
87 
88 /* DMA Status register defines */
89 #define DMA_STATUS_GMI          0x08000000   /* MMC interrupt */
90 #define DMA_STATUS_GLI          0x04000000   /* GMAC Line interface int */
91 #define DMA_STATUS_EB_MASK      0x00380000   /* Error Bits Mask */
92 #define DMA_STATUS_EB_TX_ABORT  0x00080000   /* Error Bits - TX Abort */
93 #define DMA_STATUS_EB_RX_ABORT  0x00100000   /* Error Bits - RX Abort */
94 #define DMA_STATUS_TS_MASK      0x00700000   /* Transmit Process State */
95 #define DMA_STATUS_TS_SHIFT     20
96 #define DMA_STATUS_RS_MASK      0x000e0000   /* Receive Process State */
97 #define DMA_STATUS_RS_SHIFT     17
98 #define DMA_STATUS_NIS          0x00010000   /* Normal Interrupt Summary */
99 #define DMA_STATUS_AIS          0x00008000   /* Abnormal Interrupt Summary */
100 #define DMA_STATUS_ERI          0x00004000   /* Early Receive Interrupt */
101 #define DMA_STATUS_FBI          0x00002000   /* Fatal Bus Error Interrupt */
102 #define DMA_STATUS_ETI          0x00000400   /* Early Transmit Interrupt */
103 #define DMA_STATUS_RWT          0x00000200   /* Receive Watchdog Timeout */
104 #define DMA_STATUS_RPS          0x00000100   /* Receive Process Stopped */
105 #define DMA_STATUS_RU           0x00000080   /* Receive Buffer Unavailable */
106 #define DMA_STATUS_RI           0x00000040   /* Receive Interrupt */
107 #define DMA_STATUS_UNF          0x00000020   /* Transmit Underflow */
108 #define DMA_STATUS_OVF          0x00000010   /* Receive Overflow */
109 #define DMA_STATUS_TJT          0x00000008   /* Transmit Jabber Timeout */
110 #define DMA_STATUS_TU           0x00000004   /* Transmit Buffer Unavailable */
111 #define DMA_STATUS_TPS          0x00000002   /* Transmit Process Stopped */
112 #define DMA_STATUS_TI           0x00000001   /* Transmit Interrupt */
113 
114 /* DMA Control register defines */
115 #define DMA_CONTROL_ST          0x00002000   /* Start/Stop Transmission */
116 #define DMA_CONTROL_SR          0x00000002   /* Start/Stop Receive */
117 #define DMA_CONTROL_DFF         0x01000000   /* Disable flush of rx frames */
118 
119 struct desc {
120     uint32_t ctl_stat;
121     uint16_t buffer1_size;
122     uint16_t buffer2_size;
123     uint32_t buffer1_addr;
124     uint32_t buffer2_addr;
125     uint32_t ext_stat;
126     uint32_t res[3];
127 };
128 
129 #define R_MAX 0x400
130 
131 typedef struct RxTxStats {
132     uint64_t rx_bytes;
133     uint64_t tx_bytes;
134 
135     uint64_t rx;
136     uint64_t rx_bcast;
137     uint64_t rx_mcast;
138 } RxTxStats;
139 
140 #define TYPE_XGMAC "xgmac"
141 #define XGMAC(obj) OBJECT_CHECK(XgmacState, (obj), TYPE_XGMAC)
142 
143 typedef struct XgmacState {
144     SysBusDevice parent_obj;
145 
146     MemoryRegion iomem;
147     qemu_irq sbd_irq;
148     qemu_irq pmt_irq;
149     qemu_irq mci_irq;
150     NICState *nic;
151     NICConf conf;
152 
153     struct RxTxStats stats;
154     uint32_t regs[R_MAX];
155 } XgmacState;
156 
157 static const VMStateDescription vmstate_rxtx_stats = {
158     .name = "xgmac_stats",
159     .version_id = 1,
160     .minimum_version_id = 1,
161     .fields = (VMStateField[]) {
162         VMSTATE_UINT64(rx_bytes, RxTxStats),
163         VMSTATE_UINT64(tx_bytes, RxTxStats),
164         VMSTATE_UINT64(rx, RxTxStats),
165         VMSTATE_UINT64(rx_bcast, RxTxStats),
166         VMSTATE_UINT64(rx_mcast, RxTxStats),
167         VMSTATE_END_OF_LIST()
168     }
169 };
170 
171 static const VMStateDescription vmstate_xgmac = {
172     .name = "xgmac",
173     .version_id = 1,
174     .minimum_version_id = 1,
175     .fields = (VMStateField[]) {
176         VMSTATE_STRUCT(stats, XgmacState, 0, vmstate_rxtx_stats, RxTxStats),
177         VMSTATE_UINT32_ARRAY(regs, XgmacState, R_MAX),
178         VMSTATE_END_OF_LIST()
179     }
180 };
181 
182 static void xgmac_read_desc(XgmacState *s, struct desc *d, int rx)
183 {
184     uint32_t addr = rx ? s->regs[DMA_CUR_RX_DESC_ADDR] :
185         s->regs[DMA_CUR_TX_DESC_ADDR];
186     cpu_physical_memory_read(addr, d, sizeof(*d));
187 }
188 
189 static void xgmac_write_desc(XgmacState *s, struct desc *d, int rx)
190 {
191     int reg = rx ? DMA_CUR_RX_DESC_ADDR : DMA_CUR_TX_DESC_ADDR;
192     uint32_t addr = s->regs[reg];
193 
194     if (!rx && (d->ctl_stat & 0x00200000)) {
195         s->regs[reg] = s->regs[DMA_TX_BASE_ADDR];
196     } else if (rx && (d->buffer1_size & 0x8000)) {
197         s->regs[reg] = s->regs[DMA_RCV_BASE_ADDR];
198     } else {
199         s->regs[reg] += sizeof(*d);
200     }
201     cpu_physical_memory_write(addr, d, sizeof(*d));
202 }
203 
204 static void xgmac_enet_send(XgmacState *s)
205 {
206     struct desc bd;
207     int frame_size;
208     int len;
209     uint8_t frame[8192];
210     uint8_t *ptr;
211 
212     ptr = frame;
213     frame_size = 0;
214     while (1) {
215         xgmac_read_desc(s, &bd, 0);
216         if ((bd.ctl_stat & 0x80000000) == 0) {
217             /* Run out of descriptors to transmit.  */
218             break;
219         }
220         len = (bd.buffer1_size & 0xfff) + (bd.buffer2_size & 0xfff);
221 
222         if ((bd.buffer1_size & 0xfff) > 2048) {
223             DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- "
224                         "xgmac buffer 1 len on send > 2048 (0x%x)\n",
225                          __func__, bd.buffer1_size & 0xfff);
226         }
227         if ((bd.buffer2_size & 0xfff) != 0) {
228             DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- "
229                         "xgmac buffer 2 len on send != 0 (0x%x)\n",
230                         __func__, bd.buffer2_size & 0xfff);
231         }
232         if (len >= sizeof(frame)) {
233             DEBUGF_BRK("qemu:%s: buffer overflow %d read into %zu "
234                         "buffer\n" , __func__, len, sizeof(frame));
235             DEBUGF_BRK("qemu:%s: buffer1.size=%d; buffer2.size=%d\n",
236                         __func__, bd.buffer1_size, bd.buffer2_size);
237         }
238 
239         cpu_physical_memory_read(bd.buffer1_addr, ptr, len);
240         ptr += len;
241         frame_size += len;
242         if (bd.ctl_stat & 0x20000000) {
243             /* Last buffer in frame.  */
244             qemu_send_packet(qemu_get_queue(s->nic), frame, len);
245             ptr = frame;
246             frame_size = 0;
247             s->regs[DMA_STATUS] |= DMA_STATUS_TI | DMA_STATUS_NIS;
248         }
249         bd.ctl_stat &= ~0x80000000;
250         /* Write back the modified descriptor.  */
251         xgmac_write_desc(s, &bd, 0);
252     }
253 }
254 
255 static void enet_update_irq(XgmacState *s)
256 {
257     int stat = s->regs[DMA_STATUS] & s->regs[DMA_INTR_ENA];
258     qemu_set_irq(s->sbd_irq, !!stat);
259 }
260 
261 static uint64_t enet_read(void *opaque, hwaddr addr, unsigned size)
262 {
263     XgmacState *s = opaque;
264     uint64_t r = 0;
265     addr >>= 2;
266 
267     switch (addr) {
268     case XGMAC_VERSION:
269         r = 0x1012;
270         break;
271     default:
272         if (addr < ARRAY_SIZE(s->regs)) {
273             r = s->regs[addr];
274         }
275         break;
276     }
277     return r;
278 }
279 
280 static void enet_write(void *opaque, hwaddr addr,
281                        uint64_t value, unsigned size)
282 {
283     XgmacState *s = opaque;
284 
285     addr >>= 2;
286     switch (addr) {
287     case DMA_BUS_MODE:
288         s->regs[DMA_BUS_MODE] = value & ~0x1;
289         break;
290     case DMA_XMT_POLL_DEMAND:
291         xgmac_enet_send(s);
292         break;
293     case DMA_STATUS:
294         s->regs[DMA_STATUS] = s->regs[DMA_STATUS] & ~value;
295         break;
296     case DMA_RCV_BASE_ADDR:
297         s->regs[DMA_RCV_BASE_ADDR] = s->regs[DMA_CUR_RX_DESC_ADDR] = value;
298         break;
299     case DMA_TX_BASE_ADDR:
300         s->regs[DMA_TX_BASE_ADDR] = s->regs[DMA_CUR_TX_DESC_ADDR] = value;
301         break;
302     default:
303         if (addr < ARRAY_SIZE(s->regs)) {
304             s->regs[addr] = value;
305         }
306         break;
307     }
308     enet_update_irq(s);
309 }
310 
311 static const MemoryRegionOps enet_mem_ops = {
312     .read = enet_read,
313     .write = enet_write,
314     .endianness = DEVICE_LITTLE_ENDIAN,
315 };
316 
317 static int eth_can_rx(XgmacState *s)
318 {
319     /* RX enabled?  */
320     return s->regs[DMA_CONTROL] & DMA_CONTROL_SR;
321 }
322 
323 static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
324 {
325     XgmacState *s = qemu_get_nic_opaque(nc);
326     static const unsigned char sa_bcast[6] = {0xff, 0xff, 0xff,
327                                               0xff, 0xff, 0xff};
328     int unicast, broadcast, multicast;
329     struct desc bd;
330     ssize_t ret;
331 
332     if (!eth_can_rx(s)) {
333         return -1;
334     }
335     unicast = ~buf[0] & 0x1;
336     broadcast = memcmp(buf, sa_bcast, 6) == 0;
337     multicast = !unicast && !broadcast;
338     if (size < 12) {
339         s->regs[DMA_STATUS] |= DMA_STATUS_RI | DMA_STATUS_NIS;
340         ret = -1;
341         goto out;
342     }
343 
344     xgmac_read_desc(s, &bd, 1);
345     if ((bd.ctl_stat & 0x80000000) == 0) {
346         s->regs[DMA_STATUS] |= DMA_STATUS_RU | DMA_STATUS_AIS;
347         ret = size;
348         goto out;
349     }
350 
351     cpu_physical_memory_write(bd.buffer1_addr, buf, size);
352 
353     /* Add in the 4 bytes for crc (the real hw returns length incl crc) */
354     size += 4;
355     bd.ctl_stat = (size << 16) | 0x300;
356     xgmac_write_desc(s, &bd, 1);
357 
358     s->stats.rx_bytes += size;
359     s->stats.rx++;
360     if (multicast) {
361         s->stats.rx_mcast++;
362     } else if (broadcast) {
363         s->stats.rx_bcast++;
364     }
365 
366     s->regs[DMA_STATUS] |= DMA_STATUS_RI | DMA_STATUS_NIS;
367     ret = size;
368 
369 out:
370     enet_update_irq(s);
371     return ret;
372 }
373 
374 static NetClientInfo net_xgmac_enet_info = {
375     .type = NET_CLIENT_DRIVER_NIC,
376     .size = sizeof(NICState),
377     .receive = eth_rx,
378 };
379 
380 static void xgmac_enet_realize(DeviceState *dev, Error **errp)
381 {
382     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
383     XgmacState *s = XGMAC(dev);
384 
385     memory_region_init_io(&s->iomem, OBJECT(s), &enet_mem_ops, s,
386                           "xgmac", 0x1000);
387     sysbus_init_mmio(sbd, &s->iomem);
388     sysbus_init_irq(sbd, &s->sbd_irq);
389     sysbus_init_irq(sbd, &s->pmt_irq);
390     sysbus_init_irq(sbd, &s->mci_irq);
391 
392     qemu_macaddr_default_if_unset(&s->conf.macaddr);
393     s->nic = qemu_new_nic(&net_xgmac_enet_info, &s->conf,
394                           object_get_typename(OBJECT(dev)), dev->id, s);
395     qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
396 
397     s->regs[XGMAC_ADDR_HIGH(0)] = (s->conf.macaddr.a[5] << 8) |
398                                    s->conf.macaddr.a[4];
399     s->regs[XGMAC_ADDR_LOW(0)] = (s->conf.macaddr.a[3] << 24) |
400                                  (s->conf.macaddr.a[2] << 16) |
401                                  (s->conf.macaddr.a[1] << 8) |
402                                   s->conf.macaddr.a[0];
403 }
404 
405 static Property xgmac_properties[] = {
406     DEFINE_NIC_PROPERTIES(XgmacState, conf),
407     DEFINE_PROP_END_OF_LIST(),
408 };
409 
410 static void xgmac_enet_class_init(ObjectClass *klass, void *data)
411 {
412     DeviceClass *dc = DEVICE_CLASS(klass);
413 
414     dc->realize = xgmac_enet_realize;
415     dc->vmsd = &vmstate_xgmac;
416     dc->props = xgmac_properties;
417 }
418 
419 static const TypeInfo xgmac_enet_info = {
420     .name          = TYPE_XGMAC,
421     .parent        = TYPE_SYS_BUS_DEVICE,
422     .instance_size = sizeof(XgmacState),
423     .class_init    = xgmac_enet_class_init,
424 };
425 
426 static void xgmac_enet_register_types(void)
427 {
428     type_register_static(&xgmac_enet_info);
429 }
430 
431 type_init(xgmac_enet_register_types)
432