2 * QEMU Freescale eTSEC Emulator
4 * Copyright (c) 2011-2013 AdaCore
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 * This implementation doesn't include ring priority, TCP/IP Off-Load, QoS.
29 #include "qemu/osdep.h"
30 #include "hw/sysbus.h"
32 #include "hw/net/mii.h"
33 #include "hw/ptimer.h"
34 #include "hw/qdev-properties.h"
36 #include "registers.h"
37 #include "qapi/error.h"
39 #include "qemu/module.h"
41 /* #define HEX_DUMP */
42 /* #define DEBUG_REGISTER */
45 static const int debug_etsec
= 1;
47 static const int debug_etsec
;
50 #define DPRINTF(fmt, ...) do { \
52 qemu_log(fmt , ## __VA_ARGS__); \
56 /* call after any change to IEVENT or IMASK */
57 void etsec_update_irq(eTSEC
*etsec
)
59 uint32_t ievent
= etsec
->regs
[IEVENT
].value
;
60 uint32_t imask
= etsec
->regs
[IMASK
].value
;
61 uint32_t active
= ievent
& imask
;
63 int tx
= !!(active
& IEVENT_TX_MASK
);
64 int rx
= !!(active
& IEVENT_RX_MASK
);
65 int err
= !!(active
& IEVENT_ERR_MASK
);
67 DPRINTF("%s IRQ ievent=%"PRIx32
" imask=%"PRIx32
" %c%c%c",
68 __func__
, ievent
, imask
,
73 qemu_set_irq(etsec
->tx_irq
, tx
);
74 qemu_set_irq(etsec
->rx_irq
, rx
);
75 qemu_set_irq(etsec
->err_irq
, err
);
78 static uint64_t etsec_read(void *opaque
, hwaddr addr
, unsigned size
)
80 eTSEC
*etsec
= opaque
;
81 uint32_t reg_index
= addr
/ 4;
82 eTSEC_Register
*reg
= NULL
;
85 assert(reg_index
< ETSEC_REG_NUMBER
);
87 reg
= &etsec
->regs
[reg_index
];
90 switch (reg
->access
) {
103 DPRINTF("Read 0x%08x @ 0x" HWADDR_FMT_plx
105 ret
, addr
, reg
->name
, reg
->desc
);
110 static void write_tstat(eTSEC
*etsec
,
117 for (i
= 0; i
< 8; i
++) {
118 /* Check THLTi flag in TSTAT */
119 if (value
& (1 << (31 - i
))) {
120 etsec_walk_tx_ring(etsec
, i
);
124 /* Write 1 to clear */
125 reg
->value
&= ~value
;
128 static void write_rstat(eTSEC
*etsec
,
135 for (i
= 0; i
< 8; i
++) {
136 /* Check QHLTi flag in RSTAT */
137 if (value
& (1 << (23 - i
)) && !(reg
->value
& (1 << (23 - i
)))) {
138 etsec_walk_rx_ring(etsec
, i
);
142 /* Write 1 to clear */
143 reg
->value
&= ~value
;
146 static void write_tbasex(eTSEC
*etsec
,
151 reg
->value
= value
& ~0x7;
153 /* Copy this value in the ring's TxBD pointer */
154 etsec
->regs
[TBPTR0
+ (reg_index
- TBASE0
)].value
= value
& ~0x7;
157 static void write_rbasex(eTSEC
*etsec
,
162 reg
->value
= value
& ~0x7;
164 /* Copy this value in the ring's RxBD pointer */
165 etsec
->regs
[RBPTR0
+ (reg_index
- RBASE0
)].value
= value
& ~0x7;
168 static void write_dmactrl(eTSEC
*etsec
,
175 if (value
& DMACTRL_GRS
) {
177 if (etsec
->rx_buffer_len
!= 0) {
178 /* Graceful receive stop delayed until end of frame */
180 /* Graceful receive stop now */
181 etsec
->regs
[IEVENT
].value
|= IEVENT_GRSC
;
182 etsec_update_irq(etsec
);
186 if (value
& DMACTRL_GTS
) {
188 if (etsec
->tx_buffer_len
!= 0) {
189 /* Graceful transmit stop delayed until end of frame */
191 /* Graceful transmit stop now */
192 etsec
->regs
[IEVENT
].value
|= IEVENT_GTSC
;
193 etsec_update_irq(etsec
);
197 if (!(value
& DMACTRL_WOP
)) {
199 ptimer_transaction_begin(etsec
->ptimer
);
200 ptimer_stop(etsec
->ptimer
);
201 ptimer_set_count(etsec
->ptimer
, 1);
202 ptimer_run(etsec
->ptimer
, 1);
203 ptimer_transaction_commit(etsec
->ptimer
);
207 static void etsec_write(void *opaque
,
212 eTSEC
*etsec
= opaque
;
213 uint32_t reg_index
= addr
/ 4;
214 eTSEC_Register
*reg
= NULL
;
215 uint32_t before
= 0x0;
217 assert(reg_index
< ETSEC_REG_NUMBER
);
219 reg
= &etsec
->regs
[reg_index
];
224 /* Write 1 to clear */
225 reg
->value
&= ~value
;
227 etsec_update_irq(etsec
);
233 etsec_update_irq(etsec
);
237 write_dmactrl(etsec
, reg
, reg_index
, value
);
241 write_tstat(etsec
, reg
, reg_index
, value
);
245 write_rstat(etsec
, reg
, reg_index
, value
);
248 case TBASE0
... TBASE7
:
249 write_tbasex(etsec
, reg
, reg_index
, value
);
252 case RBASE0
... RBASE7
:
253 write_rbasex(etsec
, reg
, reg_index
, value
);
256 case MIIMCFG
... MIIMIND
:
257 etsec_write_miim(etsec
, reg
, reg_index
, value
);
261 /* Default handling */
262 switch (reg
->access
) {
270 reg
->value
&= ~value
;
275 /* Read Only or Unknown register */
280 DPRINTF("Write 0x%08x @ 0x" HWADDR_FMT_plx
281 " val:0x%08x->0x%08x : %s (%s)\n",
282 (unsigned int)value
, addr
, before
, reg
->value
,
283 reg
->name
, reg
->desc
);
286 static const MemoryRegionOps etsec_ops
= {
288 .write
= etsec_write
,
289 .endianness
= DEVICE_NATIVE_ENDIAN
,
291 .min_access_size
= 4,
292 .max_access_size
= 4,
296 static void etsec_timer_hit(void *opaque
)
298 eTSEC
*etsec
= opaque
;
300 ptimer_stop(etsec
->ptimer
);
302 if (!(etsec
->regs
[DMACTRL
].value
& DMACTRL_WOP
)) {
304 if (!(etsec
->regs
[DMACTRL
].value
& DMACTRL_GTS
)) {
305 etsec_walk_tx_ring(etsec
, 0);
307 ptimer_set_count(etsec
->ptimer
, 1);
308 ptimer_run(etsec
->ptimer
, 1);
312 static void etsec_reset(DeviceState
*d
)
314 eTSEC
*etsec
= ETSEC_COMMON(d
);
318 /* Default value for all registers */
319 for (i
= 0; i
< ETSEC_REG_NUMBER
; i
++) {
320 etsec
->regs
[i
].name
= "Reserved";
321 etsec
->regs
[i
].desc
= "";
322 etsec
->regs
[i
].access
= ACC_UNKNOWN
;
323 etsec
->regs
[i
].value
= 0x00000000;
326 /* Set-up known registers */
327 for (i
= 0; eTSEC_registers_def
[i
].name
!= NULL
; i
++) {
329 reg_index
= eTSEC_registers_def
[i
].offset
/ 4;
331 etsec
->regs
[reg_index
].name
= eTSEC_registers_def
[i
].name
;
332 etsec
->regs
[reg_index
].desc
= eTSEC_registers_def
[i
].desc
;
333 etsec
->regs
[reg_index
].access
= eTSEC_registers_def
[i
].access
;
334 etsec
->regs
[reg_index
].value
= eTSEC_registers_def
[i
].reset
;
337 etsec
->tx_buffer
= NULL
;
338 etsec
->tx_buffer_len
= 0;
339 etsec
->rx_buffer
= NULL
;
340 etsec
->rx_buffer_len
= 0;
343 MII_BMSR_EXTCAP
| MII_BMSR_LINK_ST
| MII_BMSR_AUTONEG
|
344 MII_BMSR_AN_COMP
| MII_BMSR_MFPS
| MII_BMSR_EXTSTAT
|
345 MII_BMSR_100T2_HD
| MII_BMSR_100T2_FD
|
346 MII_BMSR_10T_HD
| MII_BMSR_10T_FD
|
347 MII_BMSR_100TX_HD
| MII_BMSR_100TX_FD
| MII_BMSR_100T4
;
349 etsec_update_irq(etsec
);
352 static ssize_t
etsec_receive(NetClientState
*nc
,
357 eTSEC
*etsec
= qemu_get_nic_opaque(nc
);
359 #if defined(HEX_DUMP)
360 fprintf(stderr
, "%s receive size:%zd\n", nc
->name
, size
);
361 qemu_hexdump(stderr
, "", buf
, size
);
363 /* Flush is unnecessary as are already in receiving path */
364 etsec
->need_flush
= false;
365 ret
= etsec_rx_ring_write(etsec
, buf
, size
);
367 /* The packet will be queued, let's flush it when buffer is available
369 etsec
->need_flush
= true;
375 static void etsec_set_link_status(NetClientState
*nc
)
377 eTSEC
*etsec
= qemu_get_nic_opaque(nc
);
379 etsec_miim_link_status(etsec
, nc
);
382 static NetClientInfo net_etsec_info
= {
383 .type
= NET_CLIENT_DRIVER_NIC
,
384 .size
= sizeof(NICState
),
385 .receive
= etsec_receive
,
386 .link_status_changed
= etsec_set_link_status
,
389 static void etsec_realize(DeviceState
*dev
, Error
**errp
)
391 eTSEC
*etsec
= ETSEC_COMMON(dev
);
393 etsec
->nic
= qemu_new_nic(&net_etsec_info
, &etsec
->conf
,
394 object_get_typename(OBJECT(dev
)), dev
->id
,
395 &dev
->mem_reentrancy_guard
, etsec
);
396 qemu_format_nic_info_str(qemu_get_queue(etsec
->nic
), etsec
->conf
.macaddr
.a
);
398 etsec
->ptimer
= ptimer_init(etsec_timer_hit
, etsec
, PTIMER_POLICY_LEGACY
);
399 ptimer_transaction_begin(etsec
->ptimer
);
400 ptimer_set_freq(etsec
->ptimer
, 100);
401 ptimer_transaction_commit(etsec
->ptimer
);
404 static void etsec_instance_init(Object
*obj
)
406 eTSEC
*etsec
= ETSEC_COMMON(obj
);
407 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
409 memory_region_init_io(&etsec
->io_area
, OBJECT(etsec
), &etsec_ops
, etsec
,
411 sysbus_init_mmio(sbd
, &etsec
->io_area
);
413 sysbus_init_irq(sbd
, &etsec
->tx_irq
);
414 sysbus_init_irq(sbd
, &etsec
->rx_irq
);
415 sysbus_init_irq(sbd
, &etsec
->err_irq
);
418 static Property etsec_properties
[] = {
419 DEFINE_NIC_PROPERTIES(eTSEC
, conf
),
420 DEFINE_PROP_END_OF_LIST(),
423 static void etsec_class_init(ObjectClass
*klass
, void *data
)
425 DeviceClass
*dc
= DEVICE_CLASS(klass
);
427 dc
->realize
= etsec_realize
;
428 device_class_set_legacy_reset(dc
, etsec_reset
);
429 device_class_set_props(dc
, etsec_properties
);
430 /* Supported by ppce500 machine */
431 dc
->user_creatable
= true;
434 static const TypeInfo etsec_info
= {
435 .name
= TYPE_ETSEC_COMMON
,
436 .parent
= TYPE_SYS_BUS_DEVICE
,
437 .instance_size
= sizeof(eTSEC
),
438 .class_init
= etsec_class_init
,
439 .instance_init
= etsec_instance_init
,
442 static void etsec_register_types(void)
444 type_register_static(&etsec_info
);
447 type_init(etsec_register_types
)