Statistics
| Branch: | Revision:

root / hw / xgmac.c @ 847c25d0

History | View | Annotate | Download (14.6 kB)

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