1 /* 2 * QEMU Freescale eTSEC Emulator 3 * 4 * Copyright (c) 2011-2013 AdaCore 5 * 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: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 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 22 * THE SOFTWARE. 23 */ 24 25 /* 26 * This implementation doesn't include ring priority, TCP/IP Off-Load, QoS. 27 */ 28 29 #include "sysemu/sysemu.h" 30 #include "hw/sysbus.h" 31 #include "trace.h" 32 #include "hw/ptimer.h" 33 #include "etsec.h" 34 #include "registers.h" 35 36 /* #define HEX_DUMP */ 37 /* #define DEBUG_REGISTER */ 38 39 #ifdef DEBUG_REGISTER 40 static const int debug_etsec = 1; 41 #else 42 static const int debug_etsec; 43 #endif 44 45 #define DPRINTF(fmt, ...) do { \ 46 if (debug_etsec) { \ 47 qemu_log(fmt , ## __VA_ARGS__); \ 48 } \ 49 } while (0) 50 51 static uint64_t etsec_read(void *opaque, hwaddr addr, unsigned size) 52 { 53 eTSEC *etsec = opaque; 54 uint32_t reg_index = addr / 4; 55 eTSEC_Register *reg = NULL; 56 uint32_t ret = 0x0; 57 58 assert(reg_index < ETSEC_REG_NUMBER); 59 60 reg = &etsec->regs[reg_index]; 61 62 63 switch (reg->access) { 64 case ACC_WO: 65 ret = 0x00000000; 66 break; 67 68 case ACC_RW: 69 case ACC_W1C: 70 case ACC_RO: 71 default: 72 ret = reg->value; 73 break; 74 } 75 76 DPRINTF("Read 0x%08x @ 0x" TARGET_FMT_plx 77 " : %s (%s)\n", 78 ret, addr, reg->name, reg->desc); 79 80 return ret; 81 } 82 83 static void write_tstat(eTSEC *etsec, 84 eTSEC_Register *reg, 85 uint32_t reg_index, 86 uint32_t value) 87 { 88 int i = 0; 89 90 for (i = 0; i < 8; i++) { 91 /* Check THLTi flag in TSTAT */ 92 if (value & (1 << (31 - i))) { 93 etsec_walk_tx_ring(etsec, i); 94 } 95 } 96 97 /* Write 1 to clear */ 98 reg->value &= ~value; 99 } 100 101 static void write_rstat(eTSEC *etsec, 102 eTSEC_Register *reg, 103 uint32_t reg_index, 104 uint32_t value) 105 { 106 int i = 0; 107 108 for (i = 0; i < 8; i++) { 109 /* Check QHLTi flag in RSTAT */ 110 if (value & (1 << (23 - i)) && !(reg->value & (1 << (23 - i)))) { 111 etsec_walk_rx_ring(etsec, i); 112 } 113 } 114 115 /* Write 1 to clear */ 116 reg->value &= ~value; 117 } 118 119 static void write_tbasex(eTSEC *etsec, 120 eTSEC_Register *reg, 121 uint32_t reg_index, 122 uint32_t value) 123 { 124 reg->value = value & ~0x7; 125 126 /* Copy this value in the ring's TxBD pointer */ 127 etsec->regs[TBPTR0 + (reg_index - TBASE0)].value = value & ~0x7; 128 } 129 130 static void write_rbasex(eTSEC *etsec, 131 eTSEC_Register *reg, 132 uint32_t reg_index, 133 uint32_t value) 134 { 135 reg->value = value & ~0x7; 136 137 /* Copy this value in the ring's RxBD pointer */ 138 etsec->regs[RBPTR0 + (reg_index - RBASE0)].value = value & ~0x7; 139 } 140 141 static void write_ievent(eTSEC *etsec, 142 eTSEC_Register *reg, 143 uint32_t reg_index, 144 uint32_t value) 145 { 146 /* Write 1 to clear */ 147 reg->value &= ~value; 148 149 if (!(reg->value & (IEVENT_TXF | IEVENT_TXF))) { 150 qemu_irq_lower(etsec->tx_irq); 151 } 152 if (!(reg->value & (IEVENT_RXF | IEVENT_RXF))) { 153 qemu_irq_lower(etsec->rx_irq); 154 } 155 156 if (!(reg->value & (IEVENT_MAG | IEVENT_GTSC | IEVENT_GRSC | IEVENT_TXC | 157 IEVENT_RXC | IEVENT_BABR | IEVENT_BABT | IEVENT_LC | 158 IEVENT_CRL | IEVENT_FGPI | IEVENT_FIR | IEVENT_FIQ | 159 IEVENT_DPE | IEVENT_PERR | IEVENT_EBERR | IEVENT_TXE | 160 IEVENT_XFUN | IEVENT_BSY | IEVENT_MSRO | IEVENT_MMRD | 161 IEVENT_MMRW))) { 162 qemu_irq_lower(etsec->err_irq); 163 } 164 } 165 166 static void write_dmactrl(eTSEC *etsec, 167 eTSEC_Register *reg, 168 uint32_t reg_index, 169 uint32_t value) 170 { 171 reg->value = value; 172 173 if (value & DMACTRL_GRS) { 174 175 if (etsec->rx_buffer_len != 0) { 176 /* Graceful receive stop delayed until end of frame */ 177 } else { 178 /* Graceful receive stop now */ 179 etsec->regs[IEVENT].value |= IEVENT_GRSC; 180 if (etsec->regs[IMASK].value & IMASK_GRSCEN) { 181 qemu_irq_raise(etsec->err_irq); 182 } 183 } 184 } 185 186 if (value & DMACTRL_GTS) { 187 188 if (etsec->tx_buffer_len != 0) { 189 /* Graceful transmit stop delayed until end of frame */ 190 } else { 191 /* Graceful transmit stop now */ 192 etsec->regs[IEVENT].value |= IEVENT_GTSC; 193 if (etsec->regs[IMASK].value & IMASK_GTSCEN) { 194 qemu_irq_raise(etsec->err_irq); 195 } 196 } 197 } 198 199 if (!(value & DMACTRL_WOP)) { 200 /* Start polling */ 201 ptimer_stop(etsec->ptimer); 202 ptimer_set_count(etsec->ptimer, 1); 203 ptimer_run(etsec->ptimer, 1); 204 } 205 } 206 207 static void etsec_write(void *opaque, 208 hwaddr addr, 209 uint64_t value, 210 unsigned size) 211 { 212 eTSEC *etsec = opaque; 213 uint32_t reg_index = addr / 4; 214 eTSEC_Register *reg = NULL; 215 uint32_t before = 0x0; 216 217 assert(reg_index < ETSEC_REG_NUMBER); 218 219 reg = &etsec->regs[reg_index]; 220 before = reg->value; 221 222 switch (reg_index) { 223 case IEVENT: 224 write_ievent(etsec, reg, reg_index, value); 225 break; 226 227 case DMACTRL: 228 write_dmactrl(etsec, reg, reg_index, value); 229 break; 230 231 case TSTAT: 232 write_tstat(etsec, reg, reg_index, value); 233 break; 234 235 case RSTAT: 236 write_rstat(etsec, reg, reg_index, value); 237 break; 238 239 case TBASE0 ... TBASE7: 240 write_tbasex(etsec, reg, reg_index, value); 241 break; 242 243 case RBASE0 ... RBASE7: 244 write_rbasex(etsec, reg, reg_index, value); 245 break; 246 247 case MIIMCFG ... MIIMIND: 248 etsec_write_miim(etsec, reg, reg_index, value); 249 break; 250 251 default: 252 /* Default handling */ 253 switch (reg->access) { 254 255 case ACC_RW: 256 case ACC_WO: 257 reg->value = value; 258 break; 259 260 case ACC_W1C: 261 reg->value &= ~value; 262 break; 263 264 case ACC_RO: 265 default: 266 /* Read Only or Unknown register */ 267 break; 268 } 269 } 270 271 DPRINTF("Write 0x%08x @ 0x" TARGET_FMT_plx 272 " val:0x%08x->0x%08x : %s (%s)\n", 273 (unsigned int)value, addr, before, reg->value, 274 reg->name, reg->desc); 275 } 276 277 static const MemoryRegionOps etsec_ops = { 278 .read = etsec_read, 279 .write = etsec_write, 280 .endianness = DEVICE_NATIVE_ENDIAN, 281 .impl = { 282 .min_access_size = 4, 283 .max_access_size = 4, 284 }, 285 }; 286 287 static void etsec_timer_hit(void *opaque) 288 { 289 eTSEC *etsec = opaque; 290 291 ptimer_stop(etsec->ptimer); 292 293 if (!(etsec->regs[DMACTRL].value & DMACTRL_WOP)) { 294 295 if (!(etsec->regs[DMACTRL].value & DMACTRL_GTS)) { 296 etsec_walk_tx_ring(etsec, 0); 297 } 298 ptimer_set_count(etsec->ptimer, 1); 299 ptimer_run(etsec->ptimer, 1); 300 } 301 } 302 303 static void etsec_reset(DeviceState *d) 304 { 305 eTSEC *etsec = ETSEC_COMMON(d); 306 int i = 0; 307 int reg_index = 0; 308 309 /* Default value for all registers */ 310 for (i = 0; i < ETSEC_REG_NUMBER; i++) { 311 etsec->regs[i].name = "Reserved"; 312 etsec->regs[i].desc = ""; 313 etsec->regs[i].access = ACC_UNKNOWN; 314 etsec->regs[i].value = 0x00000000; 315 } 316 317 /* Set-up known registers */ 318 for (i = 0; eTSEC_registers_def[i].name != NULL; i++) { 319 320 reg_index = eTSEC_registers_def[i].offset / 4; 321 322 etsec->regs[reg_index].name = eTSEC_registers_def[i].name; 323 etsec->regs[reg_index].desc = eTSEC_registers_def[i].desc; 324 etsec->regs[reg_index].access = eTSEC_registers_def[i].access; 325 etsec->regs[reg_index].value = eTSEC_registers_def[i].reset; 326 } 327 328 etsec->tx_buffer = NULL; 329 etsec->tx_buffer_len = 0; 330 etsec->rx_buffer = NULL; 331 etsec->rx_buffer_len = 0; 332 333 etsec->phy_status = 334 MII_SR_EXTENDED_CAPS | MII_SR_LINK_STATUS | MII_SR_AUTONEG_CAPS | 335 MII_SR_AUTONEG_COMPLETE | MII_SR_PREAMBLE_SUPPRESS | 336 MII_SR_EXTENDED_STATUS | MII_SR_100T2_HD_CAPS | MII_SR_100T2_FD_CAPS | 337 MII_SR_10T_HD_CAPS | MII_SR_10T_FD_CAPS | MII_SR_100X_HD_CAPS | 338 MII_SR_100X_FD_CAPS | MII_SR_100T4_CAPS; 339 } 340 341 static void etsec_cleanup(NetClientState *nc) 342 { 343 /* qemu_log("eTSEC cleanup\n"); */ 344 } 345 346 static int etsec_can_receive(NetClientState *nc) 347 { 348 eTSEC *etsec = qemu_get_nic_opaque(nc); 349 350 return etsec->rx_buffer_len == 0; 351 } 352 353 static ssize_t etsec_receive(NetClientState *nc, 354 const uint8_t *buf, 355 size_t size) 356 { 357 eTSEC *etsec = qemu_get_nic_opaque(nc); 358 359 #if defined(HEX_DUMP) 360 fprintf(stderr, "%s receive size:%d\n", etsec->nic->nc.name, size); 361 qemu_hexdump(buf, stderr, "", size); 362 #endif 363 etsec_rx_ring_write(etsec, buf, size); 364 return size; 365 } 366 367 368 static void etsec_set_link_status(NetClientState *nc) 369 { 370 eTSEC *etsec = qemu_get_nic_opaque(nc); 371 372 etsec_miim_link_status(etsec, nc); 373 } 374 375 static NetClientInfo net_etsec_info = { 376 .type = NET_CLIENT_OPTIONS_KIND_NIC, 377 .size = sizeof(NICState), 378 .can_receive = etsec_can_receive, 379 .receive = etsec_receive, 380 .cleanup = etsec_cleanup, 381 .link_status_changed = etsec_set_link_status, 382 }; 383 384 static void etsec_realize(DeviceState *dev, Error **errp) 385 { 386 eTSEC *etsec = ETSEC_COMMON(dev); 387 388 etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf, 389 object_get_typename(OBJECT(dev)), dev->id, etsec); 390 qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a); 391 392 393 etsec->bh = qemu_bh_new(etsec_timer_hit, etsec); 394 etsec->ptimer = ptimer_init(etsec->bh); 395 ptimer_set_freq(etsec->ptimer, 100); 396 } 397 398 static void etsec_instance_init(Object *obj) 399 { 400 eTSEC *etsec = ETSEC_COMMON(obj); 401 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 402 403 memory_region_init_io(&etsec->io_area, OBJECT(etsec), &etsec_ops, etsec, 404 "eTSEC", 0x1000); 405 sysbus_init_mmio(sbd, &etsec->io_area); 406 407 sysbus_init_irq(sbd, &etsec->tx_irq); 408 sysbus_init_irq(sbd, &etsec->rx_irq); 409 sysbus_init_irq(sbd, &etsec->err_irq); 410 } 411 412 static Property etsec_properties[] = { 413 DEFINE_NIC_PROPERTIES(eTSEC, conf), 414 DEFINE_PROP_END_OF_LIST(), 415 }; 416 417 static void etsec_class_init(ObjectClass *klass, void *data) 418 { 419 DeviceClass *dc = DEVICE_CLASS(klass); 420 421 dc->realize = etsec_realize; 422 dc->reset = etsec_reset; 423 dc->props = etsec_properties; 424 } 425 426 static TypeInfo etsec_info = { 427 .name = "eTSEC", 428 .parent = TYPE_SYS_BUS_DEVICE, 429 .instance_size = sizeof(eTSEC), 430 .class_init = etsec_class_init, 431 .instance_init = etsec_instance_init, 432 }; 433 434 static void etsec_register_types(void) 435 { 436 type_register_static(&etsec_info); 437 } 438 439 type_init(etsec_register_types) 440 441 DeviceState *etsec_create(hwaddr base, 442 MemoryRegion * mr, 443 NICInfo * nd, 444 qemu_irq tx_irq, 445 qemu_irq rx_irq, 446 qemu_irq err_irq) 447 { 448 DeviceState *dev; 449 450 dev = qdev_create(NULL, "eTSEC"); 451 qdev_set_nic_properties(dev, nd); 452 453 if (qdev_init(dev)) { 454 return NULL; 455 } 456 457 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, tx_irq); 458 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, rx_irq); 459 sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, err_irq); 460 461 memory_region_add_subregion(mr, base, 462 SYS_BUS_DEVICE(dev)->mmio[0].memory); 463 464 return dev; 465 } 466