use tock_registers::{register_bitfields, register_structs, registers::ReadWrite};

register_bitfields! {
    u32,
    pub DMAMR [
        /// Interrupt mode
        INTM    OFFSET(16)  NUMBITS(2)  [],
        /// Transmit priority
        TXPR    OFFSET(11)  NUMBITS(1)  [],
        /// Descriptor posted write
        DSPW    OFFSET(8)   NUMBITS(1)  [],
        /// Transmit arbitration algorithm
        TAA     OFFSET(2)   NUMBITS(3)  [],
        /// Software reset
        ///
        /// When this bit is set, the MAC and the DMA controllers are reset. This bit is cleared
        /// automatically when the MAC/DMA reset completes.
        SWR     OFFSET(0)   NUMBITS(1)  [],
    ],

    pub DMASBMR [
        /// Enable Low Power interface
        EN_LPI      OFFSET(31)  NUMBITS(1)  [],
        /// Unlock on Magic packet or Remote Wakeup packet
        LPI_XIT_PKT OFFSET(30)  NUMBITS(1)  [],
        /// AXI maximum write outstanding request limit
        ///
        /// Maximum outstanding requests = WR_OSR_LMT + 1
        WR_OSR_LMT  OFFSET(24)  NUMBITS(2)  [],
        /// AXI maximum reaad outstanding request limit
        ///
        /// Maximum outstanding requests = RD_OSR_LMT + 1
        RD_OSR_LMT  OFFSET(16)  NUMBITS(2)  [],
        /// 1 Kbyte boundary crossing enable for the AXI master
        ///
        /// If set, the burst transfers performed by the AXI master do not cross 1 Kbyte boundary
        /// If not, the transfers do not cross 4 Kbyte boundary
        ONEKBBE     OFFSET(13)  NUMBITS(1)  [],
        /// Address aligned bursts
        ///
        /// If set, the master performs addres-aligned burst transfers on read and write channels
        AAL         OFFSET(12)  NUMBITS(1)  [],
        /// Automatic AXI LPI enable
        ///
        /// When set, enables AXI master to enter into LPI state when there is no activity on the
        /// Ethernet peripheral for a number of clock cycles programmed in ETH_DMALPIEI register.
        AALE        OFFSET(10)  NUMBITS(1)  [],
        /// AXI burst length 256
        BLEN256     OFFSET(7)   NUMBITS(1)  [],
        /// AXI burst length 128
        BLEN128     OFFSET(6)   NUMBITS(1)  [],
        /// AXI burst length 64
        BLEN64      OFFSET(5)   NUMBITS(1)  [],
        /// AXI burst length 32
        BLEN32      OFFSET(4)   NUMBITS(1)  [],
        /// AXI burst length 16
        BLEN16      OFFSET(3)   NUMBITS(1)  [],
        /// AXI burst length 8
        BLEN8       OFFSET(2)   NUMBITS(1)  [],
        /// AXI burst length 4
        BLEN4       OFFSET(1)   NUMBITS(1)  [],
        /// Fixed burst length
        FB          OFFSET(0)   NUMBITS(1)  [],
    ],

    pub DMACiCR [
        /// Descriptor skip length
        DSL     OFFSET(18)  NUMBITS(1)  [],
        /// 8xPBL mode
        PBLX8   OFFSET(16)  NUMBITS(1)  [],
        /// Maximum segment size
        MSS     OFFSET(0)   NUMBITS(14)  [],
    ],

    pub DMACiTXCR [
        /// Tx QOS
        TQOS    OFFSET(24)  NUMBITS(4)  [],
        /// Transmit programmable burst length
        TXPBL   OFFSET(16)  NUMBITS(6)  [],
        /// Ignore PBL requirement
        IPBL    OFFSET(15)  NUMBITS(1)  [],
        /// TCP segmentation enabled
        TSE     OFFSET(12)  NUMBITS(1)  [],
        /// Operate on second packet
        OSF     OFFSET(4)   NUMBITS(1)  [],
        /// Tx channel weight
        TCW     OFFSET(1)   NUMBITS(3)  [],
        /// Start or stop Tx command
        ///
        /// When set, the DMA checks the transmit list at current position for a packet to be
        /// transmitted. If the DMA does not own the current descriptor, the transmission enters
        /// the Suspended state with TBU bit in DMACiSR set.
        ST      OFFSET(0)   NUMBITS(1)  [],
    ],

    pub DMAC0RXCR [
        /// DMA Rx channel 0 packet flush
        ///
        /// When set, the DMA automatically flushes the packet from the Rx queues destined to DMA
        /// Rx channel 0 when the DMA Rx 0 is stopped after a system bus error.
        RPF     OFFSET(31)  NUMBITS(1)  [],
        /// Rx QOS
        RQOS    OFFSET(24)  NUMBITS(4)  [],
        /// Rx programmable burst length
        RXPBL   OFFSET(16)  NUMBITS(6)  [],
        /// Receive buffer size
        RBSZ    OFFSET(1)   NUMBITS(14) [],
        /// Start or stop Rx
        ///
        /// When set, the DMA tries to acquire the descriptor from the receive list and process the
        /// incoming packets.
        SR      OFFSET(0)   NUMBITS(1)  [],
    ],

    pub DMACiIER [
        /// Normal interrupt summary enable
        ///
        /// When this bit is set, the following interrupts are enabled in the Channel i status
        /// register:
        ///
        /// * Tx interrupt
        /// * Tx buffer unavailable
        /// * Rx interrupt
        /// * Early Rx interrupt
        NIE     OFFSET(15)  NUMBITS(1)  [],
        /// Abnormal interrupt summary enable
        ///
        /// When this bit is set, the following interrupt summary is enabled:
        ///
        /// * Tx process stopped
        /// * Rx buffer unavailable
        /// * Rx process stopped
        /// * Rx watchdog timeout
        /// * Early Tx interrupt
        /// * Fatal bus error
        AIE     OFFSET(14)  NUMBITS(1)  [],
        /// Context descriptor error enable (+AIE)
        CDEE    OFFSET(13)  NUMBITS(1)  [],
        /// Fatal bus error enable (+AIE)
        FBEE    OFFSET(12)  NUMBITS(1)  [],
        /// Early Rx interrupt enable
        ///
        /// When this bit is set along with the NIE bit, the Early Rx interrupt is enabled
        ERIE    OFFSET(11)  NUMBITS(1)  [],
        /// Early Tx interrupt enable
        ///
        /// When this bit is set along with the AIE bit, the Early Tx interrupt is enabled
        ETIE    OFFSET(10)  NUMBITS(1)  [],
        /// Receive watchdog timeout enable (+AIE)
        RWTE    OFFSET(9)   NUMBITS(1)  [],
        /// Rx stopped enable (+AIE)
        RSE     OFFSET(8)   NUMBITS(1)  [],
        /// Rx buffer unavailable enable (+AIE)
        RBUE    OFFSET(7)   NUMBITS(1)  [],
        /// Rx interrupt enable (+NIE)
        RIE     OFFSET(6)   NUMBITS(1)  [],
        /// Tx buffer unavailable enable (+NIE)
        TBUE    OFFSET(2)   NUMBITS(1)  [],
        /// Tx stopped enable (+AIE)
        TXSE    OFFSET(1)   NUMBITS(1)  [],
        /// Tx interrupt enable (+NIE)
        TIE     OFFSET(0)   NUMBITS(1)  [],
    ],

    pub DMACiSR [
        /// Rx DMA error bits
        REB     OFFSET(19)  NUMBITS(3)  [],
        /// Tx DMA error bits
        TEB     OFFSET(16)  NUMBITS(3)  [],
        /// Normal interrupt summary
        NIS     OFFSET(15)  NUMBITS(1)  [],
        /// Abnormal interrupt summary
        AIS     OFFSET(14)  NUMBITS(1)  [],
        /// Context descriptor error
        CDE     OFFSET(13)  NUMBITS(1)  [],
        /// Fatal bus error
        FBE     OFFSET(12)  NUMBITS(1)  [],
        /// Early Rx interrupt
        ERI     OFFSET(11)  NUMBITS(1)  [],
        /// Early Tx interrupt
        ETI     OFFSET(10)  NUMBITS(1)  [],
        /// Rx watchdog timeout
        RWT     OFFSET(9)   NUMBITS(1)  [],
        /// Rx process stopped
        RPS     OFFSET(8)   NUMBITS(1)  [],
        /// Rx buffer unavailable. To resume processing Rx descriptors, the driver should change
        /// the ownership of the descriptors and issue a Rx Poll Demand command. In ring mode, the
        /// driver should advance the Rx descriptor tail pointer of a channel.
        RBU     OFFSET(7)   NUMBITS(1)  [],
        /// Rx interrupt
        RI      OFFSET(6)   NUMBITS(1)  [],
        /// Tx buffer unavailable (see RBU, but for Tx)
        TBU     OFFSET(2)   NUMBITS(1)  [],
        /// Tx process stopped
        TPS     OFFSET(1)   NUMBITS(1)  [],
        /// Tx interrupt
        TI      OFFSET(0)   NUMBITS(1)  [],
    ],
}

