101c966b5SDoug Evans /* 201c966b5SDoug Evans * Nuvoton NPCM7xx EMC Module 301c966b5SDoug Evans * 401c966b5SDoug Evans * Copyright 2020 Google LLC 501c966b5SDoug Evans * 601c966b5SDoug Evans * This program is free software; you can redistribute it and/or modify it 701c966b5SDoug Evans * under the terms of the GNU General Public License as published by the 801c966b5SDoug Evans * Free Software Foundation; either version 2 of the License, or 901c966b5SDoug Evans * (at your option) any later version. 1001c966b5SDoug Evans * 1101c966b5SDoug Evans * This program is distributed in the hope that it will be useful, but WITHOUT 1201c966b5SDoug Evans * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1301c966b5SDoug Evans * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1401c966b5SDoug Evans * for more details. 1501c966b5SDoug Evans */ 1601c966b5SDoug Evans 1701c966b5SDoug Evans #ifndef NPCM7XX_EMC_H 1801c966b5SDoug Evans #define NPCM7XX_EMC_H 1901c966b5SDoug Evans 2001c966b5SDoug Evans #include "hw/irq.h" 2101c966b5SDoug Evans #include "hw/sysbus.h" 2201c966b5SDoug Evans #include "net/net.h" 2301c966b5SDoug Evans 2401c966b5SDoug Evans /* 32-bit register indices. */ 2501c966b5SDoug Evans enum NPCM7xxPWMRegister { 2601c966b5SDoug Evans /* Control registers. */ 2701c966b5SDoug Evans REG_CAMCMR, 2801c966b5SDoug Evans REG_CAMEN, 2901c966b5SDoug Evans 3001c966b5SDoug Evans /* There are 16 CAMn[ML] registers. */ 3101c966b5SDoug Evans REG_CAMM_BASE, 3201c966b5SDoug Evans REG_CAML_BASE, 3301c966b5SDoug Evans REG_CAMML_LAST = 0x21, 3401c966b5SDoug Evans 3501c966b5SDoug Evans REG_TXDLSA = 0x22, 3601c966b5SDoug Evans REG_RXDLSA, 3701c966b5SDoug Evans REG_MCMDR, 3801c966b5SDoug Evans REG_MIID, 3901c966b5SDoug Evans REG_MIIDA, 4001c966b5SDoug Evans REG_FFTCR, 4101c966b5SDoug Evans REG_TSDR, 4201c966b5SDoug Evans REG_RSDR, 4301c966b5SDoug Evans REG_DMARFC, 4401c966b5SDoug Evans REG_MIEN, 4501c966b5SDoug Evans 4601c966b5SDoug Evans /* Status registers. */ 4701c966b5SDoug Evans REG_MISTA, 4801c966b5SDoug Evans REG_MGSTA, 4901c966b5SDoug Evans REG_MPCNT, 5001c966b5SDoug Evans REG_MRPC, 5101c966b5SDoug Evans REG_MRPCC, 5201c966b5SDoug Evans REG_MREPC, 5301c966b5SDoug Evans REG_DMARFS, 5401c966b5SDoug Evans REG_CTXDSA, 5501c966b5SDoug Evans REG_CTXBSA, 5601c966b5SDoug Evans REG_CRXDSA, 5701c966b5SDoug Evans REG_CRXBSA, 5801c966b5SDoug Evans 5901c966b5SDoug Evans NPCM7XX_NUM_EMC_REGS, 6001c966b5SDoug Evans }; 6101c966b5SDoug Evans 6201c966b5SDoug Evans /* REG_CAMCMR fields */ 6301c966b5SDoug Evans /* Enable CAM Compare */ 6401c966b5SDoug Evans #define REG_CAMCMR_ECMP (1 << 4) 6501c966b5SDoug Evans /* Complement CAM Compare */ 6601c966b5SDoug Evans #define REG_CAMCMR_CCAM (1 << 3) 6701c966b5SDoug Evans /* Accept Broadcast Packet */ 6801c966b5SDoug Evans #define REG_CAMCMR_ABP (1 << 2) 6901c966b5SDoug Evans /* Accept Multicast Packet */ 7001c966b5SDoug Evans #define REG_CAMCMR_AMP (1 << 1) 7101c966b5SDoug Evans /* Accept Unicast Packet */ 7201c966b5SDoug Evans #define REG_CAMCMR_AUP (1 << 0) 7301c966b5SDoug Evans 7401c966b5SDoug Evans /* REG_MCMDR fields */ 7501c966b5SDoug Evans /* Software Reset */ 7601c966b5SDoug Evans #define REG_MCMDR_SWR (1 << 24) 7701c966b5SDoug Evans /* Internal Loopback Select */ 7801c966b5SDoug Evans #define REG_MCMDR_LBK (1 << 21) 7901c966b5SDoug Evans /* Operation Mode Select */ 8001c966b5SDoug Evans #define REG_MCMDR_OPMOD (1 << 20) 8101c966b5SDoug Evans /* Enable MDC Clock Generation */ 8201c966b5SDoug Evans #define REG_MCMDR_ENMDC (1 << 19) 8301c966b5SDoug Evans /* Full-Duplex Mode Select */ 8401c966b5SDoug Evans #define REG_MCMDR_FDUP (1 << 18) 8501c966b5SDoug Evans /* Enable SQE Checking */ 8601c966b5SDoug Evans #define REG_MCMDR_ENSEQ (1 << 17) 8701c966b5SDoug Evans /* Send PAUSE Frame */ 8801c966b5SDoug Evans #define REG_MCMDR_SDPZ (1 << 16) 8901c966b5SDoug Evans /* No Defer */ 9001c966b5SDoug Evans #define REG_MCMDR_NDEF (1 << 9) 9101c966b5SDoug Evans /* Frame Transmission On */ 9201c966b5SDoug Evans #define REG_MCMDR_TXON (1 << 8) 9301c966b5SDoug Evans /* Strip CRC Checksum */ 9401c966b5SDoug Evans #define REG_MCMDR_SPCRC (1 << 5) 9501c966b5SDoug Evans /* Accept CRC Error Packet */ 9601c966b5SDoug Evans #define REG_MCMDR_AEP (1 << 4) 9701c966b5SDoug Evans /* Accept Control Packet */ 9801c966b5SDoug Evans #define REG_MCMDR_ACP (1 << 3) 9901c966b5SDoug Evans /* Accept Runt Packet */ 10001c966b5SDoug Evans #define REG_MCMDR_ARP (1 << 2) 10101c966b5SDoug Evans /* Accept Long Packet */ 10201c966b5SDoug Evans #define REG_MCMDR_ALP (1 << 1) 10301c966b5SDoug Evans /* Frame Reception On */ 10401c966b5SDoug Evans #define REG_MCMDR_RXON (1 << 0) 10501c966b5SDoug Evans 10601c966b5SDoug Evans /* REG_MIEN fields */ 10701c966b5SDoug Evans /* Enable Transmit Descriptor Unavailable Interrupt */ 10801c966b5SDoug Evans #define REG_MIEN_ENTDU (1 << 23) 10901c966b5SDoug Evans /* Enable Transmit Completion Interrupt */ 11001c966b5SDoug Evans #define REG_MIEN_ENTXCP (1 << 18) 11101c966b5SDoug Evans /* Enable Transmit Interrupt */ 11201c966b5SDoug Evans #define REG_MIEN_ENTXINTR (1 << 16) 11301c966b5SDoug Evans /* Enable Receive Descriptor Unavailable Interrupt */ 11401c966b5SDoug Evans #define REG_MIEN_ENRDU (1 << 10) 11501c966b5SDoug Evans /* Enable Receive Good Interrupt */ 11601c966b5SDoug Evans #define REG_MIEN_ENRXGD (1 << 4) 11701c966b5SDoug Evans /* Enable Receive Interrupt */ 11801c966b5SDoug Evans #define REG_MIEN_ENRXINTR (1 << 0) 11901c966b5SDoug Evans 12001c966b5SDoug Evans /* REG_MISTA fields */ 12101c966b5SDoug Evans /* TODO: Add error fields and support simulated errors? */ 12201c966b5SDoug Evans /* Transmit Bus Error Interrupt */ 12301c966b5SDoug Evans #define REG_MISTA_TXBERR (1 << 24) 12401c966b5SDoug Evans /* Transmit Descriptor Unavailable Interrupt */ 12501c966b5SDoug Evans #define REG_MISTA_TDU (1 << 23) 12601c966b5SDoug Evans /* Transmit Completion Interrupt */ 12701c966b5SDoug Evans #define REG_MISTA_TXCP (1 << 18) 12801c966b5SDoug Evans /* Transmit Interrupt */ 12901c966b5SDoug Evans #define REG_MISTA_TXINTR (1 << 16) 13001c966b5SDoug Evans /* Receive Bus Error Interrupt */ 13101c966b5SDoug Evans #define REG_MISTA_RXBERR (1 << 11) 13201c966b5SDoug Evans /* Receive Descriptor Unavailable Interrupt */ 13301c966b5SDoug Evans #define REG_MISTA_RDU (1 << 10) 13401c966b5SDoug Evans /* DMA Early Notification Interrupt */ 13501c966b5SDoug Evans #define REG_MISTA_DENI (1 << 9) 13601c966b5SDoug Evans /* Maximum Frame Length Interrupt */ 13701c966b5SDoug Evans #define REG_MISTA_DFOI (1 << 8) 13801c966b5SDoug Evans /* Receive Good Interrupt */ 13901c966b5SDoug Evans #define REG_MISTA_RXGD (1 << 4) 14001c966b5SDoug Evans /* Packet Too Long Interrupt */ 14101c966b5SDoug Evans #define REG_MISTA_PTLE (1 << 3) 14201c966b5SDoug Evans /* Receive Interrupt */ 14301c966b5SDoug Evans #define REG_MISTA_RXINTR (1 << 0) 14401c966b5SDoug Evans 14501c966b5SDoug Evans /* REG_MGSTA fields */ 14601c966b5SDoug Evans /* Transmission Halted */ 14701c966b5SDoug Evans #define REG_MGSTA_TXHA (1 << 11) 14801c966b5SDoug Evans /* Receive Halted */ 14901c966b5SDoug Evans #define REG_MGSTA_RXHA (1 << 11) 15001c966b5SDoug Evans 15101c966b5SDoug Evans /* REG_DMARFC fields */ 15201c966b5SDoug Evans /* Maximum Receive Frame Length */ 15301c966b5SDoug Evans #define REG_DMARFC_RXMS(word) extract32((word), 0, 16) 15401c966b5SDoug Evans 15501c966b5SDoug Evans /* REG MIIDA fields */ 15601c966b5SDoug Evans /* Busy Bit */ 15701c966b5SDoug Evans #define REG_MIIDA_BUSY (1 << 17) 15801c966b5SDoug Evans 15901c966b5SDoug Evans /* Transmit and receive descriptors */ 16001c966b5SDoug Evans typedef struct NPCM7xxEMCTxDesc NPCM7xxEMCTxDesc; 16101c966b5SDoug Evans typedef struct NPCM7xxEMCRxDesc NPCM7xxEMCRxDesc; 16201c966b5SDoug Evans 16301c966b5SDoug Evans struct NPCM7xxEMCTxDesc { 16401c966b5SDoug Evans uint32_t flags; 16501c966b5SDoug Evans uint32_t txbsa; 16601c966b5SDoug Evans uint32_t status_and_length; 16701c966b5SDoug Evans uint32_t ntxdsa; 16801c966b5SDoug Evans }; 16901c966b5SDoug Evans 17001c966b5SDoug Evans struct NPCM7xxEMCRxDesc { 17101c966b5SDoug Evans uint32_t status_and_length; 17201c966b5SDoug Evans uint32_t rxbsa; 17301c966b5SDoug Evans uint32_t reserved; 17401c966b5SDoug Evans uint32_t nrxdsa; 17501c966b5SDoug Evans }; 17601c966b5SDoug Evans 17701c966b5SDoug Evans /* NPCM7xxEMCTxDesc.flags values */ 17801c966b5SDoug Evans /* Owner: 0 = cpu, 1 = emc */ 17901c966b5SDoug Evans #define TX_DESC_FLAG_OWNER_MASK (1 << 31) 18001c966b5SDoug Evans /* Transmit interrupt enable */ 18101c966b5SDoug Evans #define TX_DESC_FLAG_INTEN (1 << 2) 18201c966b5SDoug Evans /* CRC append */ 18301c966b5SDoug Evans #define TX_DESC_FLAG_CRCAPP (1 << 1) 18401c966b5SDoug Evans /* Padding enable */ 18501c966b5SDoug Evans #define TX_DESC_FLAG_PADEN (1 << 0) 18601c966b5SDoug Evans 18701c966b5SDoug Evans /* NPCM7xxEMCTxDesc.status_and_length values */ 18801c966b5SDoug Evans /* Collision count */ 18901c966b5SDoug Evans #define TX_DESC_STATUS_CCNT_SHIFT 28 19001c966b5SDoug Evans #define TX_DESC_STATUS_CCNT_BITSIZE 4 19101c966b5SDoug Evans /* SQE error */ 19201c966b5SDoug Evans #define TX_DESC_STATUS_SQE (1 << 26) 19301c966b5SDoug Evans /* Transmission paused */ 19401c966b5SDoug Evans #define TX_DESC_STATUS_PAU (1 << 25) 19501c966b5SDoug Evans /* P transmission halted */ 19601c966b5SDoug Evans #define TX_DESC_STATUS_TXHA (1 << 24) 19701c966b5SDoug Evans /* Late collision */ 19801c966b5SDoug Evans #define TX_DESC_STATUS_LC (1 << 23) 19901c966b5SDoug Evans /* Transmission abort */ 20001c966b5SDoug Evans #define TX_DESC_STATUS_TXABT (1 << 22) 20101c966b5SDoug Evans /* No carrier sense */ 20201c966b5SDoug Evans #define TX_DESC_STATUS_NCS (1 << 21) 20301c966b5SDoug Evans /* Defer exceed */ 20401c966b5SDoug Evans #define TX_DESC_STATUS_EXDEF (1 << 20) 20501c966b5SDoug Evans /* Transmission complete */ 20601c966b5SDoug Evans #define TX_DESC_STATUS_TXCP (1 << 19) 20701c966b5SDoug Evans /* Transmission deferred */ 20801c966b5SDoug Evans #define TX_DESC_STATUS_DEF (1 << 17) 20901c966b5SDoug Evans /* Transmit interrupt */ 21001c966b5SDoug Evans #define TX_DESC_STATUS_TXINTR (1 << 16) 21101c966b5SDoug Evans 21201c966b5SDoug Evans #define TX_DESC_PKT_LEN(word) extract32((word), 0, 16) 21301c966b5SDoug Evans 21401c966b5SDoug Evans /* Transmit buffer start address */ 21501c966b5SDoug Evans #define TX_DESC_TXBSA(word) ((uint32_t) (word) & ~3u) 21601c966b5SDoug Evans 21701c966b5SDoug Evans /* Next transmit descriptor start address */ 21801c966b5SDoug Evans #define TX_DESC_NTXDSA(word) ((uint32_t) (word) & ~3u) 21901c966b5SDoug Evans 22001c966b5SDoug Evans /* NPCM7xxEMCRxDesc.status_and_length values */ 22101c966b5SDoug Evans /* Owner: 0b00 = cpu, 0b01 = undefined, 0b10 = emc, 0b11 = undefined */ 22201c966b5SDoug Evans #define RX_DESC_STATUS_OWNER_SHIFT 30 22301c966b5SDoug Evans #define RX_DESC_STATUS_OWNER_BITSIZE 2 22401c966b5SDoug Evans #define RX_DESC_STATUS_OWNER_MASK (3 << RX_DESC_STATUS_OWNER_SHIFT) 22501c966b5SDoug Evans /* Runt packet */ 22601c966b5SDoug Evans #define RX_DESC_STATUS_RP (1 << 22) 22701c966b5SDoug Evans /* Alignment error */ 22801c966b5SDoug Evans #define RX_DESC_STATUS_ALIE (1 << 21) 22901c966b5SDoug Evans /* Frame reception complete */ 23001c966b5SDoug Evans #define RX_DESC_STATUS_RXGD (1 << 20) 23101c966b5SDoug Evans /* Packet too long */ 23201c966b5SDoug Evans #define RX_DESC_STATUS_PTLE (1 << 19) 23301c966b5SDoug Evans /* CRC error */ 23401c966b5SDoug Evans #define RX_DESC_STATUS_CRCE (1 << 17) 23501c966b5SDoug Evans /* Receive interrupt */ 23601c966b5SDoug Evans #define RX_DESC_STATUS_RXINTR (1 << 16) 23701c966b5SDoug Evans 23801c966b5SDoug Evans #define RX_DESC_PKT_LEN(word) extract32((word), 0, 16) 23901c966b5SDoug Evans 24001c966b5SDoug Evans /* Receive buffer start address */ 24101c966b5SDoug Evans #define RX_DESC_RXBSA(word) ((uint32_t) (word) & ~3u) 24201c966b5SDoug Evans 24301c966b5SDoug Evans /* Next receive descriptor start address */ 24401c966b5SDoug Evans #define RX_DESC_NRXDSA(word) ((uint32_t) (word) & ~3u) 24501c966b5SDoug Evans 24601c966b5SDoug Evans /* Minimum packet length, when TX_DESC_FLAG_PADEN is set. */ 24701c966b5SDoug Evans #define MIN_PACKET_LENGTH 64 24801c966b5SDoug Evans 24901c966b5SDoug Evans struct NPCM7xxEMCState { 25001c966b5SDoug Evans /*< private >*/ 25101c966b5SDoug Evans SysBusDevice parent; 25201c966b5SDoug Evans /*< public >*/ 25301c966b5SDoug Evans 25401c966b5SDoug Evans MemoryRegion iomem; 25501c966b5SDoug Evans 25601c966b5SDoug Evans qemu_irq tx_irq; 25701c966b5SDoug Evans qemu_irq rx_irq; 25801c966b5SDoug Evans 25901c966b5SDoug Evans NICState *nic; 26001c966b5SDoug Evans NICConf conf; 26101c966b5SDoug Evans 26201c966b5SDoug Evans /* 0 or 1, for log messages */ 26301c966b5SDoug Evans uint8_t emc_num; 26401c966b5SDoug Evans 26501c966b5SDoug Evans uint32_t regs[NPCM7XX_NUM_EMC_REGS]; 26601c966b5SDoug Evans 26701c966b5SDoug Evans /* 26801c966b5SDoug Evans * tx is active. Set to true by TSDR and then switches off when out of 26901c966b5SDoug Evans * descriptors. If the TXON bit in REG_MCMDR is off then this is off. 27001c966b5SDoug Evans */ 27101c966b5SDoug Evans bool tx_active; 27201c966b5SDoug Evans 27301c966b5SDoug Evans /* 27401c966b5SDoug Evans * rx is active. Set to true by RSDR and then switches off when out of 27501c966b5SDoug Evans * descriptors. If the RXON bit in REG_MCMDR is off then this is off. 27601c966b5SDoug Evans */ 27701c966b5SDoug Evans bool rx_active; 27801c966b5SDoug Evans }; 27901c966b5SDoug Evans 28001c966b5SDoug Evans #define TYPE_NPCM7XX_EMC "npcm7xx-emc" 281*c79aa350SPhilippe Mathieu-Daudé OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxEMCState, NPCM7XX_EMC) 28201c966b5SDoug Evans 28301c966b5SDoug Evans #endif /* NPCM7XX_EMC_H */ 284