Lines Matching +full:dma +full:- +full:poll +full:- +full:cnt
4 * Copyright (C) 2016-2017, IBM Corporation.
11 * COPYING file in the top-level directory.
17 #include "sysemu/dma.h"
24 #include "hw/qdev-properties.h"
61 * values below are offset by - FTGMAC100_REG_HIGH_OFFSET from datasheet
64 #define FTGMAC100_NPTXR_BADR_HIGH (0x17C - FTGMAC100_REG_HIGH_OFFSET)
65 #define FTGMAC100_HPTXR_BADR_HIGH (0x184 - FTGMAC100_REG_HIGH_OFFSET)
66 #define FTGMAC100_RXR_BADR_HIGH (0x18C - FTGMAC100_REG_HIGH_OFFSET)
92 * DMA burst length and arbitration control register
117 * PHY control register - New MDC/MDIO interface
220 uint32_t des2; /* used by HW 64 bits DMA */
262 int max = (s->maccr & FTGMAC100_MACCR_JUMBO_LF ? 9216 : 1518); in ftgmac100_max_frame_size()
269 qemu_set_irq(s->irq, s->isr & s->ier); in ftgmac100_update_irq()
276 * have to poll for the PHY status.
286 if (qemu_get_queue(s->nic)->link_down) { in phy_update_link()
287 s->phy_status &= ~(MII_BMSR_LINK_ST | MII_BMSR_AN_COMP); in phy_update_link()
288 s->phy_int |= PHY_INT_DOWN; in phy_update_link()
290 s->phy_status |= (MII_BMSR_LINK_ST | MII_BMSR_AN_COMP); in phy_update_link()
291 s->phy_int |= PHY_INT_AUTONEG_COMPLETE; in phy_update_link()
303 s->phy_status = (MII_BMSR_100TX_FD | MII_BMSR_100TX_HD | MII_BMSR_10T_FD | in phy_reset()
307 s->phy_control = (MII_BMCR_AUTOEN | MII_BMCR_FD | MII_BMCR_SPEED1000); in phy_reset()
308 s->phy_advertise = (MII_ANAR_PAUSE_ASYM | MII_ANAR_PAUSE | MII_ANAR_TXFD | in phy_reset()
311 s->phy_int_mask = 0; in phy_reset()
312 s->phy_int = 0; in phy_reset()
321 val = s->phy_control; in do_phy_read()
324 val = s->phy_status; in do_phy_read()
332 case MII_ANAR: /* Auto-neg advertisement */ in do_phy_read()
333 val = s->phy_advertise; in do_phy_read()
335 case MII_ANLPAR: /* Auto-neg Link Partner Ability */ in do_phy_read()
340 case MII_ANER: /* Auto-neg Expansion */ in do_phy_read()
343 case MII_CTRL1000: /* 1000BASE-T control */ in do_phy_read()
346 case MII_STAT1000: /* 1000BASE-T status */ in do_phy_read()
350 val = s->phy_int; in do_phy_read()
351 s->phy_int = 0; in do_phy_read()
355 val = s->phy_int_mask; in do_phy_read()
389 s->phy_control = val & MII_BMCR_MASK; in do_phy_write()
392 s->phy_status |= MII_BMSR_AN_COMP; in do_phy_write()
396 case MII_ANAR: /* Auto-neg advertisement */ in do_phy_write()
397 s->phy_advertise = (val & MII_ANAR_MASK) | MII_ANAR_TX; in do_phy_write()
400 s->phy_int_mask = val & 0xff; in do_phy_write()
424 if (!(s->phycr & FTGMAC100_PHYCR_NEW_ST_22)) { in do_phy_new_ctl()
430 if (!(s->phycr & FTGMAC100_PHYCR_NEW_FIRE)) { in do_phy_new_ctl()
434 reg = FTGMAC100_PHYCR_NEW_REG(s->phycr); in do_phy_new_ctl()
435 data = FTGMAC100_PHYCR_NEW_DATA(s->phycr); in do_phy_new_ctl()
437 switch (FTGMAC100_PHYCR_NEW_OP(s->phycr)) { in do_phy_new_ctl()
442 s->phydata = do_phy_read(s, reg) & 0xffff; in do_phy_new_ctl()
446 __func__, s->phycr); in do_phy_new_ctl()
449 s->phycr &= ~FTGMAC100_PHYCR_NEW_FIRE; in do_phy_new_ctl()
454 uint8_t reg = FTGMAC100_PHYCR_REG(s->phycr); in do_phy_ctl()
456 if (s->phycr & FTGMAC100_PHYCR_MIIWR) { in do_phy_ctl()
457 do_phy_write(s, reg, s->phydata & 0xffff); in do_phy_ctl()
458 s->phycr &= ~FTGMAC100_PHYCR_MIIWR; in do_phy_ctl()
459 } else if (s->phycr & FTGMAC100_PHYCR_MIIRD) { in do_phy_ctl()
460 s->phydata = do_phy_read(s, reg) << 16; in do_phy_ctl()
461 s->phycr &= ~FTGMAC100_PHYCR_MIIRD; in do_phy_ctl()
464 __func__, s->phycr); in do_phy_ctl()
474 return -1; in ftgmac100_read_bd()
476 bd->des0 = le32_to_cpu(bd->des0); in ftgmac100_read_bd()
477 bd->des1 = le32_to_cpu(bd->des1); in ftgmac100_read_bd()
478 bd->des2 = le32_to_cpu(bd->des2); in ftgmac100_read_bd()
479 bd->des3 = le32_to_cpu(bd->des3); in ftgmac100_read_bd()
487 lebd.des0 = cpu_to_le32(bd->des0); in ftgmac100_write_bd()
488 lebd.des1 = cpu_to_le32(bd->des1); in ftgmac100_write_bd()
489 lebd.des2 = cpu_to_le32(bd->des2); in ftgmac100_write_bd()
490 lebd.des3 = cpu_to_le32(bd->des3); in ftgmac100_write_bd()
495 return -1; in ftgmac100_write_bd()
503 uint8_t *vlan_hdr = s->frame + (ETH_ALEN * 2); in ftgmac100_insert_vlan()
510 s->isr |= FTGMAC100_INT_XPKT_LOST; in ftgmac100_insert_vlan()
514 if (frame_size + sizeof(struct vlan_header) > sizeof(s->frame)) { in ftgmac100_insert_vlan()
518 s->isr |= FTGMAC100_INT_XPKT_LOST; in ftgmac100_insert_vlan()
519 frame_size -= sizeof(struct vlan_header); in ftgmac100_insert_vlan()
522 memmove(payload, vlan_hdr, frame_size - (ETH_ALEN * 2)); in ftgmac100_insert_vlan()
535 uint8_t *ptr = s->frame; in ftgmac100_do_tx()
547 s->isr |= FTGMAC100_INT_NO_NPTXBUF; in ftgmac100_do_tx()
569 if (frame_size + len > sizeof(s->frame)) { in ftgmac100_do_tx()
572 s->isr |= FTGMAC100_INT_XPKT_LOST; in ftgmac100_do_tx()
573 len = sizeof(s->frame) - frame_size; in ftgmac100_do_tx()
577 if (s->dma64) { in ftgmac100_do_tx()
585 s->isr |= FTGMAC100_INT_AHB_ERR; in ftgmac100_do_tx()
596 be16_to_cpu(PKT_GET_ETH_HDR(s->frame)->h_proto) != ETH_P_VLAN) { in ftgmac100_do_tx()
611 net_checksum_calculate(s->frame, frame_size, csum); in ftgmac100_do_tx()
615 qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size); in ftgmac100_do_tx()
616 ptr = s->frame; in ftgmac100_do_tx()
618 s->isr |= FTGMAC100_INT_XPKT_ETH; in ftgmac100_do_tx()
622 s->isr |= FTGMAC100_INT_XPKT_FIFO; in ftgmac100_do_tx()
629 if (bd.des0 & s->txdes0_edotr) { in ftgmac100_do_tx()
632 addr += FTGMAC100_DBLAC_TXDES_SIZE(s->dblac); in ftgmac100_do_tx()
636 s->tx_descriptor = addr; in ftgmac100_do_tx()
646 if ((s->maccr & (FTGMAC100_MACCR_RXDMA_EN | FTGMAC100_MACCR_RXMAC_EN)) in ftgmac100_can_receive()
651 if (ftgmac100_read_bd(&bd, s->rx_descriptor)) { in ftgmac100_can_receive()
658 * This is purely informative. The HW can poll the RW (and RX) ring
675 uint32_t cnt = 1024 * FTGMAC100_APTC_RXPOLL_CNT(s->aptcr); in ftgmac100_rxpoll() local
676 uint32_t speed = (s->maccr & FTGMAC100_MACCR_FAST_MODE) ? 1 : 0; in ftgmac100_rxpoll()
678 if (s->aptcr & FTGMAC100_APTC_RXPOLL_TIME_SEL) { in ftgmac100_rxpoll()
679 cnt <<= 4; in ftgmac100_rxpoll()
682 if (s->maccr & FTGMAC100_MACCR_GIGA_MODE) { in ftgmac100_rxpoll()
686 return cnt / div[speed]; in ftgmac100_rxpoll()
692 s->isr = 0; in ftgmac100_do_reset()
693 s->ier = 0; in ftgmac100_do_reset()
694 s->rx_enabled = 0; in ftgmac100_do_reset()
695 s->rx_ring = 0; in ftgmac100_do_reset()
696 s->rbsr = 0x640; in ftgmac100_do_reset()
697 s->rx_descriptor = 0; in ftgmac100_do_reset()
698 s->tx_ring = 0; in ftgmac100_do_reset()
699 s->tx_descriptor = 0; in ftgmac100_do_reset()
700 s->math[0] = 0; in ftgmac100_do_reset()
701 s->math[1] = 0; in ftgmac100_do_reset()
702 s->itc = 0; in ftgmac100_do_reset()
703 s->aptcr = 1; in ftgmac100_do_reset()
704 s->dblac = 0x00022f00; in ftgmac100_do_reset()
705 s->revr = 0; in ftgmac100_do_reset()
706 s->fear1 = 0; in ftgmac100_do_reset()
707 s->tpafcr = 0xf1; in ftgmac100_do_reset()
710 s->maccr &= FTGMAC100_MACCR_GIGA_MODE | FTGMAC100_MACCR_FAST_MODE; in ftgmac100_do_reset()
712 s->maccr = 0; in ftgmac100_do_reset()
715 s->phycr = 0; in ftgmac100_do_reset()
716 s->phydata = 0; in ftgmac100_do_reset()
717 s->fcr = 0x400; in ftgmac100_do_reset()
734 return s->isr; in ftgmac100_read()
736 return s->ier; in ftgmac100_read()
738 return (s->conf.macaddr.a[0] << 8) | s->conf.macaddr.a[1]; in ftgmac100_read()
740 return ((uint32_t) s->conf.macaddr.a[2] << 24) | in ftgmac100_read()
741 (s->conf.macaddr.a[3] << 16) | (s->conf.macaddr.a[4] << 8) | in ftgmac100_read()
742 s->conf.macaddr.a[5]; in ftgmac100_read()
744 return s->math[0]; in ftgmac100_read()
746 return s->math[1]; in ftgmac100_read()
748 return extract64(s->rx_ring, 0, 32); in ftgmac100_read()
750 return extract64(s->tx_ring, 0, 32); in ftgmac100_read()
752 return s->itc; in ftgmac100_read()
754 return s->dblac; in ftgmac100_read()
756 return s->revr; in ftgmac100_read()
758 return s->fear1; in ftgmac100_read()
760 return s->tpafcr; in ftgmac100_read()
762 return s->fcr; in ftgmac100_read()
764 return s->maccr; in ftgmac100_read()
766 return s->phycr; in ftgmac100_read()
768 return s->phydata; in ftgmac100_read()
771 case FTGMAC100_HPTXPD: /* High Priority Transmit Poll Demand */ in ftgmac100_read()
791 s->isr &= ~value; in ftgmac100_write()
794 s->ier = value; in ftgmac100_write()
797 s->conf.macaddr.a[0] = value >> 8; in ftgmac100_write()
798 s->conf.macaddr.a[1] = value; in ftgmac100_write()
801 s->conf.macaddr.a[2] = value >> 24; in ftgmac100_write()
802 s->conf.macaddr.a[3] = value >> 16; in ftgmac100_write()
803 s->conf.macaddr.a[4] = value >> 8; in ftgmac100_write()
804 s->conf.macaddr.a[5] = value; in ftgmac100_write()
807 s->math[0] = value; in ftgmac100_write()
810 s->math[1] = value; in ftgmac100_write()
813 s->itc = value; in ftgmac100_write()
821 s->rx_ring = deposit64(s->rx_ring, 0, 32, value); in ftgmac100_write()
822 s->rx_descriptor = deposit64(s->rx_descriptor, 0, 32, value); in ftgmac100_write()
825 case FTGMAC100_RBSR: /* DMA buffer size */ in ftgmac100_write()
826 s->rbsr = value; in ftgmac100_write()
835 s->tx_ring = deposit64(s->tx_ring, 0, 32, value); in ftgmac100_write()
836 s->tx_descriptor = deposit64(s->tx_descriptor, 0, 32, value); in ftgmac100_write()
840 if ((s->maccr & (FTGMAC100_MACCR_TXDMA_EN | FTGMAC100_MACCR_TXMAC_EN)) in ftgmac100_write()
843 ftgmac100_do_tx(s, s->tx_ring, s->tx_descriptor); in ftgmac100_write()
845 if (ftgmac100_can_receive(qemu_get_queue(s->nic))) { in ftgmac100_write()
846 qemu_flush_queued_packets(qemu_get_queue(s->nic)); in ftgmac100_write()
850 case FTGMAC100_RXPD: /* Receive Poll Demand Register */ in ftgmac100_write()
851 if (ftgmac100_can_receive(qemu_get_queue(s->nic))) { in ftgmac100_write()
852 qemu_flush_queued_packets(qemu_get_queue(s->nic)); in ftgmac100_write()
857 s->aptcr = value; in ftgmac100_write()
859 if (FTGMAC100_APTC_RXPOLL_CNT(s->aptcr)) { in ftgmac100_write()
863 if (FTGMAC100_APTC_TXPOLL_CNT(s->aptcr)) { in ftgmac100_write()
869 s->maccr = value; in ftgmac100_write()
874 if (ftgmac100_can_receive(qemu_get_queue(s->nic))) { in ftgmac100_write()
875 qemu_flush_queued_packets(qemu_get_queue(s->nic)); in ftgmac100_write()
880 s->phycr = value; in ftgmac100_write()
881 if (s->revr & FTGMAC100_REVR_NEW_MDIO_INTERFACE) { in ftgmac100_write()
888 s->phydata = value & 0xffff; in ftgmac100_write()
890 case FTGMAC100_DBLAC: /* DMA Burst Length and Arbitration Control */ in ftgmac100_write()
905 s->dblac = value; in ftgmac100_write()
908 s->revr = value; in ftgmac100_write()
911 s->fear1 = value; in ftgmac100_write()
914 s->tpafcr = value; in ftgmac100_write()
917 s->fcr = value; in ftgmac100_write()
920 case FTGMAC100_HPTXPD: /* High Priority Transmit Poll Demand */ in ftgmac100_write()
942 val = extract64(s->tx_ring, 32, 32); in ftgmac100_high_read()
950 val = extract64(s->rx_ring, 32, 32); in ftgmac100_high_read()
968 s->tx_ring = deposit64(s->tx_ring, 32, 32, value); in ftgmac100_high_write()
969 s->tx_descriptor = deposit64(s->tx_descriptor, 32, 32, value); in ftgmac100_high_write()
977 s->rx_ring = deposit64(s->rx_ring, 32, 32, value); in ftgmac100_high_write()
978 s->rx_descriptor = deposit64(s->rx_descriptor, 32, 32, value); in ftgmac100_high_write()
993 if (s->maccr & FTGMAC100_MACCR_RX_ALL) { in ftgmac100_filter()
999 if (!(s->maccr & FTGMAC100_MACCR_RX_BROADPKT)) { in ftgmac100_filter()
1004 if (!(s->maccr & FTGMAC100_MACCR_RX_MULTIPKT)) { in ftgmac100_filter()
1005 if (!(s->maccr & FTGMAC100_MACCR_HT_MULTI_EN)) { in ftgmac100_filter()
1011 if (!(s->math[mcast_idx / 32] & (1 << (mcast_idx % 32)))) { in ftgmac100_filter()
1017 if (memcmp(s->conf.macaddr.a, buf, 6)) { in ftgmac100_filter()
1039 uint16_t proto = be16_to_cpu(PKT_GET_ETH_HDR(buf)->h_proto); in ftgmac100_receive()
1042 if ((s->maccr & (FTGMAC100_MACCR_RXDMA_EN | FTGMAC100_MACCR_RXMAC_EN)) in ftgmac100_receive()
1044 return -1; in ftgmac100_receive()
1075 s->isr |= FTGMAC100_INT_RPKT_FIFO; in ftgmac100_receive()
1076 addr = s->rx_descriptor; in ftgmac100_receive()
1080 return -1; in ftgmac100_receive()
1088 s->isr |= FTGMAC100_INT_NO_RXBUF; in ftgmac100_receive()
1091 buf_len = (size <= s->rbsr) ? size : s->rbsr; in ftgmac100_receive()
1093 size -= buf_len; in ftgmac100_receive()
1097 buf_len += size - 4; in ftgmac100_receive()
1101 if (s->dma64) { in ftgmac100_receive()
1108 if (s->maccr & FTGMAC100_MACCR_RM_VLAN) { in ftgmac100_receive()
1112 buf + 16, buf_len - 16, in ftgmac100_receive()
1126 crc_ptr, 4 - size, MEMTXATTRS_UNSPECIFIED); in ftgmac100_receive()
1127 crc_ptr += 4 - size; in ftgmac100_receive()
1135 s->isr |= FTGMAC100_INT_RPKT_BUF; in ftgmac100_receive()
1138 if (bd.des0 & s->rxdes0_edorr) { in ftgmac100_receive()
1139 addr = s->rx_ring; in ftgmac100_receive()
1141 addr += FTGMAC100_DBLAC_RXDES_SIZE(s->dblac); in ftgmac100_receive()
1144 s->rx_descriptor = addr; in ftgmac100_receive()
1170 s->nic = NULL; in ftgmac100_cleanup()
1187 if (s->aspeed) { in ftgmac100_realize()
1188 s->txdes0_edotr = FTGMAC100_TXDES0_EDOTR_ASPEED; in ftgmac100_realize()
1189 s->rxdes0_edorr = FTGMAC100_RXDES0_EDORR_ASPEED; in ftgmac100_realize()
1191 s->txdes0_edotr = FTGMAC100_TXDES0_EDOTR; in ftgmac100_realize()
1192 s->rxdes0_edorr = FTGMAC100_RXDES0_EDORR; in ftgmac100_realize()
1195 memory_region_init(&s->iomem_container, OBJECT(s), in ftgmac100_realize()
1197 sysbus_init_mmio(sbd, &s->iomem_container); in ftgmac100_realize()
1199 memory_region_init_io(&s->iomem, OBJECT(s), &ftgmac100_ops, s, in ftgmac100_realize()
1201 memory_region_add_subregion(&s->iomem_container, 0x0, &s->iomem); in ftgmac100_realize()
1203 if (s->dma64) { in ftgmac100_realize()
1204 memory_region_init_io(&s->iomem_high, OBJECT(s), &ftgmac100_high_ops, in ftgmac100_realize()
1207 memory_region_add_subregion(&s->iomem_container, in ftgmac100_realize()
1209 &s->iomem_high); in ftgmac100_realize()
1212 sysbus_init_irq(sbd, &s->irq); in ftgmac100_realize()
1213 qemu_macaddr_default_if_unset(&s->conf.macaddr); in ftgmac100_realize()
1215 s->nic = qemu_new_nic(&net_ftgmac100_info, &s->conf, in ftgmac100_realize()
1216 object_get_typename(OBJECT(dev)), dev->id, in ftgmac100_realize()
1217 &dev->mem_reentrancy_guard, s); in ftgmac100_realize()
1218 qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); in ftgmac100_realize()
1268 dc->vmsd = &vmstate_ftgmac100; in ftgmac100_class_init()
1271 set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); in ftgmac100_class_init()
1272 dc->realize = ftgmac100_realize; in ftgmac100_class_init()
1273 dc->desc = "Faraday FTGMAC100 Gigabit Ethernet emulation"; in ftgmac100_class_init()
1301 s->phycr |= ASPEED_MII_PHYCR_FIRE; in aspeed_mii_transition()
1302 s->phydata &= ~ASPEED_MII_PHYDATA_IDLE; in aspeed_mii_transition()
1304 s->phycr &= ~ASPEED_MII_PHYCR_FIRE; in aspeed_mii_transition()
1305 s->phydata |= ASPEED_MII_PHYDATA_IDLE; in aspeed_mii_transition()
1314 if (!(s->phycr & ASPEED_MII_PHYCR_ST_22)) { in aspeed_mii_do_phy_ctl()
1321 if (!(s->phycr & ASPEED_MII_PHYCR_FIRE)) { in aspeed_mii_do_phy_ctl()
1325 reg = ASPEED_MII_PHYCR_REG(s->phycr); in aspeed_mii_do_phy_ctl()
1326 data = ASPEED_MII_PHYCR_DATA(s->phycr); in aspeed_mii_do_phy_ctl()
1328 switch (ASPEED_MII_PHYCR_OP(s->phycr)) { in aspeed_mii_do_phy_ctl()
1330 do_phy_write(s->nic, reg, data); in aspeed_mii_do_phy_ctl()
1333 s->phydata = (s->phydata & ~0xffff) | do_phy_read(s->nic, reg); in aspeed_mii_do_phy_ctl()
1337 __func__, s->phycr); in aspeed_mii_do_phy_ctl()
1349 return s->phycr; in aspeed_mii_read()
1351 return s->phydata; in aspeed_mii_read()
1364 s->phycr = value & ~(s->phycr & ASPEED_MII_PHYCR_FIRE); in aspeed_mii_write()
1367 s->phydata = value & ~(0xffff | ASPEED_MII_PHYDATA_IDLE); in aspeed_mii_write()
1373 aspeed_mii_transition(s, !!(s->phycr & ASPEED_MII_PHYCR_FIRE)); in aspeed_mii_write()
1389 s->phycr = 0; in aspeed_mii_reset()
1390 s->phydata = 0; in aspeed_mii_reset()
1392 aspeed_mii_transition(s, !!(s->phycr & ASPEED_MII_PHYCR_FIRE)); in aspeed_mii_reset()
1400 assert(s->nic); in aspeed_mii_realize()
1402 memory_region_init_io(&s->iomem, OBJECT(dev), &aspeed_mii_ops, s, in aspeed_mii_realize()
1404 sysbus_init_mmio(sbd, &s->iomem); in aspeed_mii_realize()
1428 dc->vmsd = &vmstate_aspeed_mii; in aspeed_mii_class_init()
1430 dc->realize = aspeed_mii_realize; in aspeed_mii_class_init()
1431 dc->desc = "Aspeed MII controller"; in aspeed_mii_class_init()