#ifndef __zlregs_h__
#define __zlregs_h__

//
// Group 0: Ethernet port control 
//

#define ECR1P_ADDR(port) (2*(port))
#define ECR2P_ADDR(port) ((2*(port))+ 1)
#define ECR3P_ADDR(port) ((2*(port))+ 0x080)
#define ECR4P_ADDR(port) ((2*(port))+ 0x081)

//
// Group 1: VLAN control
//

#define PVMAP_0_ADDR(port) ((4*(port)) + 0x102)
#define PVMAP_1_ADDR(port) ((4*(port)) + 0x103)
#define PVMAP_3_ADDR(port) ((4*(port)) + 0x105)

#define PVMODE (0x170) // VLAN operating mode

// PVMODE bit fields
#define TAG_BASED_VLAN (0x01)
#define SLOW_LEARNING (0x02)
#define DISABLE_FRAME_DROP (0x04)
#define FLOOD_CONTROL_DISABLE (0x08)
#define MAC_ADDR_ZERO_LEARNED (0x10)
#define FORWARD_AS_MULTICAST (0x20)
#define IP_MULTICAST_ENABLE (0x40)
#define SECURE_LOG_PORT_MATCH (0x80)

//
// Group 2: Trunk control
//

#define TRUNK_GROUP(group)  ((group) + 0x200)
#define TRANK_HASH10(group) ((4*(group)) + 0x208)
#define TRANK_HASH32(group) ((4*(group)) + 0x209)
#define TRANK_HASH54(group) ((4*(group)) + 0x20a)
#define TRANK_HASH76(group) ((4*(group)) + 0x20b)

#define MCAST_HASH_L(hash) ((2*(hash)) + 0x228)
#define MCAST_HASH_H(hash) ((2*(hash)) + 0x229)

//
// Group 3: CPU port configuration
//

#define MAC0 (0x300) // MSB
#define MAC1 (0x301)
#define MAC2 (0x302)
#define MAC3 (0x303)
#define MAC4 (0x304)
#define MAC5 (0x305) // LSB

#define INT_MASK0 (0x306)

#define INTP_MASK(port) (0x310 + ((port) >> 1))
#define INTP_MASK0 (0x310)
#define INTP_MASK1 (0x311)
#define INTP_MASK2 (0x312)
#define INTP_MASK3 (0x313)
#define INTP_MASK4 (0x314)

#define CPU_FRAME_INT_MASK (0x01)
#define CONTROL_FRAME_1_INT_MASK (0x02)
#define CONTROL_FRAME_2_INT_MASK (0x04)

#define PORT_EVEN_WAS_INT_MASK (0x01)
#define PORT_EVEN_LNK_CHANGE_INT_MASK (0x02)
#define PORT_EVEN_MOD_DETECT_INT_MASK (0x04)

#define PORT_ODD_WAS_INT_MASK (0x10)
#define PORT_ODD_LNK_CHANGE_INT_MASK (0x20)
#define PORT_ODD_MOD_DETECT_INT_MASK (0x40)

#define RQS  (0x323) // receive queue select
#define RQSS (0x324) // receive queue status 

#define MACB01 (0x325) // increment MAC port 0,1 byte5[0:3] addr
#define MACB23 (0x326) // increment MAC port 2,3 byte5[0:3] addr
#define MACB45 (0x327) // increment MAC port 4,5 byte5[0:3] addr
#define MACB67 (0x328) // increment MAC port 6,7 byte5[0:3] addr
#define MACB5G (0x329) // gig MAC last byte value

#define CPUQINS(n) (0x330 + (n)) // n = 0..6
#define CPUQINSRPT (0x337)
#define CPUGRNHDL0 (0x338)
#define CPUGRNHDL1 (0x339)
#define CPURLSINFO(n) (0x33a + (n)) // n = 0..4
#define CPUGRNCTR  (0x33f)

