/*
Copyright (C) 2008, 2009  GE Intelligent Platforms, Inc
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#ifndef __PRESTERA_REG_INCLUDED__
#define __PRESTERA_REG_INCLUDED__

#define PRESTERA_SGMII			0
#define PRESTERA_SERDES			1

/* Global Registers */
#define REG_GOP_BIT( gop )		(( 8 + gop ) << 23 )
#define REG_PORT_BIT(port)		((port % 6) << 8 )

#define GLOBAL_CONTROL			0x00000000
#define	GLOBAL_CONFIG			0x00000004
#define GLOBAL_DEVID			0x0000004C
#define GLOBAL_ICR				0x00000030
#define GLOBAL_IMR				0x00000034
#define GLOBAL_MISC_ICR			0x00000038
#define GLOBAL_MISC_IMR			0x0000003C
#define GLOBAL_ICR_GPPINTSUM	( 1 << 15 )
#define GLOBAL_ICR_GOPSUM1(x)	( 1 << (8+(x<<1)) )
#define GLOBAL_ICR_GOPSUM0(x)	( 1 << (7+(x<<1)) )
#define GLOBAL_ICR_MTINTSUM		( 1 << 6 )
#define GLOBAL_ICR_BMINTSUM		( 1 << 5 )
#define GLOBAL_ICR_L2INTSUM		( 1 << 4 )
#define GLOBAL_ICR_TXQINTSUM	( 1 << 3 )
#define GLOBAL_ICR_MISCINTSUM	( 1 << 1 )
#define GLOBAL_ICR_GLOBALINTSUM	( 1 << 0 )

#define TWSI_CONFIG				0x00000010
#define TWSI_LAST_ADDR			0x00000014
#define TWSI_TIMEOUT_LIMIT		0x00000018
#define TWSI_STATE_HISTORY		0x00000020

#define CPU_PORT_CONTROL		0x000000A0
#define CPU_PORT_STATUS			0x000000A4
#define CPU_PORT_SERIAL_CFG		0x000000A8
#define CPU_PORT_SRC_ADDR_MID	0x000000AC
#define CPU_PORT_SRC_ADDR_HI	0x000000B0
#define CPU_PORT_VLAN_ETHERTYPE 0x000000B4
#define CPU_PORT_THRESHOLD		0x000000B8

#define CPU_FRAME_XMIT			0x00000060
#define CPU_FRAME_XMIT_ERR		0x00000064
#define CPU_FRAME_XMIT_BYTE		0x00000068
#define CPU_FRAME_RCVD			0x00000070
#define CPU_FRAME_RCVD_ERR		0x00000074
#define CPU_FRAME_RCVD_BYTE		0x00000078
#define CPU_FRAME_RCVD_ERR_BYTE 0x0000007C

#define P0_P1_VID				0x02000004
#define P2_P3_VID				0x02002004
#define P4_P5_VID				0x02004004
#define P6_P7_VID				0x02006004
#define P8_P9_VID				0x02008004
#define MAC_TABLE_CONTROL		0x06000000
#define VLT_BASE				0x0A000000
#define IVT_BASE				0x0A002000

#if NOTYET
#define PORT_MAC_CONTROL(port)	( 0x00000000 | REG_PORT_BIT(port) | REG_GOP_BIT(port/6) )
#else
#define PORT_MAC_CONTROL		0x00000000
#endif
#  define PORT_MAC_CONTROL_SERDES	( 1 << 14 )
#  define PORT_MAC_ENABLE			( 1 <<  0 )
#if NOTYET
#define PORT_AUTO_NEG(port)		( 0x00000008 | REG_PORT_BIT(port) | REG_GOP_BIT(port/6) )
#else
#define PORT_AUTO_NEG			0x00000008
#endif
#  define PORT_AUTO_NEG_INBAND	( 1 << 10 )
#  define PORT_AUTO_NEG_RESTART	( 1 << 11 )
#  define PORT_AUTO_NEG_SPEED	( 1 <<  7 )
#  define PORT_AUTO_NEG_SFCEN	( 1 <<  6 )
#  define PORT_AUTO_NEG_ANFC	( 1 <<  4 )
#  define PORT_AUTO_NEG_SFD		( 1 <<  3 )
#  define PORT_AUTO_NEG_DUPLEX	( 1 <<  2 )
#  define PORT_AUTO_NEG_LINKUP	( 1 <<  1 )
#  define PORT_AUTO_NEG_LINKDWN ( 1 <<  0 )
#define PORT_MAC_STATUS(port)	( 0x00000004 | REG_PORT_BIT(port) | REG_GOP_BIT(port/6) )
#  define PORT_MAC_STATUS_LINK_UP ( 1 << 0 )
#define PORT_SERDES_CFG(port)	( 0x00000010 | REG_PORT_BIT(port) | REG_GOP_BIT(port/6) )
#  define PORT_SERDES_CFG_PU_TX	( 1 << 14 )
#  define PORT_SERDES_CFG_RESET	( 1 << 15 )
#define PORT_PRBS_STATUS(port)	( 0x00000014 | REG_PORT_BIT(port) | REG_GOP_BIT(port/6) )

