/******************************************************************************
 *
 * Name:	skdrv1st.h
 * Project:	SysKonnect SK-9Dxx Gigabit Ethernet
 * Version:	$Revision: 1.7 $
 * Date:	$Date: 2001/10/22 15:47:02 $
 * Purpose:	First header file for driver and all other modules
 *
 ******************************************************************************/

/******************************************************************************
 *
 *	(C)Copyright 2001 SysKonnect GmbH.
 *
 *	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.
 *
 *	The information in this file is provided "AS IS" without warranty.
 *
 ******************************************************************************/

/******************************************************************************
 *
 * History:
 *
 *	$Log: skdrv1st.h,v $
 *	Revision 1.7  2001/10/22 15:47:02  rschmidt
 *	Defines for diff MTU sizes
 *	
 *	Revision 1.6  2001/10/05 13:35:52  rschmidt
 *	Moved defines for HIGH32, LOW32 from HWAC
 *	
 *	Revision 1.5  2001/08/23 08:16:39  mlindner
 *	Added typedef for SK_TX_PACKET
 *	
 *	Revision 1.4  2001/08/14 14:15:20  rschmidt
 *	Eliminated define for SK_JUMBO.
 *	
 *	Revision 1.3  2001/08/08 13:03:10  rschmidt
 *	Added SkErrorLog(), changed DMA descriptors (address field) and
 *	moved some register values and macros into skgihw.h.
 *	
 *	Revision 1.2  2001/06/05 15:09:40  rassmann
 *	Kernel 2.4 support.
 *	
 *	Revision 1.1  2001/06/05 08:28:24  rassmann
 *	First public version.
 *	
 *
 ******************************************************************************/

/******************************************************************************
 *
 * Description:
 *
 * This is the first include file of the driver, which includes all
 * neccessary system header files and some of the GEnesis header files.
 * It also defines some basic items.
 *
 * Include File Hierarchy:
 *
 *	see skgi.c
 *
 ******************************************************************************/

#ifndef __INC_SKDRV1ST_H
#define __INC_SKDRV1ST_H

#include <linux/version.h>

#if (LINUX_VERSION_CODE < 0x020300)
#define	SK_KERNEL_22
#endif	/* (LINUX_VERSION_CODE < 0x020300) */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#ifdef SK_KERNEL_22
#include <linux/malloc.h>
#else  /* !SK_KERNEL_22 */
#include <linux/slab.h>
#endif /* !SK_KERNEL_22 */
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <asm/byteorder.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <net/checksum.h>
#include <linux/delay.h>

#include "h/sktypes.h"
#include "h/skdebug.h"
#include "h/skerror.h"


#ifdef SK_KERNEL_22

#define	INITFUNC(Type,Function,Parms)	__initfunc(Type Function Parms)
#define	INITMOD(Type,Pre,Name,Parms)	Type Name Parms
#define	EXITMOD(Type,Pre,Name,Parms)	Type Name Parms
typedef struct device		NET_DEV;

#else  /* !SK_KERNEL_22 */

#define	INITFUNC(Type,Function,Parms)	static Type __init Function (void)
#define	INITMOD(Type,Pre,Name,Parms)	static Type __init Pre##Name Parms
#define	EXITMOD(Type,Pre,Name,Parms)	static Type __exit Pre##Name Parms
typedef struct net_device	NET_DEV;

#endif /* !SK_KERNEL_22 */

#ifdef __LITTLE_ENDIAN
#define	SK_LITTLE_ENDIAN
#else	/* !__LITTLE_ENDIAN */
#define SK_BIG_ENDIAN
#endif	/* !__LITTLE_ENDIAN */

/* Enable 16-bit PCI Conf. access */
#define PCI_CONF_16BIT

/* Defines for RLMT */
#define	SK_MAX_MACS		1
#define	SK_MAX_NETS		1

/* Enable WAs. */
#define	SK_WA_B2_3
#define	SK_WA_B2_5
#define	SK_WA_BX_1
#define	SK_WA_BX_5
/* #define	SK_WA_BX_7 */
#define	SK_WA_BX_10

#ifndef	SK_WA_BX_1
#define	SK_OSTIMER_STOPPABLE
#endif	/* !SK_WA_BX_1 */

#ifdef	SK_WA_BX_7
Not sure what has to be done.
#endif	/* SK_WA_BX_7 */