//
// Group 4: Search engine configuration
//

#define AGETIME_LOW  (0x400)
#define AGETIME_HIGH (0x401)
#define SE_OPMODE    (0x403)

// SE_OPMODE bit fields
#define PROTOCOL_FILTERING_EXCLUSIVE (0x02)
#define DISABLE_REPORT_DELETE_MAC    (0x04)
#define DISABLE_MAC_AGING            (0x08)
#define ENABLE_SLOW_LEARNING         (0x80)

//
// Group 5: Buffer and QOS control
//

#define QOSC  (0x500) // QOS control
#define UCC   (0x510) // unicast congestion control
#define MCC   (0x511) // multicast congestion control
#define MCCTH (0x512) // multicast threshold control
#define RDRC0 (0x513) // WRED drop rate control 0 
#define RDRC1 (0x514) // WRED drop rate control 1
#define RDRC2 (0x515) // WRED drop rate control 2
 

//
// Group 6: Miscellaneous configuration
//

#define MII_OP0 (0x600) // MII register option 0
#define MII_OP1 (0x601) // MII register option 1

#define FEN     (0x602) // Feature enable 

// FEN bit fields
#define STATISTIC_COUNTER_ENABLE   (0x01)
#define RATE_CONTROL_ENABLE        (0x02)
#define SUPPORT_DS_EF_CODE         (0x04)
#define VLAN_HASHING_ENABLE        (0x08)
#define IP_MULTICAST_DISABLE       (0x10)
#define NEW_MAC_VLAN_REPORT_ENABLE (0x20)
#define MII_STATE_MACHINE_DISABLE  (0x40)
#define MCT_LINK_LIST_DISABLE      (0x80)

#define MIIC0   (0x603) // MII command reg 0
#define MIIC1   (0x604) // MII command reg 1
#define MIIC2   (0x605) // MII command reg 2

// MIIC2 bit fields
#define MII_READ_OP  (0x40)
#define MII_WRITE_OP (0x20)

#define MIIC3   (0x606) // MII command reg 3

// MIIC3 bit fields
#define MII_READY (0x80)
#define MII_VALID (0x40)

#define MIID0   (0x607) // MII data reg 0
#define MIID1   (0x608) // MII data reg 1

#define USD     (0x609) // 1 uSec divider

#define DEVICE  (0x60a) // Device ID and test
#define SUM     (0x60b) // EEPROM checksum

#define LHBTIMER (0x610) // Link heartbeat timeout timer
#define LHBREG0  (0x611) // LHB control field value[ 7:0]
#define LHBREG1  (0x612) // LHB control field value[15:8]

#define FMACCREG0 (0x613)
#define FMACCREG1 (0x614)

#define FCB_BASE_ADDR0 (0x620)
#define FCB_BASE_ADDR1 (0x621)
#define FCB_BASE_ADDR2 (0x622)

//
// Group 7: Port mirroring
//

#define MIRROR_CTL (0x70c)
#define RMII_MIRROR(n) (0x710 + (n)) // physical mirroring n=0,1
 
//
// Group 8: Per port QOS Control

#define FCR_P(port)    ((port) + 0x800) // flooding control for ports 0-9
#define BMRC_P(port)   ((port) + 0x820) // bcast/mcast rate control for pts 0-9
#define PR100_P(port)  ((port) + 0x840) // port reservation for 10/100 (0-7)
#define PRG            (0x849) // port reservation for GB port
#define PR100_CPU      (0x848) // port reservation for CPU port
#define PTH100_P(port) ((port) + 0x860) // port threshold for 10/100 ports
#define PTHG           (0x869) // port threshold for GB port
#define PTH100_CPU     (0x868) // port threshold for CPU port

#define QOSC_P_L1(port) (0x880 + 2 * (port)) // port 0-7 queue 1
#define QOSC_P_L2(port) (0x881 + 2 * (port)) // port 0-7 queue 2