register_structs! {
    pub DmaRegs {
        (0x000 => pub DMAMR: ReadWrite<u32, DMAMR::Register>),
        (0x004 => pub DMASBMR: ReadWrite<u32, DMASBMR::Register>),
        (0x008 => pub DMAISR: ReadWrite<u32>),
        (0x00C => pub DMADSR: ReadWrite<u32>),
        (0x010 => _0),
        (0x020 => pub DMAA4TXACR: ReadWrite<u32>),
        (0x024 => pub DMAA4RXACR: ReadWrite<u32>),
        (0x028 => pub DMAA4DACR: ReadWrite<u32>),
        (0x02C => _1),
        (0x040 => pub DMALPIEI: ReadWrite<u32>),
        (0x044 => _2),
        (0x100 => pub DMAC0CR: ReadWrite<u32, DMACiCR::Register>),
        (0x104 => pub DMAC0TXCR: ReadWrite<u32, DMACiTXCR::Register>),
        (0x108 => pub DMAC0RXCR: ReadWrite<u32, DMAC0RXCR::Register>),
        (0x10C => _3),
        (0x114 => pub DMAC0TXDLAR: ReadWrite<u32>),
        (0x118 => _4),
        (0x11C => pub DMAC0RXDLAR: ReadWrite<u32>),
        (0x120 => pub DMAC0TXDTPR: ReadWrite<u32>),
        (0x124 => _5),
        (0x128 => pub DMAC0RXDTPR: ReadWrite<u32>),
        (0x12C => pub DMAC0TXRLR: ReadWrite<u32>),
        (0x130 => pub DMAC0RXRLR: ReadWrite<u32>),
        (0x134 => pub DMAC0IER: ReadWrite<u32, DMACiIER::Register>),
        (0x138 => pub DMAC0RXIWTR: ReadWrite<u32>),
        (0x13C => pub DMAC0SFCSR: ReadWrite<u32>),
        (0x140 => _6),
        (0x144 => pub DMAC0CATXDR: ReadWrite<u32>),
        (0x148 => _7),
        (0x14C => pub DMAC0CARXDR: ReadWrite<u32>),
        (0x150 => _8),
        (0x154 => pub DMAC0CATXBR: ReadWrite<u32>),
        (0x158 => _9),
        (0x15C => pub DMAC0CARXBR: ReadWrite<u32>),
        (0x160 => pub DMAC0SR: ReadWrite<u32, DMACiSR::Register>),
        (0x164 => _10),
        (0x16C => pub DMAC0MFCR: ReadWrite<u32>),
        (0x170 => _11),
        (0x200 => @END),
    }
}