#define SK_TICKS_PER_SEC	HZ
#define	SK_USEC_PER_TICK	(1000000 / HZ)
#define	SK_NUM_RX_RINGS		16
#define	SK_NUM_TX_RINGS		1

#define SK_ALLOC_IRQ		0x00000001

#define SK_MEM_ALLOC_ERR    "Unable to allocate memory for"

/* These sizes exclude header and CRC bytes. */
#define	ETH_MIN_FRAME_SIZE	60
#define	SK_MIN_MTU			ETH_MIN_FRAME_SIZE
#define	SK_NORM_MTU			ETH_DATA_LEN
#define	SK_JUMBO_MTU		9000
#define	SK_MAX_MTU			SK_JUMBO_MTU

/* These sizes include header and CRC bytes. */
#define	SK_MIN_ETHSIZE		64
#define	SK_NORM_ETHSIZE		1518
#define	SK_JUMBO_ETHSIZE	9018

#define SkOsGetTime(pAC)		((SK_U64)(jiffies))
#define SkOsGetTimeUsec(pAC,pUsec)	\
{								\
	struct timeval t;			\
	do_gettimeofday(&t);		\
	*pUsec = (((t.tv_sec) * 1000000L) + t.tv_usec);	\
}

#define SkOsWaitUsec(pAC,Usec)	udelay(Usec)
#define SkOsWaitMsec(pAC,Msec)	mdelay(Msec)

#define SK_MEMCPY(dest,src,size)	memcpy(dest,src,size)
#define SK_MEMCMP(s1,s2,size)		memcmp(s1,s2,size)
#define SK_MEMSET(dest,val,size)	memset(dest,val,size)
#define SK_STRLEN(pStr)				strlen((char*)pStr)
#define SK_STRNCPY(pDest,pSrc,size)	strncpy((char*)pDest,(char*)pSrc,size)
#define SK_STRCMP(pStr1,pStr2)		strcmp((char*)pStr1,(char*)pStr2)

/* Macros to access the adapter. */
#define SK_OUT8(b,a,v)		writeb((v), ((b) + (a)))
#define SK_OUT16(b,a,v)		writew((v), ((b) + (a)))
#define SK_OUT32(b,a,v)		writel((v), ((b) + (a)))
#define SK_IN8(b,a,pv)		(*(pv) = readb((b) + (a)))
#define SK_IN16(b,a,pv)		(*(pv) = readw((b) + (a)))
#define SK_IN32(b,a,pv)		(*(pv) = readl((b) + (a)))

#define SK_PCI_OUT8(p,o,v)	pci_write_config_byte(&(p)->PciDev, (o), (v))
#define SK_PCI_OUT16(p,o,v)	pci_write_config_word(&(p)->PciDev, (o), (v))
#define SK_PCI_OUT32(p,o,v)	pci_write_config_dword(&(p)->PciDev, (o), (v))
#define SK_PCI_IN8(p,o,pv)	pci_read_config_byte(&(p)->PciDev, (o), (pv))
#define SK_PCI_IN16(p,o,pv)	pci_read_config_word(&(p)->PciDev, (o), (pv))
#define SK_PCI_IN32(p,o,pv)	pci_read_config_dword(&(p)->PciDev, (o), (pv))

#define SK_MEM_RD32(p,o,pv)						\
	SK_PCI_OUT32((p), PCI_MEM_WIN_BASE, (o));	\
	SK_PCI_IN32((p), PCI_MEM_WIN_DATA, (pv))

#define SK_MEM_WR32(p,o,v)						\
	SK_PCI_OUT32((p), PCI_MEM_WIN_BASE, (o));	\
	SK_PCI_OUT32((p), PCI_MEM_WIN_DATA, (v))

#define PHY_READ16(io, ofs, pData)		\
{										\
	SK_U32	__loc32;					\
	int		__i;						\
	SK_OUT32((io), MI_COMMUNICATION,									\
		MI_START | MI_CMD_READ | MI_PHY_ADDR(MDI_PHY_ADDR) | 			\
		MI_REG_ADDR(ofs));												\
	__i = 0;															\
	do {																\
		SkOsWaitUsec(pAC, 10);											\
		SK_IN32((io), MI_COMMUNICATION, &__loc32);						\
		__i++;															\
	} while ((__loc32 & MI_START) && (__i < 5000));						\
	if (__i == 5000) {													\
		SK_DBG_MSG(pAC, 0xffffffff, 0xffffffff, ("PHY_READ16 error"));	\
	}																	\
	SK_IN32((io), MI_COMMUNICATION, &__loc32);							\
	*pData = (SK_U16)(__loc32 & 0xffff);								\
}

