1*01c966b5SDoug Evans /* 2*01c966b5SDoug Evans * Nuvoton NPCM7xx EMC Module 3*01c966b5SDoug Evans * 4*01c966b5SDoug Evans * Copyright 2020 Google LLC 5*01c966b5SDoug Evans * 6*01c966b5SDoug Evans * This program is free software; you can redistribute it and/or modify it 7*01c966b5SDoug Evans * under the terms of the GNU General Public License as published by the 8*01c966b5SDoug Evans * Free Software Foundation; either version 2 of the License, or 9*01c966b5SDoug Evans * (at your option) any later version. 10*01c966b5SDoug Evans * 11*01c966b5SDoug Evans * This program is distributed in the hope that it will be useful, but WITHOUT 12*01c966b5SDoug Evans * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13*01c966b5SDoug Evans * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14*01c966b5SDoug Evans * for more details. 15*01c966b5SDoug Evans */ 16*01c966b5SDoug Evans 17*01c966b5SDoug Evans #ifndef NPCM7XX_EMC_H 18*01c966b5SDoug Evans #define NPCM7XX_EMC_H 19*01c966b5SDoug Evans 20*01c966b5SDoug Evans #include "hw/irq.h" 21*01c966b5SDoug Evans #include "hw/sysbus.h" 22*01c966b5SDoug Evans #include "net/net.h" 23*01c966b5SDoug Evans 24*01c966b5SDoug Evans /* 32-bit register indices. */ 25*01c966b5SDoug Evans enum NPCM7xxPWMRegister { 26*01c966b5SDoug Evans /* Control registers. */ 27*01c966b5SDoug Evans REG_CAMCMR, 28*01c966b5SDoug Evans REG_CAMEN, 29*01c966b5SDoug Evans 30*01c966b5SDoug Evans /* There are 16 CAMn[ML] registers. */ 31*01c966b5SDoug Evans REG_CAMM_BASE, 32*01c966b5SDoug Evans REG_CAML_BASE, 33*01c966b5SDoug Evans REG_CAMML_LAST = 0x21, 34*01c966b5SDoug Evans 35*01c966b5SDoug Evans REG_TXDLSA = 0x22, 36*01c966b5SDoug Evans REG_RXDLSA, 37*01c966b5SDoug Evans REG_MCMDR, 38*01c966b5SDoug Evans REG_MIID, 39*01c966b5SDoug Evans REG_MIIDA, 40*01c966b5SDoug Evans REG_FFTCR, 41*01c966b5SDoug Evans REG_TSDR, 42*01c966b5SDoug Evans REG_RSDR, 43*01c966b5SDoug Evans REG_DMARFC, 44*01c966b5SDoug Evans REG_MIEN, 45*01c966b5SDoug Evans 46*01c966b5SDoug Evans /* Status registers. */ 47*01c966b5SDoug Evans REG_MISTA, 48*01c966b5SDoug Evans REG_MGSTA, 49*01c966b5SDoug Evans REG_MPCNT, 50*01c966b5SDoug Evans REG_MRPC, 51*01c966b5SDoug Evans REG_MRPCC, 52*01c966b5SDoug Evans REG_MREPC, 53*01c966b5SDoug Evans REG_DMARFS, 54*01c966b5SDoug Evans REG_CTXDSA, 55*01c966b5SDoug Evans REG_CTXBSA, 56*01c966b5SDoug Evans REG_CRXDSA, 57*01c966b5SDoug Evans REG_CRXBSA, 58*01c966b5SDoug Evans 59*01c966b5SDoug Evans NPCM7XX_NUM_EMC_REGS, 60*01c966b5SDoug Evans }; 61*01c966b5SDoug Evans 62*01c966b5SDoug Evans /* REG_CAMCMR fields */ 63*01c966b5SDoug Evans /* Enable CAM Compare */ 64*01c966b5SDoug Evans #define REG_CAMCMR_ECMP (1 << 4) 65*01c966b5SDoug Evans /* Complement CAM Compare */ 66*01c966b5SDoug Evans #define REG_CAMCMR_CCAM (1 << 3) 67*01c966b5SDoug Evans /* Accept Broadcast Packet */ 68*01c966b5SDoug Evans #define REG_CAMCMR_ABP (1 << 2) 69*01c966b5SDoug Evans /* Accept Multicast Packet */ 70*01c966b5SDoug Evans #define REG_CAMCMR_AMP (1 << 1) 71*01c966b5SDoug Evans /* Accept Unicast Packet */ 72*01c966b5SDoug Evans #define REG_CAMCMR_AUP (1 << 0) 73*01c966b5SDoug Evans 74*01c966b5SDoug Evans /* REG_MCMDR fields */ 75*01c966b5SDoug Evans /* Software Reset */ 76*01c966b5SDoug Evans #define REG_MCMDR_SWR (1 << 24) 77*01c966b5SDoug Evans /* Internal Loopback Select */ 78*01c966b5SDoug Evans #define REG_MCMDR_LBK (1 << 21) 79*01c966b5SDoug Evans /* Operation Mode Select */ 80*01c966b5SDoug Evans #define REG_MCMDR_OPMOD (1 << 20) 81*01c966b5SDoug Evans /* Enable MDC Clock Generation */ 82*01c966b5SDoug Evans #define REG_MCMDR_ENMDC (1 << 19) 83*01c966b5SDoug Evans /* Full-Duplex Mode Select */ 84*01c966b5SDoug Evans #define REG_MCMDR_FDUP (1 << 18) 85*01c966b5SDoug Evans /* Enable SQE Checking */ 86*01c966b5SDoug Evans #define REG_MCMDR_ENSEQ (1 << 17) 87*01c966b5SDoug Evans /* Send PAUSE Frame */ 88*01c966b5SDoug Evans #define REG_MCMDR_SDPZ (1 << 16) 89*01c966b5SDoug Evans /* No Defer */ 90*01c966b5SDoug Evans #define REG_MCMDR_NDEF (1 << 9) 91*01c966b5SDoug Evans /* Frame Transmission On */ 92*01c966b5SDoug Evans #define REG_MCMDR_TXON (1 << 8) 93*01c966b5SDoug Evans /* Strip CRC Checksum */ 94*01c966b5SDoug Evans #define REG_MCMDR_SPCRC (1 << 5) 95*01c966b5SDoug Evans /* Accept CRC Error Packet */ 96*01c966b5SDoug Evans #define REG_MCMDR_AEP (1 << 4) 97*01c966b5SDoug Evans /* Accept Control Packet */ 98*01c966b5SDoug Evans #define REG_MCMDR_ACP (1 << 3) 99*01c966b5SDoug Evans /* Accept Runt Packet */ 100*01c966b5SDoug Evans #define REG_MCMDR_ARP (1 << 2) 101*01c966b5SDoug Evans /* Accept Long Packet */ 102*01c966b5SDoug Evans #define REG_MCMDR_ALP (1 << 1) 103*01c966b5SDoug Evans /* Frame Reception On */ 104*01c966b5SDoug Evans #define REG_MCMDR_RXON (1 << 0) 105*01c966b5SDoug Evans 106*01c966b5SDoug Evans /* REG_MIEN fields */ 107*01c966b5SDoug Evans /* Enable Transmit Descriptor Unavailable Interrupt */ 108*01c966b5SDoug Evans #define REG_MIEN_ENTDU (1 << 23) 109*01c966b5SDoug Evans /* Enable Transmit Completion Interrupt */ 110*01c966b5SDoug Evans #define REG_MIEN_ENTXCP (1 << 18) 111*01c966b5SDoug Evans /* Enable Transmit Interrupt */ 112*01c966b5SDoug Evans #define REG_MIEN_ENTXINTR (1 << 16) 113*01c966b5SDoug Evans /* Enable Receive Descriptor Unavailable Interrupt */ 114*01c966b5SDoug Evans #define REG_MIEN_ENRDU (1 << 10) 115*01c966b5SDoug Evans /* Enable Receive Good Interrupt */ 116*01c966b5SDoug Evans #define REG_MIEN_ENRXGD (1 << 4) 117*01c966b5SDoug Evans /* Enable Receive Interrupt */ 118*01c966b5SDoug Evans #define REG_MIEN_ENRXINTR (1 << 0) 119*01c966b5SDoug Evans 120*01c966b5SDoug Evans /* REG_MISTA fields */ 121*01c966b5SDoug Evans /* TODO: Add error fields and support simulated errors? */ 122*01c966b5SDoug Evans /* Transmit Bus Error Interrupt */ 123*01c966b5SDoug Evans #define REG_MISTA_TXBERR (1 << 24) 124*01c966b5SDoug Evans /* Transmit Descriptor Unavailable Interrupt */ 125*01c966b5SDoug Evans #define REG_MISTA_TDU (1 << 23) 126*01c966b5SDoug Evans /* Transmit Completion Interrupt */ 127*01c966b5SDoug Evans #define REG_MISTA_TXCP (1 << 18) 128*01c966b5SDoug Evans /* Transmit Interrupt */ 129*01c966b5SDoug Evans #define REG_MISTA_TXINTR (1 << 16) 130*01c966b5SDoug Evans /* Receive Bus Error Interrupt */ 131*01c966b5SDoug Evans #define REG_MISTA_RXBERR (1 << 11) 132*01c966b5SDoug Evans /* Receive Descriptor Unavailable Interrupt */ 133*01c966b5SDoug Evans #define REG_MISTA_RDU (1 << 10) 134*01c966b5SDoug Evans /* DMA Early Notification Interrupt */ 135*01c966b5SDoug Evans #define REG_MISTA_DENI (1 << 9) 136*01c966b5SDoug Evans /* Maximum Frame Length Interrupt */ 137*01c966b5SDoug Evans #define REG_MISTA_DFOI (1 << 8) 138*01c966b5SDoug Evans /* Receive Good Interrupt */ 139*01c966b5SDoug Evans #define REG_MISTA_RXGD (1 << 4) 140*01c966b5SDoug Evans /* Packet Too Long Interrupt */ 141*01c966b5SDoug Evans #define REG_MISTA_PTLE (1 << 3) 142*01c966b5SDoug Evans /* Receive Interrupt */ 143*01c966b5SDoug Evans #define REG_MISTA_RXINTR (1 << 0) 144*01c966b5SDoug Evans 145*01c966b5SDoug Evans /* REG_MGSTA fields */ 146*01c966b5SDoug Evans /* Transmission Halted */ 147*01c966b5SDoug Evans #define REG_MGSTA_TXHA (1 << 11) 148*01c966b5SDoug Evans /* Receive Halted */ 149*01c966b5SDoug Evans #define REG_MGSTA_RXHA (1 << 11) 150*01c966b5SDoug Evans 151*01c966b5SDoug Evans /* REG_DMARFC fields */ 152*01c966b5SDoug Evans /* Maximum Receive Frame Length */ 153*01c966b5SDoug Evans #define REG_DMARFC_RXMS(word) extract32((word), 0, 16) 154*01c966b5SDoug Evans 155*01c966b5SDoug Evans /* REG MIIDA fields */ 156*01c966b5SDoug Evans /* Busy Bit */ 157*01c966b5SDoug Evans #define REG_MIIDA_BUSY (1 << 17) 158*01c966b5SDoug Evans 159*01c966b5SDoug Evans /* Transmit and receive descriptors */ 160*01c966b5SDoug Evans typedef struct NPCM7xxEMCTxDesc NPCM7xxEMCTxDesc; 161*01c966b5SDoug Evans typedef struct NPCM7xxEMCRxDesc NPCM7xxEMCRxDesc; 162*01c966b5SDoug Evans 163*01c966b5SDoug Evans struct NPCM7xxEMCTxDesc { 164*01c966b5SDoug Evans uint32_t flags; 165*01c966b5SDoug Evans uint32_t txbsa; 166*01c966b5SDoug Evans uint32_t status_and_length; 167*01c966b5SDoug Evans uint32_t ntxdsa; 168*01c966b5SDoug Evans }; 169*01c966b5SDoug Evans 170*01c966b5SDoug Evans struct NPCM7xxEMCRxDesc { 171*01c966b5SDoug Evans uint32_t status_and_length; 172*01c966b5SDoug Evans uint32_t rxbsa; 173*01c966b5SDoug Evans uint32_t reserved; 174*01c966b5SDoug Evans uint32_t nrxdsa; 175*01c966b5SDoug Evans }; 176*01c966b5SDoug Evans 177*01c966b5SDoug Evans /* NPCM7xxEMCTxDesc.flags values */ 178*01c966b5SDoug Evans /* Owner: 0 = cpu, 1 = emc */ 179*01c966b5SDoug Evans #define TX_DESC_FLAG_OWNER_MASK (1 << 31) 180*01c966b5SDoug Evans /* Transmit interrupt enable */ 181*01c966b5SDoug Evans #define TX_DESC_FLAG_INTEN (1 << 2) 182*01c966b5SDoug Evans /* CRC append */ 183*01c966b5SDoug Evans #define TX_DESC_FLAG_CRCAPP (1 << 1) 184*01c966b5SDoug Evans /* Padding enable */ 185*01c966b5SDoug Evans #define TX_DESC_FLAG_PADEN (1 << 0) 186*01c966b5SDoug Evans 187*01c966b5SDoug Evans /* NPCM7xxEMCTxDesc.status_and_length values */ 188*01c966b5SDoug Evans /* Collision count */ 189*01c966b5SDoug Evans #define TX_DESC_STATUS_CCNT_SHIFT 28 190*01c966b5SDoug Evans #define TX_DESC_STATUS_CCNT_BITSIZE 4 191*01c966b5SDoug Evans /* SQE error */ 192*01c966b5SDoug Evans #define TX_DESC_STATUS_SQE (1 << 26) 193*01c966b5SDoug Evans /* Transmission paused */ 194*01c966b5SDoug Evans #define TX_DESC_STATUS_PAU (1 << 25) 195*01c966b5SDoug Evans /* P transmission halted */ 196*01c966b5SDoug Evans #define TX_DESC_STATUS_TXHA (1 << 24) 197*01c966b5SDoug Evans /* Late collision */ 198*01c966b5SDoug Evans #define TX_DESC_STATUS_LC (1 << 23) 199*01c966b5SDoug Evans /* Transmission abort */ 200*01c966b5SDoug Evans #define TX_DESC_STATUS_TXABT (1 << 22) 201*01c966b5SDoug Evans /* No carrier sense */ 202*01c966b5SDoug Evans #define TX_DESC_STATUS_NCS (1 << 21) 203*01c966b5SDoug Evans /* Defer exceed */ 204*01c966b5SDoug Evans #define TX_DESC_STATUS_EXDEF (1 << 20) 205*01c966b5SDoug Evans /* Transmission complete */ 206*01c966b5SDoug Evans #define TX_DESC_STATUS_TXCP (1 << 19) 207*01c966b5SDoug Evans /* Transmission deferred */ 208*01c966b5SDoug Evans #define TX_DESC_STATUS_DEF (1 << 17) 209*01c966b5SDoug Evans /* Transmit interrupt */ 210*01c966b5SDoug Evans #define TX_DESC_STATUS_TXINTR (1 << 16) 211*01c966b5SDoug Evans 212*01c966b5SDoug Evans #define TX_DESC_PKT_LEN(word) extract32((word), 0, 16) 213*01c966b5SDoug Evans 214*01c966b5SDoug Evans /* Transmit buffer start address */ 215*01c966b5SDoug Evans #define TX_DESC_TXBSA(word) ((uint32_t) (word) & ~3u) 216*01c966b5SDoug Evans 217*01c966b5SDoug Evans /* Next transmit descriptor start address */ 218*01c966b5SDoug Evans #define TX_DESC_NTXDSA(word) ((uint32_t) (word) & ~3u) 219*01c966b5SDoug Evans 220*01c966b5SDoug Evans /* NPCM7xxEMCRxDesc.status_and_length values */ 221*01c966b5SDoug Evans /* Owner: 0b00 = cpu, 0b01 = undefined, 0b10 = emc, 0b11 = undefined */ 222*01c966b5SDoug Evans #define RX_DESC_STATUS_OWNER_SHIFT 30 223*01c966b5SDoug Evans #define RX_DESC_STATUS_OWNER_BITSIZE 2 224*01c966b5SDoug Evans #define RX_DESC_STATUS_OWNER_MASK (3 << RX_DESC_STATUS_OWNER_SHIFT) 225*01c966b5SDoug Evans /* Runt packet */ 226*01c966b5SDoug Evans #define RX_DESC_STATUS_RP (1 << 22) 227*01c966b5SDoug Evans /* Alignment error */ 228*01c966b5SDoug Evans #define RX_DESC_STATUS_ALIE (1 << 21) 229*01c966b5SDoug Evans /* Frame reception complete */ 230*01c966b5SDoug Evans #define RX_DESC_STATUS_RXGD (1 << 20) 231*01c966b5SDoug Evans /* Packet too long */ 232*01c966b5SDoug Evans #define RX_DESC_STATUS_PTLE (1 << 19) 233*01c966b5SDoug Evans /* CRC error */ 234*01c966b5SDoug Evans #define RX_DESC_STATUS_CRCE (1 << 17) 235*01c966b5SDoug Evans /* Receive interrupt */ 236*01c966b5SDoug Evans #define RX_DESC_STATUS_RXINTR (1 << 16) 237*01c966b5SDoug Evans 238*01c966b5SDoug Evans #define RX_DESC_PKT_LEN(word) extract32((word), 0, 16) 239*01c966b5SDoug Evans 240*01c966b5SDoug Evans /* Receive buffer start address */ 241*01c966b5SDoug Evans #define RX_DESC_RXBSA(word) ((uint32_t) (word) & ~3u) 242*01c966b5SDoug Evans 243*01c966b5SDoug Evans /* Next receive descriptor start address */ 244*01c966b5SDoug Evans #define RX_DESC_NRXDSA(word) ((uint32_t) (word) & ~3u) 245*01c966b5SDoug Evans 246*01c966b5SDoug Evans /* Minimum packet length, when TX_DESC_FLAG_PADEN is set. */ 247*01c966b5SDoug Evans #define MIN_PACKET_LENGTH 64 248*01c966b5SDoug Evans 249*01c966b5SDoug Evans struct NPCM7xxEMCState { 250*01c966b5SDoug Evans /*< private >*/ 251*01c966b5SDoug Evans SysBusDevice parent; 252*01c966b5SDoug Evans /*< public >*/ 253*01c966b5SDoug Evans 254*01c966b5SDoug Evans MemoryRegion iomem; 255*01c966b5SDoug Evans 256*01c966b5SDoug Evans qemu_irq tx_irq; 257*01c966b5SDoug Evans qemu_irq rx_irq; 258*01c966b5SDoug Evans 259*01c966b5SDoug Evans NICState *nic; 260*01c966b5SDoug Evans NICConf conf; 261*01c966b5SDoug Evans 262*01c966b5SDoug Evans /* 0 or 1, for log messages */ 263*01c966b5SDoug Evans uint8_t emc_num; 264*01c966b5SDoug Evans 265*01c966b5SDoug Evans uint32_t regs[NPCM7XX_NUM_EMC_REGS]; 266*01c966b5SDoug Evans 267*01c966b5SDoug Evans /* 268*01c966b5SDoug Evans * tx is active. Set to true by TSDR and then switches off when out of 269*01c966b5SDoug Evans * descriptors. If the TXON bit in REG_MCMDR is off then this is off. 270*01c966b5SDoug Evans */ 271*01c966b5SDoug Evans bool tx_active; 272*01c966b5SDoug Evans 273*01c966b5SDoug Evans /* 274*01c966b5SDoug Evans * rx is active. Set to true by RSDR and then switches off when out of 275*01c966b5SDoug Evans * descriptors. If the RXON bit in REG_MCMDR is off then this is off. 276*01c966b5SDoug Evans */ 277*01c966b5SDoug Evans bool rx_active; 278*01c966b5SDoug Evans }; 279*01c966b5SDoug Evans 280*01c966b5SDoug Evans typedef struct NPCM7xxEMCState NPCM7xxEMCState; 281*01c966b5SDoug Evans 282*01c966b5SDoug Evans #define TYPE_NPCM7XX_EMC "npcm7xx-emc" 283*01c966b5SDoug Evans #define NPCM7XX_EMC(obj) \ 284*01c966b5SDoug Evans OBJECT_CHECK(NPCM7xxEMCState, (obj), TYPE_NPCM7XX_EMC) 285*01c966b5SDoug Evans 286*01c966b5SDoug Evans #endif /* NPCM7XX_EMC_H */ 287