#define QOSC_CPU_L1(q)  (0x890 + 2 * (q)) // cpu port queue 1-3 (0-2)
#define QOSC_CPU_L2(q)  (0x891 + 2 * (q)) // cpu port queue 1-3 (0-2)

#define QOSC_GIG_L1(q)  (0x896 + 2 * (q)) // GB port queue 1-3 (0-2)
#define QOSC_GIG_L2(q)  (0x897 + 2 * (q)) // GB port queue 1-3 (0-2)

#define QOSC_WFQ_C(q)   (0x89c + (q)) // GB port WFQ credit q0-q3
#define QOSC_SHAPER_C(q)(0x8a4 + (q)) // GB port shaper control q0-q3

#define RATE_MASK (0x80)
#define U2MR_MASK (0x0f)

//
// Group E: Test group control
//

#define DTSRL (0xe00) // test register
#define DTSRM (0xe01) 
#define TESTOUT0 (0xe02) // test output register [ 7:0]
#define TESTOUT1 (0xe03) // test output register [15:8]

#define MASK0 (0xe10) // mask timeout
#define MASK1 (0xe11) // mask timeout
#define MASK2 (0xe12) // mask timeout
#define MASK3 (0xe13) // mask timeout
#define MASK4 (0xe14) // mask timeout

#define BOOTSTRAP0 (0xe80) // bootstrap value of test[ 7:0]
#define BOOTSTRAP1 (0xe81) // bootstrap value of test[15:8]
#define BOOTSTRAP2 (0xe82) // bootstrap value of port 0-7
#define BOOTSTRAP3 (0xe83) // bootstrap for GB port

//
// Group F: Device configuration
//

#define GCR (0xf00) // global control register

// GCR bit fields
#define STORE_CONFIG (0x01)
#define STORE_RESET  (0x02)
#define START_BIST   (0x04)
#define SOFT_RESET   (0x08)
#define INIT_DONE    (0x10)

#define DCR (0xf01) // device control register

// DCR bit fields
#define BW (0x01)
#define BR (0x02)
#define BIST_INP (0x04)
#define RAM_ERROR (0x08)
#define SIGNATURE_MASK (0x30)
#define REVISION_MASK  (0xC0)

#define DCR1 (0xf02) // GB port status
#define DPST (0xf03) // device port status selector register
#define DTST (0xf04) // data read back register
#define DA (0xfff) // 'dead or alive' register -- returns 0xda always

//
// Bit masks for Command/Status register
// RX and TX are from the CPU's point of view relative to Zarlink
//

#define CMD_CONTROL_FRAME_RX_DONE (0x01) // after cpu write frame complete
#define CMD_CONTROL_FRAME_BUF1_TX_DONE (0x02) // after cpu reads out frame
#define CMD_CONTROL_FRAME_BUF2_TX_DONE (0x04) // after cpu reads out frame
#define CMD_CPU_FRAME_TX_DONE_AND_FLUSH (0x08) // entire frame received OK
#define CMD_LAST_BYTE_WRITE (0x10) // set to indicate transfer of whole frame
#define CMD_RESTART_RX_FIFO (0x20) // restart receive FIFO on Zarlink from CPU

#define STATUS_CONTROL_FRAME_RX_RDY (0x01) // ready for CPU to write new frame
#define STATUS_CONTROL_FRAME_TX_BUF1_RDY (0x02) // ready for cpu to read 
#define STATUS_CONTROL_FRAME_TX_BUF2_RDY (0x04) // ready for cpu to read 
#define STATUS_CPU_FRAME_TX_BUF_RDY (0x08) // txfifo has data for cpu to read
#define STATUS_CPU_FRAME_RX_BUF_RDY (0x10) // rxfifo has space for frame write
#define STATUS_CPU_FRAME_TX_EOF (0x20) // txfifo end of frame

#endif /* __zlregs_h__ */