#define PHY_WRITE16(io, ofs, Data)		\
{										\
	SK_U32	__loc32;					\
	int		__i;						\
	SK_OUT32((io), MI_COMMUNICATION,									\
		MI_START | MI_CMD_WRITE | MI_PHY_ADDR(MDI_PHY_ADDR) |			\
		MI_REG_ADDR(ofs) | (Data));										\
	__i = 0;															\
	do {																\
		SkOsWaitUsec(pAC, 10);											\
		SK_IN32((io), MI_COMMUNICATION, &__loc32);						\
		__i++;															\
	} while ((__loc32 & MI_START) && (__i < 5000));						\
	if (__i == 5000) {													\
		SK_DBG_MSG(pAC, 0xffffffff, 0xffffffff, ("PHY_WRITE16 error"));	\
	}																	\
}

#define HIGH32(x)	((((SK_U64)(x)) >> 32) & 0xffffffff)
#define LOW32(x)	((x) & 0xffffffff)

//#define START_TIMEOUT()			SkOsGetTime(pAC)
//#define TIMEOUT_REACHED(s,t,n)	SkCheckTimeout(pAC,s,t,n)

/*
 * Compare macros
 */
#define SK_STAT_CMP_SUCCEEDED(function)	((function) >= SK_STATUS_OK)
#define SK_STAT_CMP_FAILED(function)	((function) < SK_STATUS_OK)

#define SK_IOC	char*

#ifdef DEBUG
#define SK_DBG_PRINTF				printk
#if 0
#ifndef SK_DEBUG_CHKMOD
#define SK_DEBUG_CHKMOD				0
#endif	/* SK_DEBUG_CHKMOD*/
#ifndef SK_DEBUG_CHKCAT
#define SK_DEBUG_CHKCAT				0
#endif	/* SK_DEBUG_CHKCAT */
/* Those come from the makefile. */
#define SK_DBG_CHKMOD(pAC)			(SK_DEBUG_CHKMOD)
#define SK_DBG_CHKCAT(pAC)			(SK_DEBUG_CHKCAT)
#else	/* !0 */
/* These come from the command line. */
#define SK_DBG_CHKMOD(pAC)			(pAC->DbgComp)
#define SK_DBG_CHKCAT(pAC)			(pAC->DbgCat)
#endif	/* !0 */

#define SK_DBGMOD_DRV				0x00010000

/**** possible driver debug categories ********************************/
#define SK_DBGCAT_DRV_ENTRY			0x00010000
#define SK_DBGCAT_DRV_SAP			0x00020000
#define SK_DBGCAT_DRV_MCA			0x00040000
#define SK_DBGCAT_DRV_TX_PROGRESS	0x00080000
#define SK_DBGCAT_DRV_RX_PROGRESS	0x00100000
#define SK_DBGCAT_DRV_PROGRESS		0x00200000
#define SK_DBGCAT_DRV_MSG			0x00400000
#define SK_DBGCAT_DRV_PROM			0x00800000
#define SK_DBGCAT_DRV_TX_FRAME		0x01000000
#define SK_DBGCAT_DRV_ERROR			0x02000000
#define SK_DBGCAT_DRV_INT_SRC		0x04000000
#define SK_DBGCAT_DRV_EVENT			0x08000000
#endif	/* DEBUG */


/*
 * Define the driver events.
 * Usually the events are defined by the destination module. In case of the
 * driver we put the definition of the events here.
 */
#define SK_DRV_PORT_RESET		1	/* The port needs to be reset */
#define SK_DRV_NET_UP   		2	/* The net is now operational */
#define SK_DRV_NET_DOWN			3	/* The net is now down */
#define	SK_DRV_RLMT_SEND		4	/* Send a RLMT packet */
#define	SK_DRV_ADAP_FAIL		5	/* The whole adapter fails */
#define	SK_DRV_PORT_FAIL		6	/* One port fails */


typedef struct s_AC	SK_AC;
typedef struct s_DrvRlmtMbuf SK_MBUF;
typedef struct s_SK_TX_PACKET SK_TX_PACKET, *P_SK_TX_PACKET;

#define SK_ERR_LOG		SkErrorLog
//#define SK_ERR_LOG(pAC,Class,ErrNum,ErrMsg);

extern void SkErrorLog(const SK_AC*, int, int, char*);

#endif /* __INC_SKDRV1ST_H */

