PageRenderTime 54ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/hw/net/fsl_etsec/etsec.c

https://gitlab.com/storedmirrors/qemu
C | 468 lines | 332 code | 87 blank | 49 comment | 26 complexity | 5f7211aa10f2d095adea11967e7c7f3f MD5 | raw file
  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. * This implementation doesn't include ring priority, TCP/IP Off-Load, QoS.
  26. */
  27. #include "qemu/osdep.h"
  28. #include "hw/sysbus.h"
  29. #include "hw/irq.h"
  30. #include "hw/ptimer.h"
  31. #include "hw/qdev-properties.h"
  32. #include "etsec.h"
  33. #include "registers.h"
  34. #include "qapi/error.h"
  35. #include "qemu/log.h"
  36. #include "qemu/module.h"
  37. /* #define HEX_DUMP */
  38. /* #define DEBUG_REGISTER */
  39. #ifdef DEBUG_REGISTER
  40. static const int debug_etsec = 1;
  41. #else
  42. static const int debug_etsec;
  43. #endif
  44. #define DPRINTF(fmt, ...) do { \
  45. if (debug_etsec) { \
  46. qemu_log(fmt , ## __VA_ARGS__); \
  47. } \
  48. } while (0)
  49. /* call after any change to IEVENT or IMASK */
  50. void etsec_update_irq(eTSEC *etsec)
  51. {
  52. uint32_t ievent = etsec->regs[IEVENT].value;
  53. uint32_t imask = etsec->regs[IMASK].value;
  54. uint32_t active = ievent & imask;
  55. int tx = !!(active & IEVENT_TX_MASK);
  56. int rx = !!(active & IEVENT_RX_MASK);
  57. int err = !!(active & IEVENT_ERR_MASK);
  58. DPRINTF("%s IRQ ievent=%"PRIx32" imask=%"PRIx32" %c%c%c",
  59. __func__, ievent, imask,
  60. tx ? 'T' : '_',
  61. rx ? 'R' : '_',
  62. err ? 'E' : '_');
  63. qemu_set_irq(etsec->tx_irq, tx);
  64. qemu_set_irq(etsec->rx_irq, rx);
  65. qemu_set_irq(etsec->err_irq, err);
  66. }
  67. static uint64_t etsec_read(void *opaque, hwaddr addr, unsigned size)
  68. {
  69. eTSEC *etsec = opaque;
  70. uint32_t reg_index = addr / 4;
  71. eTSEC_Register *reg = NULL;
  72. uint32_t ret = 0x0;
  73. assert(reg_index < ETSEC_REG_NUMBER);
  74. reg = &etsec->regs[reg_index];
  75. switch (reg->access) {
  76. case ACC_WO:
  77. ret = 0x00000000;
  78. break;
  79. case ACC_RW:
  80. case ACC_W1C:
  81. case ACC_RO:
  82. default:
  83. ret = reg->value;
  84. break;
  85. }
  86. DPRINTF("Read 0x%08x @ 0x" TARGET_FMT_plx
  87. " : %s (%s)\n",
  88. ret, addr, reg->name, reg->desc);
  89. return ret;
  90. }
  91. static void write_tstat(eTSEC *etsec,
  92. eTSEC_Register *reg,
  93. uint32_t reg_index,
  94. uint32_t value)
  95. {
  96. int i = 0;
  97. for (i = 0; i < 8; i++) {
  98. /* Check THLTi flag in TSTAT */
  99. if (value & (1 << (31 - i))) {
  100. etsec_walk_tx_ring(etsec, i);
  101. }
  102. }
  103. /* Write 1 to clear */
  104. reg->value &= ~value;
  105. }
  106. static void write_rstat(eTSEC *etsec,
  107. eTSEC_Register *reg,
  108. uint32_t reg_index,
  109. uint32_t value)
  110. {
  111. int i = 0;
  112. for (i = 0; i < 8; i++) {
  113. /* Check QHLTi flag in RSTAT */
  114. if (value & (1 << (23 - i)) && !(reg->value & (1 << (23 - i)))) {
  115. etsec_walk_rx_ring(etsec, i);
  116. }
  117. }
  118. /* Write 1 to clear */
  119. reg->value &= ~value;
  120. }
  121. static void write_tbasex(eTSEC *etsec,
  122. eTSEC_Register *reg,
  123. uint32_t reg_index,
  124. uint32_t value)
  125. {
  126. reg->value = value & ~0x7;
  127. /* Copy this value in the ring's TxBD pointer */
  128. etsec->regs[TBPTR0 + (reg_index - TBASE0)].value = value & ~0x7;
  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. /* Copy this value in the ring's RxBD pointer */
  137. etsec->regs[RBPTR0 + (reg_index - RBASE0)].value = value & ~0x7;
  138. }
  139. static void write_dmactrl(eTSEC *etsec,
  140. eTSEC_Register *reg,
  141. uint32_t reg_index,
  142. uint32_t value)
  143. {
  144. reg->value = value;
  145. if (value & DMACTRL_GRS) {
  146. if (etsec->rx_buffer_len != 0) {
  147. /* Graceful receive stop delayed until end of frame */
  148. } else {
  149. /* Graceful receive stop now */
  150. etsec->regs[IEVENT].value |= IEVENT_GRSC;
  151. etsec_update_irq(etsec);
  152. }
  153. }
  154. if (value & DMACTRL_GTS) {
  155. if (etsec->tx_buffer_len != 0) {
  156. /* Graceful transmit stop delayed until end of frame */
  157. } else {
  158. /* Graceful transmit stop now */
  159. etsec->regs[IEVENT].value |= IEVENT_GTSC;
  160. etsec_update_irq(etsec);
  161. }
  162. }
  163. if (!(value & DMACTRL_WOP)) {
  164. /* Start polling */
  165. ptimer_transaction_begin(etsec->ptimer);
  166. ptimer_stop(etsec->ptimer);
  167. ptimer_set_count(etsec->ptimer, 1);
  168. ptimer_run(etsec->ptimer, 1);
  169. ptimer_transaction_commit(etsec->ptimer);
  170. }
  171. }
  172. static void etsec_write(void *opaque,
  173. hwaddr addr,
  174. uint64_t value,
  175. unsigned size)
  176. {
  177. eTSEC *etsec = opaque;
  178. uint32_t reg_index = addr / 4;
  179. eTSEC_Register *reg = NULL;
  180. uint32_t before = 0x0;
  181. assert(reg_index < ETSEC_REG_NUMBER);
  182. reg = &etsec->regs[reg_index];
  183. before = reg->value;
  184. switch (reg_index) {
  185. case IEVENT:
  186. /* Write 1 to clear */
  187. reg->value &= ~value;
  188. etsec_update_irq(etsec);
  189. break;
  190. case IMASK:
  191. reg->value = value;
  192. etsec_update_irq(etsec);
  193. break;
  194. case DMACTRL:
  195. write_dmactrl(etsec, reg, reg_index, value);
  196. break;
  197. case TSTAT:
  198. write_tstat(etsec, reg, reg_index, value);
  199. break;
  200. case RSTAT:
  201. write_rstat(etsec, reg, reg_index, value);
  202. break;
  203. case TBASE0 ... TBASE7:
  204. write_tbasex(etsec, reg, reg_index, value);
  205. break;
  206. case RBASE0 ... RBASE7:
  207. write_rbasex(etsec, reg, reg_index, value);
  208. break;
  209. case MIIMCFG ... MIIMIND:
  210. etsec_write_miim(etsec, reg, reg_index, value);
  211. break;
  212. default:
  213. /* Default handling */
  214. switch (reg->access) {
  215. case ACC_RW:
  216. case ACC_WO:
  217. reg->value = value;
  218. break;
  219. case ACC_W1C:
  220. reg->value &= ~value;
  221. break;
  222. case ACC_RO:
  223. default:
  224. /* Read Only or Unknown register */
  225. break;
  226. }
  227. }
  228. DPRINTF("Write 0x%08x @ 0x" TARGET_FMT_plx
  229. " val:0x%08x->0x%08x : %s (%s)\n",
  230. (unsigned int)value, addr, before, reg->value,
  231. reg->name, reg->desc);
  232. }
  233. static const MemoryRegionOps etsec_ops = {
  234. .read = etsec_read,
  235. .write = etsec_write,
  236. .endianness = DEVICE_NATIVE_ENDIAN,
  237. .impl = {
  238. .min_access_size = 4,
  239. .max_access_size = 4,
  240. },
  241. };
  242. static void etsec_timer_hit(void *opaque)
  243. {
  244. eTSEC *etsec = opaque;
  245. ptimer_stop(etsec->ptimer);
  246. if (!(etsec->regs[DMACTRL].value & DMACTRL_WOP)) {
  247. if (!(etsec->regs[DMACTRL].value & DMACTRL_GTS)) {
  248. etsec_walk_tx_ring(etsec, 0);
  249. }
  250. ptimer_set_count(etsec->ptimer, 1);
  251. ptimer_run(etsec->ptimer, 1);
  252. }
  253. }
  254. static void etsec_reset(DeviceState *d)
  255. {
  256. eTSEC *etsec = ETSEC_COMMON(d);
  257. int i = 0;
  258. int reg_index = 0;
  259. /* Default value for all registers */
  260. for (i = 0; i < ETSEC_REG_NUMBER; i++) {
  261. etsec->regs[i].name = "Reserved";
  262. etsec->regs[i].desc = "";
  263. etsec->regs[i].access = ACC_UNKNOWN;
  264. etsec->regs[i].value = 0x00000000;
  265. }
  266. /* Set-up known registers */
  267. for (i = 0; eTSEC_registers_def[i].name != NULL; i++) {
  268. reg_index = eTSEC_registers_def[i].offset / 4;
  269. etsec->regs[reg_index].name = eTSEC_registers_def[i].name;
  270. etsec->regs[reg_index].desc = eTSEC_registers_def[i].desc;
  271. etsec->regs[reg_index].access = eTSEC_registers_def[i].access;
  272. etsec->regs[reg_index].value = eTSEC_registers_def[i].reset;
  273. }
  274. etsec->tx_buffer = NULL;
  275. etsec->tx_buffer_len = 0;
  276. etsec->rx_buffer = NULL;
  277. etsec->rx_buffer_len = 0;
  278. etsec->phy_status =
  279. MII_SR_EXTENDED_CAPS | MII_SR_LINK_STATUS | MII_SR_AUTONEG_CAPS |
  280. MII_SR_AUTONEG_COMPLETE | MII_SR_PREAMBLE_SUPPRESS |
  281. MII_SR_EXTENDED_STATUS | MII_SR_100T2_HD_CAPS | MII_SR_100T2_FD_CAPS |
  282. MII_SR_10T_HD_CAPS | MII_SR_10T_FD_CAPS | MII_SR_100X_HD_CAPS |
  283. MII_SR_100X_FD_CAPS | MII_SR_100T4_CAPS;
  284. etsec_update_irq(etsec);
  285. }
  286. static ssize_t etsec_receive(NetClientState *nc,
  287. const uint8_t *buf,
  288. size_t size)
  289. {
  290. ssize_t ret;
  291. eTSEC *etsec = qemu_get_nic_opaque(nc);
  292. #if defined(HEX_DUMP)
  293. fprintf(stderr, "%s receive size:%zd\n", nc->name, size);
  294. qemu_hexdump(stderr, "", buf, size);
  295. #endif
  296. /* Flush is unnecessary as are already in receiving path */
  297. etsec->need_flush = false;
  298. ret = etsec_rx_ring_write(etsec, buf, size);
  299. if (ret == 0) {
  300. /* The packet will be queued, let's flush it when buffer is available
  301. * again. */
  302. etsec->need_flush = true;
  303. }
  304. return ret;
  305. }
  306. static void etsec_set_link_status(NetClientState *nc)
  307. {
  308. eTSEC *etsec = qemu_get_nic_opaque(nc);
  309. etsec_miim_link_status(etsec, nc);
  310. }
  311. static NetClientInfo net_etsec_info = {
  312. .type = NET_CLIENT_DRIVER_NIC,
  313. .size = sizeof(NICState),
  314. .receive = etsec_receive,
  315. .link_status_changed = etsec_set_link_status,
  316. };
  317. static void etsec_realize(DeviceState *dev, Error **errp)
  318. {
  319. eTSEC *etsec = ETSEC_COMMON(dev);
  320. etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf,
  321. object_get_typename(OBJECT(dev)), dev->id, etsec);
  322. qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a);
  323. etsec->ptimer = ptimer_init(etsec_timer_hit, etsec, PTIMER_POLICY_LEGACY);
  324. ptimer_transaction_begin(etsec->ptimer);
  325. ptimer_set_freq(etsec->ptimer, 100);
  326. ptimer_transaction_commit(etsec->ptimer);
  327. }
  328. static void etsec_instance_init(Object *obj)
  329. {
  330. eTSEC *etsec = ETSEC_COMMON(obj);
  331. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  332. memory_region_init_io(&etsec->io_area, OBJECT(etsec), &etsec_ops, etsec,
  333. "eTSEC", 0x1000);
  334. sysbus_init_mmio(sbd, &etsec->io_area);
  335. sysbus_init_irq(sbd, &etsec->tx_irq);
  336. sysbus_init_irq(sbd, &etsec->rx_irq);
  337. sysbus_init_irq(sbd, &etsec->err_irq);
  338. }
  339. static Property etsec_properties[] = {
  340. DEFINE_NIC_PROPERTIES(eTSEC, conf),
  341. DEFINE_PROP_END_OF_LIST(),
  342. };
  343. static void etsec_class_init(ObjectClass *klass, void *data)
  344. {
  345. DeviceClass *dc = DEVICE_CLASS(klass);
  346. dc->realize = etsec_realize;
  347. dc->reset = etsec_reset;
  348. device_class_set_props(dc, etsec_properties);
  349. /* Supported by ppce500 machine */
  350. dc->user_creatable = true;
  351. }
  352. static const TypeInfo etsec_info = {
  353. .name = TYPE_ETSEC_COMMON,
  354. .parent = TYPE_SYS_BUS_DEVICE,
  355. .instance_size = sizeof(eTSEC),
  356. .class_init = etsec_class_init,
  357. .instance_init = etsec_instance_init,
  358. };
  359. static void etsec_register_types(void)
  360. {
  361. type_register_static(&etsec_info);
  362. }
  363. type_init(etsec_register_types)
  364. DeviceState *etsec_create(hwaddr base,
  365. MemoryRegion * mr,
  366. NICInfo * nd,
  367. qemu_irq tx_irq,
  368. qemu_irq rx_irq,
  369. qemu_irq err_irq)
  370. {
  371. DeviceState *dev;
  372. dev = qdev_new("eTSEC");
  373. qdev_set_nic_properties(dev, nd);
  374. sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
  375. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, tx_irq);
  376. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, rx_irq);
  377. sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, err_irq);
  378. memory_region_add_subregion(mr, base,
  379. SYS_BUS_DEVICE(dev)->mmio[0].memory);
  380. return dev;
  381. }