#define PORT_GOP_SERIAL(port)		( 0x00004018 | REG_GOP_BIT(port/6) )
#define PORT_GOP_SRC_ADDR_HI(port)	( 0x00004024 | REG_GOP_BIT(port/6) )
#define PORT_GOP_SRC_ADDR_MID(port)	( 0x00004028 | REG_GOP_BIT(port/6) )
#define PORT_GOP_VLAN_ETHERTYPE(port)	( 0x0000402C | REG_GOP_BIT(port/6) )
#define PORT_GOP_ICR0(port)			( 0x00004000 | REG_GOP_BIT(port/6) )
#  define PORT_GOP_ICR0_ACCESS		( 1 << 25 )
#  define PORT_GOP_ICR0_TXFIFO(x)	( 1 << (19+x) )
#  define PORT_GOP_ICR0_RXFIFO(x)	( 1 << (13+x) )
#  define PORT_GOP_ICR0_ANDONE(x)	( 1 << ( 7+x) )
#  define PORT_GOP_ICR0_LINK(x)		( 1 << ( 1+x) )
#define PORT_GOP_IMR0(port)			( 0x00004004 | REG_GOP_BIT(port/6) )
#define PORT_GOP_ICR1(port)			( 0x00004008 | REG_GOP_BIT(port/6) )
#define PORT_GOP_ICR1_TXCRC(x)		( 1 << (13+x) )
#define PORT_GOP_ICR1_PRBS(x)		( 1 << ( 7+x) )
#define PORT_GOP_ICR1_SYNC(x)		( 1 << ( 1+x) )
#define PORT_GOP_IMR1(port)			( 0x0000400C | REG_GOP_BIT(port/6) )

#define MIB_COUNTER_CONTROL(port)	( 0x00004020 | REG_GOP_BIT(port/6) )
#  define MIB_COUNTER_CONTROL_PORT_ENABLE(x) ( 1 << ( 8 + x ) )
#  define MIB_COUNTER_CONTROL_PORT_CAPTURE(x)( ( x << 1 | 0x1 ) )
#  define MIB_COUNTER_CONTROL_COPYDONE	0x1
#define MIB_COUNTER_PORT_SIZE			0x00000080
#define MIB_COUNTER_PORT_OFFSET(port)	( (0x00010000 + (MIB_COUNTER_PORT_SIZE * (port%6))) | REG_GOP_BIT(port/6))
#define MIB_COUNTER_GOP_OFFSET(port)	( 0x00010300 | REG_GOP_BIT(port/6) )
#define MIB_COUNTER_GOP_END(port)		( 0x0001037C | REG_GOP_BIT(port/6) )

#define SMI_MANAGEMENT_0			0x04004054
#define SMI_MANAGEMENT_1			0x05004054
#  define SMI_MANAGEMENT_BUSY			( 1 << 28 )
#  define SMI_MANAGEMENT_READVALID		( 1 << 27 )
#  define SMI_MANAGEMENT_SETREAD( x )		( x |= ( 1 << 26 ) )
#  define SMI_MANAGEMENT_SETWRITE( x )		( x &= ~( 1 << 26 ) )
#  define SMI_MANAGEMENT_SETPHY( x )		( ( x & 0x1F) << 16 )
#  define SMI_MANAGEMENT_SETREG( x )		( ( x & 0x1F) << 21 )
#  define SMI_MANAGEMENT_DATA( x )		( x & 0xFFFF )
#define SMI_PHY_ADDR(port)			( 0x0004030 | REG_GOP_BIT(port/6) )
#define SMI_CONTROL(port)			( 0x0004034 | REG_GOP_BIT(port/6) )

#define PRESTERA_GLOBAL_DEVICE_ID			0xD151

#define PRESTERA_RESET_WAIT					200

typedef struct _MIB_COUNTER_OVERLAY  {
	uint32_t	GoodOctetsReceivedLsb;		/* 0x00 */
	uint32_t	GoodOctetsReceivedMsb;		/* 0x04 */
	uint32_t	BadOctetsReceived;			/* 0x08 */
	uint32_t	MACTransErr;				/* 0x0C */
	uint32_t	GoodFramesReceived;			/* 0x10 */
	uint32_t	BadFramesReceived;			/* 0x14 */
	uint32_t	BroadcastFramesReceived;	/* 0x18 */
	uint32_t	MulticastFramesReceived;	/* 0x1C */
	uint32_t	Frames64Octets;				/* 0x20 */
	uint32_t	Frames65to127Octets;		/* 0x24 */
	uint32_t	Frames128to255Octets;		/* 0x28 */
	uint32_t	Frames256to511Octets;		/* 0x2C */
	uint32_t	Frames512to1023Octets;		/* 0x30 */
	uint32_t	Frames1024toMaxOctets;		/* 0x34 */
	uint32_t	GoodOctetsSentLsb;			/* 0x38 */
	uint32_t	GoodOctetsSentMsb;			/* 0x3C */
	uint32_t	GoodFramesSent;				/* 0x40 */
	uint32_t	ExcessiveCollision;			/* 0x44 */
	uint32_t	MulticastFramesSent;		/* 0x48 */
	uint32_t	BroadcastFramesSent;		/* 0x4C */
	uint32_t	UnrecogMACControlReceived;	/* 0x50 */
	uint32_t	FCSent;						/* 0x54 */
	uint32_t	GoodFCReceived;				/* 0x58 */
	uint32_t	DropEvent;					/* 0x5C */
	uint32_t	Undersize;					/* 0x60 */
	uint32_t	Fragments;					/* 0x64 */
	uint32_t	Oversize;					/* 0x68 */
	uint32_t	Jabber;						/* 0x6C */
	uint32_t	MACRcvError;				/* 0x70 */
	uint32_t	BadCRC;						/* 0x74 */
	uint32_t	Collisions;					/* 0x78 */
	uint32_t	LateCollisions;				/* 0x7C */
} MIB_COUNTER_OVERLAY_t;


#endif
