Lines Matching full:emc

2  * Nuvoton NPCM7xx EMC Module
98 static void emc_reset(NPCM7xxEMCState *emc) in emc_reset() argument
102 trace_npcm7xx_emc_reset(emc->emc_num); in emc_reset()
104 memset(&emc->regs[0], 0, sizeof(emc->regs)); in emc_reset()
107 emc->regs[REG_TXDLSA] = 0xfffffffc; in emc_reset()
108 emc->regs[REG_RXDLSA] = 0xfffffffc; in emc_reset()
109 emc->regs[REG_MIIDA] = 0x00900000; in emc_reset()
110 emc->regs[REG_FFTCR] = 0x0101; in emc_reset()
111 emc->regs[REG_DMARFC] = 0x0800; in emc_reset()
112 emc->regs[REG_MPCNT] = 0x7fff; in emc_reset()
114 emc->tx_active = false; in emc_reset()
115 emc->rx_active = false; in emc_reset()
118 value = (emc->conf.macaddr.a[0] << 24) | in emc_reset()
119 (emc->conf.macaddr.a[1] << 16) | in emc_reset()
120 (emc->conf.macaddr.a[2] << 8) | in emc_reset()
121 emc->conf.macaddr.a[3]; in emc_reset()
122 emc->regs[REG_CAMM_BASE] = value; in emc_reset()
124 value = (emc->conf.macaddr.a[4] << 24) | (emc->conf.macaddr.a[5] << 16); in emc_reset()
125 emc->regs[REG_CAML_BASE] = value; in emc_reset()
130 NPCM7xxEMCState *emc = NPCM7XX_EMC(dev); in npcm7xx_emc_reset() local
131 emc_reset(emc); in npcm7xx_emc_reset()
134 static void emc_soft_reset(NPCM7xxEMCState *emc) in emc_soft_reset() argument
140 uint32_t mcmdr = emc->regs[REG_MCMDR]; in emc_soft_reset()
141 emc_reset(emc); in emc_soft_reset()
142 emc->regs[REG_MCMDR] = mcmdr & (REG_MCMDR_LBK | REG_MCMDR_OPMOD); in emc_soft_reset()
144 qemu_set_irq(emc->tx_irq, 0); in emc_soft_reset()
145 qemu_set_irq(emc->rx_irq, 0); in emc_soft_reset()
154 static void emc_update_mista_txintr(NPCM7xxEMCState *emc) in emc_update_mista_txintr() argument
160 if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & mask) { in emc_update_mista_txintr()
161 emc->regs[REG_MISTA] |= REG_MISTA_TXINTR; in emc_update_mista_txintr()
163 emc->regs[REG_MISTA] &= ~REG_MISTA_TXINTR; in emc_update_mista_txintr()
168 static void emc_update_mista_rxintr(NPCM7xxEMCState *emc) in emc_update_mista_rxintr() argument
174 if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & mask) { in emc_update_mista_rxintr()
175 emc->regs[REG_MISTA] |= REG_MISTA_RXINTR; in emc_update_mista_rxintr()
177 emc->regs[REG_MISTA] &= ~REG_MISTA_RXINTR; in emc_update_mista_rxintr()
182 static void emc_update_tx_irq(NPCM7xxEMCState *emc) in emc_update_tx_irq() argument
184 int level = !!(emc->regs[REG_MISTA] & in emc_update_tx_irq()
185 emc->regs[REG_MIEN] & in emc_update_tx_irq()
188 qemu_set_irq(emc->tx_irq, level); in emc_update_tx_irq()
192 static void emc_update_rx_irq(NPCM7xxEMCState *emc) in emc_update_rx_irq() argument
194 int level = !!(emc->regs[REG_MISTA] & in emc_update_rx_irq()
195 emc->regs[REG_MIEN] & in emc_update_rx_irq()
198 qemu_set_irq(emc->rx_irq, level); in emc_update_rx_irq()
202 static void emc_update_irq_from_reg_change(NPCM7xxEMCState *emc) in emc_update_irq_from_reg_change() argument
204 emc_update_mista_txintr(emc); in emc_update_irq_from_reg_change()
205 emc_update_tx_irq(emc); in emc_update_irq_from_reg_change()
207 emc_update_mista_rxintr(emc); in emc_update_irq_from_reg_change()
208 emc_update_rx_irq(emc); in emc_update_irq_from_reg_change()
275 static void emc_set_mista(NPCM7xxEMCState *emc, uint32_t flags) in emc_set_mista() argument
278 emc->regs[REG_MISTA] |= flags; in emc_set_mista()
280 emc_update_mista_txintr(emc); in emc_set_mista()
283 emc_update_mista_rxintr(emc); in emc_set_mista()
287 static void emc_halt_tx(NPCM7xxEMCState *emc, uint32_t mista_flag) in emc_halt_tx() argument
289 emc->tx_active = false; in emc_halt_tx()
290 emc_set_mista(emc, mista_flag); in emc_halt_tx()
293 static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag) in emc_halt_rx() argument
295 emc->rx_active = false; in emc_halt_rx()
296 emc_set_mista(emc, mista_flag); in emc_halt_rx()
299 static void emc_enable_rx_and_flush(NPCM7xxEMCState *emc) in emc_enable_rx_and_flush() argument
301 emc->rx_active = true; in emc_enable_rx_and_flush()
302 qemu_flush_queued_packets(qemu_get_queue(emc->nic)); in emc_enable_rx_and_flush()
305 static void emc_set_next_tx_descriptor(NPCM7xxEMCState *emc, in emc_set_next_tx_descriptor() argument
315 emc_set_mista(emc, REG_MISTA_TXBERR); in emc_set_next_tx_descriptor()
317 emc->regs[REG_CTXDSA] = TX_DESC_NTXDSA(tx_desc->ntxdsa); in emc_set_next_tx_descriptor()
320 static void emc_set_next_rx_descriptor(NPCM7xxEMCState *emc, in emc_set_next_rx_descriptor() argument
330 emc_set_mista(emc, REG_MISTA_RXBERR); in emc_set_next_rx_descriptor()
332 emc->regs[REG_CRXDSA] = RX_DESC_NRXDSA(rx_desc->nrxdsa); in emc_set_next_rx_descriptor()
335 static void emc_try_send_next_packet(NPCM7xxEMCState *emc) in emc_try_send_next_packet() argument
340 uint32_t desc_addr = TX_DESC_NTXDSA(emc->regs[REG_CTXDSA]); in emc_try_send_next_packet()
348 emc_halt_tx(emc, REG_MISTA_TXBERR); in emc_try_send_next_packet()
349 emc_update_tx_irq(emc); in emc_try_send_next_packet()
356 emc_halt_tx(emc, REG_MISTA_TDU); in emc_try_send_next_packet()
357 emc_update_tx_irq(emc); in emc_try_send_next_packet()
372 emc->regs[REG_CTXBSA] = next_buf_addr; in emc_try_send_next_packet()
385 emc_set_mista(emc, REG_MISTA_TXBERR); in emc_try_send_next_packet()
386 emc_set_next_tx_descriptor(emc, &tx_desc, desc_addr); in emc_try_send_next_packet()
387 emc_update_tx_irq(emc); in emc_try_send_next_packet()
388 trace_npcm7xx_emc_tx_done(emc->regs[REG_CTXDSA]); in emc_try_send_next_packet()
398 qemu_send_packet(qemu_get_queue(emc->nic), buf, length); in emc_try_send_next_packet()
403 emc_set_mista(emc, REG_MISTA_TXCP); in emc_try_send_next_packet()
405 if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & REG_MISTA_TXINTR) { in emc_try_send_next_packet()
409 emc_set_next_tx_descriptor(emc, &tx_desc, desc_addr); in emc_try_send_next_packet()
410 emc_update_tx_irq(emc); in emc_try_send_next_packet()
411 trace_npcm7xx_emc_tx_done(emc->regs[REG_CTXDSA]); in emc_try_send_next_packet()
416 NPCM7xxEMCState *emc = NPCM7XX_EMC(qemu_get_nic_opaque(nc)); in emc_can_receive() local
418 bool can_receive = emc->rx_active; in emc_can_receive()
424 static bool emc_receive_filter1(NPCM7xxEMCState *emc, const uint8_t *buf, in emc_receive_filter1() argument
431 if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) { in emc_receive_filter1()
435 return !!(emc->regs[REG_CAMCMR] & REG_CAMCMR_ABP); in emc_receive_filter1()
438 if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) { in emc_receive_filter1()
442 return !!(emc->regs[REG_CAMCMR] & REG_CAMCMR_AMP); in emc_receive_filter1()
448 if (emc->regs[REG_CAMCMR] & REG_CAMCMR_AUP) { in emc_receive_filter1()
452 value = emc->regs[REG_CAMM_BASE]; in emc_receive_filter1()
457 value = emc->regs[REG_CAML_BASE]; in emc_receive_filter1()
461 matches = ((emc->regs[REG_CAMCMR] & REG_CAMCMR_ECMP) && in emc_receive_filter1()
463 (emc->regs[REG_CAMEN] & (1 << 0)) && in emc_receive_filter1()
465 if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) { in emc_receive_filter1()
478 static bool emc_receive_filter(NPCM7xxEMCState *emc, const uint8_t *buf, in emc_receive_filter() argument
482 bool ok = emc_receive_filter1(emc, buf, len, &fail_reason); in emc_receive_filter()
491 NPCM7xxEMCState *emc = NPCM7XX_EMC(qemu_get_nic_opaque(nc)); in emc_receive() local
517 * DENI is set if EMC received the Length/Type field of the incoming in emc_receive()
520 emc_set_mista(emc, REG_MISTA_DENI); in emc_receive()
522 if (!emc_receive_filter(emc, buf, len)) { in emc_receive()
523 emc_update_rx_irq(emc); in emc_receive()
528 max_frame_len = REG_DMARFC_RXMS(emc->regs[REG_DMARFC]); in emc_receive()
531 emc_set_mista(emc, REG_MISTA_DFOI); in emc_receive()
532 emc_update_rx_irq(emc); in emc_receive()
542 if (emc->regs[REG_MCMDR] & REG_MCMDR_ALP) { in emc_receive()
546 emc_set_mista(emc, REG_MISTA_PTLE); in emc_receive()
547 emc_update_rx_irq(emc); in emc_receive()
552 desc_addr = RX_DESC_NRXDSA(emc->regs[REG_CRXDSA]); in emc_receive()
555 emc_halt_rx(emc, REG_MISTA_RXBERR); in emc_receive()
556 emc_update_rx_irq(emc); in emc_receive()
563 emc_halt_rx(emc, REG_MISTA_RDU); in emc_receive()
564 emc_update_rx_irq(emc); in emc_receive()
570 if (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC)) { in emc_receive()
578 emc->regs[REG_CRXBSA] = buf_addr; in emc_receive()
581 (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC) && in emc_receive()
586 emc_set_mista(emc, REG_MISTA_RXBERR); in emc_receive()
587 emc_set_next_rx_descriptor(emc, &rx_desc, desc_addr); in emc_receive()
588 emc_update_rx_irq(emc); in emc_receive()
589 trace_npcm7xx_emc_rx_done(emc->regs[REG_CRXDSA]); in emc_receive()
597 if (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC)) { in emc_receive()
601 emc_set_mista(emc, REG_MISTA_RXGD); in emc_receive()
603 if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & REG_MISTA_RXINTR) { in emc_receive()
610 emc_set_next_rx_descriptor(emc, &rx_desc, desc_addr); in emc_receive()
611 emc_update_rx_irq(emc); in emc_receive()
612 trace_npcm7xx_emc_rx_done(emc->regs[REG_CRXDSA]); in emc_receive()
618 NPCM7xxEMCState *emc = opaque; in npcm7xx_emc_read() local
645 result = emc->regs[reg]; in npcm7xx_emc_read()
649 trace_npcm7xx_emc_reg_read(emc->emc_num, result, emc_reg_name(reg), reg); in npcm7xx_emc_read()
656 NPCM7xxEMCState *emc = opaque; in npcm7xx_emc_write() local
669 trace_npcm7xx_emc_reg_write(emc->emc_num, emc_reg_name(reg), reg, value); in npcm7xx_emc_write()
673 emc->regs[reg] = value; in npcm7xx_emc_write()
683 emc->regs[reg] = value & 1; in npcm7xx_emc_write()
686 emc->regs[reg] = value; in npcm7xx_emc_write()
689 emc->regs[reg] = value; in npcm7xx_emc_write()
694 emc_soft_reset(emc); in npcm7xx_emc_write()
698 prev = emc->regs[reg]; in npcm7xx_emc_write()
699 emc->regs[reg] = value; in npcm7xx_emc_write()
703 emc->regs[REG_CTXDSA] = emc->regs[REG_TXDLSA]; in npcm7xx_emc_write()
711 emc->regs[REG_MGSTA] |= REG_MGSTA_TXHA; in npcm7xx_emc_write()
714 emc_halt_tx(emc, 0); in npcm7xx_emc_write()
719 emc->regs[REG_CRXDSA] = emc->regs[REG_RXDLSA]; in npcm7xx_emc_write()
722 emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA; in npcm7xx_emc_write()
725 emc_enable_rx_and_flush(emc); in npcm7xx_emc_write()
727 emc_halt_rx(emc, 0); in npcm7xx_emc_write()
735 emc->regs[reg] = value; in npcm7xx_emc_write()
738 emc->regs[reg] = value; in npcm7xx_emc_write()
739 emc_update_irq_from_reg_change(emc); in npcm7xx_emc_write()
743 emc->regs[reg] &= ~value; in npcm7xx_emc_write()
744 emc_update_irq_from_reg_change(emc); in npcm7xx_emc_write()
748 emc->regs[reg] &= ~value; in npcm7xx_emc_write()
751 if (emc->regs[REG_MCMDR] & REG_MCMDR_TXON) { in npcm7xx_emc_write()
752 emc->tx_active = true; in npcm7xx_emc_write()
754 while (emc->tx_active) { in npcm7xx_emc_write()
755 emc_try_send_next_packet(emc); in npcm7xx_emc_write()
760 if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) { in npcm7xx_emc_write()
761 emc_enable_rx_and_flush(emc); in npcm7xx_emc_write()
765 emc->regs[reg] = value & ~REG_MIIDA_BUSY; in npcm7xx_emc_write()
812 NPCM7xxEMCState *emc = NPCM7XX_EMC(dev); in npcm7xx_emc_realize() local
813 SysBusDevice *sbd = SYS_BUS_DEVICE(emc); in npcm7xx_emc_realize()
815 memory_region_init_io(&emc->iomem, OBJECT(emc), &npcm7xx_emc_ops, emc, in npcm7xx_emc_realize()
817 sysbus_init_mmio(sbd, &emc->iomem); in npcm7xx_emc_realize()
818 sysbus_init_irq(sbd, &emc->tx_irq); in npcm7xx_emc_realize()
819 sysbus_init_irq(sbd, &emc->rx_irq); in npcm7xx_emc_realize()
821 qemu_macaddr_default_if_unset(&emc->conf.macaddr); in npcm7xx_emc_realize()
822 emc->nic = qemu_new_nic(&net_npcm7xx_emc_info, &emc->conf, in npcm7xx_emc_realize()
824 &dev->mem_reentrancy_guard, emc); in npcm7xx_emc_realize()
825 qemu_format_nic_info_str(qemu_get_queue(emc->nic), emc->conf.macaddr.a); in npcm7xx_emc_realize()
830 NPCM7xxEMCState *emc = NPCM7XX_EMC(dev); in npcm7xx_emc_unrealize() local
832 qemu_del_nic(emc->nic); in npcm7xx_emc_unrealize()
858 dc->desc = "NPCM7xx EMC Controller"; in npcm7xx_emc_class_init()