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 "sysemu/sysemu.h"
31 #include "hw/sysbus.h"
32 #include "hw/ptimer.h"
34 #include "registers.h"
37 /* #define HEX_DUMP */
38 /* #define DEBUG_REGISTER */
41 static const int debug_etsec
= 1;
43 static const int debug_etsec
;
46 #define DPRINTF(fmt, ...) do { \
48 qemu_log(fmt , ## __VA_ARGS__); \
52 static uint64_t etsec_read(void *opaque
, hwaddr addr
, unsigned size
)
54 eTSEC
*etsec
= opaque
;
55 uint32_t reg_index
= addr
/ 4;
56 eTSEC_Register
*reg
= NULL
;
59 assert(reg_index
< ETSEC_REG_NUMBER
);
61 reg
= &etsec
->regs
[reg_index
];
64 switch (reg
->access
) {
77 DPRINTF("Read 0x%08x @ 0x" TARGET_FMT_plx
79 ret
, addr
, reg
->name
, reg
->desc
);
84 static void write_tstat(eTSEC
*etsec
,
91 for (i
= 0; i
< 8; i
++) {
92 /* Check THLTi flag in TSTAT */
93 if (value
& (1 << (31 - i
))) {
94 etsec_walk_tx_ring(etsec
, i
);
98 /* Write 1 to clear */
102 static void write_rstat(eTSEC
*etsec
,
109 for (i
= 0; i
< 8; i
++) {
110 /* Check QHLTi flag in RSTAT */
111 if (value
& (1 << (23 - i
)) && !(reg
->value
& (1 << (23 - i
)))) {
112 etsec_walk_rx_ring(etsec
, i
);
116 /* Write 1 to clear */
117 reg
->value
&= ~value
;
120 static void write_tbasex(eTSEC
*etsec
,
125 reg
->value
= value
& ~0x7;
127 /* Copy this value in the ring's TxBD pointer */
128 etsec
->regs
[TBPTR0
+ (reg_index
- TBASE0
)].value
= value
& ~0x7;
131 static void write_rbasex(eTSEC
*etsec
,
136 reg
->value
= value
& ~0x7;
138 /* Copy this value in the ring's RxBD pointer */
139 etsec
->regs
[RBPTR0
+ (reg_index
- RBASE0
)].value
= value
& ~0x7;
142 static void write_ievent(eTSEC
*etsec
,
147 /* Write 1 to clear */
148 reg
->value
&= ~value
;
150 if (!(reg
->value
& (IEVENT_TXF
| IEVENT_TXF
))) {
151 qemu_irq_lower(etsec
->tx_irq
);
153 if (!(reg
->value
& (IEVENT_RXF
| IEVENT_RXF
))) {
154 qemu_irq_lower(etsec
->rx_irq
);
157 if (!(reg
->value
& (IEVENT_MAG
| IEVENT_GTSC
| IEVENT_GRSC
| IEVENT_TXC
|
158 IEVENT_RXC
| IEVENT_BABR
| IEVENT_BABT
| IEVENT_LC
|
159 IEVENT_CRL
| IEVENT_FGPI
| IEVENT_FIR
| IEVENT_FIQ
|
160 IEVENT_DPE
| IEVENT_PERR
| IEVENT_EBERR
| IEVENT_TXE
|
161 IEVENT_XFUN
| IEVENT_BSY
| IEVENT_MSRO
| IEVENT_MMRD
|
163 qemu_irq_lower(etsec
->err_irq
);
167 static void write_dmactrl(eTSEC
*etsec
,
174 if (value
& DMACTRL_GRS
) {
176 if (etsec
->rx_buffer_len
!= 0) {
177 /* Graceful receive stop delayed until end of frame */
179 /* Graceful receive stop now */
180 etsec
->regs
[IEVENT
].value
|= IEVENT_GRSC
;
181 if (etsec
->regs
[IMASK
].value
& IMASK_GRSCEN
) {
182 qemu_irq_raise(etsec
->err_irq
);
187 if (value
& DMACTRL_GTS
) {
189 if (etsec
->tx_buffer_len
!= 0) {
190 /* Graceful transmit stop delayed until end of frame */
192 /* Graceful transmit stop now */
193 etsec
->regs
[IEVENT
].value
|= IEVENT_GTSC
;
194 if (etsec
->regs
[IMASK
].value
& IMASK_GTSCEN
) {
195 qemu_irq_raise(etsec
->err_irq
);
200 if (!(value
& DMACTRL_WOP
)) {
202 ptimer_stop(etsec
->ptimer
);
203 ptimer_set_count(etsec
->ptimer
, 1);
204 ptimer_run(etsec
->ptimer
, 1);
208 static void etsec_write(void *opaque
,
213 eTSEC
*etsec
= opaque
;
214 uint32_t reg_index
= addr
/ 4;
215 eTSEC_Register
*reg
= NULL
;
216 uint32_t before
= 0x0;
218 assert(reg_index
< ETSEC_REG_NUMBER
);
220 reg
= &etsec
->regs
[reg_index
];
225 write_ievent(etsec
, reg
, reg_index
, value
);
229 write_dmactrl(etsec
, reg
, reg_index
, value
);
233 write_tstat(etsec
, reg
, reg_index
, value
);
237 write_rstat(etsec
, reg
, reg_index
, value
);
240 case TBASE0
... TBASE7
:
241 write_tbasex(etsec
, reg
, reg_index
, value
);
244 case RBASE0
... RBASE7
:
245 write_rbasex(etsec
, reg
, reg_index
, value
);
248 case MIIMCFG
... MIIMIND
:
249 etsec_write_miim(etsec
, reg
, reg_index
, value
);
253 /* Default handling */
254 switch (reg
->access
) {
262 reg
->value
&= ~value
;
267 /* Read Only or Unknown register */
272 DPRINTF("Write 0x%08x @ 0x" TARGET_FMT_plx
273 " val:0x%08x->0x%08x : %s (%s)\n",
274 (unsigned int)value
, addr
, before
, reg
->value
,
275 reg
->name
, reg
->desc
);
278 static const MemoryRegionOps etsec_ops
= {
280 .write
= etsec_write
,
281 .endianness
= DEVICE_NATIVE_ENDIAN
,
283 .min_access_size
= 4,
284 .max_access_size
= 4,
288 static void etsec_timer_hit(void *opaque
)
290 eTSEC
*etsec
= opaque
;
292 ptimer_stop(etsec
->ptimer
);
294 if (!(etsec
->regs
[DMACTRL
].value
& DMACTRL_WOP
)) {
296 if (!(etsec
->regs
[DMACTRL
].value
& DMACTRL_GTS
)) {
297 etsec_walk_tx_ring(etsec
, 0);
299 ptimer_set_count(etsec
->ptimer
, 1);
300 ptimer_run(etsec
->ptimer
, 1);
304 static void etsec_reset(DeviceState
*d
)
306 eTSEC
*etsec
= ETSEC_COMMON(d
);
310 /* Default value for all registers */
311 for (i
= 0; i
< ETSEC_REG_NUMBER
; i
++) {
312 etsec
->regs
[i
].name
= "Reserved";
313 etsec
->regs
[i
].desc
= "";
314 etsec
->regs
[i
].access
= ACC_UNKNOWN
;
315 etsec
->regs
[i
].value
= 0x00000000;
318 /* Set-up known registers */
319 for (i
= 0; eTSEC_registers_def
[i
].name
!= NULL
; i
++) {
321 reg_index
= eTSEC_registers_def
[i
].offset
/ 4;
323 etsec
->regs
[reg_index
].name
= eTSEC_registers_def
[i
].name
;
324 etsec
->regs
[reg_index
].desc
= eTSEC_registers_def
[i
].desc
;
325 etsec
->regs
[reg_index
].access
= eTSEC_registers_def
[i
].access
;
326 etsec
->regs
[reg_index
].value
= eTSEC_registers_def
[i
].reset
;
329 etsec
->tx_buffer
= NULL
;
330 etsec
->tx_buffer_len
= 0;
331 etsec
->rx_buffer
= NULL
;
332 etsec
->rx_buffer_len
= 0;
335 MII_SR_EXTENDED_CAPS
| MII_SR_LINK_STATUS
| MII_SR_AUTONEG_CAPS
|
336 MII_SR_AUTONEG_COMPLETE
| MII_SR_PREAMBLE_SUPPRESS
|
337 MII_SR_EXTENDED_STATUS
| MII_SR_100T2_HD_CAPS
| MII_SR_100T2_FD_CAPS
|
338 MII_SR_10T_HD_CAPS
| MII_SR_10T_FD_CAPS
| MII_SR_100X_HD_CAPS
|
339 MII_SR_100X_FD_CAPS
| MII_SR_100T4_CAPS
;
342 static ssize_t
etsec_receive(NetClientState
*nc
,
347 eTSEC
*etsec
= qemu_get_nic_opaque(nc
);
349 #if defined(HEX_DUMP)
350 fprintf(stderr
, "%s receive size:%zd\n", nc
->name
, size
);
351 qemu_hexdump((void *)buf
, stderr
, "", size
);
353 /* Flush is unnecessary as are already in receiving path */
354 etsec
->need_flush
= false;
355 ret
= etsec_rx_ring_write(etsec
, buf
, size
);
357 /* The packet will be queued, let's flush it when buffer is available
359 etsec
->need_flush
= true;
365 static void etsec_set_link_status(NetClientState
*nc
)
367 eTSEC
*etsec
= qemu_get_nic_opaque(nc
);
369 etsec_miim_link_status(etsec
, nc
);
372 static NetClientInfo net_etsec_info
= {
373 .type
= NET_CLIENT_DRIVER_NIC
,
374 .size
= sizeof(NICState
),
375 .receive
= etsec_receive
,
376 .link_status_changed
= etsec_set_link_status
,
379 static void etsec_realize(DeviceState
*dev
, Error
**errp
)
381 eTSEC
*etsec
= ETSEC_COMMON(dev
);
383 etsec
->nic
= qemu_new_nic(&net_etsec_info
, &etsec
->conf
,
384 object_get_typename(OBJECT(dev
)), dev
->id
, etsec
);
385 qemu_format_nic_info_str(qemu_get_queue(etsec
->nic
), etsec
->conf
.macaddr
.a
);
388 etsec
->bh
= qemu_bh_new(etsec_timer_hit
, etsec
);
389 etsec
->ptimer
= ptimer_init(etsec
->bh
, PTIMER_POLICY_DEFAULT
);
390 ptimer_set_freq(etsec
->ptimer
, 100);
393 static void etsec_instance_init(Object
*obj
)
395 eTSEC
*etsec
= ETSEC_COMMON(obj
);
396 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
398 memory_region_init_io(&etsec
->io_area
, OBJECT(etsec
), &etsec_ops
, etsec
,
400 sysbus_init_mmio(sbd
, &etsec
->io_area
);
402 sysbus_init_irq(sbd
, &etsec
->tx_irq
);
403 sysbus_init_irq(sbd
, &etsec
->rx_irq
);
404 sysbus_init_irq(sbd
, &etsec
->err_irq
);
407 static Property etsec_properties
[] = {
408 DEFINE_NIC_PROPERTIES(eTSEC
, conf
),
409 DEFINE_PROP_END_OF_LIST(),
412 static void etsec_class_init(ObjectClass
*klass
, void *data
)
414 DeviceClass
*dc
= DEVICE_CLASS(klass
);
416 dc
->realize
= etsec_realize
;
417 dc
->reset
= etsec_reset
;
418 dc
->props
= etsec_properties
;
419 /* Supported by ppce500 machine */
420 dc
->user_creatable
= true;
423 static TypeInfo etsec_info
= {
425 .parent
= TYPE_SYS_BUS_DEVICE
,
426 .instance_size
= sizeof(eTSEC
),
427 .class_init
= etsec_class_init
,
428 .instance_init
= etsec_instance_init
,
431 static void etsec_register_types(void)
433 type_register_static(&etsec_info
);
436 type_init(etsec_register_types
)
438 DeviceState
*etsec_create(hwaddr base
,
447 dev
= qdev_create(NULL
, "eTSEC");
448 qdev_set_nic_properties(dev
, nd
);
449 qdev_init_nofail(dev
);
451 sysbus_connect_irq(SYS_BUS_DEVICE(dev
), 0, tx_irq
);
452 sysbus_connect_irq(SYS_BUS_DEVICE(dev
), 1, rx_irq
);
453 sysbus_connect_irq(SYS_BUS_DEVICE(dev
), 2, err_irq
);
455 memory_region_add_subregion(mr
, base
,
456 SYS_BUS_DEVICE(dev
)->mmio
[0].memory
);