summaryrefslogtreecommitdiff
path: root/drivers/net/sk98lin
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/sk98lin
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/net/sk98lin')
-rw-r--r--drivers/net/sk98lin/Makefile89
-rw-r--r--drivers/net/sk98lin/h/lm80.h179
-rw-r--r--drivers/net/sk98lin/h/skaddr.h333
-rw-r--r--drivers/net/sk98lin/h/skcsum.h219
-rw-r--r--drivers/net/sk98lin/h/skdebug.h74
-rw-r--r--drivers/net/sk98lin/h/skdrv1st.h191
-rw-r--r--drivers/net/sk98lin/h/skdrv2nd.h456
-rw-r--r--drivers/net/sk98lin/h/skerror.h55
-rw-r--r--drivers/net/sk98lin/h/skgedrv.h51
-rw-r--r--drivers/net/sk98lin/h/skgehw.h2126
-rw-r--r--drivers/net/sk98lin/h/skgehwt.h48
-rw-r--r--drivers/net/sk98lin/h/skgei2c.h210
-rw-r--r--drivers/net/sk98lin/h/skgeinit.h853
-rw-r--r--drivers/net/sk98lin/h/skgepnm2.h334
-rw-r--r--drivers/net/sk98lin/h/skgepnmi.h966
-rw-r--r--drivers/net/sk98lin/h/skgesirq.h111
-rw-r--r--drivers/net/sk98lin/h/ski2c.h177
-rw-r--r--drivers/net/sk98lin/h/skqueue.h94
-rw-r--r--drivers/net/sk98lin/h/skrlmt.h438
-rw-r--r--drivers/net/sk98lin/h/sktimer.h63
-rw-r--r--drivers/net/sk98lin/h/sktypes.h69
-rw-r--r--drivers/net/sk98lin/h/skversion.h38
-rw-r--r--drivers/net/sk98lin/h/skvpd.h271
-rw-r--r--drivers/net/sk98lin/h/xmac_ii.h1579
-rw-r--r--drivers/net/sk98lin/skaddr.c1773
-rw-r--r--drivers/net/sk98lin/skcsum.c871
-rw-r--r--drivers/net/sk98lin/skdim.c742
-rw-r--r--drivers/net/sk98lin/skethtool.c552
-rw-r--r--drivers/net/sk98lin/skge.c5186
-rw-r--r--drivers/net/sk98lin/skgehwt.c171
-rw-r--r--drivers/net/sk98lin/skgeinit.c2151
-rw-r--r--drivers/net/sk98lin/skgemib.c1082
-rw-r--r--drivers/net/sk98lin/skgepnmi.c8359
-rw-r--r--drivers/net/sk98lin/skgesirq.c2251
-rw-r--r--drivers/net/sk98lin/ski2c.c1296
-rw-r--r--drivers/net/sk98lin/sklm80.c213
-rw-r--r--drivers/net/sk98lin/skproc.c265
-rw-r--r--drivers/net/sk98lin/skqueue.c179
-rw-r--r--drivers/net/sk98lin/skrlmt.c3258
-rw-r--r--drivers/net/sk98lin/sktimer.c250
-rw-r--r--drivers/net/sk98lin/skvpd.c1197
-rw-r--r--drivers/net/sk98lin/skxmac2.c4607
42 files changed, 43427 insertions, 0 deletions
diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
new file mode 100644
index 000000000000..6783039ffb75
--- /dev/null
+++ b/drivers/net/sk98lin/Makefile
@@ -0,0 +1,89 @@
+#
+# Makefile for the SysKonnect SK-98xx device driver.
+#
+
+
+#
+# Standalone driver params
+# SKPARAM += -DSK_KERNEL_24
+# SKPARAM += -DSK_KERNEL_24_26
+# SKPARAM += -DSK_KERNEL_26
+# SKPARAM += -DSK_KERNEL_22_24
+
+obj-$(CONFIG_SK98LIN) += sk98lin.o
+sk98lin-objs := \
+ skge.o \
+ skethtool.o \
+ skdim.o \
+ skaddr.o \
+ skgehwt.o \
+ skgeinit.o \
+ skgepnmi.o \
+ skgesirq.o \
+ ski2c.o \
+ sklm80.o \
+ skqueue.o \
+ skrlmt.o \
+ sktimer.o \
+ skvpd.o \
+ skxmac2.o \
+ skproc.o \
+ skcsum.o
+
+# DBGDEF = \
+# -DDEBUG
+
+ifdef DEBUG
+DBGDEF += \
+-DSK_DEBUG_CHKMOD=0x00000000L \
+-DSK_DEBUG_CHKCAT=0x00000000L
+endif
+
+
+# **** possible debug modules for SK_DEBUG_CHKMOD *****************
+# SK_DBGMOD_MERR 0x00000001L /* general module error indication */
+# SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
+# SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
+# SK_DBGMOD_VPD 0x00000008L /* VPD module */
+# SK_DBGMOD_I2C 0x00000010L /* I2C module */
+# SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
+# SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
+# SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
+# SK_DBGMOD_DRV 0x00010000L /* DRV module */
+
+# **** possible debug categories for SK_DEBUG_CHKCAT **************
+# *** common modules ***
+# SK_DBGCAT_INIT 0x00000001L module/driver initialization
+# SK_DBGCAT_CTRL 0x00000002L controlling: add/rmv MCA/MAC and other controls (IOCTL)
+# SK_DBGCAT_ERR 0x00000004L error handling paths
+# SK_DBGCAT_TX 0x00000008L transmit path
+# SK_DBGCAT_RX 0x00000010L receive path
+# SK_DBGCAT_IRQ 0x00000020L general IRQ handling
+# SK_DBGCAT_QUEUE 0x00000040L any queue management
+# SK_DBGCAT_DUMP 0x00000080L large data output e.g. hex dump
+# SK_DBGCAT_FATAL 0x00000100L large data output e.g. hex dump
+
+# *** driver (file skge.c) ***
+# SK_DBGCAT_DRV_ENTRY 0x00010000 entry points
+# SK_DBGCAT_DRV_??? 0x00020000 not used
+# SK_DBGCAT_DRV_MCA 0x00040000 multicast
+# SK_DBGCAT_DRV_TX_PROGRESS 0x00080000 tx path
+# SK_DBGCAT_DRV_RX_PROGRESS 0x00100000 rx path
+# SK_DBGCAT_DRV_PROGRESS 0x00200000 general runtime
+# SK_DBGCAT_DRV_??? 0x00400000 not used
+# SK_DBGCAT_DRV_PROM 0x00800000 promiscuous mode
+# SK_DBGCAT_DRV_TX_FRAME 0x01000000 display tx frames
+# SK_DBGCAT_DRV_ERROR 0x02000000 error conditions
+# SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources
+# SK_DBGCAT_DRV_EVENT 0x08000000 driver events
+
+EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
+
+clean:
+ rm -f core *.o *.a *.s
+
+
+
+
+
+
diff --git a/drivers/net/sk98lin/h/lm80.h b/drivers/net/sk98lin/h/lm80.h
new file mode 100644
index 000000000000..4e2dbbf78000
--- /dev/null
+++ b/drivers/net/sk98lin/h/lm80.h
@@ -0,0 +1,179 @@
+/******************************************************************************
+ *
+ * Name: lm80.h
+ * Project: Gigabit Ethernet Adapters, Common Modules
+ * Version: $Revision: 1.6 $
+ * Date: $Date: 2003/05/13 17:26:52 $
+ * Purpose: Contains all defines for the LM80 Chip
+ * (National Semiconductor).
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef __INC_LM80_H
+#define __INC_LM80_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* defines ********************************************************************/
+
+/*
+ * LM80 register definition
+ *
+ * All registers are 8 bit wide
+ */
+#define LM80_CFG 0x00 /* Configuration Register */
+#define LM80_ISRC_1 0x01 /* Interrupt Status Register 1 */
+#define LM80_ISRC_2 0x02 /* Interrupt Status Register 2 */
+#define LM80_IMSK_1 0x03 /* Interrupt Mask Register 1 */
+#define LM80_IMSK_2 0x04 /* Interrupt Mask Register 2 */
+#define LM80_FAN_CTRL 0x05 /* Fan Devisor/RST#/OS# Register */
+#define LM80_TEMP_CTRL 0x06 /* OS# Config, Temp Res. Reg */
+ /* 0x07 - 0x1f reserved */
+ /* current values */
+#define LM80_VT0_IN 0x20 /* current Voltage 0 value */
+#define LM80_VT1_IN 0x21 /* current Voltage 1 value */
+#define LM80_VT2_IN 0x22 /* current Voltage 2 value */
+#define LM80_VT3_IN 0x23 /* current Voltage 3 value */
+#define LM80_VT4_IN 0x24 /* current Voltage 4 value */
+#define LM80_VT5_IN 0x25 /* current Voltage 5 value */
+#define LM80_VT6_IN 0x26 /* current Voltage 6 value */
+#define LM80_TEMP_IN 0x27 /* current Temperature value */
+#define LM80_FAN1_IN 0x28 /* current Fan 1 count */
+#define LM80_FAN2_IN 0x29 /* current Fan 2 count */
+ /* limit values */
+#define LM80_VT0_HIGH_LIM 0x2a /* high limit val for Voltage 0 */
+#define LM80_VT0_LOW_LIM 0x2b /* low limit val for Voltage 0 */
+#define LM80_VT1_HIGH_LIM 0x2c /* high limit val for Voltage 1 */
+#define LM80_VT1_LOW_LIM 0x2d /* low limit val for Voltage 1 */
+#define LM80_VT2_HIGH_LIM 0x2e /* high limit val for Voltage 2 */
+#define LM80_VT2_LOW_LIM 0x2f /* low limit val for Voltage 2 */
+#define LM80_VT3_HIGH_LIM 0x30 /* high limit val for Voltage 3 */
+#define LM80_VT3_LOW_LIM 0x31 /* low limit val for Voltage 3 */
+#define LM80_VT4_HIGH_LIM 0x32 /* high limit val for Voltage 4 */
+#define LM80_VT4_LOW_LIM 0x33 /* low limit val for Voltage 4 */
+#define LM80_VT5_HIGH_LIM 0x34 /* high limit val for Voltage 5 */
+#define LM80_VT5_LOW_LIM 0x35 /* low limit val for Voltage 5 */
+#define LM80_VT6_HIGH_LIM 0x36 /* high limit val for Voltage 6 */
+#define LM80_VT6_LOW_LIM 0x37 /* low limit val for Voltage 6 */
+#define LM80_THOT_LIM_UP 0x38 /* hot temperature limit (high) */
+#define LM80_THOT_LIM_LO 0x39 /* hot temperature limit (low) */
+#define LM80_TOS_LIM_UP 0x3a /* OS temperature limit (high) */
+#define LM80_TOS_LIM_LO 0x3b /* OS temperature limit (low) */
+#define LM80_FAN1_COUNT_LIM 0x3c /* Fan 1 count limit (high) */
+#define LM80_FAN2_COUNT_LIM 0x3d /* Fan 2 count limit (low) */
+ /* 0x3e - 0x3f reserved */
+
+/*
+ * LM80 bit definitions
+ */
+
+/* LM80_CFG Configuration Register */
+#define LM80_CFG_START (1<<0) /* start monitoring operation */
+#define LM80_CFG_INT_ENA (1<<1) /* enables the INT# Interrupt output */
+#define LM80_CFG_INT_POL (1<<2) /* INT# pol: 0 act low, 1 act high */
+#define LM80_CFG_INT_CLR (1<<3) /* disables INT#/RST_OUT#/OS# outputs */
+#define LM80_CFG_RESET (1<<4) /* signals a reset */
+#define LM80_CFG_CHASS_CLR (1<<5) /* clears Chassis Intrusion (CI) pin */
+#define LM80_CFG_GPO (1<<6) /* drives the GPO# pin */
+#define LM80_CFG_INIT (1<<7) /* restore power on defaults */
+
+/* LM80_ISRC_1 Interrupt Status Register 1 */
+/* LM80_IMSK_1 Interrupt Mask Register 1 */
+#define LM80_IS_VT0 (1<<0) /* limit exceeded for Voltage 0 */
+#define LM80_IS_VT1 (1<<1) /* limit exceeded for Voltage 1 */
+#define LM80_IS_VT2 (1<<2) /* limit exceeded for Voltage 2 */
+#define LM80_IS_VT3 (1<<3) /* limit exceeded for Voltage 3 */
+#define LM80_IS_VT4 (1<<4) /* limit exceeded for Voltage 4 */
+#define LM80_IS_VT5 (1<<5) /* limit exceeded for Voltage 5 */
+#define LM80_IS_VT6 (1<<6) /* limit exceeded for Voltage 6 */
+#define LM80_IS_INT_IN (1<<7) /* state of INT_IN# */
+
+/* LM80_ISRC_2 Interrupt Status Register 2 */
+/* LM80_IMSK_2 Interrupt Mask Register 2 */
+#define LM80_IS_TEMP (1<<0) /* HOT temperature limit exceeded */
+#define LM80_IS_BTI (1<<1) /* state of BTI# pin */
+#define LM80_IS_FAN1 (1<<2) /* count limit exceeded for Fan 1 */
+#define LM80_IS_FAN2 (1<<3) /* count limit exceeded for Fan 2 */
+#define LM80_IS_CI (1<<4) /* Chassis Intrusion occured */
+#define LM80_IS_OS (1<<5) /* OS temperature limit exceeded */
+ /* bit 6 and 7 are reserved in LM80_ISRC_2 */
+#define LM80_IS_HT_IRQ_MD (1<<6) /* Hot temperature interrupt mode */
+#define LM80_IS_OT_IRQ_MD (1<<7) /* OS temperature interrupt mode */
+
+/* LM80_FAN_CTRL Fan Devisor/RST#/OS# Register */
+#define LM80_FAN1_MD_SEL (1<<0) /* Fan 1 mode select */
+#define LM80_FAN2_MD_SEL (1<<1) /* Fan 2 mode select */
+#define LM80_FAN1_PRM_CTL (3<<2) /* Fan 1 speed control */
+#define LM80_FAN2_PRM_CTL (3<<4) /* Fan 2 speed control */
+#define LM80_FAN_OS_ENA (1<<6) /* enable OS mode on RST_OUT#/OS# pins*/
+#define LM80_FAN_RST_ENA (1<<7) /* sets RST_OUT#/OS# pins in RST mode */
+
+/* LM80_TEMP_CTRL OS# Config, Temp Res. Reg */
+#define LM80_TEMP_OS_STAT (1<<0) /* mirrors the state of RST_OUT#/OS# */
+#define LM80_TEMP_OS_POL (1<<1) /* select OS# polarity */
+#define LM80_TEMP_OS_MODE (1<<2) /* selects Interrupt mode */
+#define LM80_TEMP_RES (1<<3) /* selects 9 or 11 bit temp resulution*/
+#define LM80_TEMP_LSB (0xf<<4)/* 4 LSBs of 11 bit temp data */
+#define LM80_TEMP_LSB_9 (1<<7) /* LSB of 9 bit temperature data */
+
+ /* 0x07 - 0x1f reserved */
+/* LM80_VT0_IN current Voltage 0 value */
+/* LM80_VT1_IN current Voltage 1 value */
+/* LM80_VT2_IN current Voltage 2 value */
+/* LM80_VT3_IN current Voltage 3 value */
+/* LM80_VT4_IN current Voltage 4 value */
+/* LM80_VT5_IN current Voltage 5 value */
+/* LM80_VT6_IN current Voltage 6 value */
+/* LM80_TEMP_IN current temperature value */
+/* LM80_FAN1_IN current Fan 1 count */
+/* LM80_FAN2_IN current Fan 2 count */
+/* LM80_VT0_HIGH_LIM high limit val for Voltage 0 */
+/* LM80_VT0_LOW_LIM low limit val for Voltage 0 */
+/* LM80_VT1_HIGH_LIM high limit val for Voltage 1 */
+/* LM80_VT1_LOW_LIM low limit val for Voltage 1 */
+/* LM80_VT2_HIGH_LIM high limit val for Voltage 2 */
+/* LM80_VT2_LOW_LIM low limit val for Voltage 2 */
+/* LM80_VT3_HIGH_LIM high limit val for Voltage 3 */
+/* LM80_VT3_LOW_LIM low limit val for Voltage 3 */
+/* LM80_VT4_HIGH_LIM high limit val for Voltage 4 */
+/* LM80_VT4_LOW_LIM low limit val for Voltage 4 */
+/* LM80_VT5_HIGH_LIM high limit val for Voltage 5 */
+/* LM80_VT5_LOW_LIM low limit val for Voltage 5 */
+/* LM80_VT6_HIGH_LIM high limit val for Voltage 6 */
+/* LM80_VT6_LOW_LIM low limit val for Voltage 6 */
+/* LM80_THOT_LIM_UP hot temperature limit (high) */
+/* LM80_THOT_LIM_LO hot temperature limit (low) */
+/* LM80_TOS_LIM_UP OS temperature limit (high) */
+/* LM80_TOS_LIM_LO OS temperature limit (low) */
+/* LM80_FAN1_COUNT_LIM Fan 1 count limit (high) */
+/* LM80_FAN2_COUNT_LIM Fan 2 count limit (low) */
+ /* 0x3e - 0x3f reserved */
+
+#define LM80_ADDR 0x28 /* LM80 default addr */
+
+/* typedefs *******************************************************************/
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INC_LM80_H */
diff --git a/drivers/net/sk98lin/h/skaddr.h b/drivers/net/sk98lin/h/skaddr.h
new file mode 100644
index 000000000000..3a2ea4a4b539
--- /dev/null
+++ b/drivers/net/sk98lin/h/skaddr.h
@@ -0,0 +1,333 @@
+/******************************************************************************
+ *
+ * Name: skaddr.h
+ * Project: Gigabit Ethernet Adapters, ADDR-Modul
+ * Version: $Revision: 1.29 $
+ * Date: $Date: 2003/05/13 16:57:24 $
+ * Purpose: Header file for Address Management (MC, UC, Prom).
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This module is intended to manage multicast addresses and promiscuous mode
+ * on GEnesis adapters.
+ *
+ * Include File Hierarchy:
+ *
+ * "skdrv1st.h"
+ * ...
+ * "sktypes.h"
+ * "skqueue.h"
+ * "skaddr.h"
+ * ...
+ * "skdrv2nd.h"
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKADDR_H
+#define __INC_SKADDR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* cplusplus */
+
+/* defines ********************************************************************/
+
+#define SK_MAC_ADDR_LEN 6 /* Length of MAC address. */
+#define SK_MAX_ADDRS 14 /* #Addrs for exact match. */
+
+/* ----- Common return values ----- */
+
+#define SK_ADDR_SUCCESS 0 /* Function returned successfully. */
+#define SK_ADDR_ILLEGAL_PORT 100 /* Port number too high. */
+#define SK_ADDR_TOO_EARLY 101 /* Function called too early. */
+
+/* ----- Clear/Add flag bits ----- */
+
+#define SK_ADDR_PERMANENT 1 /* RLMT Address */
+
+/* ----- Additional Clear flag bits ----- */
+
+#define SK_MC_SW_ONLY 2 /* Do not update HW when clearing. */
+
+/* ----- Override flag bits ----- */
+
+#define SK_ADDR_LOGICAL_ADDRESS 0
+#define SK_ADDR_VIRTUAL_ADDRESS (SK_ADDR_LOGICAL_ADDRESS) /* old */
+#define SK_ADDR_PHYSICAL_ADDRESS 1
+#define SK_ADDR_CLEAR_LOGICAL 2
+#define SK_ADDR_SET_LOGICAL 4
+
+/* ----- Override return values ----- */
+
+#define SK_ADDR_OVERRIDE_SUCCESS (SK_ADDR_SUCCESS)
+#define SK_ADDR_DUPLICATE_ADDRESS 1
+#define SK_ADDR_MULTICAST_ADDRESS 2
+
+/* ----- Partitioning of excact match table ----- */
+
+#define SK_ADDR_EXACT_MATCHES 16 /* #Exact match entries. */
+
+#define SK_ADDR_FIRST_MATCH_RLMT 1
+#define SK_ADDR_LAST_MATCH_RLMT 2
+#define SK_ADDR_FIRST_MATCH_DRV 3
+#define SK_ADDR_LAST_MATCH_DRV (SK_ADDR_EXACT_MATCHES - 1)
+
+/* ----- SkAddrMcAdd/SkAddrMcUpdate return values ----- */
+
+#define SK_MC_FILTERING_EXACT 0 /* Exact filtering. */
+#define SK_MC_FILTERING_INEXACT 1 /* Inexact filtering. */
+
+/* ----- Additional SkAddrMcAdd return values ----- */
+
+#define SK_MC_ILLEGAL_ADDRESS 2 /* Illegal address. */
+#define SK_MC_ILLEGAL_PORT 3 /* Illegal port (not the active one). */
+#define SK_MC_RLMT_OVERFLOW 4 /* Too many RLMT mc addresses. */
+
+/* Promiscuous mode bits ----- */
+
+#define SK_PROM_MODE_NONE 0 /* Normal receive. */
+#define SK_PROM_MODE_LLC 1 /* Receive all LLC frames. */
+#define SK_PROM_MODE_ALL_MC 2 /* Receive all multicast frames. */
+/* #define SK_PROM_MODE_NON_LLC 4 */ /* Receive all non-LLC frames. */
+
+/* Macros */
+
+#ifdef OLD_STUFF
+#ifndef SK_ADDR_EQUAL
+/*
+ * "&" instead of "&&" allows better optimization on IA-64.
+ * The replacement is safe here, as all bytes exist.
+ */
+#ifndef SK_ADDR_DWORD_COMPARE
+#define SK_ADDR_EQUAL(A1,A2) ( \
+ (((SK_U8 *)(A1))[5] == ((SK_U8 *)(A2))[5]) & \
+ (((SK_U8 *)(A1))[4] == ((SK_U8 *)(A2))[4]) & \
+ (((SK_U8 *)(A1))[3] == ((SK_U8 *)(A2))[3]) & \
+ (((SK_U8 *)(A1))[2] == ((SK_U8 *)(A2))[2]) & \
+ (((SK_U8 *)(A1))[1] == ((SK_U8 *)(A2))[1]) & \
+ (((SK_U8 *)(A1))[0] == ((SK_U8 *)(A2))[0]))
+#else /* SK_ADDR_DWORD_COMPARE */
+#define SK_ADDR_EQUAL(A1,A2) ( \
+ (*(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2])) & \
+ (*(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0])))
+#endif /* SK_ADDR_DWORD_COMPARE */
+#endif /* SK_ADDR_EQUAL */
+#endif /* 0 */
+
+#ifndef SK_ADDR_EQUAL
+#ifndef SK_ADDR_DWORD_COMPARE
+#define SK_ADDR_EQUAL(A1,A2) ( \
+ (((SK_U8 SK_FAR *)(A1))[5] == ((SK_U8 SK_FAR *)(A2))[5]) & \
+ (((SK_U8 SK_FAR *)(A1))[4] == ((SK_U8 SK_FAR *)(A2))[4]) & \
+ (((SK_U8 SK_FAR *)(A1))[3] == ((SK_U8 SK_FAR *)(A2))[3]) & \
+ (((SK_U8 SK_FAR *)(A1))[2] == ((SK_U8 SK_FAR *)(A2))[2]) & \
+ (((SK_U8 SK_FAR *)(A1))[1] == ((SK_U8 SK_FAR *)(A2))[1]) & \
+ (((SK_U8 SK_FAR *)(A1))[0] == ((SK_U8 SK_FAR *)(A2))[0]))
+#else /* SK_ADDR_DWORD_COMPARE */
+#define SK_ADDR_EQUAL(A1,A2) ( \
+ (*(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[4]) == \
+ *(SK_U16 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[4])) && \
+ (*(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A1))[0]) == \
+ *(SK_U32 SK_FAR *)&(((SK_U8 SK_FAR *)(A2))[0])))
+#endif /* SK_ADDR_DWORD_COMPARE */
+#endif /* SK_ADDR_EQUAL */
+
+/* typedefs *******************************************************************/
+
+typedef struct s_MacAddr {
+ SK_U8 a[SK_MAC_ADDR_LEN];
+} SK_MAC_ADDR;
+
+
+/* SK_FILTER is used to ensure alignment of the filter. */
+typedef union s_InexactFilter {
+ SK_U8 Bytes[8];
+ SK_U64 Val; /* Dummy entry for alignment only. */
+} SK_FILTER64;
+
+
+typedef struct s_AddrNet SK_ADDR_NET;
+
+
+typedef struct s_AddrPort {
+
+/* ----- Public part (read-only) ----- */
+
+ SK_MAC_ADDR CurrentMacAddress; /* Current physical MAC Address. */
+ SK_MAC_ADDR PermanentMacAddress; /* Permanent physical MAC Address. */
+ int PromMode; /* Promiscuous Mode. */
+
+/* ----- Private part ----- */
+
+ SK_MAC_ADDR PreviousMacAddress; /* Prev. phys. MAC Address. */
+ SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
+ SK_U8 Align01;
+
+ SK_U32 FirstExactMatchRlmt;
+ SK_U32 NextExactMatchRlmt;
+ SK_U32 FirstExactMatchDrv;
+ SK_U32 NextExactMatchDrv;
+ SK_MAC_ADDR Exact[SK_ADDR_EXACT_MATCHES];
+ SK_FILTER64 InexactFilter; /* For 64-bit hash register. */
+ SK_FILTER64 InexactRlmtFilter; /* For 64-bit hash register. */
+ SK_FILTER64 InexactDrvFilter; /* For 64-bit hash register. */
+} SK_ADDR_PORT;
+
+
+struct s_AddrNet {
+/* ----- Public part (read-only) ----- */
+
+ SK_MAC_ADDR CurrentMacAddress; /* Logical MAC Address. */
+ SK_MAC_ADDR PermanentMacAddress; /* Logical MAC Address. */
+
+/* ----- Private part ----- */
+
+ SK_U32 ActivePort; /* View of module ADDR. */
+ SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
+ SK_U8 Align01;
+ SK_U16 Align02;
+};
+
+
+typedef struct s_Addr {
+
+/* ----- Public part (read-only) ----- */
+
+ SK_ADDR_NET Net[SK_MAX_NETS];
+ SK_ADDR_PORT Port[SK_MAX_MACS];
+
+/* ----- Private part ----- */
+} SK_ADDR;
+
+/* function prototypes ********************************************************/
+
+#ifndef SK_KR_PROTO
+
+/* Functions provided by SkAddr */
+
+/* ANSI/C++ compliant function prototypes */
+
+extern int SkAddrInit(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Level);
+
+extern int SkAddrMcClear(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber,
+ int Flags);
+
+extern int SkAddrXmacMcClear(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber,
+ int Flags);
+
+extern int SkAddrGmacMcClear(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber,
+ int Flags);
+
+extern int SkAddrMcAdd(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber,
+ SK_MAC_ADDR *pMc,
+ int Flags);
+
+extern int SkAddrXmacMcAdd(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber,
+ SK_MAC_ADDR *pMc,
+ int Flags);
+
+extern int SkAddrGmacMcAdd(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber,
+ SK_MAC_ADDR *pMc,
+ int Flags);
+
+extern int SkAddrMcUpdate(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber);
+
+extern int SkAddrXmacMcUpdate(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber);
+
+extern int SkAddrGmacMcUpdate(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber);
+
+extern int SkAddrOverride(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber,
+ SK_MAC_ADDR SK_FAR *pNewAddr,
+ int Flags);
+
+extern int SkAddrPromiscuousChange(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber,
+ int NewPromMode);
+
+extern int SkAddrXmacPromiscuousChange(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber,
+ int NewPromMode);
+
+extern int SkAddrGmacPromiscuousChange(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 PortNumber,
+ int NewPromMode);
+
+#ifndef SK_SLIM
+extern int SkAddrSwap(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 FromPortNumber,
+ SK_U32 ToPortNumber);
+#endif
+
+#else /* defined(SK_KR_PROTO)) */
+
+/* Non-ANSI/C++ compliant function prototypes */
+
+#error KR-style prototypes are not yet provided.
+
+#endif /* defined(SK_KR_PROTO)) */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INC_SKADDR_H */
diff --git a/drivers/net/sk98lin/h/skcsum.h b/drivers/net/sk98lin/h/skcsum.h
new file mode 100644
index 000000000000..2b94adb93331
--- /dev/null
+++ b/drivers/net/sk98lin/h/skcsum.h
@@ -0,0 +1,219 @@
+/******************************************************************************
+ *
+ * Name: skcsum.h
+ * Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
+ * Version: $Revision: 1.10 $
+ * Date: $Date: 2003/08/20 13:59:57 $
+ * Purpose: Store/verify Internet checksum in send/receive packets.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * Public header file for the "GEnesis" common module "CSUM".
+ *
+ * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
+ * and is the code name of this SysKonnect project.
+ *
+ * Compilation Options:
+ *
+ * SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
+ * empty module.
+ *
+ * SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
+ * definitions. In this case, all SKCS_PROTO_xxx definitions must be made
+ * external.
+ *
+ * SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
+ * definitions. In this case, all SKCS_STATUS_xxx definitions must be made
+ * external.
+ *
+ * Include File Hierarchy:
+ *
+ * "h/skcsum.h"
+ * "h/sktypes.h"
+ * "h/skqueue.h"
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKCSUM_H
+#define __INC_SKCSUM_H
+
+#include "h/sktypes.h"
+#include "h/skqueue.h"
+
+/* defines ********************************************************************/
+
+/*
+ * Define the default bit flags for 'SKCS_PACKET_INFO.ProtocolFlags' if no user
+ * overwrite.
+ */
+#ifndef SKCS_OVERWRITE_PROTO /* User overwrite? */
+#define SKCS_PROTO_IP 0x1 /* IP (Internet Protocol version 4) */
+#define SKCS_PROTO_TCP 0x2 /* TCP (Transmission Control Protocol) */
+#define SKCS_PROTO_UDP 0x4 /* UDP (User Datagram Protocol) */
+
+/* Indices for protocol statistics. */
+#define SKCS_PROTO_STATS_IP 0
+#define SKCS_PROTO_STATS_UDP 1
+#define SKCS_PROTO_STATS_TCP 2
+#define SKCS_NUM_PROTOCOLS 3 /* Number of supported protocols. */
+#endif /* !SKCS_OVERWRITE_PROTO */
+
+/*
+ * Define the default SKCS_STATUS type and values if no user overwrite.
+ *
+ * SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
+ * SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
+ * SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
+ * SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
+ * SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
+ * SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
+ * SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
+ * SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
+ * SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
+ * SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
+ * SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
+ */
+#ifndef SKCS_OVERWRITE_STATUS /* User overwrite? */
+#define SKCS_STATUS int /* Define status type. */
+
+#define SKCS_STATUS_UNKNOWN_IP_VERSION 1
+#define SKCS_STATUS_IP_CSUM_ERROR 2
+#define SKCS_STATUS_IP_FRAGMENT 3
+#define SKCS_STATUS_IP_CSUM_OK 4
+#define SKCS_STATUS_TCP_CSUM_ERROR 5
+#define SKCS_STATUS_UDP_CSUM_ERROR 6
+#define SKCS_STATUS_TCP_CSUM_OK 7
+#define SKCS_STATUS_UDP_CSUM_OK 8
+/* needed for Microsoft */
+#define SKCS_STATUS_IP_CSUM_ERROR_UDP 9
+#define SKCS_STATUS_IP_CSUM_ERROR_TCP 10
+/* UDP checksum may be omitted */
+#define SKCS_STATUS_IP_CSUM_OK_NO_UDP 11
+#endif /* !SKCS_OVERWRITE_STATUS */
+
+/* Clear protocol statistics event. */
+#define SK_CSUM_EVENT_CLEAR_PROTO_STATS 1
+
+/*
+ * Add two values in one's complement.
+ *
+ * Note: One of the two input values may be "longer" than 16-bit, but then the
+ * resulting sum may be 17 bits long. In this case, add zero to the result using
+ * SKCS_OC_ADD() again.
+ *
+ * Result = Value1 + Value2
+ */
+#define SKCS_OC_ADD(Result, Value1, Value2) { \
+ unsigned long Sum; \
+ \
+ Sum = (unsigned long) (Value1) + (unsigned long) (Value2); \
+ /* Add-in any carry. */ \
+ (Result) = (Sum & 0xffff) + (Sum >> 16); \
+}
+
+/*
+ * Subtract two values in one's complement.
+ *
+ * Result = Value1 - Value2
+ */
+#define SKCS_OC_SUB(Result, Value1, Value2) \
+ SKCS_OC_ADD((Result), (Value1), ~(Value2) & 0xffff)
+
+/* typedefs *******************************************************************/
+
+/*
+ * SKCS_PROTO_STATS - The CSUM protocol statistics structure.
+ *
+ * There is one instance of this structure for each protocol supported.
+ */
+typedef struct s_CsProtocolStatistics {
+ SK_U64 RxOkCts; /* Receive checksum ok. */
+ SK_U64 RxUnableCts; /* Unable to verify receive checksum. */
+ SK_U64 RxErrCts; /* Receive checksum error. */
+ SK_U64 TxOkCts; /* Transmit checksum ok. */
+ SK_U64 TxUnableCts; /* Unable to calculate checksum in hw. */
+} SKCS_PROTO_STATS;
+
+/*
+ * s_Csum - The CSUM module context structure.
+ */
+typedef struct s_Csum {
+ /* Enabled receive SK_PROTO_XXX bit flags. */
+ unsigned ReceiveFlags[SK_MAX_NETS];
+#ifdef TX_CSUM
+ unsigned TransmitFlags[SK_MAX_NETS];
+#endif /* TX_CSUM */
+
+ /* The protocol statistics structure; one per supported protocol. */
+ SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS];
+} SK_CSUM;
+
+/*
+ * SKCS_PACKET_INFO - The packet information structure.
+ */
+typedef struct s_CsPacketInfo {
+ /* Bit field specifiying the desired/found protocols. */
+ unsigned ProtocolFlags;
+
+ /* Length of complete IP header, including any option fields. */
+ unsigned IpHeaderLength;
+
+ /* IP header checksum. */
+ unsigned IpHeaderChecksum;
+
+ /* TCP/UDP pseudo header checksum. */
+ unsigned PseudoHeaderChecksum;
+} SKCS_PACKET_INFO;
+
+/* function prototypes ********************************************************/
+
+#ifndef SK_CS_CALCULATE_CHECKSUM
+extern unsigned SkCsCalculateChecksum(
+ void *pData,
+ unsigned Length);
+#endif /* SK_CS_CALCULATE_CHECKSUM */
+
+extern int SkCsEvent(
+ SK_AC *pAc,
+ SK_IOC Ioc,
+ SK_U32 Event,
+ SK_EVPARA Param);
+
+extern SKCS_STATUS SkCsGetReceiveInfo(
+ SK_AC *pAc,
+ void *pIpHeader,
+ unsigned Checksum1,
+ unsigned Checksum2,
+ int NetNumber);
+
+extern void SkCsGetSendInfo(
+ SK_AC *pAc,
+ void *pIpHeader,
+ SKCS_PACKET_INFO *pPacketInfo,
+ int NetNumber);
+
+extern void SkCsSetReceiveFlags(
+ SK_AC *pAc,
+ unsigned ReceiveFlags,
+ unsigned *pChecksum1Offset,
+ unsigned *pChecksum2Offset,
+ int NetNumber);
+
+#endif /* __INC_SKCSUM_H */
diff --git a/drivers/net/sk98lin/h/skdebug.h b/drivers/net/sk98lin/h/skdebug.h
new file mode 100644
index 000000000000..3cba171d74b2
--- /dev/null
+++ b/drivers/net/sk98lin/h/skdebug.h
@@ -0,0 +1,74 @@
+/******************************************************************************
+ *
+ * Name: skdebug.h
+ * Project: Gigabit Ethernet Adapters, Common Modules
+ * Version: $Revision: 1.14 $
+ * Date: $Date: 2003/05/13 17:26:00 $
+ * Purpose: SK specific DEBUG support
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKDEBUG_H
+#define __INC_SKDEBUG_H
+
+#ifdef DEBUG
+#ifndef SK_DBG_MSG
+#define SK_DBG_MSG(pAC,comp,cat,arg) \
+ if ( ((comp) & SK_DBG_CHKMOD(pAC)) && \
+ ((cat) & SK_DBG_CHKCAT(pAC)) ) { \
+ SK_DBG_PRINTF arg ; \
+ }
+#endif
+#else
+#define SK_DBG_MSG(pAC,comp,lev,arg)
+#endif
+
+/* PLS NOTE:
+ * =========
+ * Due to any restrictions of kernel printf routines do not use other
+ * format identifiers as: %x %d %c %s .
+ * Never use any combined format identifiers such as: %lx %ld in your
+ * printf - argument (arg) because some OS specific kernel printfs may
+ * only support some basic identifiers.
+ */
+
+/* Debug modules */
+
+#define SK_DBGMOD_MERR 0x00000001L /* general module error indication */
+#define SK_DBGMOD_HWM 0x00000002L /* Hardware init module */
+#define SK_DBGMOD_RLMT 0x00000004L /* RLMT module */
+#define SK_DBGMOD_VPD 0x00000008L /* VPD module */
+#define SK_DBGMOD_I2C 0x00000010L /* I2C module */
+#define SK_DBGMOD_PNMI 0x00000020L /* PNMI module */
+#define SK_DBGMOD_CSUM 0x00000040L /* CSUM module */
+#define SK_DBGMOD_ADDR 0x00000080L /* ADDR module */
+#define SK_DBGMOD_PECP 0x00000100L /* PECP module */
+#define SK_DBGMOD_POWM 0x00000200L /* Power Management module */
+
+/* Debug events */
+
+#define SK_DBGCAT_INIT 0x00000001L /* module/driver initialization */
+#define SK_DBGCAT_CTRL 0x00000002L /* controlling devices */
+#define SK_DBGCAT_ERR 0x00000004L /* error handling paths */
+#define SK_DBGCAT_TX 0x00000008L /* transmit path */
+#define SK_DBGCAT_RX 0x00000010L /* receive path */
+#define SK_DBGCAT_IRQ 0x00000020L /* general IRQ handling */
+#define SK_DBGCAT_QUEUE 0x00000040L /* any queue management */
+#define SK_DBGCAT_DUMP 0x00000080L /* large data output e.g. hex dump */
+#define SK_DBGCAT_FATAL 0x00000100L /* fatal error */
+
+#endif /* __INC_SKDEBUG_H */
diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
new file mode 100644
index 000000000000..308440bd0e12
--- /dev/null
+++ b/drivers/net/sk98lin/h/skdrv1st.h
@@ -0,0 +1,191 @@
+/******************************************************************************
+ *
+ * Name: skdrv1st.h
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.4 $
+ * Date: $Date: 2003/11/12 14:28:14 $
+ * Purpose: First header file for driver and all other modules
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * 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 skge.c
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKDRV1ST_H
+#define __INC_SKDRV1ST_H
+
+/* Check kernel version */
+#include <linux/version.h>
+
+typedef struct s_AC SK_AC;
+
+/* Set card versions */
+#define SK_FAR
+
+/* override some default functions with optimized linux functions */
+
+#define SK_PNMI_STORE_U16(p,v) memcpy((char*)(p),(char*)&(v),2)
+#define SK_PNMI_STORE_U32(p,v) memcpy((char*)(p),(char*)&(v),4)
+#define SK_PNMI_STORE_U64(p,v) memcpy((char*)(p),(char*)&(v),8)
+#define SK_PNMI_READ_U16(p,v) memcpy((char*)&(v),(char*)(p),2)
+#define SK_PNMI_READ_U32(p,v) memcpy((char*)&(v),(char*)(p),4)
+#define SK_PNMI_READ_U64(p,v) memcpy((char*)&(v),(char*)(p),8)
+
+#define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6))
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.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>
+
+#define SK_CS_CALCULATE_CHECKSUM
+#ifndef CONFIG_X86_64
+#define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff)
+#else
+#define SkCsCalculateChecksum(p,l) ((~ip_fast_csum(p, l)) & 0xffff)
+#endif
+
+#include "h/sktypes.h"
+#include "h/skerror.h"
+#include "h/skdebug.h"
+#include "h/lm80.h"
+#include "h/xmac_ii.h"
+
+#ifdef __LITTLE_ENDIAN
+#define SK_LITTLE_ENDIAN
+#else
+#define SK_BIG_ENDIAN
+#endif
+
+#define SK_NET_DEVICE net_device
+
+
+/* we use gethrtime(), return unit: nanoseconds */
+#define SK_TICKS_PER_SEC 100
+
+#define SK_MEM_MAPPED_IO
+
+// #define SK_RLMT_SLOW_LOOKAHEAD
+
+#define SK_MAX_MACS 2
+#define SK_MAX_NETS 2
+
+#define SK_IOC char __iomem *
+
+typedef struct s_DrvRlmtMbuf SK_MBUF;
+
+#define SK_CONST64 INT64_C
+#define SK_CONSTU64 UINT64_C
+
+#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 int8_t char
+#define int16_t short
+#define int32_t long
+#define int64_t long long
+#define uint8_t u_char
+#define uint16_t u_short
+#define uint32_t u_long
+#define uint64_t unsigned long long
+#define t_scalar_t int
+#define t_uscalar_t unsigned int
+#define uintptr_t unsigned long
+
+#define __CONCAT__(A,B) A##B
+
+#define INT32_C(a) __CONCAT__(a,L)
+#define INT64_C(a) __CONCAT__(a,LL)
+#define UINT32_C(a) __CONCAT__(a,UL)
+#define UINT64_C(a) __CONCAT__(a,ULL)
+
+#ifdef DEBUG
+#define SK_DBG_PRINTF printk
+#ifndef SK_DEBUG_CHKMOD
+#define SK_DEBUG_CHKMOD 0
+#endif
+#ifndef SK_DEBUG_CHKCAT
+#define SK_DEBUG_CHKCAT 0
+#endif
+/* those come from the makefile */
+#define SK_DBG_CHKMOD(pAC) (SK_DEBUG_CHKMOD)
+#define SK_DBG_CHKCAT(pAC) (SK_DEBUG_CHKCAT)
+
+extern void SkDbgPrintf(const char *format,...);
+
+#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
+
+#define SK_ERR_LOG SkErrorLog
+
+extern void SkErrorLog(SK_AC*, int, int, char*);
+
+#endif
+
diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
new file mode 100644
index 000000000000..542cec57f86a
--- /dev/null
+++ b/drivers/net/sk98lin/h/skdrv2nd.h
@@ -0,0 +1,456 @@
+/******************************************************************************
+ *
+ * Name: skdrv2nd.h
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.10 $
+ * Date: $Date: 2003/12/11 16:04:45 $
+ * Purpose: Second header file for driver and all other modules
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This is the second include file of the driver, which includes all other
+ * neccessary files and defines all structures and constants used by the
+ * driver and the common modules.
+ *
+ * Include File Hierarchy:
+ *
+ * see skge.c
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKDRV2ND_H
+#define __INC_SKDRV2ND_H
+
+#include "h/skqueue.h"
+#include "h/skgehwt.h"
+#include "h/sktimer.h"
+#include "h/ski2c.h"
+#include "h/skgepnmi.h"
+#include "h/skvpd.h"
+#include "h/skgehw.h"
+#include "h/skgeinit.h"
+#include "h/skaddr.h"
+#include "h/skgesirq.h"
+#include "h/skcsum.h"
+#include "h/skrlmt.h"
+#include "h/skgedrv.h"
+
+
+extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned);
+extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*);
+extern SK_U64 SkOsGetTime(SK_AC*);
+extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
+extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*);
+extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*);
+extern int SkPciWriteCfgDWord(SK_AC*, int, SK_U32);
+extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16);
+extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8);
+extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
+
+#ifdef SK_DIAG_SUPPORT
+extern int SkDrvEnterDiagMode(SK_AC *pAc);
+extern int SkDrvLeaveDiagMode(SK_AC *pAc);
+#endif
+
+struct s_DrvRlmtMbuf {
+ SK_MBUF *pNext; /* Pointer to next RLMT Mbuf. */
+ SK_U8 *pData; /* Data buffer (virtually contig.). */
+ unsigned Size; /* Data buffer size. */
+ unsigned Length; /* Length of packet (<= Size). */
+ SK_U32 PortIdx; /* Receiving/transmitting port. */
+#ifdef SK_RLMT_MBUF_PRIVATE
+ SK_RLMT_MBUF Rlmt; /* Private part for RLMT. */
+#endif /* SK_RLMT_MBUF_PRIVATE */
+ struct sk_buff *pOs; /* Pointer to message block */
+};
+
+
+/*
+ * Time macros
+ */
+#if SK_TICKS_PER_SEC == 100
+#define SK_PNMI_HUNDREDS_SEC(t) (t)
+#else
+#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t) * 100) / \
+ (SK_TICKS_PER_SEC))
+#endif
+
+/*
+ * New SkOsGetTime
+ */
+#define SkOsGetTimeCurrent(pAC, pUsec) {\
+ struct timeval t;\
+ do_gettimeofday(&t);\
+ *pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\
+}
+
+
+/*
+ * ioctl definitions
+ */
+#define SK_IOCTL_BASE (SIOCDEVPRIVATE)
+#define SK_IOCTL_GETMIB (SK_IOCTL_BASE + 0)
+#define SK_IOCTL_SETMIB (SK_IOCTL_BASE + 1)
+#define SK_IOCTL_PRESETMIB (SK_IOCTL_BASE + 2)
+#define SK_IOCTL_GEN (SK_IOCTL_BASE + 3)
+#define SK_IOCTL_DIAG (SK_IOCTL_BASE + 4)
+
+typedef struct s_IOCTL SK_GE_IOCTL;
+
+struct s_IOCTL {
+ char __user * pData;
+ unsigned int Len;
+};
+
+
+/*
+ * define sizes of descriptor rings in bytes
+ */
+
+#define TX_RING_SIZE (8*1024)
+#define RX_RING_SIZE (24*1024)
+
+/*
+ * Buffer size for ethernet packets
+ */
+#define ETH_BUF_SIZE 1540
+#define ETH_MAX_MTU 1514
+#define ETH_MIN_MTU 60
+#define ETH_MULTICAST_BIT 0x01
+#define SK_JUMBO_MTU 9000
+
+/*
+ * transmit priority selects the queue: LOW=asynchron, HIGH=synchron
+ */
+#define TX_PRIO_LOW 0
+#define TX_PRIO_HIGH 1
+
+/*
+ * alignment of rx/tx descriptors
+ */
+#define DESCR_ALIGN 64
+
+/*
+ * definitions for pnmi. TODO
+ */
+#define SK_DRIVER_RESET(pAC, IoC) 0
+#define SK_DRIVER_SENDEVENT(pAC, IoC) 0
+#define SK_DRIVER_SELFTEST(pAC, IoC) 0
+/* For get mtu you must add an own function */
+#define SK_DRIVER_GET_MTU(pAc,IoC,i) 0
+#define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0
+#define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v) 0
+
+/*
+** Interim definition of SK_DRV_TIMER placed in this file until
+** common modules have boon finallized
+*/
+#define SK_DRV_TIMER 11
+#define SK_DRV_MODERATION_TIMER 1
+#define SK_DRV_MODERATION_TIMER_LENGTH 1000000 /* 1 second */
+#define SK_DRV_RX_CLEANUP_TIMER 2
+#define SK_DRV_RX_CLEANUP_TIMER_LENGTH 1000000 /* 100 millisecs */
+
+/*
+** Definitions regarding transmitting frames
+** any calculating any checksum.
+*/
+#define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6
+#define C_LEN_ETHERMAC_HEADER_SRC_ADDR 6
+#define C_LEN_ETHERMAC_HEADER_LENTYPE 2
+#define C_LEN_ETHERMAC_HEADER ( (C_LEN_ETHERMAC_HEADER_DEST_ADDR) + \
+ (C_LEN_ETHERMAC_HEADER_SRC_ADDR) + \
+ (C_LEN_ETHERMAC_HEADER_LENTYPE) )
+
+#define C_LEN_ETHERMTU_MINSIZE 46
+#define C_LEN_ETHERMTU_MAXSIZE_STD 1500
+#define C_LEN_ETHERMTU_MAXSIZE_JUMBO 9000
+
+#define C_LEN_ETHERNET_MINSIZE ( (C_LEN_ETHERMAC_HEADER) + \
+ (C_LEN_ETHERMTU_MINSIZE) )
+
+#define C_OFFSET_IPHEADER C_LEN_ETHERMAC_HEADER
+#define C_OFFSET_IPHEADER_IPPROTO 9
+#define C_OFFSET_TCPHEADER_TCPCS 16
+#define C_OFFSET_UDPHEADER_UDPCS 6
+
+#define C_OFFSET_IPPROTO ( (C_LEN_ETHERMAC_HEADER) + \
+ (C_OFFSET_IPHEADER_IPPROTO) )
+
+#define C_PROTO_ID_UDP 17 /* refer to RFC 790 or Stevens' */
+#define C_PROTO_ID_TCP 6 /* TCP/IP illustrated for details */
+
+/* TX and RX descriptors *****************************************************/
+
+typedef struct s_RxD RXD; /* the receive descriptor */
+
+struct s_RxD {
+ volatile SK_U32 RBControl; /* Receive Buffer Control */
+ SK_U32 VNextRxd; /* Next receive descriptor,low dword */
+ SK_U32 VDataLow; /* Receive buffer Addr, low dword */
+ SK_U32 VDataHigh; /* Receive buffer Addr, high dword */
+ SK_U32 FrameStat; /* Receive Frame Status word */
+ SK_U32 TimeStamp; /* Time stamp from XMAC */
+ SK_U32 TcpSums; /* TCP Sum 2 / TCP Sum 1 */
+ SK_U32 TcpSumStarts; /* TCP Sum Start 2 / TCP Sum Start 1 */
+ RXD *pNextRxd; /* Pointer to next Rxd */
+ struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */
+};
+
+typedef struct s_TxD TXD; /* the transmit descriptor */
+
+struct s_TxD {
+ volatile SK_U32 TBControl; /* Transmit Buffer Control */
+ SK_U32 VNextTxd; /* Next transmit descriptor,low dword */
+ SK_U32 VDataLow; /* Transmit Buffer Addr, low dword */
+ SK_U32 VDataHigh; /* Transmit Buffer Addr, high dword */
+ SK_U32 FrameStat; /* Transmit Frame Status Word */
+ SK_U32 TcpSumOfs; /* Reserved / TCP Sum Offset */
+ SK_U16 TcpSumSt; /* TCP Sum Start */
+ SK_U16 TcpSumWr; /* TCP Sum Write */
+ SK_U32 TcpReserved; /* not used */
+ TXD *pNextTxd; /* Pointer to next Txd */
+ struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */
+};
+
+/* Used interrupt bits in the interrupts source register *********************/
+
+#define DRIVER_IRQS ((IS_IRQ_SW) | \
+ (IS_R1_F) |(IS_R2_F) | \
+ (IS_XS1_F) |(IS_XA1_F) | \
+ (IS_XS2_F) |(IS_XA2_F))
+
+#define SPECIAL_IRQS ((IS_HW_ERR) |(IS_I2C_READY) | \
+ (IS_EXT_REG) |(IS_TIMINT) | \
+ (IS_PA_TO_RX1) |(IS_PA_TO_RX2) | \
+ (IS_PA_TO_TX1) |(IS_PA_TO_TX2) | \
+ (IS_MAC1) |(IS_LNK_SYNC_M1)| \
+ (IS_MAC2) |(IS_LNK_SYNC_M2)| \
+ (IS_R1_C) |(IS_R2_C) | \
+ (IS_XS1_C) |(IS_XA1_C) | \
+ (IS_XS2_C) |(IS_XA2_C))
+
+#define IRQ_MASK ((IS_IRQ_SW) | \
+ (IS_R1_B) |(IS_R1_F) |(IS_R2_B) |(IS_R2_F) | \
+ (IS_XS1_B) |(IS_XS1_F) |(IS_XA1_B)|(IS_XA1_F)| \
+ (IS_XS2_B) |(IS_XS2_F) |(IS_XA2_B)|(IS_XA2_F)| \
+ (IS_HW_ERR) |(IS_I2C_READY)| \
+ (IS_EXT_REG) |(IS_TIMINT) | \
+ (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \
+ (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \
+ (IS_MAC1) |(IS_MAC2) | \
+ (IS_R1_C) |(IS_R2_C) | \
+ (IS_XS1_C) |(IS_XA1_C) | \
+ (IS_XS2_C) |(IS_XA2_C))
+
+#define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */
+
+typedef struct s_DevNet DEV_NET;
+
+struct s_DevNet {
+ int PortNr;
+ int NetNr;
+ int Mtu;
+ int Up;
+ SK_AC *pAC;
+};
+
+typedef struct s_TxPort TX_PORT;
+
+struct s_TxPort {
+ /* the transmit descriptor rings */
+ caddr_t pTxDescrRing; /* descriptor area memory */
+ SK_U64 VTxDescrRing; /* descr. area bus virt. addr. */
+ TXD *pTxdRingHead; /* Head of Tx rings */
+ TXD *pTxdRingTail; /* Tail of Tx rings */
+ TXD *pTxdRingPrev; /* descriptor sent previously */
+ int TxdRingFree; /* # of free entrys */
+ spinlock_t TxDesRingLock; /* serialize descriptor accesses */
+ SK_IOC HwAddr; /* bmu registers address */
+ int PortIndex; /* index number of port (0 or 1) */
+};
+
+typedef struct s_RxPort RX_PORT;
+
+struct s_RxPort {
+ /* the receive descriptor rings */
+ caddr_t pRxDescrRing; /* descriptor area memory */
+ SK_U64 VRxDescrRing; /* descr. area bus virt. addr. */
+ RXD *pRxdRingHead; /* Head of Rx rings */
+ RXD *pRxdRingTail; /* Tail of Rx rings */
+ RXD *pRxdRingPrev; /* descriptor given to BMU previously */
+ int RxdRingFree; /* # of free entrys */
+ spinlock_t RxDesRingLock; /* serialize descriptor accesses */
+ int RxFillLimit; /* limit for buffers in ring */
+ SK_IOC HwAddr; /* bmu registers address */
+ int PortIndex; /* index number of port (0 or 1) */
+};
+
+/* Definitions needed for interrupt moderation *******************************/
+
+#define IRQ_EOF_AS_TX ((IS_XA1_F) | (IS_XA2_F))
+#define IRQ_EOF_SY_TX ((IS_XS1_F) | (IS_XS2_F))
+#define IRQ_MASK_TX_ONLY ((IRQ_EOF_AS_TX)| (IRQ_EOF_SY_TX))
+#define IRQ_MASK_RX_ONLY ((IS_R1_F) | (IS_R2_F))
+#define IRQ_MASK_SP_ONLY (SPECIAL_IRQS)
+#define IRQ_MASK_TX_RX ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY))
+#define IRQ_MASK_SP_RX ((SPECIAL_IRQS) | (IRQ_MASK_RX_ONLY))
+#define IRQ_MASK_SP_TX ((SPECIAL_IRQS) | (IRQ_MASK_TX_ONLY))
+#define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS) | (IRQ_MASK_TX_RX))
+
+#define C_INT_MOD_NONE 1
+#define C_INT_MOD_STATIC 2
+#define C_INT_MOD_DYNAMIC 4
+
+#define C_CLK_FREQ_GENESIS 53215000 /* shorter: 53.125 MHz */
+#define C_CLK_FREQ_YUKON 78215000 /* shorter: 78.125 MHz */
+
+#define C_INTS_PER_SEC_DEFAULT 2000
+#define C_INT_MOD_ENABLE_PERCENTAGE 50 /* if higher 50% enable */
+#define C_INT_MOD_DISABLE_PERCENTAGE 50 /* if lower 50% disable */
+#define C_INT_MOD_IPS_LOWER_RANGE 30
+#define C_INT_MOD_IPS_UPPER_RANGE 40000
+
+
+typedef struct s_DynIrqModInfo DIM_INFO;
+struct s_DynIrqModInfo {
+ unsigned long PrevTimeVal;
+ unsigned int PrevSysLoad;
+ unsigned int PrevUsedTime;
+ unsigned int PrevTotalTime;
+ int PrevUsedDescrRatio;
+ int NbrProcessedDescr;
+ SK_U64 PrevPort0RxIntrCts;
+ SK_U64 PrevPort1RxIntrCts;
+ SK_U64 PrevPort0TxIntrCts;
+ SK_U64 PrevPort1TxIntrCts;
+ SK_BOOL ModJustEnabled; /* Moderation just enabled yes/no */
+
+ int MaxModIntsPerSec; /* Moderation Threshold */
+ int MaxModIntsPerSecUpperLimit; /* Upper limit for DIM */
+ int MaxModIntsPerSecLowerLimit; /* Lower limit for DIM */
+
+ long MaskIrqModeration; /* ModIrqType (eg. 'TxRx') */
+ SK_BOOL DisplayStats; /* Stats yes/no */
+ SK_BOOL AutoSizing; /* Resize DIM-timer on/off */
+ int IntModTypeSelect; /* EnableIntMod (eg. 'dynamic') */
+
+ SK_TIMER ModTimer; /* just some timer */
+};
+
+typedef struct s_PerStrm PER_STRM;
+
+#define SK_ALLOC_IRQ 0x00000001
+
+#ifdef SK_DIAG_SUPPORT
+#define DIAG_ACTIVE 1
+#define DIAG_NOTACTIVE 0
+#endif
+
+/****************************************************************************
+ * Per board structure / Adapter Context structure:
+ * Allocated within attach(9e) and freed within detach(9e).
+ * Contains all 'per device' necessary handles, flags, locks etc.:
+ */
+struct s_AC {
+ SK_GEINIT GIni; /* GE init struct */
+ SK_PNMI Pnmi; /* PNMI data struct */
+ SK_VPD vpd; /* vpd data struct */
+ SK_QUEUE Event; /* Event queue */
+ SK_HWT Hwt; /* Hardware Timer control struct */
+ SK_TIMCTRL Tim; /* Software Timer control struct */
+ SK_I2C I2c; /* I2C relevant data structure */
+ SK_ADDR Addr; /* for Address module */
+ SK_CSUM Csum; /* for checksum module */
+ SK_RLMT Rlmt; /* for rlmt module */
+ spinlock_t SlowPathLock; /* Normal IRQ lock */
+ struct timer_list BlinkTimer; /* for LED blinking */
+ int LedsOn;
+ SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */
+ int RlmtMode; /* link check mode to set */
+ int RlmtNets; /* Number of nets */
+
+ SK_IOC IoBase; /* register set of adapter */
+ int BoardLevel; /* level of active hw init (0-2) */
+ char DeviceStr[80]; /* adapter string from vpd */
+ SK_U32 AllocFlag; /* flag allocation of resources */
+ struct pci_dev *PciDev; /* for access to pci config space */
+ SK_U32 PciDevId; /* pci device id */
+ struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */
+ char Name[30]; /* driver name */
+
+ int RxBufSize; /* length of receive buffers */
+ struct net_device_stats stats; /* linux 'netstat -i' statistics */
+ int Index; /* internal board index number */
+
+ /* adapter RAM sizes for queues of active port */
+ int RxQueueSize; /* memory used for receive queue */
+ int TxSQueueSize; /* memory used for sync. tx queue */
+ int TxAQueueSize; /* memory used for async. tx queue */
+
+ int PromiscCount; /* promiscuous mode counter */
+ int AllMultiCount; /* allmulticast mode counter */
+ int MulticCount; /* number of different MC */
+ /* addresses for this board */
+ /* (may be more than HW can)*/
+
+ int HWRevision; /* Hardware revision */
+ int ActivePort; /* the active XMAC port */
+ int MaxPorts; /* number of activated ports */
+ int TxDescrPerRing; /* # of descriptors per tx ring */
+ int RxDescrPerRing; /* # of descriptors per rx ring */
+
+ caddr_t pDescrMem; /* Pointer to the descriptor area */
+ dma_addr_t pDescrMemDMA; /* PCI DMA address of area */
+
+ /* the port structures with descriptor rings */
+ TX_PORT TxPort[SK_MAX_MACS][2];
+ RX_PORT RxPort[SK_MAX_MACS];
+
+ unsigned int CsOfs1; /* for checksum calculation */
+ unsigned int CsOfs2; /* for checksum calculation */
+ SK_U32 CsOfs; /* for checksum calculation */
+
+ SK_BOOL CheckQueue; /* check event queue soon */
+ SK_TIMER DrvCleanupTimer;/* to check for pending descriptors */
+ DIM_INFO DynIrqModInfo; /* all data related to DIM */
+
+ /* Only for tests */
+ int PortUp;
+ int PortDown;
+ int ChipsetType; /* Chipset family type
+ * 0 == Genesis family support
+ * 1 == Yukon family support
+ */
+#ifdef SK_DIAG_SUPPORT
+ SK_U32 DiagModeActive; /* is diag active? */
+ SK_BOOL DiagFlowCtrl; /* for control purposes */
+ SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for all Pnmi-Data */
+ SK_BOOL WasIfUp[SK_MAX_MACS]; /* for OpenClose while
+ * DIAG is busy with NIC
+ */
+#endif
+
+};
+
+
+#endif /* __INC_SKDRV2ND_H */
+
diff --git a/drivers/net/sk98lin/h/skerror.h b/drivers/net/sk98lin/h/skerror.h
new file mode 100644
index 000000000000..da062f766238
--- /dev/null
+++ b/drivers/net/sk98lin/h/skerror.h
@@ -0,0 +1,55 @@
+/******************************************************************************
+ *
+ * Name: skerror.h
+ * Project: Gigabit Ethernet Adapters, Common Modules
+ * Version: $Revision: 1.7 $
+ * Date: $Date: 2003/05/13 17:25:13 $
+ * Purpose: SK specific Error log support
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef _INC_SKERROR_H_
+#define _INC_SKERROR_H_
+
+/*
+ * Define Error Classes
+ */
+#define SK_ERRCL_OTHER (0) /* Other error */
+#define SK_ERRCL_CONFIG (1L<<0) /* Configuration error */
+#define SK_ERRCL_INIT (1L<<1) /* Initialization error */
+#define SK_ERRCL_NORES (1L<<2) /* Out of Resources error */
+#define SK_ERRCL_SW (1L<<3) /* Internal Software error */
+#define SK_ERRCL_HW (1L<<4) /* Hardware Failure */
+#define SK_ERRCL_COMM (1L<<5) /* Communication error */
+
+
+/*
+ * Define Error Code Bases
+ */
+#define SK_ERRBASE_RLMT 100 /* Base Error number for RLMT */
+#define SK_ERRBASE_HWINIT 200 /* Base Error number for HWInit */
+#define SK_ERRBASE_VPD 300 /* Base Error number for VPD */
+#define SK_ERRBASE_PNMI 400 /* Base Error number for PNMI */
+#define SK_ERRBASE_CSUM 500 /* Base Error number for Checksum */
+#define SK_ERRBASE_SIRQ 600 /* Base Error number for Special IRQ */
+#define SK_ERRBASE_I2C 700 /* Base Error number for I2C module */
+#define SK_ERRBASE_QUEUE 800 /* Base Error number for Scheduler */
+#define SK_ERRBASE_ADDR 900 /* Base Error number for Address module */
+#define SK_ERRBASE_PECP 1000 /* Base Error number for PECP */
+#define SK_ERRBASE_DRV 1100 /* Base Error number for Driver */
+
+#endif /* _INC_SKERROR_H_ */
diff --git a/drivers/net/sk98lin/h/skgedrv.h b/drivers/net/sk98lin/h/skgedrv.h
new file mode 100644
index 000000000000..44fd4c3de818
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgedrv.h
@@ -0,0 +1,51 @@
+/******************************************************************************
+ *
+ * Name: skgedrv.h
+ * Project: Gigabit Ethernet Adapters, Common Modules
+ * Version: $Revision: 1.10 $
+ * Date: $Date: 2003/07/04 12:25:01 $
+ * Purpose: Interface with the driver
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKGEDRV_H_
+#define __INC_SKGEDRV_H_
+
+/* defines ********************************************************************/
+
+/*
+ * 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 operational */
+#define SK_DRV_NET_DOWN 3 /* The net is down */
+#define SK_DRV_SWITCH_SOFT 4 /* Ports switch with both links connected */
+#define SK_DRV_SWITCH_HARD 5 /* Port switch due to link failure */
+#define SK_DRV_RLMT_SEND 6 /* Send a RLMT packet */
+#define SK_DRV_ADAP_FAIL 7 /* The whole adapter fails */
+#define SK_DRV_PORT_FAIL 8 /* One port fails */
+#define SK_DRV_SWITCH_INTERN 9 /* Port switch by the driver itself */
+#define SK_DRV_POWER_DOWN 10 /* Power down mode */
+#define SK_DRV_TIMER 11 /* Timer for free use */
+#ifdef SK_NO_RLMT
+#define SK_DRV_LINK_UP 12 /* Link Up event for driver */
+#define SK_DRV_LINK_DOWN 13 /* Link Down event for driver */
+#endif
+#define SK_DRV_DOWNSHIFT_DET 14 /* Downshift 4-Pair / 2-Pair (YUKON only) */
+#endif /* __INC_SKGEDRV_H_ */
diff --git a/drivers/net/sk98lin/h/skgehw.h b/drivers/net/sk98lin/h/skgehw.h
new file mode 100644
index 000000000000..f6282b7956db
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgehw.h
@@ -0,0 +1,2126 @@
+/******************************************************************************
+ *
+ * Name: skgehw.h
+ * Project: Gigabit Ethernet Adapters, Common Modules
+ * Version: $Revision: 1.56 $
+ * Date: $Date: 2003/09/23 09:01:00 $
+ * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKGEHW_H
+#define __INC_SKGEHW_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* defines ********************************************************************/
+
+#define BIT_31 (1UL << 31)
+#define BIT_30 (1L << 30)
+#define BIT_29 (1L << 29)
+#define BIT_28 (1L << 28)
+#define BIT_27 (1L << 27)
+#define BIT_26 (1L << 26)
+#define BIT_25 (1L << 25)
+#define BIT_24 (1L << 24)
+#define BIT_23 (1L << 23)
+#define BIT_22 (1L << 22)
+#define BIT_21 (1L << 21)
+#define BIT_20 (1L << 20)
+#define BIT_19 (1L << 19)
+#define BIT_18 (1L << 18)
+#define BIT_17 (1L << 17)
+#define BIT_16 (1L << 16)
+#define BIT_15 (1L << 15)
+#define BIT_14 (1L << 14)
+#define BIT_13 (1L << 13)
+#define BIT_12 (1L << 12)
+#define BIT_11 (1L << 11)
+#define BIT_10 (1L << 10)
+#define BIT_9 (1L << 9)
+#define BIT_8 (1L << 8)
+#define BIT_7 (1L << 7)
+#define BIT_6 (1L << 6)
+#define BIT_5 (1L << 5)
+#define BIT_4 (1L << 4)
+#define BIT_3 (1L << 3)
+#define BIT_2 (1L << 2)
+#define BIT_1 (1L << 1)
+#define BIT_0 1L
+
+#define BIT_15S (1U << 15)
+#define BIT_14S (1 << 14)
+#define BIT_13S (1 << 13)
+#define BIT_12S (1 << 12)
+#define BIT_11S (1 << 11)
+#define BIT_10S (1 << 10)
+#define BIT_9S (1 << 9)
+#define BIT_8S (1 << 8)
+#define BIT_7S (1 << 7)
+#define BIT_6S (1 << 6)
+#define BIT_5S (1 << 5)
+#define BIT_4S (1 << 4)
+#define BIT_3S (1 << 3)
+#define BIT_2S (1 << 2)
+#define BIT_1S (1 << 1)
+#define BIT_0S 1
+
+#define SHIFT31(x) ((x) << 31)
+#define SHIFT30(x) ((x) << 30)
+#define SHIFT29(x) ((x) << 29)
+#define SHIFT28(x) ((x) << 28)
+#define SHIFT27(x) ((x) << 27)
+#define SHIFT26(x) ((x) << 26)
+#define SHIFT25(x) ((x) << 25)
+#define SHIFT24(x) ((x) << 24)
+#define SHIFT23(x) ((x) << 23)
+#define SHIFT22(x) ((x) << 22)
+#define SHIFT21(x) ((x) << 21)
+#define SHIFT20(x) ((x) << 20)
+#define SHIFT19(x) ((x) << 19)
+#define SHIFT18(x) ((x) << 18)
+#define SHIFT17(x) ((x) << 17)
+#define SHIFT16(x) ((x) << 16)
+#define SHIFT15(x) ((x) << 15)
+#define SHIFT14(x) ((x) << 14)
+#define SHIFT13(x) ((x) << 13)
+#define SHIFT12(x) ((x) << 12)
+#define SHIFT11(x) ((x) << 11)
+#define SHIFT10(x) ((x) << 10)
+#define SHIFT9(x) ((x) << 9)
+#define SHIFT8(x) ((x) << 8)
+#define SHIFT7(x) ((x) << 7)
+#define SHIFT6(x) ((x) << 6)
+#define SHIFT5(x) ((x) << 5)
+#define SHIFT4(x) ((x) << 4)
+#define SHIFT3(x) ((x) << 3)
+#define SHIFT2(x) ((x) << 2)
+#define SHIFT1(x) ((x) << 1)
+#define SHIFT0(x) ((x) << 0)
+
+/*
+ * Configuration Space header
+ * Since this module is used for different OS', those may be
+ * duplicate on some of them (e.g. Linux). But to keep the
+ * common source, we have to live with this...
+ */
+#define PCI_VENDOR_ID 0x00 /* 16 bit Vendor ID */
+#define PCI_DEVICE_ID 0x02 /* 16 bit Device ID */
+#define PCI_COMMAND 0x04 /* 16 bit Command */
+#define PCI_STATUS 0x06 /* 16 bit Status */
+#define PCI_REV_ID 0x08 /* 8 bit Revision ID */
+#define PCI_CLASS_CODE 0x09 /* 24 bit Class Code */
+#define PCI_CACHE_LSZ 0x0c /* 8 bit Cache Line Size */
+#define PCI_LAT_TIM 0x0d /* 8 bit Latency Timer */
+#define PCI_HEADER_T 0x0e /* 8 bit Header Type */
+#define PCI_BIST 0x0f /* 8 bit Built-in selftest */
+#define PCI_BASE_1ST 0x10 /* 32 bit 1st Base address */
+#define PCI_BASE_2ND 0x14 /* 32 bit 2nd Base address */
+ /* Byte 0x18..0x2b: reserved */
+#define PCI_SUB_VID 0x2c /* 16 bit Subsystem Vendor ID */
+#define PCI_SUB_ID 0x2e /* 16 bit Subsystem ID */
+#define PCI_BASE_ROM 0x30 /* 32 bit Expansion ROM Base Address */
+#define PCI_CAP_PTR 0x34 /* 8 bit Capabilities Ptr */
+ /* Byte 0x35..0x3b: reserved */
+#define PCI_IRQ_LINE 0x3c /* 8 bit Interrupt Line */
+#define PCI_IRQ_PIN 0x3d /* 8 bit Interrupt Pin */
+#define PCI_MIN_GNT 0x3e /* 8 bit Min_Gnt */
+#define PCI_MAX_LAT 0x3f /* 8 bit Max_Lat */
+ /* Device Dependent Region */
+#define PCI_OUR_REG_1 0x40 /* 32 bit Our Register 1 */
+#define PCI_OUR_REG_2 0x44 /* 32 bit Our Register 2 */
+ /* Power Management Region */
+#define PCI_PM_CAP_ID 0x48 /* 8 bit Power Management Cap. ID */
+#define PCI_PM_NITEM 0x49 /* 8 bit Next Item Ptr */
+#define PCI_PM_CAP_REG 0x4a /* 16 bit Power Management Capabilities */
+#define PCI_PM_CTL_STS 0x4c /* 16 bit Power Manag. Control/Status */
+ /* Byte 0x4e: reserved */
+#define PCI_PM_DAT_REG 0x4f /* 8 bit Power Manag. Data Register */
+ /* VPD Region */
+#define PCI_VPD_CAP_ID 0x50 /* 8 bit VPD Cap. ID */
+#define PCI_VPD_NITEM 0x51 /* 8 bit Next Item Ptr */
+#define PCI_VPD_ADR_REG 0x52 /* 16 bit VPD Address Register */
+#define PCI_VPD_DAT_REG 0x54 /* 32 bit VPD Data Register */
+ /* Byte 0x58..0x59: reserved */
+#define PCI_SER_LD_CTRL 0x5a /* 16 bit SEEPROM Loader Ctrl (YUKON only) */
+ /* Byte 0x5c..0xff: reserved */
+
+/*
+ * I2C Address (PCI Config)
+ *
+ * Note: The temperature and voltage sensors are relocated on a different
+ * I2C bus.
+ */
+#define I2C_ADDR_VPD 0xa0 /* I2C address for the VPD EEPROM */
+
+/*
+ * Define Bits and Values of the registers
+ */
+/* PCI_COMMAND 16 bit Command */
+ /* Bit 15..11: reserved */
+#define PCI_INT_DIS BIT_10S /* Interrupt INTx# disable (PCI 2.3) */
+#define PCI_FBTEN BIT_9S /* Fast Back-To-Back enable */
+#define PCI_SERREN BIT_8S /* SERR enable */
+#define PCI_ADSTEP BIT_7S /* Address Stepping */
+#define PCI_PERREN BIT_6S /* Parity Report Response enable */
+#define PCI_VGA_SNOOP BIT_5S /* VGA palette snoop */
+#define PCI_MWIEN BIT_4S /* Memory write an inv cycl ena */
+#define PCI_SCYCEN BIT_3S /* Special Cycle enable */
+#define PCI_BMEN BIT_2S /* Bus Master enable */
+#define PCI_MEMEN BIT_1S /* Memory Space Access enable */
+#define PCI_IOEN BIT_0S /* I/O Space Access enable */
+
+#define PCI_COMMAND_VAL (PCI_FBTEN | PCI_SERREN | PCI_PERREN | PCI_MWIEN |\
+ PCI_BMEN | PCI_MEMEN | PCI_IOEN)
+
+/* PCI_STATUS 16 bit Status */
+#define PCI_PERR BIT_15S /* Parity Error */
+#define PCI_SERR BIT_14S /* Signaled SERR */
+#define PCI_RMABORT BIT_13S /* Received Master Abort */
+#define PCI_RTABORT BIT_12S /* Received Target Abort */
+ /* Bit 11: reserved */
+#define PCI_DEVSEL (3<<9) /* Bit 10.. 9: DEVSEL Timing */
+#define PCI_DEV_FAST (0<<9) /* fast */
+#define PCI_DEV_MEDIUM (1<<9) /* medium */
+#define PCI_DEV_SLOW (2<<9) /* slow */
+#define PCI_DATAPERR BIT_8S /* DATA Parity error detected */
+#define PCI_FB2BCAP BIT_7S /* Fast Back-to-Back Capability */
+#define PCI_UDF BIT_6S /* User Defined Features */
+#define PCI_66MHZCAP BIT_5S /* 66 MHz PCI bus clock capable */
+#define PCI_NEWCAP BIT_4S /* New cap. list implemented */
+#define PCI_INT_STAT BIT_3S /* Interrupt INTx# Status (PCI 2.3) */
+ /* Bit 2.. 0: reserved */
+
+#define PCI_ERRBITS (PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\
+ PCI_DATAPERR)
+
+/* PCI_CLASS_CODE 24 bit Class Code */
+/* Byte 2: Base Class (02) */
+/* Byte 1: SubClass (00) */
+/* Byte 0: Programming Interface (00) */
+
+/* PCI_CACHE_LSZ 8 bit Cache Line Size */
+/* Possible values: 0,2,4,8,16,32,64,128 */
+
+/* PCI_HEADER_T 8 bit Header Type */
+#define PCI_HD_MF_DEV BIT_7S /* 0= single, 1= multi-func dev */
+#define PCI_HD_TYPE 0x7f /* Bit 6..0: Header Layout 0= normal */
+
+/* PCI_BIST 8 bit Built-in selftest */
+/* Built-in Self test not supported (optional) */
+
+/* PCI_BASE_1ST 32 bit 1st Base address */
+#define PCI_MEMSIZE 0x4000L /* use 16 kB Memory Base */
+#define PCI_MEMBASE_MSK 0xffffc000L /* Bit 31..14: Memory Base Address */
+#define PCI_MEMSIZE_MSK 0x00003ff0L /* Bit 13.. 4: Memory Size Req. */
+#define PCI_PREFEN BIT_3 /* Prefetchable */
+#define PCI_MEM_TYP (3L<<2) /* Bit 2.. 1: Memory Type */
+#define PCI_MEM32BIT (0L<<1) /* Base addr anywhere in 32 Bit range */
+#define PCI_MEM1M (1L<<1) /* Base addr below 1 MegaByte */
+#define PCI_MEM64BIT (2L<<1) /* Base addr anywhere in 64 Bit range */
+#define PCI_MEMSPACE BIT_0 /* Memory Space Indicator */
+
+/* PCI_BASE_2ND 32 bit 2nd Base address */
+#define PCI_IOBASE 0xffffff00L /* Bit 31.. 8: I/O Base address */
+#define PCI_IOSIZE 0x000000fcL /* Bit 7.. 2: I/O Size Requirements */
+ /* Bit 1: reserved */
+#define PCI_IOSPACE BIT_0 /* I/O Space Indicator */
+
+/* PCI_BASE_ROM 32 bit Expansion ROM Base Address */
+#define PCI_ROMBASE_MSK 0xfffe0000L /* Bit 31..17: ROM Base address */
+#define PCI_ROMBASE_SIZ (0x1cL<<14) /* Bit 16..14: Treat as Base or Size */
+#define PCI_ROMSIZE (0x38L<<11) /* Bit 13..11: ROM Size Requirements */
+ /* Bit 10.. 1: reserved */
+#define PCI_ROMEN BIT_0 /* Address Decode enable */
+
+/* Device Dependent Region */
+/* PCI_OUR_REG_1 32 bit Our Register 1 */
+ /* Bit 31..29: reserved */
+#define PCI_PHY_COMA BIT_28 /* Set PHY to Coma Mode (YUKON only) */
+#define PCI_TEST_CAL BIT_27 /* Test PCI buffer calib. (YUKON only) */
+#define PCI_EN_CAL BIT_26 /* Enable PCI buffer calib. (YUKON only) */
+#define PCI_VIO BIT_25 /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */
+#define PCI_DIS_BOOT BIT_24 /* Disable BOOT via ROM */
+#define PCI_EN_IO BIT_23 /* Mapping to I/O space */
+#define PCI_EN_FPROM BIT_22 /* Enable FLASH mapping to memory */
+ /* 1 = Map Flash to memory */
+ /* 0 = Disable addr. dec */
+#define PCI_PAGESIZE (3L<<20) /* Bit 21..20: FLASH Page Size */
+#define PCI_PAGE_16 (0L<<20) /* 16 k pages */
+#define PCI_PAGE_32K (1L<<20) /* 32 k pages */
+#define PCI_PAGE_64K (2L<<20) /* 64 k pages */
+#define PCI_PAGE_128K (3L<<20) /* 128 k pages */
+ /* Bit 19: reserved */
+#define PCI_PAGEREG (7L<<16) /* Bit 18..16: Page Register */
+#define PCI_NOTAR BIT_15 /* No turnaround cycle */
+#define PCI_FORCE_BE BIT_14 /* Assert all BEs on MR */
+#define PCI_DIS_MRL BIT_13 /* Disable Mem Read Line */
+#define PCI_DIS_MRM BIT_12 /* Disable Mem Read Multiple */
+#define PCI_DIS_MWI BIT_11 /* Disable Mem Write & Invalidate */
+#define PCI_DISC_CLS BIT_10 /* Disc: cacheLsz bound */
+#define PCI_BURST_DIS BIT_9 /* Burst Disable */
+#define PCI_DIS_PCI_CLK BIT_8 /* Disable PCI clock driving */
+#define PCI_SKEW_DAS (0xfL<<4) /* Bit 7.. 4: Skew Ctrl, DAS Ext */
+#define PCI_SKEW_BASE 0xfL /* Bit 3.. 0: Skew Ctrl, Base */
+
+
+/* PCI_OUR_REG_2 32 bit Our Register 2 */
+#define PCI_VPD_WR_THR (0xffL<<24) /* Bit 31..24: VPD Write Threshold */
+#define PCI_DEV_SEL (0x7fL<<17) /* Bit 23..17: EEPROM Device Select */
+#define PCI_VPD_ROM_SZ (7L<<14) /* Bit 16..14: VPD ROM Size */
+ /* Bit 13..12: reserved */
+#define PCI_PATCH_DIR (0xfL<<8) /* Bit 11.. 8: Ext Patches dir 3..0 */
+#define PCI_PATCH_DIR_3 BIT_11
+#define PCI_PATCH_DIR_2 BIT_10
+#define PCI_PATCH_DIR_1 BIT_9
+#define PCI_PATCH_DIR_0 BIT_8
+#define PCI_EXT_PATCHS (0xfL<<4) /* Bit 7.. 4: Extended Patches 3..0 */
+#define PCI_EXT_PATCH_3 BIT_7
+#define PCI_EXT_PATCH_2 BIT_6
+#define PCI_EXT_PATCH_1 BIT_5
+#define PCI_EXT_PATCH_0 BIT_4
+#define PCI_EN_DUMMY_RD BIT_3 /* Enable Dummy Read */
+#define PCI_REV_DESC BIT_2 /* Reverse Desc. Bytes */
+ /* Bit 1: reserved */
+#define PCI_USEDATA64 BIT_0 /* Use 64Bit Data bus ext */
+
+
+/* Power Management Region */
+/* PCI_PM_CAP_REG 16 bit Power Management Capabilities */
+#define PCI_PME_SUP_MSK (0x1f<<11) /* Bit 15..11: PM Event Support Mask */
+#define PCI_PME_D3C_SUP BIT_15S /* PME from D3cold Support (if Vaux) */
+#define PCI_PME_D3H_SUP BIT_14S /* PME from D3hot Support */
+#define PCI_PME_D2_SUP BIT_13S /* PME from D2 Support */
+#define PCI_PME_D1_SUP BIT_12S /* PME from D1 Support */
+#define PCI_PME_D0_SUP BIT_11S /* PME from D0 Support */
+#define PCI_PM_D2_SUP BIT_10S /* D2 Support in 33 MHz mode */
+#define PCI_PM_D1_SUP BIT_9S /* D1 Support */
+ /* Bit 8.. 6: reserved */
+#define PCI_PM_DSI BIT_5S /* Device Specific Initialization */
+#define PCI_PM_APS BIT_4S /* Auxialiary Power Source */
+#define PCI_PME_CLOCK BIT_3S /* PM Event Clock */
+#define PCI_PM_VER_MSK 7 /* Bit 2.. 0: PM PCI Spec. version */
+
+/* PCI_PM_CTL_STS 16 bit Power Management Control/Status */
+#define PCI_PME_STATUS BIT_15S /* PME Status (YUKON only) */
+#define PCI_PM_DAT_SCL (3<<13) /* Bit 14..13: Data Reg. scaling factor */
+#define PCI_PM_DAT_SEL (0xf<<9) /* Bit 12.. 9: PM data selector field */
+#define PCI_PME_EN BIT_8S /* Enable PME# generation (YUKON only) */
+ /* Bit 7.. 2: reserved */
+#define PCI_PM_STATE_MSK 3 /* Bit 1.. 0: Power Management State */
+
+#define PCI_PM_STATE_D0 0 /* D0: Operational (default) */
+#define PCI_PM_STATE_D1 1 /* D1: (YUKON only) */
+#define PCI_PM_STATE_D2 2 /* D2: (YUKON only) */
+#define PCI_PM_STATE_D3 3 /* D3: HOT, Power Down and Reset */
+
+/* VPD Region */
+/* PCI_VPD_ADR_REG 16 bit VPD Address Register */
+#define PCI_VPD_FLAG BIT_15S /* starts VPD rd/wr cycle */
+#define PCI_VPD_ADR_MSK 0x7fffL /* Bit 14.. 0: VPD address mask */
+
+/* Control Register File (Address Map) */
+
+/*
+ * Bank 0
+ */
+#define B0_RAP 0x0000 /* 8 bit Register Address Port */
+ /* 0x0001 - 0x0003: reserved */
+#define B0_CTST 0x0004 /* 16 bit Control/Status register */
+#define B0_LED 0x0006 /* 8 Bit LED register */
+#define B0_POWER_CTRL 0x0007 /* 8 Bit Power Control reg (YUKON only) */
+#define B0_ISRC 0x0008 /* 32 bit Interrupt Source Register */
+#define B0_IMSK 0x000c /* 32 bit Interrupt Mask Register */
+#define B0_HWE_ISRC 0x0010 /* 32 bit HW Error Interrupt Src Reg */
+#define B0_HWE_IMSK 0x0014 /* 32 bit HW Error Interrupt Mask Reg */
+#define B0_SP_ISRC 0x0018 /* 32 bit Special Interrupt Source Reg */
+ /* 0x001c: reserved */
+
+/* B0 XMAC 1 registers (GENESIS only) */
+#define B0_XM1_IMSK 0x0020 /* 16 bit r/w XMAC 1 Interrupt Mask Register*/
+ /* 0x0022 - 0x0027: reserved */
+#define B0_XM1_ISRC 0x0028 /* 16 bit ro XMAC 1 Interrupt Status Reg */
+ /* 0x002a - 0x002f: reserved */
+#define B0_XM1_PHY_ADDR 0x0030 /* 16 bit r/w XMAC 1 PHY Address Register */
+ /* 0x0032 - 0x0033: reserved */
+#define B0_XM1_PHY_DATA 0x0034 /* 16 bit r/w XMAC 1 PHY Data Register */
+ /* 0x0036 - 0x003f: reserved */
+
+/* B0 XMAC 2 registers (GENESIS only) */
+#define B0_XM2_IMSK 0x0040 /* 16 bit r/w XMAC 2 Interrupt Mask Register*/
+ /* 0x0042 - 0x0047: reserved */
+#define B0_XM2_ISRC 0x0048 /* 16 bit ro XMAC 2 Interrupt Status Reg */
+ /* 0x004a - 0x004f: reserved */
+#define B0_XM2_PHY_ADDR 0x0050 /* 16 bit r/w XMAC 2 PHY Address Register */
+ /* 0x0052 - 0x0053: reserved */
+#define B0_XM2_PHY_DATA 0x0054 /* 16 bit r/w XMAC 2 PHY Data Register */
+ /* 0x0056 - 0x005f: reserved */
+
+/* BMU Control Status Registers */
+#define B0_R1_CSR 0x0060 /* 32 bit BMU Ctrl/Stat Rx Queue 1 */
+#define B0_R2_CSR 0x0064 /* 32 bit BMU Ctrl/Stat Rx Queue 2 */
+#define B0_XS1_CSR 0x0068 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */
+#define B0_XA1_CSR 0x006c /* 32 bit BMU Ctrl/Stat Async Tx Queue 1*/
+#define B0_XS2_CSR 0x0070 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */
+#define B0_XA2_CSR 0x0074 /* 32 bit BMU Ctrl/Stat Async Tx Queue 2*/
+ /* 0x0078 - 0x007f: reserved */
+
+/*
+ * Bank 1
+ * - completely empty (this is the RAP Block window)
+ * Note: if RAP = 1 this page is reserved
+ */
+
+/*
+ * Bank 2
+ */
+/* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */
+#define B2_MAC_1 0x0100 /* NA reg MAC Address 1 */
+ /* 0x0106 - 0x0107: reserved */
+#define B2_MAC_2 0x0108 /* NA reg MAC Address 2 */
+ /* 0x010e - 0x010f: reserved */
+#define B2_MAC_3 0x0110 /* NA reg MAC Address 3 */
+ /* 0x0116 - 0x0117: reserved */
+#define B2_CONN_TYP 0x0118 /* 8 bit Connector type */
+#define B2_PMD_TYP 0x0119 /* 8 bit PMD type */
+#define B2_MAC_CFG 0x011a /* 8 bit MAC Configuration / Chip Revision */
+#define B2_CHIP_ID 0x011b /* 8 bit Chip Identification Number */
+ /* Eprom registers are currently of no use */
+#define B2_E_0 0x011c /* 8 bit EPROM Byte 0 (ext. SRAM size */
+#define B2_E_1 0x011d /* 8 bit EPROM Byte 1 (PHY type) */
+#define B2_E_2 0x011e /* 8 bit EPROM Byte 2 */
+#define B2_E_3 0x011f /* 8 bit EPROM Byte 3 */
+#define B2_FAR 0x0120 /* 32 bit Flash-Prom Addr Reg/Cnt */
+#define B2_FDP 0x0124 /* 8 bit Flash-Prom Data Port */
+ /* 0x0125 - 0x0127: reserved */
+#define B2_LD_CTRL 0x0128 /* 8 bit EPROM loader control register */
+#define B2_LD_TEST 0x0129 /* 8 bit EPROM loader test register */
+ /* 0x012a - 0x012f: reserved */
+#define B2_TI_INI 0x0130 /* 32 bit Timer Init Value */
+#define B2_TI_VAL 0x0134 /* 32 bit Timer Value */
+#define B2_TI_CTRL 0x0138 /* 8 bit Timer Control */
+#define B2_TI_TEST 0x0139 /* 8 Bit Timer Test */
+ /* 0x013a - 0x013f: reserved */
+#define B2_IRQM_INI 0x0140 /* 32 bit IRQ Moderation Timer Init Reg.*/
+#define B2_IRQM_VAL 0x0144 /* 32 bit IRQ Moderation Timer Value */
+#define B2_IRQM_CTRL 0x0148 /* 8 bit IRQ Moderation Timer Control */
+#define B2_IRQM_TEST 0x0149 /* 8 bit IRQ Moderation Timer Test */
+#define B2_IRQM_MSK 0x014c /* 32 bit IRQ Moderation Mask */
+#define B2_IRQM_HWE_MSK 0x0150 /* 32 bit IRQ Moderation HW Error Mask */
+ /* 0x0154 - 0x0157: reserved */
+#define B2_TST_CTRL1 0x0158 /* 8 bit Test Control Register 1 */
+#define B2_TST_CTRL2 0x0159 /* 8 bit Test Control Register 2 */
+ /* 0x015a - 0x015b: reserved */
+#define B2_GP_IO 0x015c /* 32 bit General Purpose I/O Register */
+#define B2_I2C_CTRL 0x0160 /* 32 bit I2C HW Control Register */
+#define B2_I2C_DATA 0x0164 /* 32 bit I2C HW Data Register */
+#define B2_I2C_IRQ 0x0168 /* 32 bit I2C HW IRQ Register */
+#define B2_I2C_SW 0x016c /* 32 bit I2C SW Port Register */
+
+/* Blink Source Counter (GENESIS only) */
+#define B2_BSC_INI 0x0170 /* 32 bit Blink Source Counter Init Val */
+#define B2_BSC_VAL 0x0174 /* 32 bit Blink Source Counter Value */
+#define B2_BSC_CTRL 0x0178 /* 8 bit Blink Source Counter Control */
+#define B2_BSC_STAT 0x0179 /* 8 bit Blink Source Counter Status */
+#define B2_BSC_TST 0x017a /* 16 bit Blink Source Counter Test Reg */
+ /* 0x017c - 0x017f: reserved */
+
+/*
+ * Bank 3
+ */
+/* RAM Random Registers */
+#define B3_RAM_ADDR 0x0180 /* 32 bit RAM Address, to read or write */
+#define B3_RAM_DATA_LO 0x0184 /* 32 bit RAM Data Word (low dWord) */
+#define B3_RAM_DATA_HI 0x0188 /* 32 bit RAM Data Word (high dWord) */
+ /* 0x018c - 0x018f: reserved */
+
+/* RAM Interface Registers */
+/*
+ * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
+ * not usable in SW. Please notice these are NOT real timeouts, these are
+ * the number of qWords transferred continuously.
+ */
+#define B3_RI_WTO_R1 0x0190 /* 8 bit WR Timeout Queue R1 (TO0) */
+#define B3_RI_WTO_XA1 0x0191 /* 8 bit WR Timeout Queue XA1 (TO1) */
+#define B3_RI_WTO_XS1 0x0192 /* 8 bit WR Timeout Queue XS1 (TO2) */
+#define B3_RI_RTO_R1 0x0193 /* 8 bit RD Timeout Queue R1 (TO3) */
+#define B3_RI_RTO_XA1 0x0194 /* 8 bit RD Timeout Queue XA1 (TO4) */
+#define B3_RI_RTO_XS1 0x0195 /* 8 bit RD Timeout Queue XS1 (TO5) */
+#define B3_RI_WTO_R2 0x0196 /* 8 bit WR Timeout Queue R2 (TO6) */
+#define B3_RI_WTO_XA2 0x0197 /* 8 bit WR Timeout Queue XA2 (TO7) */
+#define B3_RI_WTO_XS2 0x0198 /* 8 bit WR Timeout Queue XS2 (TO8) */
+#define B3_RI_RTO_R2 0x0199 /* 8 bit RD Timeout Queue R2 (TO9) */
+#define B3_RI_RTO_XA2 0x019a /* 8 bit RD Timeout Queue XA2 (TO10)*/
+#define B3_RI_RTO_XS2 0x019b /* 8 bit RD Timeout Queue XS2 (TO11)*/
+#define B3_RI_TO_VAL 0x019c /* 8 bit Current Timeout Count Val */
+ /* 0x019d - 0x019f: reserved */
+#define B3_RI_CTRL 0x01a0 /* 16 bit RAM Interface Control Register */
+#define B3_RI_TEST 0x01a2 /* 8 bit RAM Interface Test Register */
+ /* 0x01a3 - 0x01af: reserved */
+
+/* MAC Arbiter Registers (GENESIS only) */
+/* these are the no. of qWord transferred continuously and NOT real timeouts */
+#define B3_MA_TOINI_RX1 0x01b0 /* 8 bit Timeout Init Val Rx Path MAC 1 */
+#define B3_MA_TOINI_RX2 0x01b1 /* 8 bit Timeout Init Val Rx Path MAC 2 */
+#define B3_MA_TOINI_TX1 0x01b2 /* 8 bit Timeout Init Val Tx Path MAC 1 */
+#define B3_MA_TOINI_TX2 0x01b3 /* 8 bit Timeout Init Val Tx Path MAC 2 */
+#define B3_MA_TOVAL_RX1 0x01b4 /* 8 bit Timeout Value Rx Path MAC 1 */
+#define B3_MA_TOVAL_RX2 0x01b5 /* 8 bit Timeout Value Rx Path MAC 1 */
+#define B3_MA_TOVAL_TX1 0x01b6 /* 8 bit Timeout Value Tx Path MAC 2 */
+#define B3_MA_TOVAL_TX2 0x01b7 /* 8 bit Timeout Value Tx Path MAC 2 */
+#define B3_MA_TO_CTRL 0x01b8 /* 16 bit MAC Arbiter Timeout Ctrl Reg */
+#define B3_MA_TO_TEST 0x01ba /* 16 bit MAC Arbiter Timeout Test Reg */
+ /* 0x01bc - 0x01bf: reserved */
+#define B3_MA_RCINI_RX1 0x01c0 /* 8 bit Recovery Init Val Rx Path MAC 1 */
+#define B3_MA_RCINI_RX2 0x01c1 /* 8 bit Recovery Init Val Rx Path MAC 2 */
+#define B3_MA_RCINI_TX1 0x01c2 /* 8 bit Recovery Init Val Tx Path MAC 1 */
+#define B3_MA_RCINI_TX2 0x01c3 /* 8 bit Recovery Init Val Tx Path MAC 2 */
+#define B3_MA_RCVAL_RX1 0x01c4 /* 8 bit Recovery Value Rx Path MAC 1 */
+#define B3_MA_RCVAL_RX2 0x01c5 /* 8 bit Recovery Value Rx Path MAC 1 */
+#define B3_MA_RCVAL_TX1 0x01c6 /* 8 bit Recovery Value Tx Path MAC 2 */
+#define B3_MA_RCVAL_TX2 0x01c7 /* 8 bit Recovery Value Tx Path MAC 2 */
+#define B3_MA_RC_CTRL 0x01c8 /* 16 bit MAC Arbiter Recovery Ctrl Reg */
+#define B3_MA_RC_TEST 0x01ca /* 16 bit MAC Arbiter Recovery Test Reg */
+ /* 0x01cc - 0x01cf: reserved */
+
+/* Packet Arbiter Registers (GENESIS only) */
+/* these are real timeouts */
+#define B3_PA_TOINI_RX1 0x01d0 /* 16 bit Timeout Init Val Rx Path MAC 1 */
+ /* 0x01d2 - 0x01d3: reserved */
+#define B3_PA_TOINI_RX2 0x01d4 /* 16 bit Timeout Init Val Rx Path MAC 2 */
+ /* 0x01d6 - 0x01d7: reserved */
+#define B3_PA_TOINI_TX1 0x01d8 /* 16 bit Timeout Init Val Tx Path MAC 1 */
+ /* 0x01da - 0x01db: reserved */
+#define B3_PA_TOINI_TX2 0x01dc /* 16 bit Timeout Init Val Tx Path MAC 2 */
+ /* 0x01de - 0x01df: reserved */
+#define B3_PA_TOVAL_RX1 0x01e0 /* 16 bit Timeout Val Rx Path MAC 1 */
+ /* 0x01e2 - 0x01e3: reserved */
+#define B3_PA_TOVAL_RX2 0x01e4 /* 16 bit Timeout Val Rx Path MAC 2 */
+ /* 0x01e6 - 0x01e7: reserved */
+#define B3_PA_TOVAL_TX1 0x01e8 /* 16 bit Timeout Val Tx Path MAC 1 */
+ /* 0x01ea - 0x01eb: reserved */
+#define B3_PA_TOVAL_TX2 0x01ec /* 16 bit Timeout Val Tx Path MAC 2 */
+ /* 0x01ee - 0x01ef: reserved */
+#define B3_PA_CTRL 0x01f0 /* 16 bit Packet Arbiter Ctrl Register */
+#define B3_PA_TEST 0x01f2 /* 16 bit Packet Arbiter Test Register */
+ /* 0x01f4 - 0x01ff: reserved */
+
+/*
+ * Bank 4 - 5
+ */
+/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
+#define TXA_ITI_INI 0x0200 /* 32 bit Tx Arb Interval Timer Init Val*/
+#define TXA_ITI_VAL 0x0204 /* 32 bit Tx Arb Interval Timer Value */
+#define TXA_LIM_INI 0x0208 /* 32 bit Tx Arb Limit Counter Init Val */
+#define TXA_LIM_VAL 0x020c /* 32 bit Tx Arb Limit Counter Value */
+#define TXA_CTRL 0x0210 /* 8 bit Tx Arbiter Control Register */
+#define TXA_TEST 0x0211 /* 8 bit Tx Arbiter Test Register */
+#define TXA_STAT 0x0212 /* 8 bit Tx Arbiter Status Register */
+ /* 0x0213 - 0x027f: reserved */
+ /* 0x0280 - 0x0292: MAC 2 */
+ /* 0x0213 - 0x027f: reserved */
+
+/*
+ * Bank 6
+ */
+/* External registers (GENESIS only) */
+#define B6_EXT_REG 0x0300
+
+/*
+ * Bank 7
+ */
+/* This is a copy of the Configuration register file (lower half) */
+#define B7_CFG_SPC 0x0380
+
+/*
+ * Bank 8 - 15
+ */
+/* Receive and Transmit Queue Registers, use Q_ADDR() to access */
+#define B8_Q_REGS 0x0400
+
+/* Queue Register Offsets, use Q_ADDR() to access */
+#define Q_D 0x00 /* 8*32 bit Current Descriptor */
+#define Q_DA_L 0x20 /* 32 bit Current Descriptor Address Low dWord */
+#define Q_DA_H 0x24 /* 32 bit Current Descriptor Address High dWord */
+#define Q_AC_L 0x28 /* 32 bit Current Address Counter Low dWord */
+#define Q_AC_H 0x2c /* 32 bit Current Address Counter High dWord */
+#define Q_BC 0x30 /* 32 bit Current Byte Counter */
+#define Q_CSR 0x34 /* 32 bit BMU Control/Status Register */
+#define Q_F 0x38 /* 32 bit Flag Register */
+#define Q_T1 0x3c /* 32 bit Test Register 1 */
+#define Q_T1_TR 0x3c /* 8 bit Test Register 1 Transfer SM */
+#define Q_T1_WR 0x3d /* 8 bit Test Register 1 Write Descriptor SM */
+#define Q_T1_RD 0x3e /* 8 bit Test Register 1 Read Descriptor SM */
+#define Q_T1_SV 0x3f /* 8 bit Test Register 1 Supervisor SM */
+#define Q_T2 0x40 /* 32 bit Test Register 2 */
+#define Q_T3 0x44 /* 32 bit Test Register 3 */
+ /* 0x48 - 0x7f: reserved */
+
+/*
+ * Bank 16 - 23
+ */
+/* RAM Buffer Registers */
+#define B16_RAM_REGS 0x0800
+
+/* RAM Buffer Register Offsets, use RB_ADDR() to access */
+#define RB_START 0x00 /* 32 bit RAM Buffer Start Address */
+#define RB_END 0x04 /* 32 bit RAM Buffer End Address */
+#define RB_WP 0x08 /* 32 bit RAM Buffer Write Pointer */
+#define RB_RP 0x0c /* 32 bit RAM Buffer Read Pointer */
+#define RB_RX_UTPP 0x10 /* 32 bit Rx Upper Threshold, Pause Pack */
+#define RB_RX_LTPP 0x14 /* 32 bit Rx Lower Threshold, Pause Pack */
+#define RB_RX_UTHP 0x18 /* 32 bit Rx Upper Threshold, High Prio */
+#define RB_RX_LTHP 0x1c /* 32 bit Rx Lower Threshold, High Prio */
+ /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */
+#define RB_PC 0x20 /* 32 bit RAM Buffer Packet Counter */
+#define RB_LEV 0x24 /* 32 bit RAM Buffer Level Register */
+#define RB_CTRL 0x28 /* 8 bit RAM Buffer Control Register */
+#define RB_TST1 0x29 /* 8 bit RAM Buffer Test Register 1 */
+#define RB_TST2 0x2A /* 8 bit RAM Buffer Test Register 2 */
+ /* 0x2c - 0x7f: reserved */
+
+/*
+ * Bank 24
+ */
+/*
+ * Receive MAC FIFO, Receive LED, and Link_Sync regs (GENESIS only)
+ * use MR_ADDR() to access
+ */
+#define RX_MFF_EA 0x0c00 /* 32 bit Receive MAC FIFO End Address */
+#define RX_MFF_WP 0x0c04 /* 32 bit Receive MAC FIFO Write Pointer */
+ /* 0x0c08 - 0x0c0b: reserved */
+#define RX_MFF_RP 0x0c0c /* 32 bit Receive MAC FIFO Read Pointer */
+#define RX_MFF_PC 0x0c10 /* 32 bit Receive MAC FIFO Packet Cnt */
+#define RX_MFF_LEV 0x0c14 /* 32 bit Receive MAC FIFO Level */
+#define RX_MFF_CTRL1 0x0c18 /* 16 bit Receive MAC FIFO Control Reg 1*/
+#define RX_MFF_STAT_TO 0x0c1a /* 8 bit Receive MAC Status Timeout */
+#define RX_MFF_TIST_TO 0x0c1b /* 8 bit Receive MAC Time Stamp Timeout */
+#define RX_MFF_CTRL2 0x0c1c /* 8 bit Receive MAC FIFO Control Reg 2*/
+#define RX_MFF_TST1 0x0c1d /* 8 bit Receive MAC FIFO Test Reg 1 */
+#define RX_MFF_TST2 0x0c1e /* 8 bit Receive MAC FIFO Test Reg 2 */
+ /* 0x0c1f: reserved */
+#define RX_LED_INI 0x0c20 /* 32 bit Receive LED Cnt Init Value */
+#define RX_LED_VAL 0x0c24 /* 32 bit Receive LED Cnt Current Value */
+#define RX_LED_CTRL 0x0c28 /* 8 bit Receive LED Cnt Control Reg */
+#define RX_LED_TST 0x0c29 /* 8 bit Receive LED Cnt Test Register */
+ /* 0x0c2a - 0x0c2f: reserved */
+#define LNK_SYNC_INI 0x0c30 /* 32 bit Link Sync Cnt Init Value */
+#define LNK_SYNC_VAL 0x0c34 /* 32 bit Link Sync Cnt Current Value */
+#define LNK_SYNC_CTRL 0x0c38 /* 8 bit Link Sync Cnt Control Register */
+#define LNK_SYNC_TST 0x0c39 /* 8 bit Link Sync Cnt Test Register */
+ /* 0x0c3a - 0x0c3b: reserved */
+#define LNK_LED_REG 0x0c3c /* 8 bit Link LED Register */
+ /* 0x0c3d - 0x0c3f: reserved */
+
+/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */
+#define RX_GMF_EA 0x0c40 /* 32 bit Rx GMAC FIFO End Address */
+#define RX_GMF_AF_THR 0x0c44 /* 32 bit Rx GMAC FIFO Almost Full Thresh. */
+#define RX_GMF_CTRL_T 0x0c48 /* 32 bit Rx GMAC FIFO Control/Test */
+#define RX_GMF_FL_MSK 0x0c4c /* 32 bit Rx GMAC FIFO Flush Mask */
+#define RX_GMF_FL_THR 0x0c50 /* 32 bit Rx GMAC FIFO Flush Threshold */
+ /* 0x0c54 - 0x0c5f: reserved */
+#define RX_GMF_WP 0x0c60 /* 32 bit Rx GMAC FIFO Write Pointer */
+ /* 0x0c64 - 0x0c67: reserved */
+#define RX_GMF_WLEV 0x0c68 /* 32 bit Rx GMAC FIFO Write Level */
+ /* 0x0c6c - 0x0c6f: reserved */
+#define RX_GMF_RP 0x0c70 /* 32 bit Rx GMAC FIFO Read Pointer */
+ /* 0x0c74 - 0x0c77: reserved */
+#define RX_GMF_RLEV 0x0c78 /* 32 bit Rx GMAC FIFO Read Level */
+ /* 0x0c7c - 0x0c7f: reserved */
+
+/*
+ * Bank 25
+ */
+ /* 0x0c80 - 0x0cbf: MAC 2 */
+ /* 0x0cc0 - 0x0cff: reserved */
+
+/*
+ * Bank 26
+ */
+/*
+ * Transmit MAC FIFO and Transmit LED Registers (GENESIS only),
+ * use MR_ADDR() to access
+ */
+#define TX_MFF_EA 0x0d00 /* 32 bit Transmit MAC FIFO End Address */
+#define TX_MFF_WP 0x0d04 /* 32 bit Transmit MAC FIFO WR Pointer */
+#define TX_MFF_WSP 0x0d08 /* 32 bit Transmit MAC FIFO WR Shadow Ptr */
+#define TX_MFF_RP 0x0d0c /* 32 bit Transmit MAC FIFO RD Pointer */
+#define TX_MFF_PC 0x0d10 /* 32 bit Transmit MAC FIFO Packet Cnt */
+#define TX_MFF_LEV 0x0d14 /* 32 bit Transmit MAC FIFO Level */
+#define TX_MFF_CTRL1 0x0d18 /* 16 bit Transmit MAC FIFO Ctrl Reg 1 */
+#define TX_MFF_WAF 0x0d1a /* 8 bit Transmit MAC Wait after flush */
+ /* 0x0c1b: reserved */
+#define TX_MFF_CTRL2 0x0d1c /* 8 bit Transmit MAC FIFO Ctrl Reg 2 */
+#define TX_MFF_TST1 0x0d1d /* 8 bit Transmit MAC FIFO Test Reg 1 */
+#define TX_MFF_TST2 0x0d1e /* 8 bit Transmit MAC FIFO Test Reg 2 */
+ /* 0x0d1f: reserved */
+#define TX_LED_INI 0x0d20 /* 32 bit Transmit LED Cnt Init Value */
+#define TX_LED_VAL 0x0d24 /* 32 bit Transmit LED Cnt Current Val */
+#define TX_LED_CTRL 0x0d28 /* 8 bit Transmit LED Cnt Control Reg */
+#define TX_LED_TST 0x0d29 /* 8 bit Transmit LED Cnt Test Reg */
+ /* 0x0d2a - 0x0d3f: reserved */
+
+/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */
+#define TX_GMF_EA 0x0d40 /* 32 bit Tx GMAC FIFO End Address */
+#define TX_GMF_AE_THR 0x0d44 /* 32 bit Tx GMAC FIFO Almost Empty Thresh.*/
+#define TX_GMF_CTRL_T 0x0d48 /* 32 bit Tx GMAC FIFO Control/Test */
+ /* 0x0d4c - 0x0d5f: reserved */
+#define TX_GMF_WP 0x0d60 /* 32 bit Tx GMAC FIFO Write Pointer */
+#define TX_GMF_WSP 0x0d64 /* 32 bit Tx GMAC FIFO Write Shadow Ptr. */
+#define TX_GMF_WLEV 0x0d68 /* 32 bit Tx GMAC FIFO Write Level */
+ /* 0x0d6c - 0x0d6f: reserved */
+#define TX_GMF_RP 0x0d70 /* 32 bit Tx GMAC FIFO Read Pointer */
+#define TX_GMF_RSTP 0x0d74 /* 32 bit Tx GMAC FIFO Restart Pointer */
+#define TX_GMF_RLEV 0x0d78 /* 32 bit Tx GMAC FIFO Read Level */
+ /* 0x0d7c - 0x0d7f: reserved */
+
+/*
+ * Bank 27
+ */
+ /* 0x0d80 - 0x0dbf: MAC 2 */
+ /* 0x0daa - 0x0dff: reserved */
+
+/*
+ * Bank 28
+ */
+/* Descriptor Poll Timer Registers */
+#define B28_DPT_INI 0x0e00 /* 24 bit Descriptor Poll Timer Init Val */
+#define B28_DPT_VAL 0x0e04 /* 24 bit Descriptor Poll Timer Curr Val */
+#define B28_DPT_CTRL 0x0e08 /* 8 bit Descriptor Poll Timer Ctrl Reg */
+ /* 0x0e09: reserved */
+#define B28_DPT_TST 0x0e0a /* 8 bit Descriptor Poll Timer Test Reg */
+ /* 0x0e0b: reserved */
+
+/* Time Stamp Timer Registers (YUKON only) */
+ /* 0x0e10: reserved */
+#define GMAC_TI_ST_VAL 0x0e14 /* 32 bit Time Stamp Timer Curr Val */
+#define GMAC_TI_ST_CTRL 0x0e18 /* 8 bit Time Stamp Timer Ctrl Reg */
+ /* 0x0e19: reserved */
+#define GMAC_TI_ST_TST 0x0e1a /* 8 bit Time Stamp Timer Test Reg */
+ /* 0x0e1b - 0x0e7f: reserved */
+
+/*
+ * Bank 29
+ */
+ /* 0x0e80 - 0x0efc: reserved */
+
+/*
+ * Bank 30
+ */
+/* GMAC and GPHY Control Registers (YUKON only) */
+#define GMAC_CTRL 0x0f00 /* 32 bit GMAC Control Reg */
+#define GPHY_CTRL 0x0f04 /* 32 bit GPHY Control Reg */
+#define GMAC_IRQ_SRC 0x0f08 /* 8 bit GMAC Interrupt Source Reg */
+ /* 0x0f09 - 0x0f0b: reserved */
+#define GMAC_IRQ_MSK 0x0f0c /* 8 bit GMAC Interrupt Mask Reg */
+ /* 0x0f0d - 0x0f0f: reserved */
+#define GMAC_LINK_CTRL 0x0f10 /* 16 bit Link Control Reg */
+ /* 0x0f14 - 0x0f1f: reserved */
+
+/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
+
+#define WOL_REG_OFFS 0x20 /* HW-Bug: Address is + 0x20 against spec. */
+
+#define WOL_CTRL_STAT 0x0f20 /* 16 bit WOL Control/Status Reg */
+#define WOL_MATCH_CTL 0x0f22 /* 8 bit WOL Match Control Reg */
+#define WOL_MATCH_RES 0x0f23 /* 8 bit WOL Match Result Reg */
+#define WOL_MAC_ADDR_LO 0x0f24 /* 32 bit WOL MAC Address Low */
+#define WOL_MAC_ADDR_HI 0x0f28 /* 16 bit WOL MAC Address High */
+#define WOL_PATT_RPTR 0x0f2c /* 8 bit WOL Pattern Read Ptr */
+
+/* use this macro to access above registers */
+#define WOL_REG(Reg) ((Reg) + (pAC->GIni.GIWolOffs))
+
+
+/* WOL Pattern Length Registers (YUKON only) */
+
+#define WOL_PATT_LEN_LO 0x0f30 /* 32 bit WOL Pattern Length 3..0 */
+#define WOL_PATT_LEN_HI 0x0f34 /* 24 bit WOL Pattern Length 6..4 */
+
+/* WOL Pattern Counter Registers (YUKON only) */
+
+#define WOL_PATT_CNT_0 0x0f38 /* 32 bit WOL Pattern Counter 3..0 */
+#define WOL_PATT_CNT_4 0x0f3c /* 24 bit WOL Pattern Counter 6..4 */
+ /* 0x0f40 - 0x0f7f: reserved */
+
+/*
+ * Bank 31
+ */
+/* 0x0f80 - 0x0fff: reserved */
+
+/*
+ * Bank 32 - 33
+ */
+#define WOL_PATT_RAM_1 0x1000 /* WOL Pattern RAM Link 1 */
+
+/*
+ * Bank 0x22 - 0x3f
+ */
+/* 0x1100 - 0x1fff: reserved */
+
+/*
+ * Bank 0x40 - 0x4f
+ */
+#define BASE_XMAC_1 0x2000 /* XMAC 1 registers */
+
+/*
+ * Bank 0x50 - 0x5f
+ */
+
+#define BASE_GMAC_1 0x2800 /* GMAC 1 registers */
+
+/*
+ * Bank 0x60 - 0x6f
+ */
+#define BASE_XMAC_2 0x3000 /* XMAC 2 registers */
+
+/*
+ * Bank 0x70 - 0x7f
+ */
+#define BASE_GMAC_2 0x3800 /* GMAC 2 registers */
+
+/*
+ * Control Register Bit Definitions:
+ */
+/* B0_RAP 8 bit Register Address Port */
+ /* Bit 7: reserved */
+#define RAP_RAP 0x3f /* Bit 6..0: 0 = block 0,..,6f = block 6f */
+
+/* B0_CTST 16 bit Control/Status register */
+ /* Bit 15..14: reserved */
+#define CS_CLK_RUN_HOT BIT_13S /* CLK_RUN hot m. (YUKON-Lite only) */
+#define CS_CLK_RUN_RST BIT_12S /* CLK_RUN reset (YUKON-Lite only) */
+#define CS_CLK_RUN_ENA BIT_11S /* CLK_RUN enable (YUKON-Lite only) */
+#define CS_VAUX_AVAIL BIT_10S /* VAUX available (YUKON only) */
+#define CS_BUS_CLOCK BIT_9S /* Bus Clock 0/1 = 33/66 MHz */
+#define CS_BUS_SLOT_SZ BIT_8S /* Slot Size 0/1 = 32/64 bit slot */
+#define CS_ST_SW_IRQ BIT_7S /* Set IRQ SW Request */
+#define CS_CL_SW_IRQ BIT_6S /* Clear IRQ SW Request */
+#define CS_STOP_DONE BIT_5S /* Stop Master is finished */
+#define CS_STOP_MAST BIT_4S /* Command Bit to stop the master */
+#define CS_MRST_CLR BIT_3S /* Clear Master reset */
+#define CS_MRST_SET BIT_2S /* Set Master reset */
+#define CS_RST_CLR BIT_1S /* Clear Software reset */
+#define CS_RST_SET BIT_0S /* Set Software reset */
+
+/* B0_LED 8 Bit LED register */
+ /* Bit 7.. 2: reserved */
+#define LED_STAT_ON BIT_1S /* Status LED on */
+#define LED_STAT_OFF BIT_0S /* Status LED off */
+
+/* B0_POWER_CTRL 8 Bit Power Control reg (YUKON only) */
+#define PC_VAUX_ENA BIT_7 /* Switch VAUX Enable */
+#define PC_VAUX_DIS BIT_6 /* Switch VAUX Disable */
+#define PC_VCC_ENA BIT_5 /* Switch VCC Enable */
+#define PC_VCC_DIS BIT_4 /* Switch VCC Disable */
+#define PC_VAUX_ON BIT_3 /* Switch VAUX On */
+#define PC_VAUX_OFF BIT_2 /* Switch VAUX Off */
+#define PC_VCC_ON BIT_1 /* Switch VCC On */
+#define PC_VCC_OFF BIT_0 /* Switch VCC Off */
+
+/* B0_ISRC 32 bit Interrupt Source Register */
+/* B0_IMSK 32 bit Interrupt Mask Register */
+/* B0_SP_ISRC 32 bit Special Interrupt Source Reg */
+/* B2_IRQM_MSK 32 bit IRQ Moderation Mask */
+#define IS_ALL_MSK 0xbfffffffUL /* All Interrupt bits */
+#define IS_HW_ERR BIT_31 /* Interrupt HW Error */
+ /* Bit 30: reserved */
+#define IS_PA_TO_RX1 BIT_29 /* Packet Arb Timeout Rx1 */
+#define IS_PA_TO_RX2 BIT_28 /* Packet Arb Timeout Rx2 */
+#define IS_PA_TO_TX1 BIT_27 /* Packet Arb Timeout Tx1 */
+#define IS_PA_TO_TX2 BIT_26 /* Packet Arb Timeout Tx2 */
+#define IS_I2C_READY BIT_25 /* IRQ on end of I2C Tx */
+#define IS_IRQ_SW BIT_24 /* SW forced IRQ */
+#define IS_EXT_REG BIT_23 /* IRQ from LM80 or PHY (GENESIS only) */
+ /* IRQ from PHY (YUKON only) */
+#define IS_TIMINT BIT_22 /* IRQ from Timer */
+#define IS_MAC1 BIT_21 /* IRQ from MAC 1 */
+#define IS_LNK_SYNC_M1 BIT_20 /* Link Sync Cnt wrap MAC 1 */
+#define IS_MAC2 BIT_19 /* IRQ from MAC 2 */
+#define IS_LNK_SYNC_M2 BIT_18 /* Link Sync Cnt wrap MAC 2 */
+/* Receive Queue 1 */
+#define IS_R1_B BIT_17 /* Q_R1 End of Buffer */
+#define IS_R1_F BIT_16 /* Q_R1 End of Frame */
+#define IS_R1_C BIT_15 /* Q_R1 Encoding Error */
+/* Receive Queue 2 */
+#define IS_R2_B BIT_14 /* Q_R2 End of Buffer */
+#define IS_R2_F BIT_13 /* Q_R2 End of Frame */
+#define IS_R2_C BIT_12 /* Q_R2 Encoding Error */
+/* Synchronous Transmit Queue 1 */
+#define IS_XS1_B BIT_11 /* Q_XS1 End of Buffer */
+#define IS_XS1_F BIT_10 /* Q_XS1 End of Frame */
+#define IS_XS1_C BIT_9 /* Q_XS1 Encoding Error */
+/* Asynchronous Transmit Queue 1 */
+#define IS_XA1_B BIT_8 /* Q_XA1 End of Buffer */
+#define IS_XA1_F BIT_7 /* Q_XA1 End of Frame */
+#define IS_XA1_C BIT_6 /* Q_XA1 Encoding Error */
+/* Synchronous Transmit Queue 2 */
+#define IS_XS2_B BIT_5 /* Q_XS2 End of Buffer */
+#define IS_XS2_F BIT_4 /* Q_XS2 End of Frame */
+#define IS_XS2_C BIT_3 /* Q_XS2 Encoding Error */
+/* Asynchronous Transmit Queue 2 */
+#define IS_XA2_B BIT_2 /* Q_XA2 End of Buffer */
+#define IS_XA2_F BIT_1 /* Q_XA2 End of Frame */
+#define IS_XA2_C BIT_0 /* Q_XA2 Encoding Error */
+
+
+/* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */
+/* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */
+/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */
+#define IS_ERR_MSK 0x00000fffL /* All Error bits */
+ /* Bit 31..14: reserved */
+#define IS_IRQ_TIST_OV BIT_13 /* Time Stamp Timer Overflow (YUKON only) */
+#define IS_IRQ_SENSOR BIT_12 /* IRQ from Sensor (YUKON only) */
+#define IS_IRQ_MST_ERR BIT_11 /* IRQ master error detected */
+#define IS_IRQ_STAT BIT_10 /* IRQ status exception */
+#define IS_NO_STAT_M1 BIT_9 /* No Rx Status from MAC 1 */
+#define IS_NO_STAT_M2 BIT_8 /* No Rx Status from MAC 2 */
+#define IS_NO_TIST_M1 BIT_7 /* No Time Stamp from MAC 1 */
+#define IS_NO_TIST_M2 BIT_6 /* No Time Stamp from MAC 2 */
+#define IS_RAM_RD_PAR BIT_5 /* RAM Read Parity Error */
+#define IS_RAM_WR_PAR BIT_4 /* RAM Write Parity Error */
+#define IS_M1_PAR_ERR BIT_3 /* MAC 1 Parity Error */
+#define IS_M2_PAR_ERR BIT_2 /* MAC 2 Parity Error */
+#define IS_R1_PAR_ERR BIT_1 /* Queue R1 Parity Error */
+#define IS_R2_PAR_ERR BIT_0 /* Queue R2 Parity Error */
+
+/* B2_CONN_TYP 8 bit Connector type */
+/* B2_PMD_TYP 8 bit PMD type */
+/* Values of connector and PMD type comply to SysKonnect internal std */
+
+/* B2_MAC_CFG 8 bit MAC Configuration / Chip Revision */
+#define CFG_CHIP_R_MSK (0xf<<4) /* Bit 7.. 4: Chip Revision */
+ /* Bit 3.. 2: reserved */
+#define CFG_DIS_M2_CLK BIT_1S /* Disable Clock for 2nd MAC */
+#define CFG_SNG_MAC BIT_0S /* MAC Config: 0=2 MACs / 1=1 MAC*/
+
+/* B2_CHIP_ID 8 bit Chip Identification Number */
+#define CHIP_ID_GENESIS 0x0a /* Chip ID for GENESIS */
+#define CHIP_ID_YUKON 0xb0 /* Chip ID for YUKON */
+#define CHIP_ID_YUKON_LITE 0xb1 /* Chip ID for YUKON-Lite (Rev. A1-A3) */
+#define CHIP_ID_YUKON_LP 0xb2 /* Chip ID for YUKON-LP */
+
+#define CHIP_REV_YU_LITE_A1 3 /* Chip Rev. for YUKON-Lite A1,A2 */
+#define CHIP_REV_YU_LITE_A3 7 /* Chip Rev. for YUKON-Lite A3 */
+
+/* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */
+#define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address mask */
+
+/* B2_LD_CTRL 8 bit EPROM loader control register */
+/* Bits are currently reserved */
+
+/* B2_LD_TEST 8 bit EPROM loader test register */
+ /* Bit 7.. 4: reserved */
+#define LD_T_ON BIT_3S /* Loader Test mode on */
+#define LD_T_OFF BIT_2S /* Loader Test mode off */
+#define LD_T_STEP BIT_1S /* Decrement FPROM addr. Counter */
+#define LD_START BIT_0S /* Start loading FPROM */
+
+/*
+ * Timer Section
+ */
+/* B2_TI_CTRL 8 bit Timer control */
+/* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */
+ /* Bit 7.. 3: reserved */
+#define TIM_START BIT_2S /* Start Timer */
+#define TIM_STOP BIT_1S /* Stop Timer */
+#define TIM_CLR_IRQ BIT_0S /* Clear Timer IRQ (!IRQM) */
+
+/* B2_TI_TEST 8 Bit Timer Test */
+/* B2_IRQM_TEST 8 bit IRQ Moderation Timer Test */
+/* B28_DPT_TST 8 bit Descriptor Poll Timer Test Reg */
+ /* Bit 7.. 3: reserved */
+#define TIM_T_ON BIT_2S /* Test mode on */
+#define TIM_T_OFF BIT_1S /* Test mode off */
+#define TIM_T_STEP BIT_0S /* Test step */
+
+/* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */
+/* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */
+ /* Bit 31..24: reserved */
+#define DPT_MSK 0x00ffffffL /* Bit 23.. 0: Desc Poll Timer Bits */
+
+/* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */
+ /* Bit 7.. 2: reserved */
+#define DPT_START BIT_1S /* Start Descriptor Poll Timer */
+#define DPT_STOP BIT_0S /* Stop Descriptor Poll Timer */
+
+/* B2_E_3 8 bit lower 4 bits used for HW self test result */
+#define B2_E3_RES_MASK 0x0f
+
+/* B2_TST_CTRL1 8 bit Test Control Register 1 */
+#define TST_FRC_DPERR_MR BIT_7S /* force DATAPERR on MST RD */
+#define TST_FRC_DPERR_MW BIT_6S /* force DATAPERR on MST WR */
+#define TST_FRC_DPERR_TR BIT_5S /* force DATAPERR on TRG RD */
+#define TST_FRC_DPERR_TW BIT_4S /* force DATAPERR on TRG WR */
+#define TST_FRC_APERR_M BIT_3S /* force ADDRPERR on MST */
+#define TST_FRC_APERR_T BIT_2S /* force ADDRPERR on TRG */
+#define TST_CFG_WRITE_ON BIT_1S /* Enable Config Reg WR */
+#define TST_CFG_WRITE_OFF BIT_0S /* Disable Config Reg WR */
+
+/* B2_TST_CTRL2 8 bit Test Control Register 2 */
+ /* Bit 7.. 4: reserved */
+ /* force the following error on the next master read/write */
+#define TST_FRC_DPERR_MR64 BIT_3S /* DataPERR RD 64 */
+#define TST_FRC_DPERR_MW64 BIT_2S /* DataPERR WR 64 */
+#define TST_FRC_APERR_1M64 BIT_1S /* AddrPERR on 1. phase */
+#define TST_FRC_APERR_2M64 BIT_0S /* AddrPERR on 2. phase */
+
+/* B2_GP_IO 32 bit General Purpose I/O Register */
+ /* Bit 31..26: reserved */
+#define GP_DIR_9 BIT_25 /* IO_9 direct, 0=In/1=Out */
+#define GP_DIR_8 BIT_24 /* IO_8 direct, 0=In/1=Out */
+#define GP_DIR_7 BIT_23 /* IO_7 direct, 0=In/1=Out */
+#define GP_DIR_6 BIT_22 /* IO_6 direct, 0=In/1=Out */
+#define GP_DIR_5 BIT_21 /* IO_5 direct, 0=In/1=Out */
+#define GP_DIR_4 BIT_20 /* IO_4 direct, 0=In/1=Out */
+#define GP_DIR_3 BIT_19 /* IO_3 direct, 0=In/1=Out */
+#define GP_DIR_2 BIT_18 /* IO_2 direct, 0=In/1=Out */
+#define GP_DIR_1 BIT_17 /* IO_1 direct, 0=In/1=Out */
+#define GP_DIR_0 BIT_16 /* IO_0 direct, 0=In/1=Out */
+ /* Bit 15..10: reserved */
+#define GP_IO_9 BIT_9 /* IO_9 pin */
+#define GP_IO_8 BIT_8 /* IO_8 pin */
+#define GP_IO_7 BIT_7 /* IO_7 pin */
+#define GP_IO_6 BIT_6 /* IO_6 pin */
+#define GP_IO_5 BIT_5 /* IO_5 pin */
+#define GP_IO_4 BIT_4 /* IO_4 pin */
+#define GP_IO_3 BIT_3 /* IO_3 pin */
+#define GP_IO_2 BIT_2 /* IO_2 pin */
+#define GP_IO_1 BIT_1 /* IO_1 pin */
+#define GP_IO_0 BIT_0 /* IO_0 pin */
+
+/* B2_I2C_CTRL 32 bit I2C HW Control Register */
+#define I2C_FLAG BIT_31 /* Start read/write if WR */
+#define I2C_ADDR (0x7fffL<<16) /* Bit 30..16: Addr to be RD/WR */
+#define I2C_DEV_SEL (0x7fL<<9) /* Bit 15.. 9: I2C Device Select */
+ /* Bit 8.. 5: reserved */
+#define I2C_BURST_LEN BIT_4 /* Burst Len, 1/4 bytes */
+#define I2C_DEV_SIZE (7<<1) /* Bit 3.. 1: I2C Device Size */
+#define I2C_025K_DEV (0<<1) /* 0: 256 Bytes or smal. */
+#define I2C_05K_DEV (1<<1) /* 1: 512 Bytes */
+#define I2C_1K_DEV (2<<1) /* 2: 1024 Bytes */
+#define I2C_2K_DEV (3<<1) /* 3: 2048 Bytes */
+#define I2C_4K_DEV (4<<1) /* 4: 4096 Bytes */
+#define I2C_8K_DEV (5<<1) /* 5: 8192 Bytes */
+#define I2C_16K_DEV (6<<1) /* 6: 16384 Bytes */
+#define I2C_32K_DEV (7<<1) /* 7: 32768 Bytes */
+#define I2C_STOP BIT_0 /* Interrupt I2C transfer */
+
+/* B2_I2C_IRQ 32 bit I2C HW IRQ Register */
+ /* Bit 31.. 1 reserved */
+#define I2C_CLR_IRQ BIT_0 /* Clear I2C IRQ */
+
+/* B2_I2C_SW 32 bit (8 bit access) I2C HW SW Port Register */
+ /* Bit 7.. 3: reserved */
+#define I2C_DATA_DIR BIT_2S /* direction of I2C_DATA */
+#define I2C_DATA BIT_1S /* I2C Data Port */
+#define I2C_CLK BIT_0S /* I2C Clock Port */
+
+/*
+ * I2C Address
+ */
+#define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address, (Volt and Temp)*/
+
+
+/* B2_BSC_CTRL 8 bit Blink Source Counter Control */
+ /* Bit 7.. 2: reserved */
+#define BSC_START BIT_1S /* Start Blink Source Counter */
+#define BSC_STOP BIT_0S /* Stop Blink Source Counter */
+
+/* B2_BSC_STAT 8 bit Blink Source Counter Status */
+ /* Bit 7.. 1: reserved */
+#define BSC_SRC BIT_0S /* Blink Source, 0=Off / 1=On */
+
+/* B2_BSC_TST 16 bit Blink Source Counter Test Reg */
+#define BSC_T_ON BIT_2S /* Test mode on */
+#define BSC_T_OFF BIT_1S /* Test mode off */
+#define BSC_T_STEP BIT_0S /* Test step */
+
+
+/* B3_RAM_ADDR 32 bit RAM Address, to read or write */
+ /* Bit 31..19: reserved */
+#define RAM_ADR_RAN 0x0007ffffL /* Bit 18.. 0: RAM Address Range */
+
+/* RAM Interface Registers */
+/* B3_RI_CTRL 16 bit RAM Iface Control Register */
+ /* Bit 15..10: reserved */
+#define RI_CLR_RD_PERR BIT_9S /* Clear IRQ RAM Read Parity Err */
+#define RI_CLR_WR_PERR BIT_8S /* Clear IRQ RAM Write Parity Err*/
+ /* Bit 7.. 2: reserved */
+#define RI_RST_CLR BIT_1S /* Clear RAM Interface Reset */
+#define RI_RST_SET BIT_0S /* Set RAM Interface Reset */
+
+/* B3_RI_TEST 8 bit RAM Iface Test Register */
+ /* Bit 15.. 4: reserved */
+#define RI_T_EV BIT_3S /* Timeout Event occured */
+#define RI_T_ON BIT_2S /* Timeout Timer Test On */
+#define RI_T_OFF BIT_1S /* Timeout Timer Test Off */
+#define RI_T_STEP BIT_0S /* Timeout Timer Step */
+
+/* MAC Arbiter Registers */
+/* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */
+ /* Bit 15.. 4: reserved */
+#define MA_FOE_ON BIT_3S /* XMAC Fast Output Enable ON */
+#define MA_FOE_OFF BIT_2S /* XMAC Fast Output Enable OFF */
+#define MA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */
+#define MA_RST_SET BIT_0S /* Set MAC Arbiter Reset */
+
+/* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */
+ /* Bit 15.. 8: reserved */
+#define MA_ENA_REC_TX2 BIT_7S /* Enable Recovery Timer TX2 */
+#define MA_DIS_REC_TX2 BIT_6S /* Disable Recovery Timer TX2 */
+#define MA_ENA_REC_TX1 BIT_5S /* Enable Recovery Timer TX1 */
+#define MA_DIS_REC_TX1 BIT_4S /* Disable Recovery Timer TX1 */
+#define MA_ENA_REC_RX2 BIT_3S /* Enable Recovery Timer RX2 */
+#define MA_DIS_REC_RX2 BIT_2S /* Disable Recovery Timer RX2 */
+#define MA_ENA_REC_RX1 BIT_1S /* Enable Recovery Timer RX1 */
+#define MA_DIS_REC_RX1 BIT_0S /* Disable Recovery Timer RX1 */
+
+/* Packet Arbiter Registers */
+/* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */
+ /* Bit 15..14: reserved */
+#define PA_CLR_TO_TX2 BIT_13S /* Clear IRQ Packet Timeout TX2 */
+#define PA_CLR_TO_TX1 BIT_12S /* Clear IRQ Packet Timeout TX1 */
+#define PA_CLR_TO_RX2 BIT_11S /* Clear IRQ Packet Timeout RX2 */
+#define PA_CLR_TO_RX1 BIT_10S /* Clear IRQ Packet Timeout RX1 */
+#define PA_ENA_TO_TX2 BIT_9S /* Enable Timeout Timer TX2 */
+#define PA_DIS_TO_TX2 BIT_8S /* Disable Timeout Timer TX2 */
+#define PA_ENA_TO_TX1 BIT_7S /* Enable Timeout Timer TX1 */
+#define PA_DIS_TO_TX1 BIT_6S /* Disable Timeout Timer TX1 */
+#define PA_ENA_TO_RX2 BIT_5S /* Enable Timeout Timer RX2 */
+#define PA_DIS_TO_RX2 BIT_4S /* Disable Timeout Timer RX2 */
+#define PA_ENA_TO_RX1 BIT_3S /* Enable Timeout Timer RX1 */
+#define PA_DIS_TO_RX1 BIT_2S /* Disable Timeout Timer RX1 */
+#define PA_RST_CLR BIT_1S /* Clear MAC Arbiter Reset */
+#define PA_RST_SET BIT_0S /* Set MAC Arbiter Reset */
+
+#define PA_ENA_TO_ALL (PA_ENA_TO_RX1 | PA_ENA_TO_RX2 |\
+ PA_ENA_TO_TX1 | PA_ENA_TO_TX2)
+
+/* Rx/Tx Path related Arbiter Test Registers */
+/* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */
+/* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */
+/* B3_PA_TEST 16 bit Packet Arbiter Test Register */
+/* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */
+#define TX2_T_EV BIT_15S /* TX2 Timeout/Recv Event occured */
+#define TX2_T_ON BIT_14S /* TX2 Timeout/Recv Timer Test On */
+#define TX2_T_OFF BIT_13S /* TX2 Timeout/Recv Timer Tst Off */
+#define TX2_T_STEP BIT_12S /* TX2 Timeout/Recv Timer Step */
+#define TX1_T_EV BIT_11S /* TX1 Timeout/Recv Event occured */
+#define TX1_T_ON BIT_10S /* TX1 Timeout/Recv Timer Test On */
+#define TX1_T_OFF BIT_9S /* TX1 Timeout/Recv Timer Tst Off */
+#define TX1_T_STEP BIT_8S /* TX1 Timeout/Recv Timer Step */
+#define RX2_T_EV BIT_7S /* RX2 Timeout/Recv Event occured */
+#define RX2_T_ON BIT_6S /* RX2 Timeout/Recv Timer Test On */
+#define RX2_T_OFF BIT_5S /* RX2 Timeout/Recv Timer Tst Off */
+#define RX2_T_STEP BIT_4S /* RX2 Timeout/Recv Timer Step */
+#define RX1_T_EV BIT_3S /* RX1 Timeout/Recv Event occured */
+#define RX1_T_ON BIT_2S /* RX1 Timeout/Recv Timer Test On */
+#define RX1_T_OFF BIT_1S /* RX1 Timeout/Recv Timer Tst Off */
+#define RX1_T_STEP BIT_0S /* RX1 Timeout/Recv Timer Step */
+
+
+/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */
+/* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */
+/* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */
+/* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */
+/* TXA_LIM_VAL 32 bit Tx Arb Limit Counter Value */
+ /* Bit 31..24: reserved */
+#define TXA_MAX_VAL 0x00ffffffUL/* Bit 23.. 0: Max TXA Timer/Cnt Val */
+
+/* TXA_CTRL 8 bit Tx Arbiter Control Register */
+#define TXA_ENA_FSYNC BIT_7S /* Enable force of sync Tx queue */
+#define TXA_DIS_FSYNC BIT_6S /* Disable force of sync Tx queue */
+#define TXA_ENA_ALLOC BIT_5S /* Enable alloc of free bandwidth */
+#define TXA_DIS_ALLOC BIT_4S /* Disable alloc of free bandwidth */
+#define TXA_START_RC BIT_3S /* Start sync Rate Control */
+#define TXA_STOP_RC BIT_2S /* Stop sync Rate Control */
+#define TXA_ENA_ARB BIT_1S /* Enable Tx Arbiter */
+#define TXA_DIS_ARB BIT_0S /* Disable Tx Arbiter */
+
+/* TXA_TEST 8 bit Tx Arbiter Test Register */
+ /* Bit 7.. 6: reserved */
+#define TXA_INT_T_ON BIT_5S /* Tx Arb Interval Timer Test On */
+#define TXA_INT_T_OFF BIT_4S /* Tx Arb Interval Timer Test Off */
+#define TXA_INT_T_STEP BIT_3S /* Tx Arb Interval Timer Step */
+#define TXA_LIM_T_ON BIT_2S /* Tx Arb Limit Timer Test On */
+#define TXA_LIM_T_OFF BIT_1S /* Tx Arb Limit Timer Test Off */
+#define TXA_LIM_T_STEP BIT_0S /* Tx Arb Limit Timer Step */
+
+/* TXA_STAT 8 bit Tx Arbiter Status Register */
+ /* Bit 7.. 1: reserved */
+#define TXA_PRIO_XS BIT_0S /* sync queue has prio to send */
+
+/* Q_BC 32 bit Current Byte Counter */
+ /* Bit 31..16: reserved */
+#define BC_MAX 0xffff /* Bit 15.. 0: Byte counter */
+
+/* BMU Control Status Registers */
+/* B0_R1_CSR 32 bit BMU Ctrl/Stat Rx Queue 1 */
+/* B0_R2_CSR 32 bit BMU Ctrl/Stat Rx Queue 2 */
+/* B0_XA1_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */
+/* B0_XS1_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 1 */
+/* B0_XA2_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 2 */
+/* B0_XS2_CSR 32 bit BMU Ctrl/Stat Async Tx Queue 2 */
+/* Q_CSR 32 bit BMU Control/Status Register */
+ /* Bit 31..25: reserved */
+#define CSR_SV_IDLE BIT_24 /* BMU SM Idle */
+ /* Bit 23..22: reserved */
+#define CSR_DESC_CLR BIT_21 /* Clear Reset for Descr */
+#define CSR_DESC_SET BIT_20 /* Set Reset for Descr */
+#define CSR_FIFO_CLR BIT_19 /* Clear Reset for FIFO */
+#define CSR_FIFO_SET BIT_18 /* Set Reset for FIFO */
+#define CSR_HPI_RUN BIT_17 /* Release HPI SM */
+#define CSR_HPI_RST BIT_16 /* Reset HPI SM to Idle */
+#define CSR_SV_RUN BIT_15 /* Release Supervisor SM */
+#define CSR_SV_RST BIT_14 /* Reset Supervisor SM */
+#define CSR_DREAD_RUN BIT_13 /* Release Descr Read SM */
+#define CSR_DREAD_RST BIT_12 /* Reset Descr Read SM */
+#define CSR_DWRITE_RUN BIT_11 /* Release Descr Write SM */
+#define CSR_DWRITE_RST BIT_10 /* Reset Descr Write SM */
+#define CSR_TRANS_RUN BIT_9 /* Release Transfer SM */
+#define CSR_TRANS_RST BIT_8 /* Reset Transfer SM */
+#define CSR_ENA_POL BIT_7 /* Enable Descr Polling */
+#define CSR_DIS_POL BIT_6 /* Disable Descr Polling */
+#define CSR_STOP BIT_5 /* Stop Rx/Tx Queue */
+#define CSR_START BIT_4 /* Start Rx/Tx Queue */
+#define CSR_IRQ_CL_P BIT_3 /* (Rx) Clear Parity IRQ */
+#define CSR_IRQ_CL_B BIT_2 /* Clear EOB IRQ */
+#define CSR_IRQ_CL_F BIT_1 /* Clear EOF IRQ */
+#define CSR_IRQ_CL_C BIT_0 /* Clear ERR IRQ */
+
+#define CSR_SET_RESET (CSR_DESC_SET | CSR_FIFO_SET | CSR_HPI_RST |\
+ CSR_SV_RST | CSR_DREAD_RST | CSR_DWRITE_RST |\
+ CSR_TRANS_RST)
+#define CSR_CLR_RESET (CSR_DESC_CLR | CSR_FIFO_CLR | CSR_HPI_RUN |\
+ CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\
+ CSR_TRANS_RUN)
+
+/* Q_F 32 bit Flag Register */
+ /* Bit 31..28: reserved */
+#define F_ALM_FULL BIT_27 /* Rx FIFO: almost full */
+#define F_EMPTY BIT_27 /* Tx FIFO: empty flag */
+#define F_FIFO_EOF BIT_26 /* Tag (EOF Flag) bit in FIFO */
+#define F_WM_REACHED BIT_25 /* Watermark reached */
+ /* reserved */
+#define F_FIFO_LEVEL (0x1fL<<16) /* Bit 23..16: # of Qwords in FIFO */
+ /* Bit 15..11: reserved */
+#define F_WATER_MARK 0x0007ffL /* Bit 10.. 0: Watermark */
+
+/* Q_T1 32 bit Test Register 1 */
+/* Holds four State Machine control Bytes */
+#define SM_CTRL_SV_MSK (0xffL<<24) /* Bit 31..24: Control Supervisor SM */
+#define SM_CTRL_RD_MSK (0xffL<<16) /* Bit 23..16: Control Read Desc SM */
+#define SM_CTRL_WR_MSK (0xffL<<8) /* Bit 15.. 8: Control Write Desc SM */
+#define SM_CTRL_TR_MSK 0xffL /* Bit 7.. 0: Control Transfer SM */
+
+/* Q_T1_TR 8 bit Test Register 1 Transfer SM */
+/* Q_T1_WR 8 bit Test Register 1 Write Descriptor SM */
+/* Q_T1_RD 8 bit Test Register 1 Read Descriptor SM */
+/* Q_T1_SV 8 bit Test Register 1 Supervisor SM */
+
+/* The control status byte of each machine looks like ... */
+#define SM_STATE 0xf0 /* Bit 7.. 4: State which shall be loaded */
+#define SM_LOAD BIT_3S /* Load the SM with SM_STATE */
+#define SM_TEST_ON BIT_2S /* Switch on SM Test Mode */
+#define SM_TEST_OFF BIT_1S /* Go off the Test Mode */
+#define SM_STEP BIT_0S /* Step the State Machine */
+/* The encoding of the states is not supported by the Diagnostics Tool */
+
+/* Q_T2 32 bit Test Register 2 */
+ /* Bit 31.. 8: reserved */
+#define T2_AC_T_ON BIT_7 /* Address Counter Test Mode on */
+#define T2_AC_T_OFF BIT_6 /* Address Counter Test Mode off */
+#define T2_BC_T_ON BIT_5 /* Byte Counter Test Mode on */
+#define T2_BC_T_OFF BIT_4 /* Byte Counter Test Mode off */
+#define T2_STEP04 BIT_3 /* Inc AC/Dec BC by 4 */
+#define T2_STEP03 BIT_2 /* Inc AC/Dec BC by 3 */
+#define T2_STEP02 BIT_1 /* Inc AC/Dec BC by 2 */
+#define T2_STEP01 BIT_0 /* Inc AC/Dec BC by 1 */
+
+/* Q_T3 32 bit Test Register 3 */
+ /* Bit 31.. 7: reserved */
+#define T3_MUX_MSK (7<<4) /* Bit 6.. 4: Mux Position */
+ /* Bit 3: reserved */
+#define T3_VRAM_MSK 7 /* Bit 2.. 0: Virtual RAM Buffer Address */
+
+/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
+/* RB_START 32 bit RAM Buffer Start Address */
+/* RB_END 32 bit RAM Buffer End Address */
+/* RB_WP 32 bit RAM Buffer Write Pointer */
+/* RB_RP 32 bit RAM Buffer Read Pointer */
+/* RB_RX_UTPP 32 bit Rx Upper Threshold, Pause Pack */
+/* RB_RX_LTPP 32 bit Rx Lower Threshold, Pause Pack */
+/* RB_RX_UTHP 32 bit Rx Upper Threshold, High Prio */
+/* RB_RX_LTHP 32 bit Rx Lower Threshold, High Prio */
+/* RB_PC 32 bit RAM Buffer Packet Counter */
+/* RB_LEV 32 bit RAM Buffer Level Register */
+ /* Bit 31..19: reserved */
+#define RB_MSK 0x0007ffff /* Bit 18.. 0: RAM Buffer Pointer Bits */
+
+/* RB_TST2 8 bit RAM Buffer Test Register 2 */
+ /* Bit 7.. 4: reserved */
+#define RB_PC_DEC BIT_3S /* Packet Counter Decrem */
+#define RB_PC_T_ON BIT_2S /* Packet Counter Test On */
+#define RB_PC_T_OFF BIT_1S /* Packet Counter Tst Off */
+#define RB_PC_INC BIT_0S /* Packet Counter Increm */
+
+/* RB_TST1 8 bit RAM Buffer Test Register 1 */
+ /* Bit 7: reserved */
+#define RB_WP_T_ON BIT_6S /* Write Pointer Test On */
+#define RB_WP_T_OFF BIT_5S /* Write Pointer Test Off */
+#define RB_WP_INC BIT_4S /* Write Pointer Increm */
+ /* Bit 3: reserved */
+#define RB_RP_T_ON BIT_2S /* Read Pointer Test On */
+#define RB_RP_T_OFF BIT_1S /* Read Pointer Test Off */
+#define RB_RP_DEC BIT_0S /* Read Pointer Decrement */
+
+/* RB_CTRL 8 bit RAM Buffer Control Register */
+ /* Bit 7.. 6: reserved */
+#define RB_ENA_STFWD BIT_5S /* Enable Store & Forward */
+#define RB_DIS_STFWD BIT_4S /* Disable Store & Forward */
+#define RB_ENA_OP_MD BIT_3S /* Enable Operation Mode */
+#define RB_DIS_OP_MD BIT_2S /* Disable Operation Mode */
+#define RB_RST_CLR BIT_1S /* Clear RAM Buf STM Reset */
+#define RB_RST_SET BIT_0S /* Set RAM Buf STM Reset */
+
+
+/* Receive and Transmit MAC FIFO Registers (GENESIS only) */
+
+/* RX_MFF_EA 32 bit Receive MAC FIFO End Address */
+/* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */
+/* RX_MFF_RP 32 bit Receive MAC FIFO Read Pointer */
+/* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter */
+/* RX_MFF_LEV 32 bit Receive MAC FIFO Level */
+/* TX_MFF_EA 32 bit Transmit MAC FIFO End Address */
+/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */
+/* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pointer */
+/* TX_MFF_RP 32 bit Transmit MAC FIFO Read Pointer */
+/* TX_MFF_PC 32 bit Transmit MAC FIFO Packet Cnt */
+/* TX_MFF_LEV 32 bit Transmit MAC FIFO Level */
+ /* Bit 31.. 6: reserved */
+#define MFF_MSK 0x007fL /* Bit 5.. 0: MAC FIFO Address/Ptr Bits */
+
+/* RX_MFF_CTRL1 16 bit Receive MAC FIFO Control Reg 1 */
+ /* Bit 15..14: reserved */
+#define MFF_ENA_RDY_PAT BIT_13S /* Enable Ready Patch */
+#define MFF_DIS_RDY_PAT BIT_12S /* Disable Ready Patch */
+#define MFF_ENA_TIM_PAT BIT_11S /* Enable Timing Patch */
+#define MFF_DIS_TIM_PAT BIT_10S /* Disable Timing Patch */
+#define MFF_ENA_ALM_FUL BIT_9S /* Enable AlmostFull Sign */
+#define MFF_DIS_ALM_FUL BIT_8S /* Disable AlmostFull Sign */
+#define MFF_ENA_PAUSE BIT_7S /* Enable Pause Signaling */
+#define MFF_DIS_PAUSE BIT_6S /* Disable Pause Signaling */
+#define MFF_ENA_FLUSH BIT_5S /* Enable Frame Flushing */
+#define MFF_DIS_FLUSH BIT_4S /* Disable Frame Flushing */
+#define MFF_ENA_TIST BIT_3S /* Enable Time Stamp Gener */
+#define MFF_DIS_TIST BIT_2S /* Disable Time Stamp Gener */
+#define MFF_CLR_INTIST BIT_1S /* Clear IRQ No Time Stamp */
+#define MFF_CLR_INSTAT BIT_0S /* Clear IRQ No Status */
+
+#define MFF_RX_CTRL_DEF MFF_ENA_TIM_PAT
+
+/* TX_MFF_CTRL1 16 bit Transmit MAC FIFO Control Reg 1 */
+#define MFF_CLR_PERR BIT_15S /* Clear Parity Error IRQ */
+ /* Bit 14: reserved */
+#define MFF_ENA_PKT_REC BIT_13S /* Enable Packet Recovery */
+#define MFF_DIS_PKT_REC BIT_12S /* Disable Packet Recovery */
+/* MFF_ENA_TIM_PAT (see RX_MFF_CTRL1) Bit 11: Enable Timing Patch */
+/* MFF_DIS_TIM_PAT (see RX_MFF_CTRL1) Bit 10: Disable Timing Patch */
+/* MFF_ENA_ALM_FUL (see RX_MFF_CTRL1) Bit 9: Enable Almost Full Sign */
+/* MFF_DIS_ALM_FUL (see RX_MFF_CTRL1) Bit 8: Disable Almost Full Sign */
+#define MFF_ENA_W4E BIT_7S /* Enable Wait for Empty */
+#define MFF_DIS_W4E BIT_6S /* Disable Wait for Empty */
+/* MFF_ENA_FLUSH (see RX_MFF_CTRL1) Bit 5: Enable Frame Flushing */
+/* MFF_DIS_FLUSH (see RX_MFF_CTRL1) Bit 4: Disable Frame Flushing */
+#define MFF_ENA_LOOPB BIT_3S /* Enable Loopback */
+#define MFF_DIS_LOOPB BIT_2S /* Disable Loopback */
+#define MFF_CLR_MAC_RST BIT_1S /* Clear XMAC Reset */
+#define MFF_SET_MAC_RST BIT_0S /* Set XMAC Reset */
+
+#define MFF_TX_CTRL_DEF (MFF_ENA_PKT_REC | MFF_ENA_TIM_PAT | MFF_ENA_FLUSH)
+
+/* RX_MFF_TST2 8 bit Receive MAC FIFO Test Register 2 */
+/* TX_MFF_TST2 8 bit Transmit MAC FIFO Test Register 2 */
+ /* Bit 7: reserved */
+#define MFF_WSP_T_ON BIT_6S /* Tx: Write Shadow Ptr TestOn */
+#define MFF_WSP_T_OFF BIT_5S /* Tx: Write Shadow Ptr TstOff */
+#define MFF_WSP_INC BIT_4S /* Tx: Write Shadow Ptr Increment */
+#define MFF_PC_DEC BIT_3S /* Packet Counter Decrement */
+#define MFF_PC_T_ON BIT_2S /* Packet Counter Test On */
+#define MFF_PC_T_OFF BIT_1S /* Packet Counter Test Off */
+#define MFF_PC_INC BIT_0S /* Packet Counter Increment */
+
+/* RX_MFF_TST1 8 bit Receive MAC FIFO Test Register 1 */
+/* TX_MFF_TST1 8 bit Transmit MAC FIFO Test Register 1 */
+ /* Bit 7: reserved */
+#define MFF_WP_T_ON BIT_6S /* Write Pointer Test On */
+#define MFF_WP_T_OFF BIT_5S /* Write Pointer Test Off */
+#define MFF_WP_INC BIT_4S /* Write Pointer Increm */
+ /* Bit 3: reserved */
+#define MFF_RP_T_ON BIT_2S /* Read Pointer Test On */
+#define MFF_RP_T_OFF BIT_1S /* Read Pointer Test Off */
+#define MFF_RP_DEC BIT_0S /* Read Pointer Decrement */
+
+/* RX_MFF_CTRL2 8 bit Receive MAC FIFO Control Reg 2 */
+/* TX_MFF_CTRL2 8 bit Transmit MAC FIFO Control Reg 2 */
+ /* Bit 7..4: reserved */
+#define MFF_ENA_OP_MD BIT_3S /* Enable Operation Mode */
+#define MFF_DIS_OP_MD BIT_2S /* Disable Operation Mode */
+#define MFF_RST_CLR BIT_1S /* Clear MAC FIFO Reset */
+#define MFF_RST_SET BIT_0S /* Set MAC FIFO Reset */
+
+
+/* Link LED Counter Registers (GENESIS only) */
+
+/* RX_LED_CTRL 8 bit Receive LED Cnt Control Reg */
+/* TX_LED_CTRL 8 bit Transmit LED Cnt Control Reg */
+/* LNK_SYNC_CTRL 8 bit Link Sync Cnt Control Register */
+ /* Bit 7.. 3: reserved */
+#define LED_START BIT_2S /* Start Timer */
+#define LED_STOP BIT_1S /* Stop Timer */
+#define LED_STATE BIT_0S /* Rx/Tx: LED State, 1=LED on */
+#define LED_CLR_IRQ BIT_0S /* Lnk: Clear Link IRQ */
+
+/* RX_LED_TST 8 bit Receive LED Cnt Test Register */
+/* TX_LED_TST 8 bit Transmit LED Cnt Test Register */
+/* LNK_SYNC_TST 8 bit Link Sync Cnt Test Register */
+ /* Bit 7.. 3: reserved */
+#define LED_T_ON BIT_2S /* LED Counter Test mode On */
+#define LED_T_OFF BIT_1S /* LED Counter Test mode Off */
+#define LED_T_STEP BIT_0S /* LED Counter Step */
+
+/* LNK_LED_REG 8 bit Link LED Register */
+ /* Bit 7.. 6: reserved */
+#define LED_BLK_ON BIT_5S /* Link LED Blinking On */
+#define LED_BLK_OFF BIT_4S /* Link LED Blinking Off */
+#define LED_SYNC_ON BIT_3S /* Use Sync Wire to switch LED */
+#define LED_SYNC_OFF BIT_2S /* Disable Sync Wire Input */
+#define LED_ON BIT_1S /* switch LED on */
+#define LED_OFF BIT_0S /* switch LED off */
+
+/* Receive and Transmit GMAC FIFO Registers (YUKON only) */
+
+/* RX_GMF_EA 32 bit Rx GMAC FIFO End Address */
+/* RX_GMF_AF_THR 32 bit Rx GMAC FIFO Almost Full Thresh. */
+/* RX_GMF_WP 32 bit Rx GMAC FIFO Write Pointer */
+/* RX_GMF_WLEV 32 bit Rx GMAC FIFO Write Level */
+/* RX_GMF_RP 32 bit Rx GMAC FIFO Read Pointer */
+/* RX_GMF_RLEV 32 bit Rx GMAC FIFO Read Level */
+/* TX_GMF_EA 32 bit Tx GMAC FIFO End Address */
+/* TX_GMF_AE_THR 32 bit Tx GMAC FIFO Almost Empty Thresh.*/
+/* TX_GMF_WP 32 bit Tx GMAC FIFO Write Pointer */
+/* TX_GMF_WSP 32 bit Tx GMAC FIFO Write Shadow Ptr. */
+/* TX_GMF_WLEV 32 bit Tx GMAC FIFO Write Level */
+/* TX_GMF_RP 32 bit Tx GMAC FIFO Read Pointer */
+/* TX_GMF_RSTP 32 bit Tx GMAC FIFO Restart Pointer */
+/* TX_GMF_RLEV 32 bit Tx GMAC FIFO Read Level */
+
+/* RX_GMF_CTRL_T 32 bit Rx GMAC FIFO Control/Test */
+ /* Bits 31..15: reserved */
+#define GMF_WP_TST_ON BIT_14 /* Write Pointer Test On */
+#define GMF_WP_TST_OFF BIT_13 /* Write Pointer Test Off */
+#define GMF_WP_STEP BIT_12 /* Write Pointer Step/Increment */
+ /* Bit 11: reserved */
+#define GMF_RP_TST_ON BIT_10 /* Read Pointer Test On */
+#define GMF_RP_TST_OFF BIT_9 /* Read Pointer Test Off */
+#define GMF_RP_STEP BIT_8 /* Read Pointer Step/Increment */
+#define GMF_RX_F_FL_ON BIT_7 /* Rx FIFO Flush Mode On */
+#define GMF_RX_F_FL_OFF BIT_6 /* Rx FIFO Flush Mode Off */
+#define GMF_CLI_RX_FO BIT_5 /* Clear IRQ Rx FIFO Overrun */
+#define GMF_CLI_RX_FC BIT_4 /* Clear IRQ Rx Frame Complete */
+#define GMF_OPER_ON BIT_3 /* Operational Mode On */
+#define GMF_OPER_OFF BIT_2 /* Operational Mode Off */
+#define GMF_RST_CLR BIT_1 /* Clear GMAC FIFO Reset */
+#define GMF_RST_SET BIT_0 /* Set GMAC FIFO Reset */
+
+/* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */
+ /* Bits 31..19: reserved */
+#define GMF_WSP_TST_ON BIT_18 /* Write Shadow Pointer Test On */
+#define GMF_WSP_TST_OFF BIT_17 /* Write Shadow Pointer Test Off */
+#define GMF_WSP_STEP BIT_16 /* Write Shadow Pointer Step/Increment */
+ /* Bits 15..7: same as for RX_GMF_CTRL_T */
+#define GMF_CLI_TX_FU BIT_6 /* Clear IRQ Tx FIFO Underrun */
+#define GMF_CLI_TX_FC BIT_5 /* Clear IRQ Tx Frame Complete */
+#define GMF_CLI_TX_PE BIT_4 /* Clear IRQ Tx Parity Error */
+ /* Bits 3..0: same as for RX_GMF_CTRL_T */
+
+#define GMF_RX_CTRL_DEF (GMF_OPER_ON | GMF_RX_F_FL_ON)
+#define GMF_TX_CTRL_DEF GMF_OPER_ON
+
+#define RX_GMF_FL_THR_DEF 0x0a /* Rx GMAC FIFO Flush Threshold default */
+
+/* GMAC_TI_ST_CTRL 8 bit Time Stamp Timer Ctrl Reg (YUKON only) */
+ /* Bit 7.. 3: reserved */
+#define GMT_ST_START BIT_2S /* Start Time Stamp Timer */
+#define GMT_ST_STOP BIT_1S /* Stop Time Stamp Timer */
+#define GMT_ST_CLR_IRQ BIT_0S /* Clear Time Stamp Timer IRQ */
+
+/* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */
+ /* Bits 31.. 8: reserved */
+#define GMC_H_BURST_ON BIT_7 /* Half Duplex Burst Mode On */
+#define GMC_H_BURST_OFF BIT_6 /* Half Duplex Burst Mode Off */
+#define GMC_F_LOOPB_ON BIT_5 /* FIFO Loopback On */
+#define GMC_F_LOOPB_OFF BIT_4 /* FIFO Loopback Off */
+#define GMC_PAUSE_ON BIT_3 /* Pause On */
+#define GMC_PAUSE_OFF BIT_2 /* Pause Off */
+#define GMC_RST_CLR BIT_1 /* Clear GMAC Reset */
+#define GMC_RST_SET BIT_0 /* Set GMAC Reset */
+
+/* GPHY_CTRL 32 bit GPHY Control Reg (YUKON only) */
+ /* Bits 31..29: reserved */
+#define GPC_SEL_BDT BIT_28 /* Select Bi-Dir. Transfer for MDC/MDIO */
+#define GPC_INT_POL_HI BIT_27 /* IRQ Polarity is Active HIGH */
+#define GPC_75_OHM BIT_26 /* Use 75 Ohm Termination instead of 50 */
+#define GPC_DIS_FC BIT_25 /* Disable Automatic Fiber/Copper Detection */
+#define GPC_DIS_SLEEP BIT_24 /* Disable Energy Detect */
+#define GPC_HWCFG_M_3 BIT_23 /* HWCFG_MODE[3] */
+#define GPC_HWCFG_M_2 BIT_22 /* HWCFG_MODE[2] */
+#define GPC_HWCFG_M_1 BIT_21 /* HWCFG_MODE[1] */
+#define GPC_HWCFG_M_0 BIT_20 /* HWCFG_MODE[0] */
+#define GPC_ANEG_0 BIT_19 /* ANEG[0] */
+#define GPC_ENA_XC BIT_18 /* Enable MDI crossover */
+#define GPC_DIS_125 BIT_17 /* Disable 125 MHz clock */
+#define GPC_ANEG_3 BIT_16 /* ANEG[3] */
+#define GPC_ANEG_2 BIT_15 /* ANEG[2] */
+#define GPC_ANEG_1 BIT_14 /* ANEG[1] */
+#define GPC_ENA_PAUSE BIT_13 /* Enable Pause (SYM_OR_REM) */
+#define GPC_PHYADDR_4 BIT_12 /* Bit 4 of Phy Addr */
+#define GPC_PHYADDR_3 BIT_11 /* Bit 3 of Phy Addr */
+#define GPC_PHYADDR_2 BIT_10 /* Bit 2 of Phy Addr */
+#define GPC_PHYADDR_1 BIT_9 /* Bit 1 of Phy Addr */
+#define GPC_PHYADDR_0 BIT_8 /* Bit 0 of Phy Addr */
+ /* Bits 7..2: reserved */
+#define GPC_RST_CLR BIT_1 /* Clear GPHY Reset */
+#define GPC_RST_SET BIT_0 /* Set GPHY Reset */
+
+#define GPC_HWCFG_GMII_COP (GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | \
+ GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
+
+#define GPC_HWCFG_GMII_FIB ( GPC_HWCFG_M_2 | \
+ GPC_HWCFG_M_1 | GPC_HWCFG_M_0)
+
+#define GPC_ANEG_ADV_ALL_M (GPC_ANEG_3 | GPC_ANEG_2 | \
+ GPC_ANEG_1 | GPC_ANEG_0)
+
+/* forced speed and duplex mode (don't mix with other ANEG bits) */
+#define GPC_FRC10MBIT_HALF 0
+#define GPC_FRC10MBIT_FULL GPC_ANEG_0
+#define GPC_FRC100MBIT_HALF GPC_ANEG_1
+#define GPC_FRC100MBIT_FULL (GPC_ANEG_0 | GPC_ANEG_1)
+
+/* auto-negotiation with limited advertised speeds */
+/* mix only with master/slave settings (for copper) */
+#define GPC_ADV_1000_HALF GPC_ANEG_2
+#define GPC_ADV_1000_FULL GPC_ANEG_3
+#define GPC_ADV_ALL (GPC_ANEG_2 | GPC_ANEG_3)
+
+/* master/slave settings */
+/* only for copper with 1000 Mbps */
+#define GPC_FORCE_MASTER 0
+#define GPC_FORCE_SLAVE GPC_ANEG_0
+#define GPC_PREF_MASTER GPC_ANEG_1
+#define GPC_PREF_SLAVE (GPC_ANEG_1 | GPC_ANEG_0)
+
+/* GMAC_IRQ_SRC 8 bit GMAC Interrupt Source Reg (YUKON only) */
+/* GMAC_IRQ_MSK 8 bit GMAC Interrupt Mask Reg (YUKON only) */
+#define GM_IS_TX_CO_OV BIT_5 /* Transmit Counter Overflow IRQ */
+#define GM_IS_RX_CO_OV BIT_4 /* Receive Counter Overflow IRQ */
+#define GM_IS_TX_FF_UR BIT_3 /* Transmit FIFO Underrun */
+#define GM_IS_TX_COMPL BIT_2 /* Frame Transmission Complete */
+#define GM_IS_RX_FF_OR BIT_1 /* Receive FIFO Overrun */
+#define GM_IS_RX_COMPL BIT_0 /* Frame Reception Complete */
+
+#define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \
+ GM_IS_TX_FF_UR)
+
+/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */
+ /* Bits 15.. 2: reserved */
+#define GMLC_RST_CLR BIT_1S /* Clear GMAC Link Reset */
+#define GMLC_RST_SET BIT_0S /* Set GMAC Link Reset */
+
+
+/* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */
+#define WOL_CTL_LINK_CHG_OCC BIT_15S
+#define WOL_CTL_MAGIC_PKT_OCC BIT_14S
+#define WOL_CTL_PATTERN_OCC BIT_13S
+
+#define WOL_CTL_CLEAR_RESULT BIT_12S
+
+#define WOL_CTL_ENA_PME_ON_LINK_CHG BIT_11S
+#define WOL_CTL_DIS_PME_ON_LINK_CHG BIT_10S
+#define WOL_CTL_ENA_PME_ON_MAGIC_PKT BIT_9S
+#define WOL_CTL_DIS_PME_ON_MAGIC_PKT BIT_8S
+#define WOL_CTL_ENA_PME_ON_PATTERN BIT_7S
+#define WOL_CTL_DIS_PME_ON_PATTERN BIT_6S
+
+#define WOL_CTL_ENA_LINK_CHG_UNIT BIT_5S
+#define WOL_CTL_DIS_LINK_CHG_UNIT BIT_4S
+#define WOL_CTL_ENA_MAGIC_PKT_UNIT BIT_3S
+#define WOL_CTL_DIS_MAGIC_PKT_UNIT BIT_2S
+#define WOL_CTL_ENA_PATTERN_UNIT BIT_1S
+#define WOL_CTL_DIS_PATTERN_UNIT BIT_0S
+
+#define WOL_CTL_DEFAULT \
+ (WOL_CTL_DIS_PME_ON_LINK_CHG | \
+ WOL_CTL_DIS_PME_ON_PATTERN | \
+ WOL_CTL_DIS_PME_ON_MAGIC_PKT | \
+ WOL_CTL_DIS_LINK_CHG_UNIT | \
+ WOL_CTL_DIS_PATTERN_UNIT | \
+ WOL_CTL_DIS_MAGIC_PKT_UNIT)
+
+/* WOL_MATCH_CTL 8 bit WOL Match Control Reg */
+#define WOL_CTL_PATT_ENA(x) (BIT_0 << (x))
+
+#define SK_NUM_WOL_PATTERN 7
+#define SK_PATTERN_PER_WORD 4
+#define SK_BITMASK_PATTERN 7
+#define SK_POW_PATTERN_LENGTH 128
+
+#define WOL_LENGTH_MSK 0x7f
+#define WOL_LENGTH_SHIFT 8
+
+
+/* Receive and Transmit Descriptors ******************************************/
+
+/* Transmit Descriptor struct */
+typedef struct s_HwTxd {
+ SK_U32 volatile TxCtrl; /* Transmit Buffer Control Field */
+ SK_U32 TxNext; /* Physical Address Pointer to the next TxD */
+ SK_U32 TxAdrLo; /* Physical Tx Buffer Address lower dword */
+ SK_U32 TxAdrHi; /* Physical Tx Buffer Address upper dword */
+ SK_U32 TxStat; /* Transmit Frame Status Word */
+#ifndef SK_USE_REV_DESC
+ SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */
+ SK_U16 TxRes1; /* 16 bit reserved field */
+ SK_U16 TxTcpWp; /* TCP Checksum Write Position */
+ SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */
+#else /* SK_USE_REV_DESC */
+ SK_U16 TxRes1; /* 16 bit reserved field */
+ SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */
+ SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */
+ SK_U16 TxTcpWp; /* TCP Checksum Write Position */
+#endif /* SK_USE_REV_DESC */
+ SK_U32 TxRes2; /* 32 bit reserved field */
+} SK_HWTXD;
+
+/* Receive Descriptor struct */
+typedef struct s_HwRxd {
+ SK_U32 volatile RxCtrl; /* Receive Buffer Control Field */
+ SK_U32 RxNext; /* Physical Address Pointer to the next RxD */
+ SK_U32 RxAdrLo; /* Physical Rx Buffer Address lower dword */
+ SK_U32 RxAdrHi; /* Physical Rx Buffer Address upper dword */
+ SK_U32 RxStat; /* Receive Frame Status Word */
+ SK_U32 RxTiSt; /* Receive Time Stamp (from XMAC on GENESIS) */
+#ifndef SK_USE_REV_DESC
+ SK_U16 RxTcpSum1; /* TCP Checksum 1 */
+ SK_U16 RxTcpSum2; /* TCP Checksum 2 */
+ SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */
+ SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */
+#else /* SK_USE_REV_DESC */
+ SK_U16 RxTcpSum2; /* TCP Checksum 2 */
+ SK_U16 RxTcpSum1; /* TCP Checksum 1 */
+ SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */
+ SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */
+#endif /* SK_USE_REV_DESC */
+} SK_HWRXD;
+
+/*
+ * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2)
+ * should set the define SK_USE_REV_DESC.
+ * Structures are 'normaly' not endianess dependent. But in
+ * this case the SK_U16 fields are bound to bit positions inside the
+ * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord.
+ * The bit positions inside a DWord are of course endianess dependent and
+ * swaps if the DWord is swapped by the hardware.
+ */
+
+
+/* Descriptor Bit Definition */
+/* TxCtrl Transmit Buffer Control Field */
+/* RxCtrl Receive Buffer Control Field */
+#define BMU_OWN BIT_31 /* OWN bit: 0=host/1=BMU */
+#define BMU_STF BIT_30 /* Start of Frame */
+#define BMU_EOF BIT_29 /* End of Frame */
+#define BMU_IRQ_EOB BIT_28 /* Req "End of Buffer" IRQ */
+#define BMU_IRQ_EOF BIT_27 /* Req "End of Frame" IRQ */
+/* TxCtrl specific bits */
+#define BMU_STFWD BIT_26 /* (Tx) Store & Forward Frame */
+#define BMU_NO_FCS BIT_25 /* (Tx) Disable MAC FCS (CRC) generation */
+#define BMU_SW BIT_24 /* (Tx) 1 bit res. for SW use */
+/* RxCtrl specific bits */
+#define BMU_DEV_0 BIT_26 /* (Rx) Transfer data to Dev0 */
+#define BMU_STAT_VAL BIT_25 /* (Rx) Rx Status Valid */
+#define BMU_TIST_VAL BIT_24 /* (Rx) Rx TimeStamp Valid */
+ /* Bit 23..16: BMU Check Opcodes */
+#define BMU_CHECK (0x55L<<16) /* Default BMU check */
+#define BMU_TCP_CHECK (0x56L<<16) /* Descr with TCP ext */
+#define BMU_UDP_CHECK (0x57L<<16) /* Descr with UDP ext (YUKON only) */
+#define BMU_BBC 0xffffL /* Bit 15.. 0: Buffer Byte Counter */
+
+/* TxStat Transmit Frame Status Word */
+/* RxStat Receive Frame Status Word */
+/*
+ *Note: TxStat is reserved for ASIC loopback mode only
+ *
+ * The Bits of the Status words are defined in xmac_ii.h
+ * (see XMR_FS bits)
+ */
+
+/* macros ********************************************************************/
+
+/* Receive and Transmit Queues */
+#define Q_R1 0x0000 /* Receive Queue 1 */
+#define Q_R2 0x0080 /* Receive Queue 2 */
+#define Q_XS1 0x0200 /* Synchronous Transmit Queue 1 */
+#define Q_XA1 0x0280 /* Asynchronous Transmit Queue 1 */
+#define Q_XS2 0x0300 /* Synchronous Transmit Queue 2 */
+#define Q_XA2 0x0380 /* Asynchronous Transmit Queue 2 */
+
+/*
+ * Macro Q_ADDR()
+ *
+ * Use this macro to access the Receive and Transmit Queue Registers.
+ *
+ * para:
+ * Queue Queue to access.
+ * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
+ * Offs Queue register offset.
+ * Values: Q_D, Q_DA_L ... Q_T2, Q_T3
+ *
+ * usage SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal)
+ */
+#define Q_ADDR(Queue, Offs) (B8_Q_REGS + (Queue) + (Offs))
+
+/*
+ * Macro RB_ADDR()
+ *
+ * Use this macro to access the RAM Buffer Registers.
+ *
+ * para:
+ * Queue Queue to access.
+ * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, and Q_XA2
+ * Offs Queue register offset.
+ * Values: RB_START, RB_END ... RB_LEV, RB_CTRL
+ *
+ * usage SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal)
+ */
+#define RB_ADDR(Queue, Offs) (B16_RAM_REGS + (Queue) + (Offs))
+
+
+/* MAC Related Registers */
+#define MAC_1 0 /* belongs to the port near the slot */
+#define MAC_2 1 /* belongs to the port far away from the slot */
+
+/*
+ * Macro MR_ADDR()
+ *
+ * Use this macro to access a MAC Related Registers inside the ASIC.
+ *
+ * para:
+ * Mac MAC to access.
+ * Values: MAC_1, MAC_2
+ * Offs MAC register offset.
+ * Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG,
+ * TX_MFF_EA, TX_MFF_WP ... TX_LED_TST
+ *
+ * usage SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal)
+ */
+#define MR_ADDR(Mac, Offs) (((Mac) << 7) + (Offs))
+
+#ifdef SK_LITTLE_ENDIAN
+#define XM_WORD_LO 0
+#define XM_WORD_HI 1
+#else /* !SK_LITTLE_ENDIAN */
+#define XM_WORD_LO 1
+#define XM_WORD_HI 0
+#endif /* !SK_LITTLE_ENDIAN */
+
+
+/*
+ * macros to access the XMAC (GENESIS only)
+ *
+ * XM_IN16(), to read a 16 bit register (e.g. XM_MMU_CMD)
+ * XM_OUT16(), to write a 16 bit register (e.g. XM_MMU_CMD)
+ * XM_IN32(), to read a 32 bit register (e.g. XM_TX_EV_CNT)
+ * XM_OUT32(), to write a 32 bit register (e.g. XM_TX_EV_CNT)
+ * XM_INADDR(), to read a network address register (e.g. XM_SRC_CHK)
+ * XM_OUTADDR(), to write a network address register (e.g. XM_SRC_CHK)
+ * XM_INHASH(), to read the XM_HSM_CHK register
+ * XM_OUTHASH() to write the XM_HSM_CHK register
+ *
+ * para:
+ * Mac XMAC to access values: MAC_1 or MAC_2
+ * IoC I/O context needed for SK I/O macros
+ * Reg XMAC Register to read or write
+ * (p)Val Value or pointer to the value which should be read or written
+ *
+ * usage: XM_OUT16(IoC, MAC_1, XM_MMU_CMD, Value);
+ */
+
+#define XMA(Mac, Reg) \
+ ((BASE_XMAC_1 + (Mac) * (BASE_XMAC_2 - BASE_XMAC_1)) | ((Reg) << 1))
+
+#define XM_IN16(IoC, Mac, Reg, pVal) \
+ SK_IN16((IoC), XMA((Mac), (Reg)), (pVal))
+
+#define XM_OUT16(IoC, Mac, Reg, Val) \
+ SK_OUT16((IoC), XMA((Mac), (Reg)), (Val))
+
+#define XM_IN32(IoC, Mac, Reg, pVal) { \
+ SK_IN16((IoC), XMA((Mac), (Reg)), \
+ (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \
+ SK_IN16((IoC), XMA((Mac), (Reg+2)), \
+ (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \
+}
+
+#define XM_OUT32(IoC, Mac, Reg, Val) { \
+ SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \
+ SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)(((Val) >> 16) & 0xffffL));\
+}
+
+/* Remember: we are always writing to / reading from LITTLE ENDIAN memory */
+
+#define XM_INADDR(IoC, Mac, Reg, pVal) { \
+ SK_U16 Word; \
+ SK_U8 *pByte; \
+ pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
+ SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \
+ pByte[0] = (SK_U8)(Word & 0x00ff); \
+ pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
+ SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \
+ pByte[2] = (SK_U8)(Word & 0x00ff); \
+ pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
+ SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \
+ pByte[4] = (SK_U8)(Word & 0x00ff); \
+ pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
+}
+
+#define XM_OUTADDR(IoC, Mac, Reg, pVal) { \
+ SK_U8 SK_FAR *pByte; \
+ pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
+ SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \
+ (((SK_U16)(pByte[0]) & 0x00ff) | \
+ (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
+ SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \
+ (((SK_U16)(pByte[2]) & 0x00ff) | \
+ (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
+ SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \
+ (((SK_U16)(pByte[4]) & 0x00ff) | \
+ (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
+}
+
+#define XM_INHASH(IoC, Mac, Reg, pVal) { \
+ SK_U16 Word; \
+ SK_U8 SK_FAR *pByte; \
+ pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
+ SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \
+ pByte[0] = (SK_U8)(Word & 0x00ff); \
+ pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
+ SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \
+ pByte[2] = (SK_U8)(Word & 0x00ff); \
+ pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
+ SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \
+ pByte[4] = (SK_U8)(Word & 0x00ff); \
+ pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
+ SK_IN16((IoC), XMA((Mac), (Reg+6)), &Word); \
+ pByte[6] = (SK_U8)(Word & 0x00ff); \
+ pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \
+}
+
+#define XM_OUTHASH(IoC, Mac, Reg, pVal) { \
+ SK_U8 SK_FAR *pByte; \
+ pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
+ SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \
+ (((SK_U16)(pByte[0]) & 0x00ff)| \
+ (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
+ SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \
+ (((SK_U16)(pByte[2]) & 0x00ff)| \
+ (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
+ SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \
+ (((SK_U16)(pByte[4]) & 0x00ff)| \
+ (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
+ SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16) \
+ (((SK_U16)(pByte[6]) & 0x00ff)| \
+ (((SK_U16)(pByte[7]) << 8) & 0xff00))); \
+}
+
+/*
+ * macros to access the GMAC (YUKON only)
+ *
+ * GM_IN16(), to read a 16 bit register (e.g. GM_GP_STAT)
+ * GM_OUT16(), to write a 16 bit register (e.g. GM_GP_CTRL)
+ * GM_IN32(), to read a 32 bit register (e.g. GM_)
+ * GM_OUT32(), to write a 32 bit register (e.g. GM_)
+ * GM_INADDR(), to read a network address register (e.g. GM_SRC_ADDR_1L)
+ * GM_OUTADDR(), to write a network address register (e.g. GM_SRC_ADDR_2L)
+ * GM_INHASH(), to read the GM_MC_ADDR_H1 register
+ * GM_OUTHASH() to write the GM_MC_ADDR_H1 register
+ *
+ * para:
+ * Mac GMAC to access values: MAC_1 or MAC_2
+ * IoC I/O context needed for SK I/O macros
+ * Reg GMAC Register to read or write
+ * (p)Val Value or pointer to the value which should be read or written
+ *
+ * usage: GM_OUT16(IoC, MAC_1, GM_GP_CTRL, Value);
+ */
+
+#define GMA(Mac, Reg) \
+ ((BASE_GMAC_1 + (Mac) * (BASE_GMAC_2 - BASE_GMAC_1)) | (Reg))
+
+#define GM_IN16(IoC, Mac, Reg, pVal) \
+ SK_IN16((IoC), GMA((Mac), (Reg)), (pVal))
+
+#define GM_OUT16(IoC, Mac, Reg, Val) \
+ SK_OUT16((IoC), GMA((Mac), (Reg)), (Val))
+
+#define GM_IN32(IoC, Mac, Reg, pVal) { \
+ SK_IN16((IoC), GMA((Mac), (Reg)), \
+ (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \
+ SK_IN16((IoC), GMA((Mac), (Reg+4)), \
+ (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \
+}
+
+#define GM_OUT32(IoC, Mac, Reg, Val) { \
+ SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \
+ SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)(((Val) >> 16) & 0xffffL));\
+}
+
+#define GM_INADDR(IoC, Mac, Reg, pVal) { \
+ SK_U16 Word; \
+ SK_U8 *pByte; \
+ pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
+ SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \
+ pByte[0] = (SK_U8)(Word & 0x00ff); \
+ pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
+ SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \
+ pByte[2] = (SK_U8)(Word & 0x00ff); \
+ pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
+ SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \
+ pByte[4] = (SK_U8)(Word & 0x00ff); \
+ pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
+}
+
+#define GM_OUTADDR(IoC, Mac, Reg, pVal) { \
+ SK_U8 SK_FAR *pByte; \
+ pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \
+ SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \
+ (((SK_U16)(pByte[0]) & 0x00ff) | \
+ (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
+ SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \
+ (((SK_U16)(pByte[2]) & 0x00ff) | \
+ (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
+ SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \
+ (((SK_U16)(pByte[4]) & 0x00ff) | \
+ (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
+}
+
+#define GM_INHASH(IoC, Mac, Reg, pVal) { \
+ SK_U16 Word; \
+ SK_U8 *pByte; \
+ pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
+ SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \
+ pByte[0] = (SK_U8)(Word & 0x00ff); \
+ pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \
+ SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \
+ pByte[2] = (SK_U8)(Word & 0x00ff); \
+ pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \
+ SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \
+ pByte[4] = (SK_U8)(Word & 0x00ff); \
+ pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \
+ SK_IN16((IoC), GMA((Mac), (Reg+12)), &Word); \
+ pByte[6] = (SK_U8)(Word & 0x00ff); \
+ pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \
+}
+
+#define GM_OUTHASH(IoC, Mac, Reg, pVal) { \
+ SK_U8 *pByte; \
+ pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \
+ SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \
+ (((SK_U16)(pByte[0]) & 0x00ff)| \
+ (((SK_U16)(pByte[1]) << 8) & 0xff00))); \
+ SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \
+ (((SK_U16)(pByte[2]) & 0x00ff)| \
+ (((SK_U16)(pByte[3]) << 8) & 0xff00))); \
+ SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \
+ (((SK_U16)(pByte[4]) & 0x00ff)| \
+ (((SK_U16)(pByte[5]) << 8) & 0xff00))); \
+ SK_OUT16((IoC), GMA((Mac), (Reg+12)), (SK_U16) \
+ (((SK_U16)(pByte[6]) & 0x00ff)| \
+ (((SK_U16)(pByte[7]) << 8) & 0xff00))); \
+}
+
+/*
+ * Different MAC Types
+ */
+#define SK_MAC_XMAC 0 /* Xaqti XMAC II */
+#define SK_MAC_GMAC 1 /* Marvell GMAC */
+
+/*
+ * Different PHY Types
+ */
+#define SK_PHY_XMAC 0 /* integrated in XMAC II */
+#define SK_PHY_BCOM 1 /* Broadcom BCM5400 */
+#define SK_PHY_LONE 2 /* Level One LXT1000 */
+#define SK_PHY_NAT 3 /* National DP83891 */
+#define SK_PHY_MARV_COPPER 4 /* Marvell 88E1011S */
+#define SK_PHY_MARV_FIBER 5 /* Marvell 88E1011S working on fiber */
+
+/*
+ * PHY addresses (bits 12..8 of PHY address reg)
+ */
+#define PHY_ADDR_XMAC (0<<8)
+#define PHY_ADDR_BCOM (1<<8)
+#define PHY_ADDR_LONE (3<<8)
+#define PHY_ADDR_NAT (0<<8)
+
+/* GPHY address (bits 15..11 of SMI control reg) */
+#define PHY_ADDR_MARV 0
+
+/*
+ * macros to access the PHY
+ *
+ * PHY_READ() read a 16 bit value from the PHY
+ * PHY_WRITE() write a 16 bit value to the PHY
+ *
+ * para:
+ * IoC I/O context needed for SK I/O macros
+ * pPort Pointer to port struct for PhyAddr
+ * Mac XMAC to access values: MAC_1 or MAC_2
+ * PhyReg PHY Register to read or write
+ * (p)Val Value or pointer to the value which should be read or
+ * written.
+ *
+ * usage: PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value);
+ * Warning: a PHY_READ on an uninitialized PHY (PHY still in reset) never
+ * comes back. This is checked in DEBUG mode.
+ */
+#ifndef DEBUG
+#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \
+ SK_U16 Mmu; \
+ \
+ XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
+ XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
+ if ((pPort)->PhyType != SK_PHY_XMAC) { \
+ do { \
+ XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
+ } while ((Mmu & XM_MMU_PHY_RDY) == 0); \
+ XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
+ } \
+}
+#else
+#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \
+ SK_U16 Mmu; \
+ int __i = 0; \
+ \
+ XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
+ XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
+ if ((pPort)->PhyType != SK_PHY_XMAC) { \
+ do { \
+ XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
+ __i++; \
+ if (__i > 100000) { \
+ SK_DBG_PRINTF("*****************************\n"); \
+ SK_DBG_PRINTF("PHY_READ on uninitialized PHY\n"); \
+ SK_DBG_PRINTF("*****************************\n"); \
+ break; \
+ } \
+ } while ((Mmu & XM_MMU_PHY_RDY) == 0); \
+ XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
+ } \
+}
+#endif /* DEBUG */
+
+#define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) { \
+ SK_U16 Mmu; \
+ \
+ if ((pPort)->PhyType != SK_PHY_XMAC) { \
+ do { \
+ XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
+ } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \
+ } \
+ XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \
+ XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val)); \
+ if ((pPort)->PhyType != SK_PHY_XMAC) { \
+ do { \
+ XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
+ } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \
+ } \
+}
+
+/*
+ * Macro PCI_C()
+ *
+ * Use this macro to access PCI config register from the I/O space.
+ *
+ * para:
+ * Addr PCI configuration register to access.
+ * Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG,
+ *
+ * usage SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal);
+ */
+#define PCI_C(Addr) (B7_CFG_SPC + (Addr)) /* PCI Config Space */
+
+/*
+ * Macro SK_HW_ADDR(Base, Addr)
+ *
+ * Calculates the effective HW address
+ *
+ * para:
+ * Base I/O or memory base address
+ * Addr Address offset
+ *
+ * usage: May be used in SK_INxx and SK_OUTxx macros
+ * #define SK_IN8(pAC, Addr, pVal) ...\
+ * *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr)))
+ */
+#ifdef SK_MEM_MAPPED_IO
+#define SK_HW_ADDR(Base, Addr) ((Base) + (Addr))
+#else /* SK_MEM_MAPPED_IO */
+#define SK_HW_ADDR(Base, Addr) \
+ ((Base) + (((Addr) & 0x7f) | (((Addr) >> 7 > 0) ? 0x80 : 0)))
+#endif /* SK_MEM_MAPPED_IO */
+
+#define SZ_LONG (sizeof(SK_U32))
+
+/*
+ * Macro SK_HWAC_LINK_LED()
+ *
+ * Use this macro to set the link LED mode.
+ * para:
+ * pAC Pointer to adapter context struct
+ * IoC I/O context needed for SK I/O macros
+ * Port Port number
+ * Mode Mode to set for this LED
+ */
+#define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \
+ SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode);
+
+
+/* typedefs *******************************************************************/
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INC_SKGEHW_H */
diff --git a/drivers/net/sk98lin/h/skgehwt.h b/drivers/net/sk98lin/h/skgehwt.h
new file mode 100644
index 000000000000..e6b0016a695c
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgehwt.h
@@ -0,0 +1,48 @@
+/******************************************************************************
+ *
+ * Name: skhwt.h
+ * Project: Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version: $Revision: 1.7 $
+ * Date: $Date: 2003/09/16 12:55:08 $
+ * Purpose: Defines for the hardware timer functions
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/*
+ * SKGEHWT.H contains all defines and types for the timer functions
+ */
+
+#ifndef _SKGEHWT_H_
+#define _SKGEHWT_H_
+
+/*
+ * SK Hardware Timer
+ * - needed wherever the HWT module is used
+ * - use in Adapters context name pAC->Hwt
+ */
+typedef struct s_Hwt {
+ SK_U32 TStart; /* HWT start */
+ SK_U32 TStop; /* HWT stop */
+ int TActive; /* HWT: flag : active/inactive */
+} SK_HWT;
+
+extern void SkHwtInit(SK_AC *pAC, SK_IOC Ioc);
+extern void SkHwtStart(SK_AC *pAC, SK_IOC Ioc, SK_U32 Time);
+extern void SkHwtStop(SK_AC *pAC, SK_IOC Ioc);
+extern SK_U32 SkHwtRead(SK_AC *pAC, SK_IOC Ioc);
+extern void SkHwtIsr(SK_AC *pAC, SK_IOC Ioc);
+#endif /* _SKGEHWT_H_ */
diff --git a/drivers/net/sk98lin/h/skgei2c.h b/drivers/net/sk98lin/h/skgei2c.h
new file mode 100644
index 000000000000..d9b6f6d8dfe2
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgei2c.h
@@ -0,0 +1,210 @@
+/******************************************************************************
+ *
+ * Name: skgei2c.h
+ * Project: Gigabit Ethernet Adapters, TWSI-Module
+ * Version: $Revision: 1.25 $
+ * Date: $Date: 2003/10/20 09:06:05 $
+ * Purpose: Special defines for TWSI
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/*
+ * SKGEI2C.H contains all SK-98xx specific defines for the TWSI handling
+ */
+
+#ifndef _INC_SKGEI2C_H_
+#define _INC_SKGEI2C_H_
+
+/*
+ * Macros to access the B2_I2C_CTRL
+ */
+#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \
+ SK_OUT32(IoC, B2_I2C_CTRL,\
+ (flag ? 0x80000000UL : 0x0L) | \
+ (((SK_U32)reg << 16) & I2C_ADDR) | \
+ (((SK_U32)dev << 9) & I2C_DEV_SEL) | \
+ (dev_size & I2C_DEV_SIZE) | \
+ ((burst << 4) & I2C_BURST_LEN))
+
+#define SK_I2C_STOP(IoC) { \
+ SK_U32 I2cCtrl; \
+ SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl); \
+ SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \
+}
+
+#define SK_I2C_GET_CTL(IoC, pI2cCtrl) SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl)
+
+/*
+ * Macros to access the TWSI SW Registers
+ */
+#define SK_I2C_SET_BIT(IoC, SetBits) { \
+ SK_U8 OrgBits; \
+ SK_IN8(IoC, B2_I2C_SW, &OrgBits); \
+ SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits)); \
+}
+
+#define SK_I2C_CLR_BIT(IoC, ClrBits) { \
+ SK_U8 OrgBits; \
+ SK_IN8(IoC, B2_I2C_SW, &OrgBits); \
+ SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \
+}
+
+#define SK_I2C_GET_SW(IoC, pI2cSw) SK_IN8(IoC, B2_I2C_SW, pI2cSw)
+
+/*
+ * define the possible sensor states
+ */
+#define SK_SEN_IDLE 0 /* Idle: sensor not read */
+#define SK_SEN_VALUE 1 /* Value Read cycle */
+#define SK_SEN_VALEXT 2 /* Extended Value Read cycle */
+
+/*
+ * Conversion factor to convert read Voltage sensor to milli Volt
+ * Conversion factor to convert read Temperature sensor to 10th degree Celsius
+ */
+#define SK_LM80_VT_LSB 22 /* 22mV LSB resolution */
+#define SK_LM80_TEMP_LSB 10 /* 1 degree LSB resolution */
+#define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for ext. val. */
+
+/*
+ * formula: counter = (22500*60)/(rpm * divisor * pulses/2)
+ * assuming: 6500rpm, 4 pulses, divisor 1
+ */
+#define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2))
+
+/*
+ * Define sensor management data
+ * Maximum is reached on Genesis copper dual port and Yukon-64
+ * Board specific maximum is in pAC->I2c.MaxSens
+ */
+#define SK_MAX_SENSORS 8 /* maximal no. of installed sensors */
+#define SK_MIN_SENSORS 5 /* minimal no. of installed sensors */
+
+/*
+ * To watch the state machine (SM) use the timer in two ways
+ * instead of one as hitherto
+ */
+#define SK_TIMER_WATCH_SM 0 /* Watch the SM to finish in a spec. time */
+#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */
+
+/*
+ * Defines for the individual thresholds
+ */
+
+/* Temperature sensor */
+#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */
+#define SK_SEN_TEMP_HIGH_WARN 700 /* Temperature High Warn Threshold */
+#define SK_SEN_TEMP_LOW_WARN 100 /* Temperature Low Warn Threshold */
+#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */
+
+/* VCC which should be 5 V */
+#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */
+#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */
+#define SK_SEN_PCI_5V_LOW_WARN 4664 /* Voltage PCI Low Warn Threshold */
+#define SK_SEN_PCI_5V_LOW_ERR 4422 /* Voltage PCI Low Err Threshold */
+
+/*
+ * VIO may be 5 V or 3.3 V. Initialization takes two parts:
+ * 1. Initialize lowest lower limit and highest higher limit.
+ * 2. After the first value is read correct the upper or the lower limit to
+ * the appropriate C constant.
+ *
+ * Warning limits are +-5% of the exepected voltage.
+ * Error limits are +-10% of the expected voltage.
+ */
+
+/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */
+
+#define SK_SEN_PCI_IO_5V_HIGH_ERR 5566 /* + 10% V PCI-IO High Err Threshold */
+#define SK_SEN_PCI_IO_5V_HIGH_WARN 5324 /* + 5% V PCI-IO High Warn Threshold */
+ /* 5000 mVolt */
+#define SK_SEN_PCI_IO_5V_LOW_WARN 4686 /* - 5% V PCI-IO Low Warn Threshold */
+#define SK_SEN_PCI_IO_5V_LOW_ERR 4444 /* - 10% V PCI-IO Low Err Threshold */
+
+#define SK_SEN_PCI_IO_RANGE_LIMITER 4000 /* 4000 mV range delimiter */
+
+/* correction values for the second pass */
+#define SK_SEN_PCI_IO_3V3_HIGH_ERR 3850 /* + 15% V PCI-IO High Err Threshold */
+#define SK_SEN_PCI_IO_3V3_HIGH_WARN 3674 /* + 10% V PCI-IO High Warn Threshold */
+ /* 3300 mVolt */
+#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */
+#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */
+
+/*
+ * VDD voltage
+ */
+#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */
+#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */
+#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */
+#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */
+
+/*
+ * PHY PLL 3V3 voltage
+ */
+#define SK_SEN_PLL_3V3_HIGH_ERR 3630 /* Voltage PMA High Err Threshold */
+#define SK_SEN_PLL_3V3_HIGH_WARN 3476 /* Voltage PMA High Warn Threshold */
+#define SK_SEN_PLL_3V3_LOW_WARN 3146 /* Voltage PMA Low Warn Threshold */
+#define SK_SEN_PLL_3V3_LOW_ERR 2970 /* Voltage PMA Low Err Threshold */
+
+/*
+ * VAUX (YUKON only)
+ */
+#define SK_SEN_VAUX_3V3_HIGH_ERR 3630 /* Voltage VAUX High Err Threshold */
+#define SK_SEN_VAUX_3V3_HIGH_WARN 3476 /* Voltage VAUX High Warn Threshold */
+#define SK_SEN_VAUX_3V3_LOW_WARN 3146 /* Voltage VAUX Low Warn Threshold */
+#define SK_SEN_VAUX_3V3_LOW_ERR 2970 /* Voltage VAUX Low Err Threshold */
+#define SK_SEN_VAUX_0V_WARN_ERR 0 /* if VAUX not present */
+#define SK_SEN_VAUX_RANGE_LIMITER 1000 /* 1000 mV range delimiter */
+
+/*
+ * PHY 2V5 voltage
+ */
+#define SK_SEN_PHY_2V5_HIGH_ERR 2750 /* Voltage PHY High Err Threshold */
+#define SK_SEN_PHY_2V5_HIGH_WARN 2640 /* Voltage PHY High Warn Threshold */
+#define SK_SEN_PHY_2V5_LOW_WARN 2376 /* Voltage PHY Low Warn Threshold */
+#define SK_SEN_PHY_2V5_LOW_ERR 2222 /* Voltage PHY Low Err Threshold */
+
+/*
+ * ASIC Core 1V5 voltage (YUKON only)
+ */
+#define SK_SEN_CORE_1V5_HIGH_ERR 1650 /* Voltage ASIC Core High Err Threshold */
+#define SK_SEN_CORE_1V5_HIGH_WARN 1575 /* Voltage ASIC Core High Warn Threshold */
+#define SK_SEN_CORE_1V5_LOW_WARN 1425 /* Voltage ASIC Core Low Warn Threshold */
+#define SK_SEN_CORE_1V5_LOW_ERR 1350 /* Voltage ASIC Core Low Err Threshold */
+
+/*
+ * FAN 1 speed
+ */
+/* assuming: 6500rpm +-15%, 4 pulses,
+ * warning at: 80 %
+ * error at: 70 %
+ * no upper limit
+ */
+#define SK_SEN_FAN_HIGH_ERR 20000 /* FAN Speed High Err Threshold */
+#define SK_SEN_FAN_HIGH_WARN 20000 /* FAN Speed High Warn Threshold */
+#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */
+#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */
+
+/*
+ * Some Voltages need dynamic thresholds
+ */
+#define SK_SEN_DYN_INIT_NONE 0 /* No dynamic init of thresholds */
+#define SK_SEN_DYN_INIT_PCI_IO 10 /* Init PCI-IO with new thresholds */
+#define SK_SEN_DYN_INIT_VAUX 11 /* Init VAUX with new thresholds */
+
+extern int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
+#endif /* n_INC_SKGEI2C_H */
diff --git a/drivers/net/sk98lin/h/skgeinit.h b/drivers/net/sk98lin/h/skgeinit.h
new file mode 100644
index 000000000000..184f47c5a60f
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgeinit.h
@@ -0,0 +1,853 @@
+/******************************************************************************
+ *
+ * Name: skgeinit.h
+ * Project: Gigabit Ethernet Adapters, Common Modules
+ * Version: $Revision: 1.83 $
+ * Date: $Date: 2003/09/16 14:07:37 $
+ * Purpose: Structures and prototypes for the GE Init Module
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKGEINIT_H_
+#define __INC_SKGEINIT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* defines ********************************************************************/
+
+#define SK_TEST_VAL 0x11335577UL
+
+/* modifying Link LED behaviour (used with SkGeLinkLED()) */
+#define SK_LNK_OFF LED_OFF
+#define SK_LNK_ON (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
+#define SK_LNK_BLINK (LED_ON | LED_BLK_ON | LED_SYNC_ON)
+#define SK_LNK_PERM (LED_ON | LED_BLK_OFF | LED_SYNC_ON)
+#define SK_LNK_TST (LED_ON | LED_BLK_ON | LED_SYNC_OFF)
+
+/* parameter 'Mode' when calling SK_HWAC_LINK_LED() */
+#define SK_LED_OFF LED_OFF
+#define SK_LED_ACTIVE (LED_ON | LED_BLK_OFF | LED_SYNC_OFF)
+#define SK_LED_STANDBY (LED_ON | LED_BLK_ON | LED_SYNC_OFF)
+
+/* addressing LED Registers in SkGeXmitLED() */
+#define XMIT_LED_INI 0
+#define XMIT_LED_CNT (RX_LED_VAL - RX_LED_INI)
+#define XMIT_LED_CTRL (RX_LED_CTRL- RX_LED_INI)
+#define XMIT_LED_TST (RX_LED_TST - RX_LED_INI)
+
+/* parameter 'Mode' when calling SkGeXmitLED() */
+#define SK_LED_DIS 0
+#define SK_LED_ENA 1
+#define SK_LED_TST 2
+
+/* Counter and Timer constants, for a host clock of 62.5 MHz */
+#define SK_XMIT_DUR 0x002faf08UL /* 50 ms */
+#define SK_BLK_DUR 0x01dcd650UL /* 500 ms */
+
+#define SK_DPOLL_DEF 0x00ee6b28UL /* 250 ms at 62.5 MHz */
+
+#define SK_DPOLL_MAX 0x00ffffffUL /* 268 ms at 62.5 MHz */
+ /* 215 ms at 78.12 MHz */
+
+#define SK_FACT_62 100 /* is given in percent */
+#define SK_FACT_53 85 /* on GENESIS: 53.12 MHz */
+#define SK_FACT_78 125 /* on YUKON: 78.12 MHz */
+
+/* Timeout values */
+#define SK_MAC_TO_53 72 /* MAC arbiter timeout */
+#define SK_PKT_TO_53 0x2000 /* Packet arbiter timeout */
+#define SK_PKT_TO_MAX 0xffff /* Maximum value */
+#define SK_RI_TO_53 36 /* RAM interface timeout */
+
+#define SK_PHY_ACC_TO 600000 /* PHY access timeout */
+
+/* RAM Buffer High Pause Threshold values */
+#define SK_RB_ULPP ( 8 * 1024) /* Upper Level in kB/8 */
+#define SK_RB_LLPP_S (10 * 1024) /* Lower Level for small Queues */
+#define SK_RB_LLPP_B (16 * 1024) /* Lower Level for big Queues */
+
+#ifndef SK_BMU_RX_WM
+#define SK_BMU_RX_WM 0x600 /* BMU Rx Watermark */
+#endif
+#ifndef SK_BMU_TX_WM
+#define SK_BMU_TX_WM 0x600 /* BMU Tx Watermark */
+#endif
+
+/* XMAC II Rx High Watermark */
+#define SK_XM_RX_HI_WM 0x05aa /* 1450 */
+
+/* XMAC II Tx Threshold */
+#define SK_XM_THR_REDL 0x01fb /* .. for redundant link usage */
+#define SK_XM_THR_SL 0x01fb /* .. for single link adapters */
+#define SK_XM_THR_MULL 0x01fb /* .. for multiple link usage */
+#define SK_XM_THR_JUMBO 0x03fc /* .. for jumbo frame usage */
+
+/* values for GIPortUsage */
+#define SK_RED_LINK 1 /* redundant link usage */
+#define SK_MUL_LINK 2 /* multiple link usage */
+#define SK_JUMBO_LINK 3 /* driver uses jumbo frames */
+
+/* Minimum RAM Buffer Rx Queue Size */
+#define SK_MIN_RXQ_SIZE 16 /* 16 kB */
+
+/* Minimum RAM Buffer Tx Queue Size */
+#define SK_MIN_TXQ_SIZE 16 /* 16 kB */
+
+/* Queue Size units */
+#define QZ_UNITS 0x7
+#define QZ_STEP 8
+
+/* Percentage of queue size from whole memory */
+/* 80 % for receive */
+#define RAM_QUOTA_RX 80L
+/* 0% for sync transfer */
+#define RAM_QUOTA_SYNC 0L
+/* the rest (20%) is taken for async transfer */
+
+/* Get the rounded queue size in Bytes in 8k steps */
+#define ROUND_QUEUE_SIZE(SizeInBytes) \
+ ((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) & \
+ ~(QZ_STEP-1))
+
+/* Get the rounded queue size in KBytes in 8k steps */
+#define ROUND_QUEUE_SIZE_KB(Kilobytes) \
+ ROUND_QUEUE_SIZE((Kilobytes) * 1024L)
+
+/* Types of RAM Buffer Queues */
+#define SK_RX_SRAM_Q 1 /* small receive queue */
+#define SK_RX_BRAM_Q 2 /* big receive queue */
+#define SK_TX_RAM_Q 3 /* small or big transmit queue */
+
+/* parameter 'Dir' when calling SkGeStopPort() */
+#define SK_STOP_TX 1 /* Stops the transmit path, resets the XMAC */
+#define SK_STOP_RX 2 /* Stops the receive path */
+#define SK_STOP_ALL 3 /* Stops Rx and Tx path, resets the XMAC */
+
+/* parameter 'RstMode' when calling SkGeStopPort() */
+#define SK_SOFT_RST 1 /* perform a software reset */
+#define SK_HARD_RST 2 /* perform a hardware reset */
+
+/* Init Levels */
+#define SK_INIT_DATA 0 /* Init level 0: init data structures */
+#define SK_INIT_IO 1 /* Init level 1: init with IOs */
+#define SK_INIT_RUN 2 /* Init level 2: init for run time */
+
+/* Link Mode Parameter */
+#define SK_LMODE_HALF 1 /* Half Duplex Mode */
+#define SK_LMODE_FULL 2 /* Full Duplex Mode */
+#define SK_LMODE_AUTOHALF 3 /* AutoHalf Duplex Mode */
+#define SK_LMODE_AUTOFULL 4 /* AutoFull Duplex Mode */
+#define SK_LMODE_AUTOBOTH 5 /* AutoBoth Duplex Mode */
+#define SK_LMODE_AUTOSENSE 6 /* configured mode auto sensing */
+#define SK_LMODE_INDETERMINATED 7 /* indeterminated */
+
+/* Auto-negotiation timeout in 100ms granularity */
+#define SK_AND_MAX_TO 6 /* Wait 600 msec before link comes up */
+
+/* Auto-negotiation error codes */
+#define SK_AND_OK 0 /* no error */
+#define SK_AND_OTHER 1 /* other error than below */
+#define SK_AND_DUP_CAP 2 /* Duplex capabilities error */
+
+
+/* Link Speed Capabilities */
+#define SK_LSPEED_CAP_AUTO (1<<0) /* Automatic resolution */
+#define SK_LSPEED_CAP_10MBPS (1<<1) /* 10 Mbps */
+#define SK_LSPEED_CAP_100MBPS (1<<2) /* 100 Mbps */
+#define SK_LSPEED_CAP_1000MBPS (1<<3) /* 1000 Mbps */
+#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* indeterminated */
+
+/* Link Speed Parameter */
+#define SK_LSPEED_AUTO 1 /* Automatic resolution */
+#define SK_LSPEED_10MBPS 2 /* 10 Mbps */
+#define SK_LSPEED_100MBPS 3 /* 100 Mbps */
+#define SK_LSPEED_1000MBPS 4 /* 1000 Mbps */
+#define SK_LSPEED_INDETERMINATED 5 /* indeterminated */
+
+/* Link Speed Current State */
+#define SK_LSPEED_STAT_UNKNOWN 1
+#define SK_LSPEED_STAT_10MBPS 2
+#define SK_LSPEED_STAT_100MBPS 3
+#define SK_LSPEED_STAT_1000MBPS 4
+#define SK_LSPEED_STAT_INDETERMINATED 5
+
+
+/* Link Capability Parameter */
+#define SK_LMODE_CAP_HALF (1<<0) /* Half Duplex Mode */
+#define SK_LMODE_CAP_FULL (1<<1) /* Full Duplex Mode */
+#define SK_LMODE_CAP_AUTOHALF (1<<2) /* AutoHalf Duplex Mode */
+#define SK_LMODE_CAP_AUTOFULL (1<<3) /* AutoFull Duplex Mode */
+#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* indeterminated */
+
+/* Link Mode Current State */
+#define SK_LMODE_STAT_UNKNOWN 1 /* Unknown Duplex Mode */
+#define SK_LMODE_STAT_HALF 2 /* Half Duplex Mode */
+#define SK_LMODE_STAT_FULL 3 /* Full Duplex Mode */
+#define SK_LMODE_STAT_AUTOHALF 4 /* Half Duplex Mode obtained by Auto-Neg */
+#define SK_LMODE_STAT_AUTOFULL 5 /* Full Duplex Mode obtained by Auto-Neg */
+#define SK_LMODE_STAT_INDETERMINATED 6 /* indeterminated */
+
+/* Flow Control Mode Parameter (and capabilities) */
+#define SK_FLOW_MODE_NONE 1 /* No Flow-Control */
+#define SK_FLOW_MODE_LOC_SEND 2 /* Local station sends PAUSE */
+#define SK_FLOW_MODE_SYMMETRIC 3 /* Both stations may send PAUSE */
+#define SK_FLOW_MODE_SYM_OR_REM 4 /* Both stations may send PAUSE or
+ * just the remote station may send PAUSE
+ */
+#define SK_FLOW_MODE_INDETERMINATED 5 /* indeterminated */
+
+/* Flow Control Status Parameter */
+#define SK_FLOW_STAT_NONE 1 /* No Flow Control */
+#define SK_FLOW_STAT_REM_SEND 2 /* Remote Station sends PAUSE */
+#define SK_FLOW_STAT_LOC_SEND 3 /* Local station sends PAUSE */
+#define SK_FLOW_STAT_SYMMETRIC 4 /* Both station may send PAUSE */
+#define SK_FLOW_STAT_INDETERMINATED 5 /* indeterminated */
+
+/* Master/Slave Mode Capabilities */
+#define SK_MS_CAP_AUTO (1<<0) /* Automatic resolution */
+#define SK_MS_CAP_MASTER (1<<1) /* This station is master */
+#define SK_MS_CAP_SLAVE (1<<2) /* This station is slave */
+#define SK_MS_CAP_INDETERMINATED (1<<3) /* indeterminated */
+
+/* Set Master/Slave Mode Parameter (and capabilities) */
+#define SK_MS_MODE_AUTO 1 /* Automatic resolution */
+#define SK_MS_MODE_MASTER 2 /* This station is master */
+#define SK_MS_MODE_SLAVE 3 /* This station is slave */
+#define SK_MS_MODE_INDETERMINATED 4 /* indeterminated */
+
+/* Master/Slave Status Parameter */
+#define SK_MS_STAT_UNSET 1 /* The M/S status is not set */
+#define SK_MS_STAT_MASTER 2 /* This station is master */
+#define SK_MS_STAT_SLAVE 3 /* This station is slave */
+#define SK_MS_STAT_FAULT 4 /* M/S resolution failed */
+#define SK_MS_STAT_INDETERMINATED 5 /* indeterminated */
+
+/* parameter 'Mode' when calling SkXmSetRxCmd() */
+#define SK_STRIP_FCS_ON (1<<0) /* Enable FCS stripping of Rx frames */
+#define SK_STRIP_FCS_OFF (1<<1) /* Disable FCS stripping of Rx frames */
+#define SK_STRIP_PAD_ON (1<<2) /* Enable pad byte stripping of Rx fr */
+#define SK_STRIP_PAD_OFF (1<<3) /* Disable pad byte stripping of Rx fr */
+#define SK_LENERR_OK_ON (1<<4) /* Don't chk fr for in range len error */
+#define SK_LENERR_OK_OFF (1<<5) /* Check frames for in range len error */
+#define SK_BIG_PK_OK_ON (1<<6) /* Don't set Rx Error bit for big frames */
+#define SK_BIG_PK_OK_OFF (1<<7) /* Set Rx Error bit for big frames */
+#define SK_SELF_RX_ON (1<<8) /* Enable Rx of own packets */
+#define SK_SELF_RX_OFF (1<<9) /* Disable Rx of own packets */
+
+/* parameter 'Para' when calling SkMacSetRxTxEn() */
+#define SK_MAC_LOOPB_ON (1<<0) /* Enable MAC Loopback Mode */
+#define SK_MAC_LOOPB_OFF (1<<1) /* Disable MAC Loopback Mode */
+#define SK_PHY_LOOPB_ON (1<<2) /* Enable PHY Loopback Mode */
+#define SK_PHY_LOOPB_OFF (1<<3) /* Disable PHY Loopback Mode */
+#define SK_PHY_FULLD_ON (1<<4) /* Enable GMII Full Duplex */
+#define SK_PHY_FULLD_OFF (1<<5) /* Disable GMII Full Duplex */
+
+/* States of PState */
+#define SK_PRT_RESET 0 /* the port is reset */
+#define SK_PRT_STOP 1 /* the port is stopped (similar to SW reset) */
+#define SK_PRT_INIT 2 /* the port is initialized */
+#define SK_PRT_RUN 3 /* the port has an active link */
+
+/* PHY power down modes */
+#define PHY_PM_OPERATIONAL_MODE 0 /* PHY operational mode */
+#define PHY_PM_DEEP_SLEEP 1 /* coma mode --> minimal power */
+#define PHY_PM_IEEE_POWER_DOWN 2 /* IEEE 22.2.4.1.5 compl. power down */
+#define PHY_PM_ENERGY_DETECT 3 /* energy detect */
+#define PHY_PM_ENERGY_DETECT_PLUS 4 /* energy detect plus */
+
+/* Default receive frame limit for Workaround of XMAC Errata */
+#define SK_DEF_RX_WA_LIM SK_CONSTU64(100)
+
+/* values for GILedBlinkCtrl (LED Blink Control) */
+#define SK_ACT_LED_BLINK (1<<0) /* Active LED blinking */
+#define SK_DUP_LED_NORMAL (1<<1) /* Duplex LED normal */
+#define SK_LED_LINK100_ON (1<<2) /* Link 100M LED on */
+
+/* Link Partner Status */
+#define SK_LIPA_UNKNOWN 0 /* Link partner is in unknown state */
+#define SK_LIPA_MANUAL 1 /* Link partner is in detected manual state */
+#define SK_LIPA_AUTO 2 /* Link partner is in auto-negotiation state */
+
+/* Maximum Restarts before restart is ignored (3Com WA) */
+#define SK_MAX_LRESTART 3 /* Max. 3 times the link is restarted */
+
+/* Max. Auto-neg. timeouts before link detection in sense mode is reset */
+#define SK_MAX_ANEG_TO 10 /* Max. 10 times the sense mode is reset */
+
+/* structures *****************************************************************/
+
+/*
+ * MAC specific functions
+ */
+typedef struct s_GeMacFunc {
+ int (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
+ int (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
+ SK_U16 StatAddr, SK_U32 SK_FAR *pVal);
+ int (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port);
+ int (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port,
+ SK_U16 IStatus, SK_U64 SK_FAR *pVal);
+} SK_GEMACFUNC;
+
+/*
+ * Port Structure
+ */
+typedef struct s_GePort {
+#ifndef SK_DIAG
+ SK_TIMER PWaTimer; /* Workaround Timer */
+ SK_TIMER HalfDupChkTimer;
+#endif /* SK_DIAG */
+ SK_U32 PPrevShorts; /* Previous Short Counter checking */
+ SK_U32 PPrevFcs; /* Previous FCS Error Counter checking */
+ SK_U64 PPrevRx; /* Previous RxOk Counter checking */
+ SK_U64 PRxLim; /* Previous RxOk Counter checking */
+ SK_U64 LastOctets; /* For half duplex hang check */
+ int PLinkResCt; /* Link Restart Counter */
+ int PAutoNegTimeOut;/* Auto-negotiation timeout current value */
+ int PAutoNegTOCt; /* Auto-negotiation Timeout Counter */
+ int PRxQSize; /* Port Rx Queue Size in kB */
+ int PXSQSize; /* Port Synchronous Transmit Queue Size in kB */
+ int PXAQSize; /* Port Asynchronous Transmit Queue Size in kB */
+ SK_U32 PRxQRamStart; /* Receive Queue RAM Buffer Start Address */
+ SK_U32 PRxQRamEnd; /* Receive Queue RAM Buffer End Address */
+ SK_U32 PXsQRamStart; /* Sync Tx Queue RAM Buffer Start Address */
+ SK_U32 PXsQRamEnd; /* Sync Tx Queue RAM Buffer End Address */
+ SK_U32 PXaQRamStart; /* Async Tx Queue RAM Buffer Start Address */
+ SK_U32 PXaQRamEnd; /* Async Tx Queue RAM Buffer End Address */
+ SK_U32 PRxOverCnt; /* Receive Overflow Counter */
+ int PRxQOff; /* Rx Queue Address Offset */
+ int PXsQOff; /* Synchronous Tx Queue Address Offset */
+ int PXaQOff; /* Asynchronous Tx Queue Address Offset */
+ int PhyType; /* PHY used on this port */
+ int PState; /* Port status (reset, stop, init, run) */
+ SK_U16 PhyId1; /* PHY Id1 on this port */
+ SK_U16 PhyAddr; /* MDIO/MDC PHY address */
+ SK_U16 PIsave; /* Saved Interrupt status word */
+ SK_U16 PSsave; /* Saved PHY status word */
+ SK_U16 PGmANegAdv; /* Saved GPhy AutoNegAdvertisment register */
+ SK_BOOL PHWLinkUp; /* The hardware Link is up (wiring) */
+ SK_BOOL PLinkBroken; /* Is Link broken ? */
+ SK_BOOL PCheckPar; /* Do we check for parity errors ? */
+ SK_BOOL HalfDupTimerActive;
+ SK_U8 PLinkCap; /* Link Capabilities */
+ SK_U8 PLinkModeConf; /* Link Mode configured */
+ SK_U8 PLinkMode; /* Link Mode currently used */
+ SK_U8 PLinkModeStatus;/* Link Mode Status */
+ SK_U8 PLinkSpeedCap; /* Link Speed Capabilities(10/100/1000 Mbps) */
+ SK_U8 PLinkSpeed; /* configured Link Speed (10/100/1000 Mbps) */
+ SK_U8 PLinkSpeedUsed; /* current Link Speed (10/100/1000 Mbps) */
+ SK_U8 PFlowCtrlCap; /* Flow Control Capabilities */
+ SK_U8 PFlowCtrlMode; /* Flow Control Mode */
+ SK_U8 PFlowCtrlStatus;/* Flow Control Status */
+ SK_U8 PMSCap; /* Master/Slave Capabilities */
+ SK_U8 PMSMode; /* Master/Slave Mode */
+ SK_U8 PMSStatus; /* Master/Slave Status */
+ SK_BOOL PAutoNegFail; /* Auto-negotiation fail flag */
+ SK_U8 PLipaAutoNeg; /* Auto-negotiation possible with Link Partner */
+ SK_U8 PCableLen; /* Cable Length */
+ SK_U8 PMdiPairLen[4]; /* MDI[0..3] Pair Length */
+ SK_U8 PMdiPairSts[4]; /* MDI[0..3] Pair Diagnostic Status */
+ SK_U8 PPhyPowerState; /* PHY current power state */
+ int PMacColThres; /* MAC Collision Threshold */
+ int PMacJamLen; /* MAC Jam length */
+ int PMacJamIpgVal; /* MAC Jam IPG */
+ int PMacJamIpgData; /* MAC IPG Jam to Data */
+ int PMacIpgData; /* MAC Data IPG */
+ SK_BOOL PMacLimit4; /* reset collision counter and backoff algorithm */
+} SK_GEPORT;
+
+/*
+ * Gigabit Ethernet Initialization Struct
+ * (has to be included in the adapter context)
+ */
+typedef struct s_GeInit {
+ int GIChipId; /* Chip Identification Number */
+ int GIChipRev; /* Chip Revision Number */
+ SK_U8 GIPciHwRev; /* PCI HW Revision Number */
+ SK_BOOL GIGenesis; /* Genesis adapter ? */
+ SK_BOOL GIYukon; /* YUKON-A1/Bx chip */
+ SK_BOOL GIYukonLite; /* YUKON-Lite chip */
+ SK_BOOL GICopperType; /* Copper Type adapter ? */
+ SK_BOOL GIPciSlot64; /* 64-bit PCI Slot */
+ SK_BOOL GIPciClock66; /* 66 MHz PCI Clock */
+ SK_BOOL GIVauxAvail; /* VAUX available (YUKON) */
+ SK_BOOL GIYukon32Bit; /* 32-Bit YUKON adapter */
+ SK_U16 GILedBlinkCtrl; /* LED Blink Control */
+ int GIMacsFound; /* Number of MACs found on this adapter */
+ int GIMacType; /* MAC Type used on this adapter */
+ int GIHstClkFact; /* Host Clock Factor (62.5 / HstClk * 100) */
+ int GIPortUsage; /* Driver Port Usage */
+ int GILevel; /* Initialization Level completed */
+ int GIRamSize; /* The RAM size of the adapter in kB */
+ int GIWolOffs; /* WOL Register Offset (HW-Bug in Rev. A) */
+ SK_U32 GIRamOffs; /* RAM Address Offset for addr calculation */
+ SK_U32 GIPollTimerVal; /* Descr. Poll Timer Init Val (HstClk ticks) */
+ SK_U32 GIValIrqMask; /* Value for Interrupt Mask */
+ SK_U32 GITimeStampCnt; /* Time Stamp High Counter (YUKON only) */
+ SK_GEPORT GP[SK_MAX_MACS];/* Port Dependent Information */
+ SK_GEMACFUNC GIFunc; /* MAC depedent functions */
+} SK_GEINIT;
+
+/*
+ * Error numbers and messages for skxmac2.c and skgeinit.c
+ */
+#define SKERR_HWI_E001 (SK_ERRBASE_HWINIT)
+#define SKERR_HWI_E001MSG "SkXmClrExactAddr() has got illegal parameters"
+#define SKERR_HWI_E002 (SKERR_HWI_E001+1)
+#define SKERR_HWI_E002MSG "SkGeInit(): Level 1 call missing"
+#define SKERR_HWI_E003 (SKERR_HWI_E002+1)
+#define SKERR_HWI_E003MSG "SkGeInit() called with illegal init Level"
+#define SKERR_HWI_E004 (SKERR_HWI_E003+1)
+#define SKERR_HWI_E004MSG "SkGeInitPort(): Queue Size illegal configured"
+#define SKERR_HWI_E005 (SKERR_HWI_E004+1)
+#define SKERR_HWI_E005MSG "SkGeInitPort(): cannot init running ports"
+#define SKERR_HWI_E006 (SKERR_HWI_E005+1)
+#define SKERR_HWI_E006MSG "SkGeMacInit(): PState does not match HW state"
+#define SKERR_HWI_E007 (SKERR_HWI_E006+1)
+#define SKERR_HWI_E007MSG "SkXmInitDupMd() called with invalid Dup Mode"
+#define SKERR_HWI_E008 (SKERR_HWI_E007+1)
+#define SKERR_HWI_E008MSG "SkXmSetRxCmd() called with invalid Mode"
+#define SKERR_HWI_E009 (SKERR_HWI_E008+1)
+#define SKERR_HWI_E009MSG "SkGeCfgSync() called although PXSQSize zero"
+#define SKERR_HWI_E010 (SKERR_HWI_E009+1)
+#define SKERR_HWI_E010MSG "SkGeCfgSync() called with invalid parameters"
+#define SKERR_HWI_E011 (SKERR_HWI_E010+1)
+#define SKERR_HWI_E011MSG "SkGeInitPort(): Receive Queue Size too small"
+#define SKERR_HWI_E012 (SKERR_HWI_E011+1)
+#define SKERR_HWI_E012MSG "SkGeInitPort(): invalid Queue Size specified"
+#define SKERR_HWI_E013 (SKERR_HWI_E012+1)
+#define SKERR_HWI_E013MSG "SkGeInitPort(): cfg changed for running queue"
+#define SKERR_HWI_E014 (SKERR_HWI_E013+1)
+#define SKERR_HWI_E014MSG "SkGeInitPort(): unknown GIPortUsage specified"
+#define SKERR_HWI_E015 (SKERR_HWI_E014+1)
+#define SKERR_HWI_E015MSG "Illegal Link mode parameter"
+#define SKERR_HWI_E016 (SKERR_HWI_E015+1)
+#define SKERR_HWI_E016MSG "Illegal Flow control mode parameter"
+#define SKERR_HWI_E017 (SKERR_HWI_E016+1)
+#define SKERR_HWI_E017MSG "Illegal value specified for GIPollTimerVal"
+#define SKERR_HWI_E018 (SKERR_HWI_E017+1)
+#define SKERR_HWI_E018MSG "FATAL: SkGeStopPort() does not terminate (Tx)"
+#define SKERR_HWI_E019 (SKERR_HWI_E018+1)
+#define SKERR_HWI_E019MSG "Illegal Speed parameter"
+#define SKERR_HWI_E020 (SKERR_HWI_E019+1)
+#define SKERR_HWI_E020MSG "Illegal Master/Slave parameter"
+#define SKERR_HWI_E021 (SKERR_HWI_E020+1)
+#define SKERR_HWI_E021MSG "MacUpdateStats(): cannot update statistic counter"
+#define SKERR_HWI_E022 (SKERR_HWI_E021+1)
+#define SKERR_HWI_E022MSG "MacStatistic(): illegal statistic base address"
+#define SKERR_HWI_E023 (SKERR_HWI_E022+1)
+#define SKERR_HWI_E023MSG "SkGeInitPort(): Transmit Queue Size too small"
+#define SKERR_HWI_E024 (SKERR_HWI_E023+1)
+#define SKERR_HWI_E024MSG "FATAL: SkGeStopPort() does not terminate (Rx)"
+#define SKERR_HWI_E025 (SKERR_HWI_E024+1)
+#define SKERR_HWI_E025MSG ""
+
+/* function prototypes ********************************************************/
+
+#ifndef SK_KR_PROTO
+
+/*
+ * public functions in skgeinit.c
+ */
+extern void SkGePollRxD(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_BOOL PollRxD);
+
+extern void SkGePollTxD(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_BOOL PollTxD);
+
+extern void SkGeYellowLED(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int State);
+
+extern int SkGeCfgSync(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_U32 IntTime,
+ SK_U32 LimCount,
+ int SyncMode);
+
+extern void SkGeLoadLnkSyncCnt(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_U32 CntVal);
+
+extern void SkGeStopPort(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ int Dir,
+ int RstMode);
+
+extern int SkGeInit(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Level);
+
+extern void SkGeDeInit(
+ SK_AC *pAC,
+ SK_IOC IoC);
+
+extern int SkGeInitPort(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkGeXmitLED(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Led,
+ int Mode);
+
+extern void SkGeInitRamIface(
+ SK_AC *pAC,
+ SK_IOC IoC);
+
+extern int SkGeInitAssignRamToQueues(
+ SK_AC *pAC,
+ int ActivePort,
+ SK_BOOL DualNet);
+
+/*
+ * public functions in skxmac2.c
+ */
+extern void SkMacRxTxDisable(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkMacSoftRst(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkMacHardRst(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkMacClearRst(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkXmInitMac(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkGmInitMac(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkMacInitPhy(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_BOOL DoLoop);
+
+extern void SkMacIrqDisable(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkMacFlushTxFifo(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkMacFlushRxFifo(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkMacIrq(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern int SkMacAutoNegDone(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkMacAutoNegLipaPhy(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_U16 IStatus);
+
+extern void SkMacSetRxTxEn(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ int Para);
+
+extern int SkMacRxTxEnable(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkMacPromiscMode(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_BOOL Enable);
+
+extern void SkMacHashing(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_BOOL Enable);
+
+extern void SkXmPhyRead(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ int Addr,
+ SK_U16 SK_FAR *pVal);
+
+extern void SkXmPhyWrite(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ int Addr,
+ SK_U16 Val);
+
+extern void SkGmPhyRead(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ int Addr,
+ SK_U16 SK_FAR *pVal);
+
+extern void SkGmPhyWrite(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ int Addr,
+ SK_U16 Val);
+
+extern void SkXmClrExactAddr(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ int StartNum,
+ int StopNum);
+
+extern void SkXmInitDupMd(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkXmInitPauseMd(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+extern void SkXmAutoNegLipaXmac(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_U16 IStatus);
+
+extern int SkXmUpdateStats(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ unsigned int Port);
+
+extern int SkGmUpdateStats(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ unsigned int Port);
+
+extern int SkXmMacStatistic(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ unsigned int Port,
+ SK_U16 StatAddr,
+ SK_U32 SK_FAR *pVal);
+
+extern int SkGmMacStatistic(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ unsigned int Port,
+ SK_U16 StatAddr,
+ SK_U32 SK_FAR *pVal);
+
+extern int SkXmResetCounter(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ unsigned int Port);
+
+extern int SkGmResetCounter(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ unsigned int Port);
+
+extern int SkXmOverflowStatus(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ unsigned int Port,
+ SK_U16 IStatus,
+ SK_U64 SK_FAR *pStatus);
+
+extern int SkGmOverflowStatus(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ unsigned int Port,
+ SK_U16 MacStatus,
+ SK_U64 SK_FAR *pStatus);
+
+extern int SkGmCableDiagStatus(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_BOOL StartTest);
+
+extern int SkGmEnterLowPowerMode(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_U8 Mode);
+
+extern int SkGmLeaveLowPowerMode(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port);
+
+#ifdef SK_DIAG
+extern void SkGePhyRead(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ int Addr,
+ SK_U16 *pVal);
+
+extern void SkGePhyWrite(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ int Addr,
+ SK_U16 Val);
+
+extern void SkMacSetRxCmd(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ int Mode);
+extern void SkMacCrcGener(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_BOOL Enable);
+extern void SkMacTimeStamp(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_BOOL Enable);
+extern void SkXmSendCont(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Port,
+ SK_BOOL Enable);
+#endif /* SK_DIAG */
+
+#else /* SK_KR_PROTO */
+
+/*
+ * public functions in skgeinit.c
+ */
+extern void SkGePollRxD();
+extern void SkGePollTxD();
+extern void SkGeYellowLED();
+extern int SkGeCfgSync();
+extern void SkGeLoadLnkSyncCnt();
+extern void SkGeStopPort();
+extern int SkGeInit();
+extern void SkGeDeInit();
+extern int SkGeInitPort();
+extern void SkGeXmitLED();
+extern void SkGeInitRamIface();
+extern int SkGeInitAssignRamToQueues();
+
+/*
+ * public functions in skxmac2.c
+ */
+extern void SkMacRxTxDisable();
+extern void SkMacSoftRst();
+extern void SkMacHardRst();
+extern void SkMacClearRst();
+extern void SkMacInitPhy();
+extern int SkMacRxTxEnable();
+extern void SkMacPromiscMode();
+extern void SkMacHashing();
+extern void SkMacIrqDisable();
+extern void SkMacFlushTxFifo();
+extern void SkMacFlushRxFifo();
+extern void SkMacIrq();
+extern int SkMacAutoNegDone();
+extern void SkMacAutoNegLipaPhy();
+extern void SkMacSetRxTxEn();
+extern void SkXmInitMac();
+extern void SkXmPhyRead();
+extern void SkXmPhyWrite();
+extern void SkGmInitMac();
+extern void SkGmPhyRead();
+extern void SkGmPhyWrite();
+extern void SkXmClrExactAddr();
+extern void SkXmInitDupMd();
+extern void SkXmInitPauseMd();
+extern void SkXmAutoNegLipaXmac();
+extern int SkXmUpdateStats();
+extern int SkGmUpdateStats();
+extern int SkXmMacStatistic();
+extern int SkGmMacStatistic();
+extern int SkXmResetCounter();
+extern int SkGmResetCounter();
+extern int SkXmOverflowStatus();
+extern int SkGmOverflowStatus();
+extern int SkGmCableDiagStatus();
+extern int SkGmEnterLowPowerMode();
+extern int SkGmLeaveLowPowerMode();
+
+#ifdef SK_DIAG
+extern void SkGePhyRead();
+extern void SkGePhyWrite();
+extern void SkMacSetRxCmd();
+extern void SkMacCrcGener();
+extern void SkMacTimeStamp();
+extern void SkXmSendCont();
+#endif /* SK_DIAG */
+
+#endif /* SK_KR_PROTO */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INC_SKGEINIT_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnm2.h b/drivers/net/sk98lin/h/skgepnm2.h
new file mode 100644
index 000000000000..ddd304f1a48b
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgepnm2.h
@@ -0,0 +1,334 @@
+/*****************************************************************************
+ *
+ * Name: skgepnm2.h
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.36 $
+ * Date: $Date: 2003/05/23 12:45:13 $
+ * Purpose: Defines for Private Network Management Interface
+ *
+ ****************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef _SKGEPNM2_H_
+#define _SKGEPNM2_H_
+
+/*
+ * General definitions
+ */
+#define SK_PNMI_CHIPSET_XMAC 1 /* XMAC11800FP */
+#define SK_PNMI_CHIPSET_YUKON 2 /* YUKON */
+
+#define SK_PNMI_BUS_PCI 1 /* PCI bus*/
+
+/*
+ * Actions
+ */
+#define SK_PNMI_ACT_IDLE 1
+#define SK_PNMI_ACT_RESET 2
+#define SK_PNMI_ACT_SELFTEST 3
+#define SK_PNMI_ACT_RESETCNT 4
+
+/*
+ * VPD releated defines
+ */
+
+#define SK_PNMI_VPD_RW 1
+#define SK_PNMI_VPD_RO 2
+
+#define SK_PNMI_VPD_OK 0
+#define SK_PNMI_VPD_NOTFOUND 1
+#define SK_PNMI_VPD_CUT 2
+#define SK_PNMI_VPD_TIMEOUT 3
+#define SK_PNMI_VPD_FULL 4
+#define SK_PNMI_VPD_NOWRITE 5
+#define SK_PNMI_VPD_FATAL 6
+
+#define SK_PNMI_VPD_IGNORE 0
+#define SK_PNMI_VPD_CREATE 1
+#define SK_PNMI_VPD_DELETE 2
+
+
+/*
+ * RLMT related defines
+ */
+#define SK_PNMI_DEF_RLMT_CHG_THRES 240 /* 4 changes per minute */
+
+
+/*
+ * VCT internal status values
+ */
+#define SK_PNMI_VCT_PENDING 32
+#define SK_PNMI_VCT_TEST_DONE 64
+#define SK_PNMI_VCT_LINK 128
+
+/*
+ * Internal table definitions
+ */
+#define SK_PNMI_GET 0
+#define SK_PNMI_PRESET 1
+#define SK_PNMI_SET 2
+
+#define SK_PNMI_RO 0
+#define SK_PNMI_RW 1
+#define SK_PNMI_WO 2
+
+typedef struct s_OidTabEntry {
+ SK_U32 Id;
+ SK_U32 InstanceNo;
+ unsigned int StructSize;
+ unsigned int Offset;
+ int Access;
+ int (* Func)(SK_AC *pAc, SK_IOC pIo, int action,
+ SK_U32 Id, char* pBuf, unsigned int* pLen,
+ SK_U32 Instance, unsigned int TableIndex,
+ SK_U32 NetNumber);
+ SK_U16 Param;
+} SK_PNMI_TAB_ENTRY;
+
+
+/*
+ * Trap lengths
+ */
+#define SK_PNMI_TRAP_SIMPLE_LEN 17
+#define SK_PNMI_TRAP_SENSOR_LEN_BASE 46
+#define SK_PNMI_TRAP_RLMT_CHANGE_LEN 23
+#define SK_PNMI_TRAP_RLMT_PORT_LEN 23
+
+/*
+ * Number of MAC types supported
+ */
+#define SK_PNMI_MAC_TYPES (SK_MAC_GMAC + 1)
+
+/*
+ * MAC statistic data list (overall set for MAC types used)
+ */
+enum SK_MACSTATS {
+ SK_PNMI_HTX = 0,
+ SK_PNMI_HTX_OCTET,
+ SK_PNMI_HTX_OCTETHIGH = SK_PNMI_HTX_OCTET,
+ SK_PNMI_HTX_OCTETLOW,
+ SK_PNMI_HTX_BROADCAST,
+ SK_PNMI_HTX_MULTICAST,
+ SK_PNMI_HTX_UNICAST,
+ SK_PNMI_HTX_BURST,
+ SK_PNMI_HTX_PMACC,
+ SK_PNMI_HTX_MACC,
+ SK_PNMI_HTX_COL,
+ SK_PNMI_HTX_SINGLE_COL,
+ SK_PNMI_HTX_MULTI_COL,
+ SK_PNMI_HTX_EXCESS_COL,
+ SK_PNMI_HTX_LATE_COL,
+ SK_PNMI_HTX_DEFFERAL,
+ SK_PNMI_HTX_EXCESS_DEF,
+ SK_PNMI_HTX_UNDERRUN,
+ SK_PNMI_HTX_CARRIER,
+ SK_PNMI_HTX_UTILUNDER,
+ SK_PNMI_HTX_UTILOVER,
+ SK_PNMI_HTX_64,
+ SK_PNMI_HTX_127,
+ SK_PNMI_HTX_255,
+ SK_PNMI_HTX_511,
+ SK_PNMI_HTX_1023,
+ SK_PNMI_HTX_MAX,
+ SK_PNMI_HTX_LONGFRAMES,
+ SK_PNMI_HTX_SYNC,
+ SK_PNMI_HTX_SYNC_OCTET,
+ SK_PNMI_HTX_RESERVED,
+
+ SK_PNMI_HRX,
+ SK_PNMI_HRX_OCTET,
+ SK_PNMI_HRX_OCTETHIGH = SK_PNMI_HRX_OCTET,
+ SK_PNMI_HRX_OCTETLOW,
+ SK_PNMI_HRX_BADOCTET,
+ SK_PNMI_HRX_BADOCTETHIGH = SK_PNMI_HRX_BADOCTET,
+ SK_PNMI_HRX_BADOCTETLOW,
+ SK_PNMI_HRX_BROADCAST,
+ SK_PNMI_HRX_MULTICAST,
+ SK_PNMI_HRX_UNICAST,
+ SK_PNMI_HRX_PMACC,
+ SK_PNMI_HRX_MACC,
+ SK_PNMI_HRX_PMACC_ERR,
+ SK_PNMI_HRX_MACC_UNKWN,
+ SK_PNMI_HRX_BURST,
+ SK_PNMI_HRX_MISSED,
+ SK_PNMI_HRX_FRAMING,
+ SK_PNMI_HRX_UNDERSIZE,
+ SK_PNMI_HRX_OVERFLOW,
+ SK_PNMI_HRX_JABBER,
+ SK_PNMI_HRX_CARRIER,
+ SK_PNMI_HRX_IRLENGTH,
+ SK_PNMI_HRX_SYMBOL,
+ SK_PNMI_HRX_SHORTS,
+ SK_PNMI_HRX_RUNT,
+ SK_PNMI_HRX_TOO_LONG,
+ SK_PNMI_HRX_FCS,
+ SK_PNMI_HRX_CEXT,
+ SK_PNMI_HRX_UTILUNDER,
+ SK_PNMI_HRX_UTILOVER,
+ SK_PNMI_HRX_64,
+ SK_PNMI_HRX_127,
+ SK_PNMI_HRX_255,
+ SK_PNMI_HRX_511,
+ SK_PNMI_HRX_1023,
+ SK_PNMI_HRX_MAX,
+ SK_PNMI_HRX_LONGFRAMES,
+
+ SK_PNMI_HRX_RESERVED,
+
+ SK_PNMI_MAX_IDX /* NOTE: Ensure SK_PNMI_CNT_NO is set to this value */
+};
+
+/*
+ * MAC specific data
+ */
+typedef struct s_PnmiStatAddr {
+ SK_U16 Reg; /* MAC register containing the value */
+ SK_BOOL GetOffset; /* TRUE: Offset managed by PNMI (call GetStatVal())*/
+} SK_PNMI_STATADDR;
+
+
+/*
+ * SK_PNMI_STRUCT_DATA copy offset evaluation macros
+ */
+#define SK_PNMI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
+#define SK_PNMI_MAI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
+#define SK_PNMI_VPD_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_VPD *)0)->e))
+#define SK_PNMI_SEN_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_SENSOR *)0)->e))
+#define SK_PNMI_CHK_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CHECKSUM *)0)->e))
+#define SK_PNMI_STA_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STAT *)0)->e))
+#define SK_PNMI_CNF_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CONF *)0)->e))
+#define SK_PNMI_RLM_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT *)0)->e))
+#define SK_PNMI_MON_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT_MONITOR *)0)->e))
+#define SK_PNMI_TRP_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_TRAP *)0)->e))
+
+#define SK_PNMI_SET_STAT(b,s,o) {SK_U32 Val32; char *pVal; \
+ Val32 = (s); \
+ pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
+ &(((SK_PNMI_STRUCT_DATA *)0)-> \
+ ReturnStatus.ErrorStatus)); \
+ SK_PNMI_STORE_U32(pVal, Val32); \
+ Val32 = (o); \
+ pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
+ &(((SK_PNMI_STRUCT_DATA *)0)-> \
+ ReturnStatus.ErrorOffset)); \
+ SK_PNMI_STORE_U32(pVal, Val32);}
+
+/*
+ * Time macros
+ */
+#ifndef SK_PNMI_HUNDREDS_SEC
+#if SK_TICKS_PER_SEC == 100
+#define SK_PNMI_HUNDREDS_SEC(t) (t)
+#else
+#define SK_PNMI_HUNDREDS_SEC(t) (((t) * 100) / (SK_TICKS_PER_SEC))
+#endif /* !SK_TICKS_PER_SEC */
+#endif /* !SK_PNMI_HUNDREDS_SEC */
+
+/*
+ * Macros to work around alignment problems
+ */
+#ifndef SK_PNMI_STORE_U16
+#define SK_PNMI_STORE_U16(p,v) {*(char *)(p) = *((char *)&(v)); \
+ *((char *)(p) + 1) = \
+ *(((char *)&(v)) + 1);}
+#endif
+
+#ifndef SK_PNMI_STORE_U32
+#define SK_PNMI_STORE_U32(p,v) {*(char *)(p) = *((char *)&(v)); \
+ *((char *)(p) + 1) = \
+ *(((char *)&(v)) + 1); \
+ *((char *)(p) + 2) = \
+ *(((char *)&(v)) + 2); \
+ *((char *)(p) + 3) = \
+ *(((char *)&(v)) + 3);}
+#endif
+
+#ifndef SK_PNMI_STORE_U64
+#define SK_PNMI_STORE_U64(p,v) {*(char *)(p) = *((char *)&(v)); \
+ *((char *)(p) + 1) = \
+ *(((char *)&(v)) + 1); \
+ *((char *)(p) + 2) = \
+ *(((char *)&(v)) + 2); \
+ *((char *)(p) + 3) = \
+ *(((char *)&(v)) + 3); \
+ *((char *)(p) + 4) = \
+ *(((char *)&(v)) + 4); \
+ *((char *)(p) + 5) = \
+ *(((char *)&(v)) + 5); \
+ *((char *)(p) + 6) = \
+ *(((char *)&(v)) + 6); \
+ *((char *)(p) + 7) = \
+ *(((char *)&(v)) + 7);}
+#endif
+
+#ifndef SK_PNMI_READ_U16
+#define SK_PNMI_READ_U16(p,v) {*((char *)&(v)) = *(char *)(p); \
+ *(((char *)&(v)) + 1) = \
+ *((char *)(p) + 1);}
+#endif
+
+#ifndef SK_PNMI_READ_U32
+#define SK_PNMI_READ_U32(p,v) {*((char *)&(v)) = *(char *)(p); \
+ *(((char *)&(v)) + 1) = \
+ *((char *)(p) + 1); \
+ *(((char *)&(v)) + 2) = \
+ *((char *)(p) + 2); \
+ *(((char *)&(v)) + 3) = \
+ *((char *)(p) + 3);}
+#endif
+
+#ifndef SK_PNMI_READ_U64
+#define SK_PNMI_READ_U64(p,v) {*((char *)&(v)) = *(char *)(p); \
+ *(((char *)&(v)) + 1) = \
+ *((char *)(p) + 1); \
+ *(((char *)&(v)) + 2) = \
+ *((char *)(p) + 2); \
+ *(((char *)&(v)) + 3) = \
+ *((char *)(p) + 3); \
+ *(((char *)&(v)) + 4) = \
+ *((char *)(p) + 4); \
+ *(((char *)&(v)) + 5) = \
+ *((char *)(p) + 5); \
+ *(((char *)&(v)) + 6) = \
+ *((char *)(p) + 6); \
+ *(((char *)&(v)) + 7) = \
+ *((char *)(p) + 7);}
+#endif
+
+/*
+ * Macros for Debug
+ */
+#ifdef DEBUG
+
+#define SK_PNMI_CHECKFLAGS(vSt) {if (pAC->Pnmi.MacUpdatedFlag > 0 || \
+ pAC->Pnmi.RlmtUpdatedFlag > 0 || \
+ pAC->Pnmi.SirqUpdatedFlag > 0) { \
+ SK_DBG_MSG(pAC, \
+ SK_DBGMOD_PNMI, \
+ SK_DBGCAT_CTRL, \
+ ("PNMI: ERR: %s MacUFlag=%d, RlmtUFlag=%d, SirqUFlag=%d\n", \
+ vSt, \
+ pAC->Pnmi.MacUpdatedFlag, \
+ pAC->Pnmi.RlmtUpdatedFlag, \
+ pAC->Pnmi.SirqUpdatedFlag))}}
+
+#else /* !DEBUG */
+
+#define SK_PNMI_CHECKFLAGS(vSt) /* Nothing */
+
+#endif /* !DEBUG */
+
+#endif /* _SKGEPNM2_H_ */
diff --git a/drivers/net/sk98lin/h/skgepnmi.h b/drivers/net/sk98lin/h/skgepnmi.h
new file mode 100644
index 000000000000..3b2773e6f822
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgepnmi.h
@@ -0,0 +1,966 @@
+/*****************************************************************************
+ *
+ * Name: skgepnmi.h
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.62 $
+ * Date: $Date: 2003/08/15 12:31:52 $
+ * Purpose: Defines for Private Network Management Interface
+ *
+ ****************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef _SKGEPNMI_H_
+#define _SKGEPNMI_H_
+
+/*
+ * Include dependencies
+ */
+#include "h/sktypes.h"
+#include "h/skerror.h"
+#include "h/sktimer.h"
+#include "h/ski2c.h"
+#include "h/skaddr.h"
+#include "h/skrlmt.h"
+#include "h/skvpd.h"
+
+/*
+ * Management Database Version
+ */
+#define SK_PNMI_MDB_VERSION 0x00030001 /* 3.1 */
+
+
+/*
+ * Event definitions
+ */
+#define SK_PNMI_EVT_SIRQ_OVERFLOW 1 /* Counter overflow */
+#define SK_PNMI_EVT_SEN_WAR_LOW 2 /* Lower war thres exceeded */
+#define SK_PNMI_EVT_SEN_WAR_UPP 3 /* Upper war thres exceeded */
+#define SK_PNMI_EVT_SEN_ERR_LOW 4 /* Lower err thres exceeded */
+#define SK_PNMI_EVT_SEN_ERR_UPP 5 /* Upper err thres exceeded */
+#define SK_PNMI_EVT_CHG_EST_TIMER 6 /* Timer event for RLMT Chg */
+#define SK_PNMI_EVT_UTILIZATION_TIMER 7 /* Timer event for Utiliza. */
+#define SK_PNMI_EVT_CLEAR_COUNTER 8 /* Clear statistic counters */
+#define SK_PNMI_EVT_XMAC_RESET 9 /* XMAC will be reset */
+
+#define SK_PNMI_EVT_RLMT_PORT_UP 10 /* Port came logically up */
+#define SK_PNMI_EVT_RLMT_PORT_DOWN 11 /* Port went logically down */
+#define SK_PNMI_EVT_RLMT_SEGMENTATION 13 /* Two SP root bridges found */
+#define SK_PNMI_EVT_RLMT_ACTIVE_DOWN 14 /* Port went logically down */
+#define SK_PNMI_EVT_RLMT_ACTIVE_UP 15 /* Port came logically up */
+#define SK_PNMI_EVT_RLMT_SET_NETS 16 /* 1. Parameter is number of nets
+ 1 = single net; 2 = dual net */
+#define SK_PNMI_EVT_VCT_RESET 17 /* VCT port reset timer event started with SET. */
+
+
+/*
+ * Return values
+ */
+#define SK_PNMI_ERR_OK 0
+#define SK_PNMI_ERR_GENERAL 1
+#define SK_PNMI_ERR_TOO_SHORT 2
+#define SK_PNMI_ERR_BAD_VALUE 3
+#define SK_PNMI_ERR_READ_ONLY 4
+#define SK_PNMI_ERR_UNKNOWN_OID 5
+#define SK_PNMI_ERR_UNKNOWN_INST 6
+#define SK_PNMI_ERR_UNKNOWN_NET 7
+#define SK_PNMI_ERR_NOT_SUPPORTED 10
+
+
+/*
+ * Return values of driver reset function SK_DRIVER_RESET() and
+ * driver event function SK_DRIVER_EVENT()
+ */
+#define SK_PNMI_ERR_OK 0
+#define SK_PNMI_ERR_FAIL 1
+
+
+/*
+ * Return values of driver test function SK_DRIVER_SELFTEST()
+ */
+#define SK_PNMI_TST_UNKNOWN (1 << 0)
+#define SK_PNMI_TST_TRANCEIVER (1 << 1)
+#define SK_PNMI_TST_ASIC (1 << 2)
+#define SK_PNMI_TST_SENSOR (1 << 3)
+#define SK_PNMI_TST_POWERMGMT (1 << 4)
+#define SK_PNMI_TST_PCI (1 << 5)
+#define SK_PNMI_TST_MAC (1 << 6)
+
+
+/*
+ * RLMT specific definitions
+ */
+#define SK_PNMI_RLMT_STATUS_STANDBY 1
+#define SK_PNMI_RLMT_STATUS_ACTIVE 2
+#define SK_PNMI_RLMT_STATUS_ERROR 3
+
+#define SK_PNMI_RLMT_LSTAT_PHY_DOWN 1
+#define SK_PNMI_RLMT_LSTAT_AUTONEG 2
+#define SK_PNMI_RLMT_LSTAT_LOG_DOWN 3
+#define SK_PNMI_RLMT_LSTAT_LOG_UP 4
+#define SK_PNMI_RLMT_LSTAT_INDETERMINATED 5
+
+#define SK_PNMI_RLMT_MODE_CHK_LINK (SK_RLMT_CHECK_LINK)
+#define SK_PNMI_RLMT_MODE_CHK_RX (SK_RLMT_CHECK_LOC_LINK)
+#define SK_PNMI_RLMT_MODE_CHK_SPT (SK_RLMT_CHECK_SEG)
+/* #define SK_PNMI_RLMT_MODE_CHK_EX */
+
+/*
+ * OID definition
+ */
+#ifndef _NDIS_ /* Check, whether NDIS already included OIDs */
+
+#define OID_GEN_XMIT_OK 0x00020101
+#define OID_GEN_RCV_OK 0x00020102
+#define OID_GEN_XMIT_ERROR 0x00020103
+#define OID_GEN_RCV_ERROR 0x00020104
+#define OID_GEN_RCV_NO_BUFFER 0x00020105
+
+/* #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 */
+#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
+/* #define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 */
+#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
+/* #define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 */
+#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
+/* #define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 */
+#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
+/* #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 */
+#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
+/* #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B */
+#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
+#define OID_GEN_RCV_CRC_ERROR 0x0002020D
+#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
+
+#define OID_802_3_PERMANENT_ADDRESS 0x01010101
+#define OID_802_3_CURRENT_ADDRESS 0x01010102
+/* #define OID_802_3_MULTICAST_LIST 0x01010103 */
+/* #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 */
+/* #define OID_802_3_MAC_OPTIONS 0x01010105 */
+
+#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
+#define OID_802_3_XMIT_ONE_COLLISION 0x01020102
+#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
+#define OID_802_3_XMIT_DEFERRED 0x01020201
+#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
+#define OID_802_3_RCV_OVERRUN 0x01020203
+#define OID_802_3_XMIT_UNDERRUN 0x01020204
+#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
+#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
+
+/*
+ * PnP and PM OIDs
+ */
+#ifdef SK_POWER_MGMT
+#define OID_PNP_CAPABILITIES 0xFD010100
+#define OID_PNP_SET_POWER 0xFD010101
+#define OID_PNP_QUERY_POWER 0xFD010102
+#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103
+#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104
+#define OID_PNP_ENABLE_WAKE_UP 0xFD010106
+#endif /* SK_POWER_MGMT */
+
+#endif /* _NDIS_ */
+
+#define OID_SKGE_MDB_VERSION 0xFF010100
+#define OID_SKGE_SUPPORTED_LIST 0xFF010101
+#define OID_SKGE_VPD_FREE_BYTES 0xFF010102
+#define OID_SKGE_VPD_ENTRIES_LIST 0xFF010103
+#define OID_SKGE_VPD_ENTRIES_NUMBER 0xFF010104
+#define OID_SKGE_VPD_KEY 0xFF010105
+#define OID_SKGE_VPD_VALUE 0xFF010106
+#define OID_SKGE_VPD_ACCESS 0xFF010107
+#define OID_SKGE_VPD_ACTION 0xFF010108
+
+#define OID_SKGE_PORT_NUMBER 0xFF010110
+#define OID_SKGE_DEVICE_TYPE 0xFF010111
+#define OID_SKGE_DRIVER_DESCR 0xFF010112
+#define OID_SKGE_DRIVER_VERSION 0xFF010113
+#define OID_SKGE_HW_DESCR 0xFF010114
+#define OID_SKGE_HW_VERSION 0xFF010115
+#define OID_SKGE_CHIPSET 0xFF010116
+#define OID_SKGE_ACTION 0xFF010117
+#define OID_SKGE_RESULT 0xFF010118
+#define OID_SKGE_BUS_TYPE 0xFF010119
+#define OID_SKGE_BUS_SPEED 0xFF01011A
+#define OID_SKGE_BUS_WIDTH 0xFF01011B
+/* 0xFF01011C unused */
+#define OID_SKGE_DIAG_ACTION 0xFF01011D
+#define OID_SKGE_DIAG_RESULT 0xFF01011E
+#define OID_SKGE_MTU 0xFF01011F
+#define OID_SKGE_PHYS_CUR_ADDR 0xFF010120
+#define OID_SKGE_PHYS_FAC_ADDR 0xFF010121
+#define OID_SKGE_PMD 0xFF010122
+#define OID_SKGE_CONNECTOR 0xFF010123
+#define OID_SKGE_LINK_CAP 0xFF010124
+#define OID_SKGE_LINK_MODE 0xFF010125
+#define OID_SKGE_LINK_MODE_STATUS 0xFF010126
+#define OID_SKGE_LINK_STATUS 0xFF010127
+#define OID_SKGE_FLOWCTRL_CAP 0xFF010128
+#define OID_SKGE_FLOWCTRL_MODE 0xFF010129
+#define OID_SKGE_FLOWCTRL_STATUS 0xFF01012A
+#define OID_SKGE_PHY_OPERATION_CAP 0xFF01012B
+#define OID_SKGE_PHY_OPERATION_MODE 0xFF01012C
+#define OID_SKGE_PHY_OPERATION_STATUS 0xFF01012D
+#define OID_SKGE_MULTICAST_LIST 0xFF01012E
+#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F
+
+#define OID_SKGE_TRAP 0xFF010130
+#define OID_SKGE_TRAP_NUMBER 0xFF010131
+
+#define OID_SKGE_RLMT_MODE 0xFF010140
+#define OID_SKGE_RLMT_PORT_NUMBER 0xFF010141
+#define OID_SKGE_RLMT_PORT_ACTIVE 0xFF010142
+#define OID_SKGE_RLMT_PORT_PREFERRED 0xFF010143
+#define OID_SKGE_INTERMEDIATE_SUPPORT 0xFF010160
+
+#define OID_SKGE_SPEED_CAP 0xFF010170
+#define OID_SKGE_SPEED_MODE 0xFF010171
+#define OID_SKGE_SPEED_STATUS 0xFF010172
+
+#define OID_SKGE_BOARDLEVEL 0xFF010180
+
+#define OID_SKGE_SENSOR_NUMBER 0xFF020100
+#define OID_SKGE_SENSOR_INDEX 0xFF020101
+#define OID_SKGE_SENSOR_DESCR 0xFF020102
+#define OID_SKGE_SENSOR_TYPE 0xFF020103
+#define OID_SKGE_SENSOR_VALUE 0xFF020104
+#define OID_SKGE_SENSOR_WAR_THRES_LOW 0xFF020105
+#define OID_SKGE_SENSOR_WAR_THRES_UPP 0xFF020106
+#define OID_SKGE_SENSOR_ERR_THRES_LOW 0xFF020107
+#define OID_SKGE_SENSOR_ERR_THRES_UPP 0xFF020108
+#define OID_SKGE_SENSOR_STATUS 0xFF020109
+#define OID_SKGE_SENSOR_WAR_CTS 0xFF02010A
+#define OID_SKGE_SENSOR_ERR_CTS 0xFF02010B
+#define OID_SKGE_SENSOR_WAR_TIME 0xFF02010C
+#define OID_SKGE_SENSOR_ERR_TIME 0xFF02010D
+
+#define OID_SKGE_CHKSM_NUMBER 0xFF020110
+#define OID_SKGE_CHKSM_RX_OK_CTS 0xFF020111
+#define OID_SKGE_CHKSM_RX_UNABLE_CTS 0xFF020112
+#define OID_SKGE_CHKSM_RX_ERR_CTS 0xFF020113
+#define OID_SKGE_CHKSM_TX_OK_CTS 0xFF020114
+#define OID_SKGE_CHKSM_TX_UNABLE_CTS 0xFF020115
+
+#define OID_SKGE_STAT_TX 0xFF020120
+#define OID_SKGE_STAT_TX_OCTETS 0xFF020121
+#define OID_SKGE_STAT_TX_BROADCAST 0xFF020122
+#define OID_SKGE_STAT_TX_MULTICAST 0xFF020123
+#define OID_SKGE_STAT_TX_UNICAST 0xFF020124
+#define OID_SKGE_STAT_TX_LONGFRAMES 0xFF020125
+#define OID_SKGE_STAT_TX_BURST 0xFF020126
+#define OID_SKGE_STAT_TX_PFLOWC 0xFF020127
+#define OID_SKGE_STAT_TX_FLOWC 0xFF020128
+#define OID_SKGE_STAT_TX_SINGLE_COL 0xFF020129
+#define OID_SKGE_STAT_TX_MULTI_COL 0xFF02012A
+#define OID_SKGE_STAT_TX_EXCESS_COL 0xFF02012B
+#define OID_SKGE_STAT_TX_LATE_COL 0xFF02012C
+#define OID_SKGE_STAT_TX_DEFFERAL 0xFF02012D
+#define OID_SKGE_STAT_TX_EXCESS_DEF 0xFF02012E
+#define OID_SKGE_STAT_TX_UNDERRUN 0xFF02012F
+#define OID_SKGE_STAT_TX_CARRIER 0xFF020130
+/* #define OID_SKGE_STAT_TX_UTIL 0xFF020131 */
+#define OID_SKGE_STAT_TX_64 0xFF020132
+#define OID_SKGE_STAT_TX_127 0xFF020133
+#define OID_SKGE_STAT_TX_255 0xFF020134
+#define OID_SKGE_STAT_TX_511 0xFF020135
+#define OID_SKGE_STAT_TX_1023 0xFF020136
+#define OID_SKGE_STAT_TX_MAX 0xFF020137
+#define OID_SKGE_STAT_TX_SYNC 0xFF020138
+#define OID_SKGE_STAT_TX_SYNC_OCTETS 0xFF020139
+#define OID_SKGE_STAT_RX 0xFF02013A
+#define OID_SKGE_STAT_RX_OCTETS 0xFF02013B
+#define OID_SKGE_STAT_RX_BROADCAST 0xFF02013C
+#define OID_SKGE_STAT_RX_MULTICAST 0xFF02013D
+#define OID_SKGE_STAT_RX_UNICAST 0xFF02013E
+#define OID_SKGE_STAT_RX_PFLOWC 0xFF02013F
+#define OID_SKGE_STAT_RX_FLOWC 0xFF020140
+#define OID_SKGE_STAT_RX_PFLOWC_ERR 0xFF020141
+#define OID_SKGE_STAT_RX_FLOWC_UNKWN 0xFF020142
+#define OID_SKGE_STAT_RX_BURST 0xFF020143
+#define OID_SKGE_STAT_RX_MISSED 0xFF020144
+#define OID_SKGE_STAT_RX_FRAMING 0xFF020145
+#define OID_SKGE_STAT_RX_OVERFLOW 0xFF020146
+#define OID_SKGE_STAT_RX_JABBER 0xFF020147
+#define OID_SKGE_STAT_RX_CARRIER 0xFF020148
+#define OID_SKGE_STAT_RX_IR_LENGTH 0xFF020149
+#define OID_SKGE_STAT_RX_SYMBOL 0xFF02014A
+#define OID_SKGE_STAT_RX_SHORTS 0xFF02014B
+#define OID_SKGE_STAT_RX_RUNT 0xFF02014C
+#define OID_SKGE_STAT_RX_CEXT 0xFF02014D
+#define OID_SKGE_STAT_RX_TOO_LONG 0xFF02014E
+#define OID_SKGE_STAT_RX_FCS 0xFF02014F
+/* #define OID_SKGE_STAT_RX_UTIL 0xFF020150 */
+#define OID_SKGE_STAT_RX_64 0xFF020151
+#define OID_SKGE_STAT_RX_127 0xFF020152
+#define OID_SKGE_STAT_RX_255 0xFF020153
+#define OID_SKGE_STAT_RX_511 0xFF020154
+#define OID_SKGE_STAT_RX_1023 0xFF020155
+#define OID_SKGE_STAT_RX_MAX 0xFF020156
+#define OID_SKGE_STAT_RX_LONGFRAMES 0xFF020157
+
+#define OID_SKGE_RLMT_CHANGE_CTS 0xFF020160
+#define OID_SKGE_RLMT_CHANGE_TIME 0xFF020161
+#define OID_SKGE_RLMT_CHANGE_ESTIM 0xFF020162
+#define OID_SKGE_RLMT_CHANGE_THRES 0xFF020163
+
+#define OID_SKGE_RLMT_PORT_INDEX 0xFF020164
+#define OID_SKGE_RLMT_STATUS 0xFF020165
+#define OID_SKGE_RLMT_TX_HELLO_CTS 0xFF020166
+#define OID_SKGE_RLMT_RX_HELLO_CTS 0xFF020167
+#define OID_SKGE_RLMT_TX_SP_REQ_CTS 0xFF020168
+#define OID_SKGE_RLMT_RX_SP_CTS 0xFF020169
+
+#define OID_SKGE_RLMT_MONITOR_NUMBER 0xFF010150
+#define OID_SKGE_RLMT_MONITOR_INDEX 0xFF010151
+#define OID_SKGE_RLMT_MONITOR_ADDR 0xFF010152
+#define OID_SKGE_RLMT_MONITOR_ERRS 0xFF010153
+#define OID_SKGE_RLMT_MONITOR_TIMESTAMP 0xFF010154
+#define OID_SKGE_RLMT_MONITOR_ADMIN 0xFF010155
+
+#define OID_SKGE_TX_SW_QUEUE_LEN 0xFF020170
+#define OID_SKGE_TX_SW_QUEUE_MAX 0xFF020171
+#define OID_SKGE_TX_RETRY 0xFF020172
+#define OID_SKGE_RX_INTR_CTS 0xFF020173
+#define OID_SKGE_TX_INTR_CTS 0xFF020174
+#define OID_SKGE_RX_NO_BUF_CTS 0xFF020175
+#define OID_SKGE_TX_NO_BUF_CTS 0xFF020176
+#define OID_SKGE_TX_USED_DESCR_NO 0xFF020177
+#define OID_SKGE_RX_DELIVERED_CTS 0xFF020178
+#define OID_SKGE_RX_OCTETS_DELIV_CTS 0xFF020179
+#define OID_SKGE_RX_HW_ERROR_CTS 0xFF02017A
+#define OID_SKGE_TX_HW_ERROR_CTS 0xFF02017B
+#define OID_SKGE_IN_ERRORS_CTS 0xFF02017C
+#define OID_SKGE_OUT_ERROR_CTS 0xFF02017D
+#define OID_SKGE_ERR_RECOVERY_CTS 0xFF02017E
+#define OID_SKGE_SYSUPTIME 0xFF02017F
+
+#define OID_SKGE_ALL_DATA 0xFF020190
+
+/* Defines for VCT. */
+#define OID_SKGE_VCT_GET 0xFF020200
+#define OID_SKGE_VCT_SET 0xFF020201
+#define OID_SKGE_VCT_STATUS 0xFF020202
+
+#ifdef SK_DIAG_SUPPORT
+/* Defines for driver DIAG mode. */
+#define OID_SKGE_DIAG_MODE 0xFF020204
+#endif /* SK_DIAG_SUPPORT */
+
+/* New OIDs */
+#define OID_SKGE_DRIVER_RELDATE 0xFF020210
+#define OID_SKGE_DRIVER_FILENAME 0xFF020211
+#define OID_SKGE_CHIPID 0xFF020212
+#define OID_SKGE_RAMSIZE 0xFF020213
+#define OID_SKGE_VAUXAVAIL 0xFF020214
+#define OID_SKGE_PHY_TYPE 0xFF020215
+#define OID_SKGE_PHY_LP_MODE 0xFF020216
+
+/* VCT struct to store a backup copy of VCT data after a port reset. */
+typedef struct s_PnmiVct {
+ SK_U8 VctStatus;
+ SK_U8 PCableLen;
+ SK_U32 PMdiPairLen[4];
+ SK_U8 PMdiPairSts[4];
+} SK_PNMI_VCT;
+
+
+/* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */
+#define SK_PNMI_VCT_NONE 0
+#define SK_PNMI_VCT_OLD_VCT_DATA 1
+#define SK_PNMI_VCT_NEW_VCT_DATA 2
+#define SK_PNMI_VCT_OLD_DSP_DATA 4
+#define SK_PNMI_VCT_NEW_DSP_DATA 8
+#define SK_PNMI_VCT_RUNNING 16
+
+
+/* VCT cable test status. */
+#define SK_PNMI_VCT_NORMAL_CABLE 0
+#define SK_PNMI_VCT_SHORT_CABLE 1
+#define SK_PNMI_VCT_OPEN_CABLE 2
+#define SK_PNMI_VCT_TEST_FAIL 3
+#define SK_PNMI_VCT_IMPEDANCE_MISMATCH 4
+
+#define OID_SKGE_TRAP_SEN_WAR_LOW 500
+#define OID_SKGE_TRAP_SEN_WAR_UPP 501
+#define OID_SKGE_TRAP_SEN_ERR_LOW 502
+#define OID_SKGE_TRAP_SEN_ERR_UPP 503
+#define OID_SKGE_TRAP_RLMT_CHANGE_THRES 520
+#define OID_SKGE_TRAP_RLMT_CHANGE_PORT 521
+#define OID_SKGE_TRAP_RLMT_PORT_DOWN 522
+#define OID_SKGE_TRAP_RLMT_PORT_UP 523
+#define OID_SKGE_TRAP_RLMT_SEGMENTATION 524
+
+#ifdef SK_DIAG_SUPPORT
+/* Defines for driver DIAG mode. */
+#define SK_DIAG_ATTACHED 2
+#define SK_DIAG_RUNNING 1
+#define SK_DIAG_IDLE 0
+#endif /* SK_DIAG_SUPPORT */
+
+/*
+ * Generic PNMI IOCTL subcommand definitions.
+ */
+#define SK_GET_SINGLE_VAR 1
+#define SK_SET_SINGLE_VAR 2
+#define SK_PRESET_SINGLE_VAR 3
+#define SK_GET_FULL_MIB 4
+#define SK_SET_FULL_MIB 5
+#define SK_PRESET_FULL_MIB 6
+
+
+/*
+ * Define error numbers and messages for syslog
+ */
+#define SK_PNMI_ERR001 (SK_ERRBASE_PNMI + 1)
+#define SK_PNMI_ERR001MSG "SkPnmiGetStruct: Unknown OID"
+#define SK_PNMI_ERR002 (SK_ERRBASE_PNMI + 2)
+#define SK_PNMI_ERR002MSG "SkPnmiGetStruct: Cannot read VPD keys"
+#define SK_PNMI_ERR003 (SK_ERRBASE_PNMI + 3)
+#define SK_PNMI_ERR003MSG "OidStruct: Called with wrong OID"
+#define SK_PNMI_ERR004 (SK_ERRBASE_PNMI + 4)
+#define SK_PNMI_ERR004MSG "OidStruct: Called with wrong action"
+#define SK_PNMI_ERR005 (SK_ERRBASE_PNMI + 5)
+#define SK_PNMI_ERR005MSG "Perform: Cannot reset driver"
+#define SK_PNMI_ERR006 (SK_ERRBASE_PNMI + 6)
+#define SK_PNMI_ERR006MSG "Perform: Unknown OID action command"
+#define SK_PNMI_ERR007 (SK_ERRBASE_PNMI + 7)
+#define SK_PNMI_ERR007MSG "General: Driver description not initialized"
+#define SK_PNMI_ERR008 (SK_ERRBASE_PNMI + 8)
+#define SK_PNMI_ERR008MSG "Addr: Tried to get unknown OID"
+#define SK_PNMI_ERR009 (SK_ERRBASE_PNMI + 9)
+#define SK_PNMI_ERR009MSG "Addr: Unknown OID"
+#define SK_PNMI_ERR010 (SK_ERRBASE_PNMI + 10)
+#define SK_PNMI_ERR010MSG "CsumStat: Unknown OID"
+#define SK_PNMI_ERR011 (SK_ERRBASE_PNMI + 11)
+#define SK_PNMI_ERR011MSG "SensorStat: Sensor descr string too long"
+#define SK_PNMI_ERR012 (SK_ERRBASE_PNMI + 12)
+#define SK_PNMI_ERR012MSG "SensorStat: Unknown OID"
+#define SK_PNMI_ERR013 (SK_ERRBASE_PNMI + 13)
+#define SK_PNMI_ERR013MSG ""
+#define SK_PNMI_ERR014 (SK_ERRBASE_PNMI + 14)
+#define SK_PNMI_ERR014MSG "Vpd: Cannot read VPD keys"
+#define SK_PNMI_ERR015 (SK_ERRBASE_PNMI + 15)
+#define SK_PNMI_ERR015MSG "Vpd: Internal array for VPD keys to small"
+#define SK_PNMI_ERR016 (SK_ERRBASE_PNMI + 16)
+#define SK_PNMI_ERR016MSG "Vpd: Key string too long"
+#define SK_PNMI_ERR017 (SK_ERRBASE_PNMI + 17)
+#define SK_PNMI_ERR017MSG "Vpd: Invalid VPD status pointer"
+#define SK_PNMI_ERR018 (SK_ERRBASE_PNMI + 18)
+#define SK_PNMI_ERR018MSG "Vpd: VPD data not valid"
+#define SK_PNMI_ERR019 (SK_ERRBASE_PNMI + 19)
+#define SK_PNMI_ERR019MSG "Vpd: VPD entries list string too long"
+#define SK_PNMI_ERR021 (SK_ERRBASE_PNMI + 21)
+#define SK_PNMI_ERR021MSG "Vpd: VPD data string too long"
+#define SK_PNMI_ERR022 (SK_ERRBASE_PNMI + 22)
+#define SK_PNMI_ERR022MSG "Vpd: VPD data string too long should be errored before"
+#define SK_PNMI_ERR023 (SK_ERRBASE_PNMI + 23)
+#define SK_PNMI_ERR023MSG "Vpd: Unknown OID in get action"
+#define SK_PNMI_ERR024 (SK_ERRBASE_PNMI + 24)
+#define SK_PNMI_ERR024MSG "Vpd: Unknown OID in preset/set action"
+#define SK_PNMI_ERR025 (SK_ERRBASE_PNMI + 25)
+#define SK_PNMI_ERR025MSG "Vpd: Cannot write VPD after modify entry"
+#define SK_PNMI_ERR026 (SK_ERRBASE_PNMI + 26)
+#define SK_PNMI_ERR026MSG "Vpd: Cannot update VPD"
+#define SK_PNMI_ERR027 (SK_ERRBASE_PNMI + 27)
+#define SK_PNMI_ERR027MSG "Vpd: Cannot delete VPD entry"
+#define SK_PNMI_ERR028 (SK_ERRBASE_PNMI + 28)
+#define SK_PNMI_ERR028MSG "Vpd: Cannot update VPD after delete entry"
+#define SK_PNMI_ERR029 (SK_ERRBASE_PNMI + 29)
+#define SK_PNMI_ERR029MSG "General: Driver description string too long"
+#define SK_PNMI_ERR030 (SK_ERRBASE_PNMI + 30)
+#define SK_PNMI_ERR030MSG "General: Driver version not initialized"
+#define SK_PNMI_ERR031 (SK_ERRBASE_PNMI + 31)
+#define SK_PNMI_ERR031MSG "General: Driver version string too long"
+#define SK_PNMI_ERR032 (SK_ERRBASE_PNMI + 32)
+#define SK_PNMI_ERR032MSG "General: Cannot read VPD Name for HW descr"
+#define SK_PNMI_ERR033 (SK_ERRBASE_PNMI + 33)
+#define SK_PNMI_ERR033MSG "General: HW description string too long"
+#define SK_PNMI_ERR034 (SK_ERRBASE_PNMI + 34)
+#define SK_PNMI_ERR034MSG "General: Unknown OID"
+#define SK_PNMI_ERR035 (SK_ERRBASE_PNMI + 35)
+#define SK_PNMI_ERR035MSG "Rlmt: Unknown OID"
+#define SK_PNMI_ERR036 (SK_ERRBASE_PNMI + 36)
+#define SK_PNMI_ERR036MSG ""
+#define SK_PNMI_ERR037 (SK_ERRBASE_PNMI + 37)
+#define SK_PNMI_ERR037MSG "Rlmt: SK_RLMT_MODE_CHANGE event return not 0"
+#define SK_PNMI_ERR038 (SK_ERRBASE_PNMI + 38)
+#define SK_PNMI_ERR038MSG "Rlmt: SK_RLMT_PREFPORT_CHANGE event return not 0"
+#define SK_PNMI_ERR039 (SK_ERRBASE_PNMI + 39)
+#define SK_PNMI_ERR039MSG "RlmtStat: Unknown OID"
+#define SK_PNMI_ERR040 (SK_ERRBASE_PNMI + 40)
+#define SK_PNMI_ERR040MSG "PowerManagement: Unknown OID"
+#define SK_PNMI_ERR041 (SK_ERRBASE_PNMI + 41)
+#define SK_PNMI_ERR041MSG "MacPrivateConf: Unknown OID"
+#define SK_PNMI_ERR042 (SK_ERRBASE_PNMI + 42)
+#define SK_PNMI_ERR042MSG "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0"
+#define SK_PNMI_ERR043 (SK_ERRBASE_PNMI + 43)
+#define SK_PNMI_ERR043MSG "MacPrivateConf: SK_HWEV_SET_LMODE returned not 0"
+#define SK_PNMI_ERR044 (SK_ERRBASE_PNMI + 44)
+#define SK_PNMI_ERR044MSG "MacPrivateConf: SK_HWEV_SET_FLOWMODE returned not 0"
+#define SK_PNMI_ERR045 (SK_ERRBASE_PNMI + 45)
+#define SK_PNMI_ERR045MSG "MacPrivateConf: SK_HWEV_SET_SPEED returned not 0"
+#define SK_PNMI_ERR046 (SK_ERRBASE_PNMI + 46)
+#define SK_PNMI_ERR046MSG "Monitor: Unknown OID"
+#define SK_PNMI_ERR047 (SK_ERRBASE_PNMI + 47)
+#define SK_PNMI_ERR047MSG "SirqUpdate: Event function returns not 0"
+#define SK_PNMI_ERR048 (SK_ERRBASE_PNMI + 48)
+#define SK_PNMI_ERR048MSG "RlmtUpdate: Event function returns not 0"
+#define SK_PNMI_ERR049 (SK_ERRBASE_PNMI + 49)
+#define SK_PNMI_ERR049MSG "SkPnmiInit: Invalid size of 'CounterOffset' struct!!"
+#define SK_PNMI_ERR050 (SK_ERRBASE_PNMI + 50)
+#define SK_PNMI_ERR050MSG "SkPnmiInit: Invalid size of 'StatAddr' table!!"
+#define SK_PNMI_ERR051 (SK_ERRBASE_PNMI + 51)
+#define SK_PNMI_ERR051MSG "SkPnmiEvent: Port switch suspicious"
+#define SK_PNMI_ERR052 (SK_ERRBASE_PNMI + 52)
+#define SK_PNMI_ERR052MSG ""
+#define SK_PNMI_ERR053 (SK_ERRBASE_PNMI + 53)
+#define SK_PNMI_ERR053MSG "General: Driver release date not initialized"
+#define SK_PNMI_ERR054 (SK_ERRBASE_PNMI + 54)
+#define SK_PNMI_ERR054MSG "General: Driver release date string too long"
+#define SK_PNMI_ERR055 (SK_ERRBASE_PNMI + 55)
+#define SK_PNMI_ERR055MSG "General: Driver file name not initialized"
+#define SK_PNMI_ERR056 (SK_ERRBASE_PNMI + 56)
+#define SK_PNMI_ERR056MSG "General: Driver file name string too long"
+
+/*
+ * Management counter macros called by the driver
+ */
+#define SK_PNMI_SET_DRIVER_DESCR(pAC,v) ((pAC)->Pnmi.pDriverDescription = \
+ (char *)(v))
+
+#define SK_PNMI_SET_DRIVER_VER(pAC,v) ((pAC)->Pnmi.pDriverVersion = \
+ (char *)(v))
+
+#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v) ((pAC)->Pnmi.pDriverReleaseDate = \
+ (char *)(v))
+
+#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v) ((pAC)->Pnmi.pDriverFileName = \
+ (char *)(v))
+
+#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \
+ { \
+ (pAC)->Pnmi.Port[p].TxSwQueueLen = (SK_U64)(v); \
+ if ((pAC)->Pnmi.Port[p].TxSwQueueLen > (pAC)->Pnmi.Port[p].TxSwQueueMax) { \
+ (pAC)->Pnmi.Port[p].TxSwQueueMax = (pAC)->Pnmi.Port[p].TxSwQueueLen; \
+ } \
+ }
+#define SK_PNMI_CNT_TX_RETRY(pAC,p) (((pAC)->Pnmi.Port[p].TxRetryCts)++)
+#define SK_PNMI_CNT_RX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].RxIntrCts)++)
+#define SK_PNMI_CNT_TX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].TxIntrCts)++)
+#define SK_PNMI_CNT_NO_RX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].RxNoBufCts)++)
+#define SK_PNMI_CNT_NO_TX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].TxNoBufCts)++)
+#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v,p) \
+ ((pAC)->Pnmi.Port[p].TxUsedDescrNo=(SK_U64)(v));
+#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v,p) \
+ { \
+ ((pAC)->Pnmi.Port[p].RxDeliveredCts)++; \
+ (pAC)->Pnmi.Port[p].RxOctetsDeliveredCts += (SK_U64)(v); \
+ }
+#define SK_PNMI_CNT_ERR_RECOVERY(pAC,p) (((pAC)->Pnmi.Port[p].ErrRecoveryCts)++);
+
+#define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \
+ { \
+ if ((p) < SK_MAX_MACS) { \
+ ((pAC)->Pnmi.Port[p].StatSyncCts)++; \
+ (pAC)->Pnmi.Port[p].StatSyncOctetsCts += (SK_U64)(v); \
+ } \
+ }
+
+#define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \
+ { \
+ if ((p) < SK_MAX_MACS) { \
+ ((pAC)->Pnmi.Port[p].StatRxLongFrameCts++); \
+ } \
+ }
+
+#define SK_PNMI_CNT_RX_FRAMETOOLONG(pAC,p) \
+ { \
+ if ((p) < SK_MAX_MACS) { \
+ ((pAC)->Pnmi.Port[p].StatRxFrameTooLongCts++); \
+ } \
+ }
+
+#define SK_PNMI_CNT_RX_PMACC_ERR(pAC,p) \
+ { \
+ if ((p) < SK_MAX_MACS) { \
+ ((pAC)->Pnmi.Port[p].StatRxPMaccErr++); \
+ } \
+ }
+
+/*
+ * Conversion Macros
+ */
+#define SK_PNMI_PORT_INST2LOG(i) ((unsigned int)(i) - 1)
+#define SK_PNMI_PORT_LOG2INST(l) ((unsigned int)(l) + 1)
+#define SK_PNMI_PORT_PHYS2LOG(p) ((unsigned int)(p) + 1)
+#define SK_PNMI_PORT_LOG2PHYS(pAC,l) ((unsigned int)(l) - 1)
+#define SK_PNMI_PORT_PHYS2INST(pAC,p) \
+ (pAC->Pnmi.DualNetActiveFlag ? 2 : ((unsigned int)(p) + 2))
+#define SK_PNMI_PORT_INST2PHYS(pAC,i) ((unsigned int)(i) - 2)
+
+/*
+ * Structure definition for SkPnmiGetStruct and SkPnmiSetStruct
+ */
+#define SK_PNMI_VPD_KEY_SIZE 5
+#define SK_PNMI_VPD_BUFSIZE (VPD_SIZE)
+#define SK_PNMI_VPD_ENTRIES (VPD_SIZE / 4)
+#define SK_PNMI_VPD_DATALEN 128 /* Number of data bytes */
+
+#define SK_PNMI_MULTICAST_LISTLEN 64
+#define SK_PNMI_SENSOR_ENTRIES (SK_MAX_SENSORS)
+#define SK_PNMI_CHECKSUM_ENTRIES 3
+#define SK_PNMI_MAC_ENTRIES (SK_MAX_MACS + 1)
+#define SK_PNMI_MONITOR_ENTRIES 20
+#define SK_PNMI_TRAP_ENTRIES 10
+#define SK_PNMI_TRAPLEN 128
+#define SK_PNMI_STRINGLEN1 80
+#define SK_PNMI_STRINGLEN2 25
+#define SK_PNMI_TRAP_QUEUE_LEN 512
+
+typedef struct s_PnmiVpd {
+ char VpdKey[SK_PNMI_VPD_KEY_SIZE];
+ char VpdValue[SK_PNMI_VPD_DATALEN];
+ SK_U8 VpdAccess;
+ SK_U8 VpdAction;
+} SK_PNMI_VPD;
+
+typedef struct s_PnmiSensor {
+ SK_U8 SensorIndex;
+ char SensorDescr[SK_PNMI_STRINGLEN2];
+ SK_U8 SensorType;
+ SK_U32 SensorValue;
+ SK_U32 SensorWarningThresholdLow;
+ SK_U32 SensorWarningThresholdHigh;
+ SK_U32 SensorErrorThresholdLow;
+ SK_U32 SensorErrorThresholdHigh;
+ SK_U8 SensorStatus;
+ SK_U64 SensorWarningCts;
+ SK_U64 SensorErrorCts;
+ SK_U64 SensorWarningTimestamp;
+ SK_U64 SensorErrorTimestamp;
+} SK_PNMI_SENSOR;
+
+typedef struct s_PnmiChecksum {
+ SK_U64 ChecksumRxOkCts;
+ SK_U64 ChecksumRxUnableCts;
+ SK_U64 ChecksumRxErrCts;
+ SK_U64 ChecksumTxOkCts;
+ SK_U64 ChecksumTxUnableCts;
+} SK_PNMI_CHECKSUM;
+
+typedef struct s_PnmiStat {
+ SK_U64 StatTxOkCts;
+ SK_U64 StatTxOctetsOkCts;
+ SK_U64 StatTxBroadcastOkCts;
+ SK_U64 StatTxMulticastOkCts;
+ SK_U64 StatTxUnicastOkCts;
+ SK_U64 StatTxLongFramesCts;
+ SK_U64 StatTxBurstCts;
+ SK_U64 StatTxPauseMacCtrlCts;
+ SK_U64 StatTxMacCtrlCts;
+ SK_U64 StatTxSingleCollisionCts;
+ SK_U64 StatTxMultipleCollisionCts;
+ SK_U64 StatTxExcessiveCollisionCts;
+ SK_U64 StatTxLateCollisionCts;
+ SK_U64 StatTxDeferralCts;
+ SK_U64 StatTxExcessiveDeferralCts;
+ SK_U64 StatTxFifoUnderrunCts;
+ SK_U64 StatTxCarrierCts;
+ SK_U64 Dummy1; /* StatTxUtilization */
+ SK_U64 StatTx64Cts;
+ SK_U64 StatTx127Cts;
+ SK_U64 StatTx255Cts;
+ SK_U64 StatTx511Cts;
+ SK_U64 StatTx1023Cts;
+ SK_U64 StatTxMaxCts;
+ SK_U64 StatTxSyncCts;
+ SK_U64 StatTxSyncOctetsCts;
+ SK_U64 StatRxOkCts;
+ SK_U64 StatRxOctetsOkCts;
+ SK_U64 StatRxBroadcastOkCts;
+ SK_U64 StatRxMulticastOkCts;
+ SK_U64 StatRxUnicastOkCts;
+ SK_U64 StatRxLongFramesCts;
+ SK_U64 StatRxPauseMacCtrlCts;
+ SK_U64 StatRxMacCtrlCts;
+ SK_U64 StatRxPauseMacCtrlErrorCts;
+ SK_U64 StatRxMacCtrlUnknownCts;
+ SK_U64 StatRxBurstCts;
+ SK_U64 StatRxMissedCts;
+ SK_U64 StatRxFramingCts;
+ SK_U64 StatRxFifoOverflowCts;
+ SK_U64 StatRxJabberCts;
+ SK_U64 StatRxCarrierCts;
+ SK_U64 StatRxIRLengthCts;
+ SK_U64 StatRxSymbolCts;
+ SK_U64 StatRxShortsCts;
+ SK_U64 StatRxRuntCts;
+ SK_U64 StatRxCextCts;
+ SK_U64 StatRxTooLongCts;
+ SK_U64 StatRxFcsCts;
+ SK_U64 Dummy2; /* StatRxUtilization */
+ SK_U64 StatRx64Cts;
+ SK_U64 StatRx127Cts;
+ SK_U64 StatRx255Cts;
+ SK_U64 StatRx511Cts;
+ SK_U64 StatRx1023Cts;
+ SK_U64 StatRxMaxCts;
+} SK_PNMI_STAT;
+
+typedef struct s_PnmiConf {
+ char ConfMacCurrentAddr[6];
+ char ConfMacFactoryAddr[6];
+ SK_U8 ConfPMD;
+ SK_U8 ConfConnector;
+ SK_U32 ConfPhyType;
+ SK_U32 ConfPhyMode;
+ SK_U8 ConfLinkCapability;
+ SK_U8 ConfLinkMode;
+ SK_U8 ConfLinkModeStatus;
+ SK_U8 ConfLinkStatus;
+ SK_U8 ConfFlowCtrlCapability;
+ SK_U8 ConfFlowCtrlMode;
+ SK_U8 ConfFlowCtrlStatus;
+ SK_U8 ConfPhyOperationCapability;
+ SK_U8 ConfPhyOperationMode;
+ SK_U8 ConfPhyOperationStatus;
+ SK_U8 ConfSpeedCapability;
+ SK_U8 ConfSpeedMode;
+ SK_U8 ConfSpeedStatus;
+} SK_PNMI_CONF;
+
+typedef struct s_PnmiRlmt {
+ SK_U32 RlmtIndex;
+ SK_U32 RlmtStatus;
+ SK_U64 RlmtTxHelloCts;
+ SK_U64 RlmtRxHelloCts;
+ SK_U64 RlmtTxSpHelloReqCts;
+ SK_U64 RlmtRxSpHelloCts;
+} SK_PNMI_RLMT;
+
+typedef struct s_PnmiRlmtMonitor {
+ SK_U32 RlmtMonitorIndex;
+ char RlmtMonitorAddr[6];
+ SK_U64 RlmtMonitorErrorCts;
+ SK_U64 RlmtMonitorTimestamp;
+ SK_U8 RlmtMonitorAdmin;
+} SK_PNMI_RLMT_MONITOR;
+
+typedef struct s_PnmiRequestStatus {
+ SK_U32 ErrorStatus;
+ SK_U32 ErrorOffset;
+} SK_PNMI_REQUEST_STATUS;
+
+typedef struct s_PnmiStrucData {
+ SK_U32 MgmtDBVersion;
+ SK_PNMI_REQUEST_STATUS ReturnStatus;
+ SK_U32 VpdFreeBytes;
+ char VpdEntriesList[SK_PNMI_VPD_ENTRIES * SK_PNMI_VPD_KEY_SIZE];
+ SK_U32 VpdEntriesNumber;
+ SK_PNMI_VPD Vpd[SK_PNMI_VPD_ENTRIES];
+ SK_U32 PortNumber;
+ SK_U32 DeviceType;
+ char DriverDescr[SK_PNMI_STRINGLEN1];
+ char DriverVersion[SK_PNMI_STRINGLEN2];
+ char DriverReleaseDate[SK_PNMI_STRINGLEN1];
+ char DriverFileName[SK_PNMI_STRINGLEN1];
+ char HwDescr[SK_PNMI_STRINGLEN1];
+ char HwVersion[SK_PNMI_STRINGLEN2];
+ SK_U16 Chipset;
+ SK_U32 ChipId;
+ SK_U8 VauxAvail;
+ SK_U32 RamSize;
+ SK_U32 MtuSize;
+ SK_U32 Action;
+ SK_U32 TestResult;
+ SK_U8 BusType;
+ SK_U8 BusSpeed;
+ SK_U8 BusWidth;
+ SK_U8 SensorNumber;
+ SK_PNMI_SENSOR Sensor[SK_PNMI_SENSOR_ENTRIES];
+ SK_U8 ChecksumNumber;
+ SK_PNMI_CHECKSUM Checksum[SK_PNMI_CHECKSUM_ENTRIES];
+ SK_PNMI_STAT Stat[SK_PNMI_MAC_ENTRIES];
+ SK_PNMI_CONF Conf[SK_PNMI_MAC_ENTRIES];
+ SK_U8 RlmtMode;
+ SK_U32 RlmtPortNumber;
+ SK_U8 RlmtPortActive;
+ SK_U8 RlmtPortPreferred;
+ SK_U64 RlmtChangeCts;
+ SK_U64 RlmtChangeTime;
+ SK_U64 RlmtChangeEstimate;
+ SK_U64 RlmtChangeThreshold;
+ SK_PNMI_RLMT Rlmt[SK_MAX_MACS];
+ SK_U32 RlmtMonitorNumber;
+ SK_PNMI_RLMT_MONITOR RlmtMonitor[SK_PNMI_MONITOR_ENTRIES];
+ SK_U32 TrapNumber;
+ SK_U8 Trap[SK_PNMI_TRAP_QUEUE_LEN];
+ SK_U64 TxSwQueueLen;
+ SK_U64 TxSwQueueMax;
+ SK_U64 TxRetryCts;
+ SK_U64 RxIntrCts;
+ SK_U64 TxIntrCts;
+ SK_U64 RxNoBufCts;
+ SK_U64 TxNoBufCts;
+ SK_U64 TxUsedDescrNo;
+ SK_U64 RxDeliveredCts;
+ SK_U64 RxOctetsDeliveredCts;
+ SK_U64 RxHwErrorsCts;
+ SK_U64 TxHwErrorsCts;
+ SK_U64 InErrorsCts;
+ SK_U64 OutErrorsCts;
+ SK_U64 ErrRecoveryCts;
+ SK_U64 SysUpTime;
+} SK_PNMI_STRUCT_DATA;
+
+#define SK_PNMI_STRUCT_SIZE (sizeof(SK_PNMI_STRUCT_DATA))
+#define SK_PNMI_MIN_STRUCT_SIZE ((unsigned int)(SK_UPTR)\
+ &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes))
+ /*
+ * ReturnStatus field
+ * must be located
+ * before VpdFreeBytes
+ */
+
+/*
+ * Various definitions
+ */
+#define SK_PNMI_MAX_PROTOS 3
+
+#define SK_PNMI_CNT_NO 66 /* Must have the value of the enum
+ * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK
+ * for check while init phase 1
+ */
+
+/*
+ * Estimate data structure
+ */
+typedef struct s_PnmiEstimate {
+ unsigned int EstValueIndex;
+ SK_U64 EstValue[7];
+ SK_U64 Estimate;
+ SK_TIMER EstTimer;
+} SK_PNMI_ESTIMATE;
+
+
+/*
+ * VCT timer data structure
+ */
+typedef struct s_VctTimer {
+ SK_TIMER VctTimer;
+} SK_PNMI_VCT_TIMER;
+
+
+/*
+ * PNMI specific adapter context structure
+ */
+typedef struct s_PnmiPort {
+ SK_U64 StatSyncCts;
+ SK_U64 StatSyncOctetsCts;
+ SK_U64 StatRxLongFrameCts;
+ SK_U64 StatRxFrameTooLongCts;
+ SK_U64 StatRxPMaccErr;
+ SK_U64 TxSwQueueLen;
+ SK_U64 TxSwQueueMax;
+ SK_U64 TxRetryCts;
+ SK_U64 RxIntrCts;
+ SK_U64 TxIntrCts;
+ SK_U64 RxNoBufCts;
+ SK_U64 TxNoBufCts;
+ SK_U64 TxUsedDescrNo;
+ SK_U64 RxDeliveredCts;
+ SK_U64 RxOctetsDeliveredCts;
+ SK_U64 RxHwErrorsCts;
+ SK_U64 TxHwErrorsCts;
+ SK_U64 InErrorsCts;
+ SK_U64 OutErrorsCts;
+ SK_U64 ErrRecoveryCts;
+ SK_U64 RxShortZeroMark;
+ SK_U64 CounterOffset[SK_PNMI_CNT_NO];
+ SK_U32 CounterHigh[SK_PNMI_CNT_NO];
+ SK_BOOL ActiveFlag;
+ SK_U8 Align[3];
+} SK_PNMI_PORT;
+
+
+typedef struct s_PnmiData {
+ SK_PNMI_PORT Port [SK_MAX_MACS];
+ SK_PNMI_PORT BufPort [SK_MAX_MACS]; /* 2002-09-13 pweber */
+ SK_U64 VirtualCounterOffset[SK_PNMI_CNT_NO];
+ SK_U32 TestResult;
+ char HwVersion[10];
+ SK_U16 Align01;
+
+ char *pDriverDescription;
+ char *pDriverVersion;
+ char *pDriverReleaseDate;
+ char *pDriverFileName;
+
+ int MacUpdatedFlag;
+ int RlmtUpdatedFlag;
+ int SirqUpdatedFlag;
+
+ SK_U64 RlmtChangeCts;
+ SK_U64 RlmtChangeTime;
+ SK_PNMI_ESTIMATE RlmtChangeEstimate;
+ SK_U64 RlmtChangeThreshold;
+
+ SK_U64 StartUpTime;
+ SK_U32 DeviceType;
+ char PciBusSpeed;
+ char PciBusWidth;
+ char Chipset;
+ char PMD;
+ char Connector;
+ SK_BOOL DualNetActiveFlag;
+ SK_U16 Align02;
+
+ char TrapBuf[SK_PNMI_TRAP_QUEUE_LEN];
+ unsigned int TrapBufFree;
+ unsigned int TrapQueueBeg;
+ unsigned int TrapQueueEnd;
+ unsigned int TrapBufPad;
+ unsigned int TrapUnique;
+ SK_U8 VctStatus[SK_MAX_MACS];
+ SK_PNMI_VCT VctBackup[SK_MAX_MACS];
+ SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS];
+#ifdef SK_DIAG_SUPPORT
+ SK_U32 DiagAttached;
+#endif /* SK_DIAG_SUPPORT */
+} SK_PNMI;
+
+
+/*
+ * Function prototypes
+ */
+extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level);
+extern int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf,
+ unsigned int* pLen, SK_U32 Instance, SK_U32 NetIndex);
+extern int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id,
+ void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
+extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf,
+ unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
+extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
+ unsigned int *pLen, SK_U32 NetIndex);
+extern int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
+ unsigned int *pLen, SK_U32 NetIndex);
+extern int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf,
+ unsigned int *pLen, SK_U32 NetIndex);
+extern int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event,
+ SK_EVPARA Param);
+extern int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
+ unsigned int * pLen, SK_U32 NetIndex);
+
+#endif
diff --git a/drivers/net/sk98lin/h/skgesirq.h b/drivers/net/sk98lin/h/skgesirq.h
new file mode 100644
index 000000000000..b486bd9b6628
--- /dev/null
+++ b/drivers/net/sk98lin/h/skgesirq.h
@@ -0,0 +1,111 @@
+/******************************************************************************
+ *
+ * Name: skgesirq.h
+ * Project: Gigabit Ethernet Adapters, Common Modules
+ * Version: $Revision: 1.30 $
+ * Date: $Date: 2003/07/04 12:34:13 $
+ * Purpose: SK specific Gigabit Ethernet special IRQ functions
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef _INC_SKGESIRQ_H_
+#define _INC_SKGESIRQ_H_
+
+/* Define return codes of SkGePortCheckUp and CheckShort */
+#define SK_HW_PS_NONE 0 /* No action needed */
+#define SK_HW_PS_RESTART 1 /* Restart needed */
+#define SK_HW_PS_LINK 2 /* Link Up actions needed */
+
+/*
+ * Define the Event the special IRQ/INI module can handle
+ */
+#define SK_HWEV_WATIM 1 /* Timeout for WA Errata #2 XMAC */
+#define SK_HWEV_PORT_START 2 /* Port Start Event by RLMT */
+#define SK_HWEV_PORT_STOP 3 /* Port Stop Event by RLMT */
+#define SK_HWEV_CLEAR_STAT 4 /* Clear Statistics by PNMI */
+#define SK_HWEV_UPDATE_STAT 5 /* Update Statistics by PNMI */
+#define SK_HWEV_SET_LMODE 6 /* Set Link Mode by PNMI */
+#define SK_HWEV_SET_FLOWMODE 7 /* Set Flow Control Mode by PNMI */
+#define SK_HWEV_SET_ROLE 8 /* Set Master/Slave (Role) by PNMI */
+#define SK_HWEV_SET_SPEED 9 /* Set Link Speed by PNMI */
+#define SK_HWEV_HALFDUP_CHK 10 /* Half Duplex Hangup Workaround */
+
+#define SK_WA_ACT_TIME (5000000UL) /* 5 sec */
+#define SK_WA_INA_TIME (100000UL) /* 100 msec */
+
+#define SK_HALFDUP_CHK_TIME (10000UL) /* 10 msec */
+
+/*
+ * Define the error numbers and messages
+ */
+#define SKERR_SIRQ_E001 (SK_ERRBASE_SIRQ+0)
+#define SKERR_SIRQ_E001MSG "Unknown event"
+#define SKERR_SIRQ_E002 (SKERR_SIRQ_E001+1)
+#define SKERR_SIRQ_E002MSG "Packet timeout RX1"
+#define SKERR_SIRQ_E003 (SKERR_SIRQ_E002+1)
+#define SKERR_SIRQ_E003MSG "Packet timeout RX2"
+#define SKERR_SIRQ_E004 (SKERR_SIRQ_E003+1)
+#define SKERR_SIRQ_E004MSG "MAC 1 not correctly initialized"
+#define SKERR_SIRQ_E005 (SKERR_SIRQ_E004+1)
+#define SKERR_SIRQ_E005MSG "MAC 2 not correctly initialized"
+#define SKERR_SIRQ_E006 (SKERR_SIRQ_E005+1)
+#define SKERR_SIRQ_E006MSG "CHECK failure R1"
+#define SKERR_SIRQ_E007 (SKERR_SIRQ_E006+1)
+#define SKERR_SIRQ_E007MSG "CHECK failure R2"
+#define SKERR_SIRQ_E008 (SKERR_SIRQ_E007+1)
+#define SKERR_SIRQ_E008MSG "CHECK failure XS1"
+#define SKERR_SIRQ_E009 (SKERR_SIRQ_E008+1)
+#define SKERR_SIRQ_E009MSG "CHECK failure XA1"
+#define SKERR_SIRQ_E010 (SKERR_SIRQ_E009+1)
+#define SKERR_SIRQ_E010MSG "CHECK failure XS2"
+#define SKERR_SIRQ_E011 (SKERR_SIRQ_E010+1)
+#define SKERR_SIRQ_E011MSG "CHECK failure XA2"
+#define SKERR_SIRQ_E012 (SKERR_SIRQ_E011+1)
+#define SKERR_SIRQ_E012MSG "unexpected IRQ Master error"
+#define SKERR_SIRQ_E013 (SKERR_SIRQ_E012+1)
+#define SKERR_SIRQ_E013MSG "unexpected IRQ Status error"
+#define SKERR_SIRQ_E014 (SKERR_SIRQ_E013+1)
+#define SKERR_SIRQ_E014MSG "Parity error on RAM (read)"
+#define SKERR_SIRQ_E015 (SKERR_SIRQ_E014+1)
+#define SKERR_SIRQ_E015MSG "Parity error on RAM (write)"
+#define SKERR_SIRQ_E016 (SKERR_SIRQ_E015+1)
+#define SKERR_SIRQ_E016MSG "Parity error MAC 1"
+#define SKERR_SIRQ_E017 (SKERR_SIRQ_E016+1)
+#define SKERR_SIRQ_E017MSG "Parity error MAC 2"
+#define SKERR_SIRQ_E018 (SKERR_SIRQ_E017+1)
+#define SKERR_SIRQ_E018MSG "Parity error RX 1"
+#define SKERR_SIRQ_E019 (SKERR_SIRQ_E018+1)
+#define SKERR_SIRQ_E019MSG "Parity error RX 2"
+#define SKERR_SIRQ_E020 (SKERR_SIRQ_E019+1)
+#define SKERR_SIRQ_E020MSG "MAC transmit FIFO underrun"
+#define SKERR_SIRQ_E021 (SKERR_SIRQ_E020+1)
+#define SKERR_SIRQ_E021MSG "Spurious TWSI interrupt"
+#define SKERR_SIRQ_E022 (SKERR_SIRQ_E021+1)
+#define SKERR_SIRQ_E022MSG "Cable pair swap error"
+#define SKERR_SIRQ_E023 (SKERR_SIRQ_E022+1)
+#define SKERR_SIRQ_E023MSG "Auto-negotiation error"
+#define SKERR_SIRQ_E024 (SKERR_SIRQ_E023+1)
+#define SKERR_SIRQ_E024MSG "FIFO overflow error"
+#define SKERR_SIRQ_E025 (SKERR_SIRQ_E024+1)
+#define SKERR_SIRQ_E025MSG "2 Pair Downshift detected"
+
+extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus);
+extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
+extern void SkHWLinkUp(SK_AC *pAC, SK_IOC IoC, int Port);
+extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port);
+
+#endif /* _INC_SKGESIRQ_H_ */
diff --git a/drivers/net/sk98lin/h/ski2c.h b/drivers/net/sk98lin/h/ski2c.h
new file mode 100644
index 000000000000..598bb42ccc3d
--- /dev/null
+++ b/drivers/net/sk98lin/h/ski2c.h
@@ -0,0 +1,177 @@
+/******************************************************************************
+ *
+ * Name: ski2c.h
+ * Project: Gigabit Ethernet Adapters, TWSI-Module
+ * Version: $Revision: 1.35 $
+ * Date: $Date: 2003/10/20 09:06:30 $
+ * Purpose: Defines to access Voltage and Temperature Sensor
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/*
+ * SKI2C.H contains all I2C specific defines
+ */
+
+#ifndef _SKI2C_H_
+#define _SKI2C_H_
+
+typedef struct s_Sensor SK_SENSOR;
+
+#include "h/skgei2c.h"
+
+/*
+ * Define the I2C events.
+ */
+#define SK_I2CEV_IRQ 1 /* IRQ happened Event */
+#define SK_I2CEV_TIM 2 /* Timeout event */
+#define SK_I2CEV_CLEAR 3 /* Clear MIB Values */
+
+/*
+ * Define READ and WRITE Constants.
+ */
+#define I2C_READ 0
+#define I2C_WRITE 1
+#define I2C_BURST 1
+#define I2C_SINGLE 0
+
+#define SKERR_I2C_E001 (SK_ERRBASE_I2C+0)
+#define SKERR_I2C_E001MSG "Sensor index unknown"
+#define SKERR_I2C_E002 (SKERR_I2C_E001+1)
+#define SKERR_I2C_E002MSG "TWSI: transfer does not complete"
+#define SKERR_I2C_E003 (SKERR_I2C_E002+1)
+#define SKERR_I2C_E003MSG "LM80: NAK on device send"
+#define SKERR_I2C_E004 (SKERR_I2C_E003+1)
+#define SKERR_I2C_E004MSG "LM80: NAK on register send"
+#define SKERR_I2C_E005 (SKERR_I2C_E004+1)
+#define SKERR_I2C_E005MSG "LM80: NAK on device (2) send"
+#define SKERR_I2C_E006 (SKERR_I2C_E005+1)
+#define SKERR_I2C_E006MSG "Unknown event"
+#define SKERR_I2C_E007 (SKERR_I2C_E006+1)
+#define SKERR_I2C_E007MSG "LM80 read out of state"
+#define SKERR_I2C_E008 (SKERR_I2C_E007+1)
+#define SKERR_I2C_E008MSG "Unexpected sensor read completed"
+#define SKERR_I2C_E009 (SKERR_I2C_E008+1)
+#define SKERR_I2C_E009MSG "WARNING: temperature sensor out of range"
+#define SKERR_I2C_E010 (SKERR_I2C_E009+1)
+#define SKERR_I2C_E010MSG "WARNING: voltage sensor out of range"
+#define SKERR_I2C_E011 (SKERR_I2C_E010+1)
+#define SKERR_I2C_E011MSG "ERROR: temperature sensor out of range"
+#define SKERR_I2C_E012 (SKERR_I2C_E011+1)
+#define SKERR_I2C_E012MSG "ERROR: voltage sensor out of range"
+#define SKERR_I2C_E013 (SKERR_I2C_E012+1)
+#define SKERR_I2C_E013MSG "ERROR: couldn't init sensor"
+#define SKERR_I2C_E014 (SKERR_I2C_E013+1)
+#define SKERR_I2C_E014MSG "WARNING: fan sensor out of range"
+#define SKERR_I2C_E015 (SKERR_I2C_E014+1)
+#define SKERR_I2C_E015MSG "ERROR: fan sensor out of range"
+#define SKERR_I2C_E016 (SKERR_I2C_E015+1)
+#define SKERR_I2C_E016MSG "TWSI: active transfer does not complete"
+
+/*
+ * Define Timeout values
+ */
+#define SK_I2C_TIM_LONG 2000000L /* 2 seconds */
+#define SK_I2C_TIM_SHORT 100000L /* 100 milliseconds */
+#define SK_I2C_TIM_WATCH 1000000L /* 1 second */
+
+/*
+ * Define trap and error log hold times
+ */
+#ifndef SK_SEN_ERR_TR_HOLD
+#define SK_SEN_ERR_TR_HOLD (4*SK_TICKS_PER_SEC)
+#endif
+#ifndef SK_SEN_ERR_LOG_HOLD
+#define SK_SEN_ERR_LOG_HOLD (60*SK_TICKS_PER_SEC)
+#endif
+#ifndef SK_SEN_WARN_TR_HOLD
+#define SK_SEN_WARN_TR_HOLD (15*SK_TICKS_PER_SEC)
+#endif
+#ifndef SK_SEN_WARN_LOG_HOLD
+#define SK_SEN_WARN_LOG_HOLD (15*60*SK_TICKS_PER_SEC)
+#endif
+
+/*
+ * Defines for SenType
+ */
+#define SK_SEN_UNKNOWN 0
+#define SK_SEN_TEMP 1
+#define SK_SEN_VOLT 2
+#define SK_SEN_FAN 3
+
+/*
+ * Define for the SenErrorFlag
+ */
+#define SK_SEN_ERR_NOT_PRESENT 0 /* Error Flag: Sensor not present */
+#define SK_SEN_ERR_OK 1 /* Error Flag: O.K. */
+#define SK_SEN_ERR_WARN 2 /* Error Flag: Warning */
+#define SK_SEN_ERR_ERR 3 /* Error Flag: Error */
+#define SK_SEN_ERR_FAULTY 4 /* Error Flag: Faulty */
+
+/*
+ * Define the Sensor struct
+ */
+struct s_Sensor {
+ char *SenDesc; /* Description */
+ int SenType; /* Voltage or Temperature */
+ SK_I32 SenValue; /* Current value of the sensor */
+ SK_I32 SenThreErrHigh; /* High error Threshhold of this sensor */
+ SK_I32 SenThreWarnHigh; /* High warning Threshhold of this sensor */
+ SK_I32 SenThreErrLow; /* Lower error Threshold of the sensor */
+ SK_I32 SenThreWarnLow; /* Lower warning Threshold of the sensor */
+ int SenErrFlag; /* Sensor indicated an error */
+ SK_BOOL SenInit; /* Is sensor initialized ? */
+ SK_U64 SenErrCts; /* Error trap counter */
+ SK_U64 SenWarnCts; /* Warning trap counter */
+ SK_U64 SenBegErrTS; /* Begin error timestamp */
+ SK_U64 SenBegWarnTS; /* Begin warning timestamp */
+ SK_U64 SenLastErrTrapTS; /* Last error trap timestamp */
+ SK_U64 SenLastErrLogTS; /* Last error log timestamp */
+ SK_U64 SenLastWarnTrapTS; /* Last warning trap timestamp */
+ SK_U64 SenLastWarnLogTS; /* Last warning log timestamp */
+ int SenState; /* Sensor State (see HW specific include) */
+ int (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen);
+ /* Sensors read function */
+ SK_U16 SenReg; /* Register Address for this sensor */
+ SK_U8 SenDev; /* Device Selection for this sensor */
+};
+
+typedef struct s_I2c {
+ SK_SENSOR SenTable[SK_MAX_SENSORS]; /* Sensor Table */
+ int CurrSens; /* Which sensor is currently queried */
+ int MaxSens; /* Max. number of sensors */
+ int TimerMode; /* Use the timer also to watch the state machine */
+ int InitLevel; /* Initialized Level */
+#ifndef SK_DIAG
+ int DummyReads; /* Number of non-checked dummy reads */
+ SK_TIMER SenTimer; /* Sensors timer */
+#endif /* !SK_DIAG */
+} SK_I2C;
+
+extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
+extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size,
+ int Reg, int Burst);
+extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
+#ifdef SK_DIAG
+extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg,
+ int Burst);
+#else /* !SK_DIAG */
+extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
+extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
+extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
+#endif /* !SK_DIAG */
+#endif /* n_SKI2C_H */
+
diff --git a/drivers/net/sk98lin/h/skqueue.h b/drivers/net/sk98lin/h/skqueue.h
new file mode 100644
index 000000000000..2ec40d4fdf60
--- /dev/null
+++ b/drivers/net/sk98lin/h/skqueue.h
@@ -0,0 +1,94 @@
+/******************************************************************************
+ *
+ * Name: skqueue.h
+ * Project: Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version: $Revision: 1.16 $
+ * Date: $Date: 2003/09/16 12:50:32 $
+ * Purpose: Defines for the Event queue
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/*
+ * SKQUEUE.H contains all defines and types for the event queue
+ */
+
+#ifndef _SKQUEUE_H_
+#define _SKQUEUE_H_
+
+
+/*
+ * define the event classes to be served
+ */
+#define SKGE_DRV 1 /* Driver Event Class */
+#define SKGE_RLMT 2 /* RLMT Event Class */
+#define SKGE_I2C 3 /* I2C Event Class */
+#define SKGE_PNMI 4 /* PNMI Event Class */
+#define SKGE_CSUM 5 /* Checksum Event Class */
+#define SKGE_HWAC 6 /* Hardware Access Event Class */
+
+#define SKGE_SWT 9 /* Software Timer Event Class */
+#define SKGE_LACP 10 /* LACP Aggregation Event Class */
+#define SKGE_RSF 11 /* RSF Aggregation Event Class */
+#define SKGE_MARKER 12 /* MARKER Aggregation Event Class */
+#define SKGE_FD 13 /* FD Distributor Event Class */
+
+/*
+ * define event queue as circular buffer
+ */
+#define SK_MAX_EVENT 64
+
+/*
+ * Parameter union for the Para stuff
+ */
+typedef union u_EvPara {
+ void *pParaPtr; /* Parameter Pointer */
+ SK_U64 Para64; /* Parameter 64bit version */
+ SK_U32 Para32[2]; /* Parameter Array of 32bit parameters */
+} SK_EVPARA;
+
+/*
+ * Event Queue
+ * skqueue.c
+ * events are class/value pairs
+ * class is addressee, e.g. RLMT, PNMI etc.
+ * value is command, e.g. line state change, ring op change etc.
+ */
+typedef struct s_EventElem {
+ SK_U32 Class; /* Event class */
+ SK_U32 Event; /* Event value */
+ SK_EVPARA Para; /* Event parameter */
+} SK_EVENTELEM;
+
+typedef struct s_Queue {
+ SK_EVENTELEM EvQueue[SK_MAX_EVENT];
+ SK_EVENTELEM *EvPut;
+ SK_EVENTELEM *EvGet;
+} SK_QUEUE;
+
+extern void SkEventInit(SK_AC *pAC, SK_IOC Ioc, int Level);
+extern void SkEventQueue(SK_AC *pAC, SK_U32 Class, SK_U32 Event,
+ SK_EVPARA Para);
+extern int SkEventDispatcher(SK_AC *pAC, SK_IOC Ioc);
+
+
+/* Define Error Numbers and messages */
+#define SKERR_Q_E001 (SK_ERRBASE_QUEUE+0)
+#define SKERR_Q_E001MSG "Event queue overflow"
+#define SKERR_Q_E002 (SKERR_Q_E001+1)
+#define SKERR_Q_E002MSG "Undefined event class"
+#endif /* _SKQUEUE_H_ */
+
diff --git a/drivers/net/sk98lin/h/skrlmt.h b/drivers/net/sk98lin/h/skrlmt.h
new file mode 100644
index 000000000000..ca75dfdcf2d6
--- /dev/null
+++ b/drivers/net/sk98lin/h/skrlmt.h
@@ -0,0 +1,438 @@
+/******************************************************************************
+ *
+ * Name: skrlmt.h
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.37 $
+ * Date: $Date: 2003/04/15 09:43:43 $
+ * Purpose: Header file for Redundant Link ManagemenT.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This is the header file for Redundant Link ManagemenT.
+ *
+ * Include File Hierarchy:
+ *
+ * "skdrv1st.h"
+ * ...
+ * "sktypes.h"
+ * "skqueue.h"
+ * "skaddr.h"
+ * "skrlmt.h"
+ * ...
+ * "skdrv2nd.h"
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKRLMT_H
+#define __INC_SKRLMT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* cplusplus */
+
+/* defines ********************************************************************/
+
+#define SK_RLMT_NET_DOWN_TEMP 1 /* NET_DOWN due to last port down. */
+#define SK_RLMT_NET_DOWN_FINAL 2 /* NET_DOWN due to RLMT_STOP. */
+
+/* ----- Default queue sizes - must be multiples of 8 KB ----- */
+
+/* Less than 8 KB free in RX queue => pause frames. */
+#define SK_RLMT_STANDBY_QRXSIZE 128 /* Size of rx standby queue in KB. */
+#define SK_RLMT_STANDBY_QXASIZE 32 /* Size of async standby queue in KB. */
+#define SK_RLMT_STANDBY_QXSSIZE 0 /* Size of sync standby queue in KB. */
+
+#define SK_RLMT_MAX_TX_BUF_SIZE 60 /* Maximum RLMT transmit size. */
+
+/* ----- PORT states ----- */
+
+#define SK_RLMT_PS_INIT 0 /* Port state: Init. */
+#define SK_RLMT_PS_LINK_DOWN 1 /* Port state: Link down. */
+#define SK_RLMT_PS_DOWN 2 /* Port state: Port down. */
+#define SK_RLMT_PS_GOING_UP 3 /* Port state: Going up. */
+#define SK_RLMT_PS_UP 4 /* Port state: Up. */
+
+/* ----- RLMT states ----- */
+
+#define SK_RLMT_RS_INIT 0 /* RLMT state: Init. */
+#define SK_RLMT_RS_NET_DOWN 1 /* RLMT state: Net down. */
+#define SK_RLMT_RS_NET_UP 2 /* RLMT state: Net up. */
+
+/* ----- PORT events ----- */
+
+#define SK_RLMT_LINK_UP 1001 /* Link came up. */
+#define SK_RLMT_LINK_DOWN 1002 /* Link went down. */
+#define SK_RLMT_PORT_ADDR 1003 /* Port address changed. */
+
+/* ----- RLMT events ----- */
+
+#define SK_RLMT_START 2001 /* Start RLMT. */
+#define SK_RLMT_STOP 2002 /* Stop RLMT. */
+#define SK_RLMT_PACKET_RECEIVED 2003 /* Packet was received for RLMT. */
+#define SK_RLMT_STATS_CLEAR 2004 /* Clear statistics. */
+#define SK_RLMT_STATS_UPDATE 2005 /* Update statistics. */
+#define SK_RLMT_PREFPORT_CHANGE 2006 /* Change preferred port. */
+#define SK_RLMT_MODE_CHANGE 2007 /* New RlmtMode. */
+#define SK_RLMT_SET_NETS 2008 /* Number of Nets (1 or 2). */
+
+/* ----- RLMT mode bits ----- */
+
+/*
+ * CAUTION: These defines are private to RLMT.
+ * Please use the RLMT mode defines below.
+ */
+
+#define SK_RLMT_CHECK_LINK 1 /* Check Link. */
+#define SK_RLMT_CHECK_LOC_LINK 2 /* Check other link on same adapter. */
+#define SK_RLMT_CHECK_SEG 4 /* Check segmentation. */
+
+#ifndef RLMT_CHECK_REMOTE
+#define SK_RLMT_CHECK_OTHERS SK_RLMT_CHECK_LOC_LINK
+#else /* RLMT_CHECK_REMOTE */
+#define SK_RLMT_CHECK_REM_LINK 8 /* Check link(s) on other adapter(s). */
+#define SK_RLMT_MAX_REMOTE_PORTS_CHECKED 3
+#define SK_RLMT_CHECK_OTHERS \
+ (SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
+#endif /* RLMT_CHECK_REMOTE */
+
+#ifndef SK_RLMT_ENABLE_TRANSPARENT
+#define SK_RLMT_TRANSPARENT 0 /* RLMT transparent - inactive. */
+#else /* SK_RLMT_ENABLE_TRANSPARENT */
+#define SK_RLMT_TRANSPARENT 128 /* RLMT transparent. */
+#endif /* SK_RLMT_ENABLE_TRANSPARENT */
+
+/* ----- RLMT modes ----- */
+
+/* Check Link State. */
+#define SK_RLMT_MODE_CLS (SK_RLMT_CHECK_LINK)
+
+/* Check Local Ports: check other links on the same adapter. */
+#define SK_RLMT_MODE_CLP (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK)
+
+/* Check Local Ports and Segmentation Status. */
+#define SK_RLMT_MODE_CLPSS \
+ (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_SEG)
+
+#ifdef RLMT_CHECK_REMOTE
+/* Check Local and Remote Ports: check links (local or remote). */
+ Name of define TBD!
+#define SK_RLMT_MODE_CRP \
+ (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | SK_RLMT_CHECK_REM_LINK)
+
+/* Check Local and Remote Ports and Segmentation Status. */
+ Name of define TBD!
+#define SK_RLMT_MODE_CRPSS \
+ (SK_RLMT_CHECK_LINK | SK_RLMT_CHECK_LOC_LINK | \
+ SK_RLMT_CHECK_REM_LINK | SK_RLMT_CHECK_SEG)
+#endif /* RLMT_CHECK_REMOTE */
+
+/* ----- RLMT lookahead result bits ----- */
+
+#define SK_RLMT_RX_RLMT 1 /* Give packet to RLMT. */
+#define SK_RLMT_RX_PROTOCOL 2 /* Give packet to protocol. */
+
+/* Macros */
+
+#if 0
+SK_AC *pAC /* adapter context */
+SK_U32 PortNum /* receiving port */
+unsigned PktLen /* received packet's length */
+SK_BOOL IsBc /* Flag: packet is broadcast */
+unsigned *pOffset /* offs. of bytes to present to SK_RLMT_LOOKAHEAD */
+unsigned *pNumBytes /* #Bytes to present to SK_RLMT_LOOKAHEAD */
+#endif /* 0 */
+
+#define SK_RLMT_PRE_LOOKAHEAD(pAC,PortNum,PktLen,IsBc,pOffset,pNumBytes) { \
+ SK_AC *_pAC; \
+ SK_U32 _PortNum; \
+ _pAC = (pAC); \
+ _PortNum = (SK_U32)(PortNum); \
+ /* _pAC->Rlmt.Port[_PortNum].PacketsRx++; */ \
+ _pAC->Rlmt.Port[_PortNum].PacketsPerTimeSlot++; \
+ if (_pAC->Rlmt.RlmtOff) { \
+ *(pNumBytes) = 0; \
+ } \
+ else {\
+ if ((_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_TRANSPARENT) != 0) { \
+ *(pNumBytes) = 0; \
+ } \
+ else if (IsBc) { \
+ if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode != SK_RLMT_MODE_CLS) { \
+ *(pNumBytes) = 6; \
+ *(pOffset) = 6; \
+ } \
+ else { \
+ *(pNumBytes) = 0; \
+ } \
+ } \
+ else { \
+ if ((PktLen) > SK_RLMT_MAX_TX_BUF_SIZE) { \
+ /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
+ *(pNumBytes) = 0; \
+ } \
+ else { \
+ *(pNumBytes) = 6; \
+ *(pOffset) = 0; \
+ } \
+ } \
+ } \
+}
+
+#if 0
+SK_AC *pAC /* adapter context */
+SK_U32 PortNum /* receiving port */
+SK_U8 *pLaPacket, /* received packet's data (points to pOffset) */
+SK_BOOL IsBc /* Flag: packet is broadcast */
+SK_BOOL IsMc /* Flag: packet is multicast */
+unsigned *pForRlmt /* Result: bits SK_RLMT_RX_RLMT, SK_RLMT_RX_PROTOCOL */
+SK_RLMT_LOOKAHEAD() expects *pNumBytes from
+packet offset *pOffset (s.a.) at *pLaPacket.
+
+If you use SK_RLMT_LOOKAHEAD in a path where you already know if the packet is
+BC, MC, or UC, you should use constants for IsBc and IsMc, so that your compiler
+can trash unneeded parts of the if construction.
+#endif /* 0 */
+
+#define SK_RLMT_LOOKAHEAD(pAC,PortNum,pLaPacket,IsBc,IsMc,pForRlmt) { \
+ SK_AC *_pAC; \
+ SK_U32 _PortNum; \
+ SK_U8 *_pLaPacket; \
+ _pAC = (pAC); \
+ _PortNum = (SK_U32)(PortNum); \
+ _pLaPacket = (SK_U8 *)(pLaPacket); \
+ if (IsBc) {\
+ if (!SK_ADDR_EQUAL(_pLaPacket, _pAC->Addr.Net[_pAC->Rlmt.Port[ \
+ _PortNum].Net->NetNumber].CurrentMacAddress.a)) { \
+ _pAC->Rlmt.Port[_PortNum].BcTimeStamp = SkOsGetTime(_pAC); \
+ _pAC->Rlmt.CheckSwitch = SK_TRUE; \
+ } \
+ /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
+ *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
+ } \
+ else if (IsMc) { \
+ if (SK_ADDR_EQUAL(_pLaPacket, BridgeMcAddr.a)) { \
+ _pAC->Rlmt.Port[_PortNum].BpduPacketsPerTimeSlot++; \
+ if (_pAC->Rlmt.Port[_PortNum].Net->RlmtMode & SK_RLMT_CHECK_SEG) { \
+ *(pForRlmt) = SK_RLMT_RX_RLMT | SK_RLMT_RX_PROTOCOL; \
+ } \
+ else { \
+ *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
+ } \
+ } \
+ else if (SK_ADDR_EQUAL(_pLaPacket, SkRlmtMcAddr.a)) { \
+ *(pForRlmt) = SK_RLMT_RX_RLMT; \
+ } \
+ else { \
+ /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
+ *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
+ } \
+ } \
+ else { \
+ if (SK_ADDR_EQUAL( \
+ _pLaPacket, \
+ _pAC->Addr.Port[_PortNum].CurrentMacAddress.a)) { \
+ *(pForRlmt) = SK_RLMT_RX_RLMT; \
+ } \
+ else { \
+ /* _pAC->Rlmt.Port[_PortNum].DataPacketsPerTimeSlot++; */ \
+ *(pForRlmt) = SK_RLMT_RX_PROTOCOL; \
+ } \
+ } \
+}
+
+#ifdef SK_RLMT_FAST_LOOKAHEAD
+Error: SK_RLMT_FAST_LOOKAHEAD no longer used. Use new macros for lookahead.
+#endif /* SK_RLMT_FAST_LOOKAHEAD */
+#ifdef SK_RLMT_SLOW_LOOKAHEAD
+Error: SK_RLMT_SLOW_LOOKAHEAD no longer used. Use new macros for lookahead.
+#endif /* SK_RLMT_SLOW_LOOKAHEAD */
+
+/* typedefs *******************************************************************/
+
+#ifdef SK_RLMT_MBUF_PRIVATE
+typedef struct s_RlmtMbuf {
+ some content
+} SK_RLMT_MBUF;
+#endif /* SK_RLMT_MBUF_PRIVATE */
+
+
+#ifdef SK_LA_INFO
+typedef struct s_Rlmt_PacketInfo {
+ unsigned PacketLength; /* Length of packet. */
+ unsigned PacketType; /* Directed/Multicast/Broadcast. */
+} SK_RLMT_PINFO;
+#endif /* SK_LA_INFO */
+
+
+typedef struct s_RootId {
+ SK_U8 Id[8]; /* Root Bridge Id. */
+} SK_RLMT_ROOT_ID;
+
+
+typedef struct s_port {
+ SK_MAC_ADDR CheckAddr;
+ SK_BOOL SuspectTx;
+} SK_PORT_CHECK;
+
+
+typedef struct s_RlmtNet SK_RLMT_NET;
+
+
+typedef struct s_RlmtPort {
+
+/* ----- Public part (read-only) ----- */
+
+ SK_U8 PortState; /* Current state of this port. */
+
+ /* For PNMI */
+ SK_BOOL LinkDown;
+ SK_BOOL PortDown;
+ SK_U8 Align01;
+
+ SK_U32 PortNumber; /* Number of port on adapter. */
+ SK_RLMT_NET * Net; /* Net port belongs to. */
+
+ SK_U64 TxHelloCts;
+ SK_U64 RxHelloCts;
+ SK_U64 TxSpHelloReqCts;
+ SK_U64 RxSpHelloCts;
+
+/* ----- Private part ----- */
+
+/* SK_U64 PacketsRx; */ /* Total packets received. */
+ SK_U32 PacketsPerTimeSlot; /* Packets rxed between TOs. */
+/* SK_U32 DataPacketsPerTimeSlot; */ /* Data packets ... */
+ SK_U32 BpduPacketsPerTimeSlot; /* BPDU packets rxed in TS. */
+ SK_U64 BcTimeStamp; /* Time of last BC receive. */
+ SK_U64 GuTimeStamp; /* Time of entering GOING_UP. */
+
+ SK_TIMER UpTimer; /* Timer struct Link/Port up. */
+ SK_TIMER DownRxTimer; /* Timer struct down rx. */
+ SK_TIMER DownTxTimer; /* Timer struct down tx. */
+
+ SK_U32 CheckingState; /* Checking State. */
+
+ SK_ADDR_PORT * AddrPort;
+
+ SK_U8 Random[4]; /* Random value. */
+ unsigned PortsChecked; /* #ports checked. */
+ unsigned PortsSuspect; /* #ports checked that are s. */
+ SK_PORT_CHECK PortCheck[1];
+/* SK_PORT_CHECK PortCheck[SK_MAX_MACS - 1]; */
+
+ SK_BOOL PortStarted; /* Port is started. */
+ SK_BOOL PortNoRx; /* NoRx for >= 1 time slot. */
+ SK_BOOL RootIdSet;
+ SK_RLMT_ROOT_ID Root; /* Root Bridge Id. */
+} SK_RLMT_PORT;
+
+
+struct s_RlmtNet {
+
+/* ----- Public part (read-only) ----- */
+
+ SK_U32 NetNumber; /* Number of net. */
+
+ SK_RLMT_PORT * Port[SK_MAX_MACS]; /* Ports that belong to this net. */
+ SK_U32 NumPorts; /* Number of ports. */
+ SK_U32 PrefPort; /* Preferred port. */
+
+ /* For PNMI */
+
+ SK_U32 ChgBcPrio; /* Change Priority of last broadcast received */
+ SK_U32 RlmtMode; /* Check ... */
+ SK_U32 ActivePort; /* Active port. */
+ SK_U32 Preference; /* 0xFFFFFFFF: Automatic. */
+
+ SK_U8 RlmtState; /* Current RLMT state. */
+
+/* ----- Private part ----- */
+ SK_BOOL RootIdSet;
+ SK_U16 Align01;
+
+ int LinksUp; /* #Links up. */
+ int PortsUp; /* #Ports up. */
+ SK_U32 TimeoutValue; /* RLMT timeout value. */
+
+ SK_U32 CheckingState; /* Checking State. */
+ SK_RLMT_ROOT_ID Root; /* Root Bridge Id. */
+
+ SK_TIMER LocTimer; /* Timer struct. */
+ SK_TIMER SegTimer; /* Timer struct. */
+};
+
+
+typedef struct s_Rlmt {
+
+/* ----- Public part (read-only) ----- */
+
+ SK_U32 NumNets; /* Number of nets. */
+ SK_U32 NetsStarted; /* Number of nets started. */
+ SK_RLMT_NET Net[SK_MAX_NETS]; /* Array of available nets. */
+ SK_RLMT_PORT Port[SK_MAX_MACS]; /* Array of available ports. */
+
+/* ----- Private part ----- */
+ SK_BOOL CheckSwitch;
+ SK_BOOL RlmtOff; /* set to zero if the Mac addresses
+ are equal or the second one
+ is zero */
+ SK_U16 Align01;
+
+} SK_RLMT;
+
+
+extern SK_MAC_ADDR BridgeMcAddr;
+extern SK_MAC_ADDR SkRlmtMcAddr;
+
+/* function prototypes ********************************************************/
+
+
+#ifndef SK_KR_PROTO
+
+/* Functions provided by SkRlmt */
+
+/* ANSI/C++ compliant function prototypes */
+
+extern void SkRlmtInit(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int Level);
+
+extern int SkRlmtEvent(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ SK_U32 Event,
+ SK_EVPARA Para);
+
+#else /* defined(SK_KR_PROTO) */
+
+/* Non-ANSI/C++ compliant function prototypes */
+
+#error KR-style function prototypes are not yet provided.
+
+#endif /* defined(SK_KR_PROTO)) */
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INC_SKRLMT_H */
diff --git a/drivers/net/sk98lin/h/sktimer.h b/drivers/net/sk98lin/h/sktimer.h
new file mode 100644
index 000000000000..04e6d7c1ec33
--- /dev/null
+++ b/drivers/net/sk98lin/h/sktimer.h
@@ -0,0 +1,63 @@
+/******************************************************************************
+ *
+ * Name: sktimer.h
+ * Project: Gigabit Ethernet Adapters, Event Scheduler Module
+ * Version: $Revision: 1.11 $
+ * Date: $Date: 2003/09/16 12:58:18 $
+ * Purpose: Defines for the timer functions
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/*
+ * SKTIMER.H contains all defines and types for the timer functions
+ */
+
+#ifndef _SKTIMER_H_
+#define _SKTIMER_H_
+
+#include "h/skqueue.h"
+
+/*
+ * SK timer
+ * - needed wherever a timer is used. Put this in your data structure
+ * wherever you want.
+ */
+typedef struct s_Timer SK_TIMER;
+
+struct s_Timer {
+ SK_TIMER *TmNext; /* linked list */
+ SK_U32 TmClass; /* Timer Event class */
+ SK_U32 TmEvent; /* Timer Event value */
+ SK_EVPARA TmPara; /* Timer Event parameter */
+ SK_U32 TmDelta; /* delta time */
+ int TmActive; /* flag: active/inactive */
+};
+
+/*
+ * Timer control struct.
+ * - use in Adapters context name pAC->Tim
+ */
+typedef struct s_TimCtrl {
+ SK_TIMER *StQueue; /* Head of Timer queue */
+} SK_TIMCTRL;
+
+extern void SkTimerInit(SK_AC *pAC, SK_IOC Ioc, int Level);
+extern void SkTimerStop(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer);
+extern void SkTimerStart(SK_AC *pAC, SK_IOC Ioc, SK_TIMER *pTimer,
+ SK_U32 Time, SK_U32 Class, SK_U32 Event, SK_EVPARA Para);
+extern void SkTimerDone(SK_AC *pAC, SK_IOC Ioc);
+#endif /* _SKTIMER_H_ */
diff --git a/drivers/net/sk98lin/h/sktypes.h b/drivers/net/sk98lin/h/sktypes.h
new file mode 100644
index 000000000000..40edc96e1055
--- /dev/null
+++ b/drivers/net/sk98lin/h/sktypes.h
@@ -0,0 +1,69 @@
+/******************************************************************************
+ *
+ * Name: sktypes.h
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.2 $
+ * Date: $Date: 2003/10/07 08:16:51 $
+ * Purpose: Define data types for Linux
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * In this file, all data types that are needed by the common modules
+ * are mapped to Linux data types.
+ *
+ *
+ * Include File Hierarchy:
+ *
+ *
+ ******************************************************************************/
+
+#ifndef __INC_SKTYPES_H
+#define __INC_SKTYPES_H
+
+
+/* defines *******************************************************************/
+
+/*
+ * Data types with a specific size. 'I' = signed, 'U' = unsigned.
+ */
+#define SK_I8 s8
+#define SK_U8 u8
+#define SK_I16 s16
+#define SK_U16 u16
+#define SK_I32 s32
+#define SK_U32 u32
+#define SK_I64 s64
+#define SK_U64 u64
+
+#define SK_UPTR ulong /* casting pointer <-> integral */
+
+/*
+* Boolean type.
+*/
+#define SK_BOOL SK_U8
+#define SK_FALSE 0
+#define SK_TRUE (!SK_FALSE)
+
+/* typedefs *******************************************************************/
+
+/* function prototypes ********************************************************/
+
+#endif /* __INC_SKTYPES_H */
diff --git a/drivers/net/sk98lin/h/skversion.h b/drivers/net/sk98lin/h/skversion.h
new file mode 100644
index 000000000000..a1a7294828e5
--- /dev/null
+++ b/drivers/net/sk98lin/h/skversion.h
@@ -0,0 +1,38 @@
+/******************************************************************************
+ *
+ * Name: version.h
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.5 $
+ * Date: $Date: 2003/10/07 08:16:51 $
+ * Purpose: SK specific Error log support
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifdef lint
+static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
+static const char SysKonnectBuildNumber[] =
+ "@(#)SK-BUILD: 6.23 PL: 01";
+#endif /* !defined(lint) */
+
+#define BOOT_STRING "sk98lin: Network Device Driver v6.23\n" \
+ "(C)Copyright 1999-2004 Marvell(R)."
+
+#define VER_STRING "6.23"
+#define DRIVER_FILE_NAME "sk98lin"
+#define DRIVER_REL_DATE "Feb-13-2004"
+
+
diff --git a/drivers/net/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h
new file mode 100644
index 000000000000..bdc1a5eaaae9
--- /dev/null
+++ b/drivers/net/sk98lin/h/skvpd.h
@@ -0,0 +1,271 @@
+/******************************************************************************
+ *
+ * Name: skvpd.h
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.15 $
+ * Date: $Date: 2003/01/13 10:39:38 $
+ * Purpose: Defines and Macros for VPD handling
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2003 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.
+ *
+ ******************************************************************************/
+
+/*
+ * skvpd.h contains Diagnostic specific defines for VPD handling
+ */
+
+#ifndef __INC_SKVPD_H_
+#define __INC_SKVPD_H_
+
+/*
+ * Define Resource Type Identifiers and VPD keywords
+ */
+#define RES_ID 0x82 /* Resource Type ID String (Product Name) */
+#define RES_VPD_R 0x90 /* start of VPD read only area */
+#define RES_VPD_W 0x91 /* start of VPD read/write area */
+#define RES_END 0x78 /* Resource Type End Tag */
+
+#ifndef VPD_NAME
+#define VPD_NAME "Name" /* Product Name, VPD name of RES_ID */
+#endif /* VPD_NAME */
+#define VPD_PN "PN" /* Adapter Part Number */
+#define VPD_EC "EC" /* Adapter Engineering Level */
+#define VPD_MN "MN" /* Manufacture ID */
+#define VPD_SN "SN" /* Serial Number */
+#define VPD_CP "CP" /* Extended Capability */
+#define VPD_RV "RV" /* Checksum and Reserved */
+#define VPD_YA "YA" /* Asset Tag Identifier */
+#define VPD_VL "VL" /* First Error Log Message (SK specific) */
+#define VPD_VF "VF" /* Second Error Log Message (SK specific) */
+#define VPD_RW "RW" /* Remaining Read / Write Area */
+
+/* 'type' values for vpd_setup_para() */
+#define VPD_RO_KEY 1 /* RO keys are "PN", "EC", "MN", "SN", "RV" */
+#define VPD_RW_KEY 2 /* RW keys are "Yx", "Vx", and "RW" */
+
+/* 'op' values for vpd_setup_para() */
+#define ADD_KEY 1 /* add the key at the pos "RV" or "RW" */
+#define OWR_KEY 2 /* overwrite key if already exists */
+
+/*
+ * Define READ and WRITE Constants.
+ */
+
+#define VPD_DEV_ID_GENESIS 0x4300
+
+#define VPD_SIZE_YUKON 256
+#define VPD_SIZE_GENESIS 512
+#define VPD_SIZE 512
+#define VPD_READ 0x0000
+#define VPD_WRITE 0x8000
+
+#define VPD_STOP(pAC,IoC) VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG,VPD_WRITE)
+
+#define VPD_GET_RES_LEN(p) ((unsigned int) \
+ (* (SK_U8 *)&(p)[1]) |\
+ ((* (SK_U8 *)&(p)[2]) << 8))
+#define VPD_GET_VPD_LEN(p) ((unsigned int)(* (SK_U8 *)&(p)[2]))
+#define VPD_GET_VAL(p) ((char *)&(p)[3])
+
+#define VPD_MAX_LEN 50
+
+/* VPD status */
+ /* bit 7..1 reserved */
+#define VPD_VALID (1<<0) /* VPD data buffer, vpd_free_ro, */
+ /* and vpd_free_rw valid */
+
+/*
+ * VPD structs
+ */
+typedef struct s_vpd_status {
+ unsigned short Align01; /* Alignment */
+ unsigned short vpd_status; /* VPD status, description see above */
+ int vpd_free_ro; /* unused bytes in read only area */
+ int vpd_free_rw; /* bytes available in read/write area */
+} SK_VPD_STATUS;
+
+typedef struct s_vpd {
+ SK_VPD_STATUS v; /* VPD status structure */
+ char vpd_buf[VPD_SIZE]; /* VPD buffer */
+ int rom_size; /* VPD ROM Size from PCI_OUR_REG_2 */
+ int vpd_size; /* saved VPD-size */
+} SK_VPD;
+
+typedef struct s_vpd_para {
+ unsigned int p_len; /* parameter length */
+ char *p_val; /* points to the value */
+} SK_VPD_PARA;
+
+/*
+ * structure of Large Resource Type Identifiers
+ */
+
+/* was removed because of alignment problems */
+
+/*
+ * structure of VPD keywords
+ */
+typedef struct s_vpd_key {
+ char p_key[2]; /* 2 bytes ID string */
+ unsigned char p_len; /* 1 byte length */
+ char p_val; /* start of the value string */
+} SK_VPD_KEY;
+
+
+/*
+ * System specific VPD macros
+ */
+#ifndef SKDIAG
+#ifndef VPD_DO_IO
+#define VPD_OUT8(pAC,IoC,Addr,Val) (void)SkPciWriteCfgByte(pAC,Addr,Val)
+#define VPD_OUT16(pAC,IoC,Addr,Val) (void)SkPciWriteCfgWord(pAC,Addr,Val)
+#define VPD_OUT32(pAC,IoC,Addr,Val) (void)SkPciWriteCfgDWord(pAC,Addr,Val)
+#define VPD_IN8(pAC,IoC,Addr,pVal) (void)SkPciReadCfgByte(pAC,Addr,pVal)
+#define VPD_IN16(pAC,IoC,Addr,pVal) (void)SkPciReadCfgWord(pAC,Addr,pVal)
+#define VPD_IN32(pAC,IoC,Addr,pVal) (void)SkPciReadCfgDWord(pAC,Addr,pVal)
+#else /* VPD_DO_IO */
+#define VPD_OUT8(pAC,IoC,Addr,Val) SK_OUT8(IoC,PCI_C(Addr),Val)
+#define VPD_OUT16(pAC,IoC,Addr,Val) SK_OUT16(IoC,PCI_C(Addr),Val)
+#define VPD_OUT32(pAC,IoC,Addr,Val) SK_OUT32(IoC,PCI_C(Addr),Val)
+#define VPD_IN8(pAC,IoC,Addr,pVal) SK_IN8(IoC,PCI_C(Addr),pVal)
+#define VPD_IN16(pAC,IoC,Addr,pVal) SK_IN16(IoC,PCI_C(Addr),pVal)
+#define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(Addr),pVal)
+#endif /* VPD_DO_IO */
+#else /* SKDIAG */
+#define VPD_OUT8(pAC,Ioc,Addr,Val) { \
+ if ((pAC)->DgT.DgUseCfgCycle) \
+ SkPciWriteCfgByte(pAC,Addr,Val); \
+ else \
+ SK_OUT8(pAC,PCI_C(Addr),Val); \
+ }
+#define VPD_OUT16(pAC,Ioc,Addr,Val) { \
+ if ((pAC)->DgT.DgUseCfgCycle) \
+ SkPciWriteCfgWord(pAC,Addr,Val); \
+ else \
+ SK_OUT16(pAC,PCI_C(Addr),Val); \
+ }
+#define VPD_OUT32(pAC,Ioc,Addr,Val) { \
+ if ((pAC)->DgT.DgUseCfgCycle) \
+ SkPciWriteCfgDWord(pAC,Addr,Val); \
+ else \
+ SK_OUT32(pAC,PCI_C(Addr),Val); \
+ }
+#define VPD_IN8(pAC,Ioc,Addr,pVal) { \
+ if ((pAC)->DgT.DgUseCfgCycle) \
+ SkPciReadCfgByte(pAC,Addr,pVal); \
+ else \
+ SK_IN8(pAC,PCI_C(Addr),pVal); \
+ }
+#define VPD_IN16(pAC,Ioc,Addr,pVal) { \
+ if ((pAC)->DgT.DgUseCfgCycle) \
+ SkPciReadCfgWord(pAC,Addr,pVal); \
+ else \
+ SK_IN16(pAC,PCI_C(Addr),pVal); \
+ }
+#define VPD_IN32(pAC,Ioc,Addr,pVal) { \
+ if ((pAC)->DgT.DgUseCfgCycle) \
+ SkPciReadCfgDWord(pAC,Addr,pVal); \
+ else \
+ SK_IN32(pAC,PCI_C(Addr),pVal); \
+ }
+#endif /* nSKDIAG */
+
+/* function prototypes ********************************************************/
+
+#ifndef SK_KR_PROTO
+#ifdef SKDIAG
+extern SK_U32 VpdReadDWord(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ int addr);
+#endif /* SKDIAG */
+
+extern int VpdSetupPara(
+ SK_AC *pAC,
+ const char *key,
+ const char *buf,
+ int len,
+ int type,
+ int op);
+
+extern SK_VPD_STATUS *VpdStat(
+ SK_AC *pAC,
+ SK_IOC IoC);
+
+extern int VpdKeys(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ char *buf,
+ int *len,
+ int *elements);
+
+extern int VpdRead(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ const char *key,
+ char *buf,
+ int *len);
+
+extern SK_BOOL VpdMayWrite(
+ char *key);
+
+extern int VpdWrite(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ const char *key,
+ const char *buf);
+
+extern int VpdDelete(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ char *key);
+
+extern int VpdUpdate(
+ SK_AC *pAC,
+ SK_IOC IoC);
+
+extern void VpdErrLog(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ char *msg);
+
+#ifdef SKDIAG
+extern int VpdReadBlock(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ char *buf,
+ int addr,
+ int len);
+
+extern int VpdWriteBlock(
+ SK_AC *pAC,
+ SK_IOC IoC,
+ char *buf,
+ int addr,
+ int len);
+#endif /* SKDIAG */
+#else /* SK_KR_PROTO */
+extern SK_U32 VpdReadDWord();
+extern int VpdSetupPara();
+extern SK_VPD_STATUS *VpdStat();
+extern int VpdKeys();
+extern int VpdRead();
+extern SK_BOOL VpdMayWrite();
+extern int VpdWrite();
+extern int VpdDelete();
+extern int VpdUpdate();
+extern void VpdErrLog();
+#endif /* SK_KR_PROTO */
+
+#endif /* __INC_SKVPD_H_ */
diff --git a/drivers/net/sk98lin/h/xmac_ii.h b/drivers/net/sk98lin/h/xmac_ii.h
new file mode 100644
index 000000000000..2b19f8ad0318
--- /dev/null
+++ b/drivers/net/sk98lin/h/xmac_ii.h
@@ -0,0 +1,1579 @@
+/******************************************************************************
+ *
+ * Name: xmac_ii.h
+ * Project: Gigabit Ethernet Adapters, Common Modules
+ * Version: $Revision: 1.52 $
+ * Date: $Date: 2003/10/02 16:35:50 $
+ * Purpose: Defines and Macros for Gigabit Ethernet Controller
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef __INC_XMAC_H
+#define __INC_XMAC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* defines ********************************************************************/
+
+/*
+ * XMAC II registers
+ *
+ * The XMAC registers are 16 or 32 bits wide.
+ * The XMACs host processor interface is set to 16 bit mode,
+ * therefore ALL registers will be addressed with 16 bit accesses.
+ *
+ * The following macros are provided to access the XMAC registers
+ * XM_IN16(), XM_OUT16, XM_IN32(), XM_OUT32(), XM_INADR(), XM_OUTADR(),
+ * XM_INHASH(), and XM_OUTHASH().
+ * The macros are defined in SkGeHw.h.
+ *
+ * Note: NA reg = Network Address e.g DA, SA etc.
+ *
+ */
+#define XM_MMU_CMD 0x0000 /* 16 bit r/w MMU Command Register */
+ /* 0x0004: reserved */
+#define XM_POFF 0x0008 /* 32 bit r/w Packet Offset Register */
+#define XM_BURST 0x000c /* 32 bit r/w Burst Register for half duplex*/
+#define XM_1L_VLAN_TAG 0x0010 /* 16 bit r/w One Level VLAN Tag ID */
+#define XM_2L_VLAN_TAG 0x0014 /* 16 bit r/w Two Level VLAN Tag ID */
+ /* 0x0018 - 0x001e: reserved */
+#define XM_TX_CMD 0x0020 /* 16 bit r/w Transmit Command Register */
+#define XM_TX_RT_LIM 0x0024 /* 16 bit r/w Transmit Retry Limit Register */
+#define XM_TX_STIME 0x0028 /* 16 bit r/w Transmit Slottime Register */
+#define XM_TX_IPG 0x002c /* 16 bit r/w Transmit Inter Packet Gap */
+#define XM_RX_CMD 0x0030 /* 16 bit r/w Receive Command Register */
+#define XM_PHY_ADDR 0x0034 /* 16 bit r/w PHY Address Register */
+#define XM_PHY_DATA 0x0038 /* 16 bit r/w PHY Data Register */
+ /* 0x003c: reserved */
+#define XM_GP_PORT 0x0040 /* 32 bit r/w General Purpose Port Register */
+#define XM_IMSK 0x0044 /* 16 bit r/w Interrupt Mask Register */
+#define XM_ISRC 0x0048 /* 16 bit r/o Interrupt Status Register */
+#define XM_HW_CFG 0x004c /* 16 bit r/w Hardware Config Register */
+ /* 0x0050 - 0x005e: reserved */
+#define XM_TX_LO_WM 0x0060 /* 16 bit r/w Tx FIFO Low Water Mark */
+#define XM_TX_HI_WM 0x0062 /* 16 bit r/w Tx FIFO High Water Mark */
+#define XM_TX_THR 0x0064 /* 16 bit r/w Tx Request Threshold */
+#define XM_HT_THR 0x0066 /* 16 bit r/w Host Request Threshold */
+#define XM_PAUSE_DA 0x0068 /* NA reg r/w Pause Destination Address */
+ /* 0x006e: reserved */
+#define XM_CTL_PARA 0x0070 /* 32 bit r/w Control Parameter Register */
+#define XM_MAC_OPCODE 0x0074 /* 16 bit r/w Opcode for MAC control frames */
+#define XM_MAC_PTIME 0x0076 /* 16 bit r/w Pause time for MAC ctrl frames*/
+#define XM_TX_STAT 0x0078 /* 32 bit r/o Tx Status LIFO Register */
+
+ /* 0x0080 - 0x00fc: 16 NA reg r/w Exact Match Address Registers */
+ /* use the XM_EXM() macro to address */
+#define XM_EXM_START 0x0080 /* r/w Start Address of the EXM Regs */
+
+ /*
+ * XM_EXM(Reg)
+ *
+ * returns the XMAC address offset of specified Exact Match Addr Reg
+ *
+ * para: Reg EXM register to addr (0 .. 15)
+ *
+ * usage: XM_INADDR(IoC, MAC_1, XM_EXM(i), &val[i]);
+ */
+#define XM_EXM(Reg) (XM_EXM_START + ((Reg) << 3))
+
+#define XM_SRC_CHK 0x0100 /* NA reg r/w Source Check Address Register */
+#define XM_SA 0x0108 /* NA reg r/w Station Address Register */
+#define XM_HSM 0x0110 /* 64 bit r/w Hash Match Address Registers */
+#define XM_RX_LO_WM 0x0118 /* 16 bit r/w Receive Low Water Mark */
+#define XM_RX_HI_WM 0x011a /* 16 bit r/w Receive High Water Mark */
+#define XM_RX_THR 0x011c /* 32 bit r/w Receive Request Threshold */
+#define XM_DEV_ID 0x0120 /* 32 bit r/o Device ID Register */
+#define XM_MODE 0x0124 /* 32 bit r/w Mode Register */
+#define XM_LSA 0x0128 /* NA reg r/o Last Source Register */
+ /* 0x012e: reserved */
+#define XM_TS_READ 0x0130 /* 32 bit r/o Time Stamp Read Register */
+#define XM_TS_LOAD 0x0134 /* 32 bit r/o Time Stamp Load Value */
+ /* 0x0138 - 0x01fe: reserved */
+#define XM_STAT_CMD 0x0200 /* 16 bit r/w Statistics Command Register */
+#define XM_RX_CNT_EV 0x0204 /* 32 bit r/o Rx Counter Event Register */
+#define XM_TX_CNT_EV 0x0208 /* 32 bit r/o Tx Counter Event Register */
+#define XM_RX_EV_MSK 0x020c /* 32 bit r/w Rx Counter Event Mask */
+#define XM_TX_EV_MSK 0x0210 /* 32 bit r/w Tx Counter Event Mask */
+ /* 0x0204 - 0x027e: reserved */
+#define XM_TXF_OK 0x0280 /* 32 bit r/o Frames Transmitted OK Conuter */
+#define XM_TXO_OK_HI 0x0284 /* 32 bit r/o Octets Transmitted OK High Cnt*/
+#define XM_TXO_OK_LO 0x0288 /* 32 bit r/o Octets Transmitted OK Low Cnt */
+#define XM_TXF_BC_OK 0x028c /* 32 bit r/o Broadcast Frames Xmitted OK */
+#define XM_TXF_MC_OK 0x0290 /* 32 bit r/o Multicast Frames Xmitted OK */
+#define XM_TXF_UC_OK 0x0294 /* 32 bit r/o Unicast Frames Xmitted OK */
+#define XM_TXF_LONG 0x0298 /* 32 bit r/o Tx Long Frame Counter */
+#define XM_TXE_BURST 0x029c /* 32 bit r/o Tx Burst Event Counter */
+#define XM_TXF_MPAUSE 0x02a0 /* 32 bit r/o Tx Pause MAC Ctrl Frame Cnt */
+#define XM_TXF_MCTRL 0x02a4 /* 32 bit r/o Tx MAC Ctrl Frame Counter */
+#define XM_TXF_SNG_COL 0x02a8 /* 32 bit r/o Tx Single Collision Counter */
+#define XM_TXF_MUL_COL 0x02ac /* 32 bit r/o Tx Multiple Collision Counter */
+#define XM_TXF_ABO_COL 0x02b0 /* 32 bit r/o Tx aborted due to Exces. Col. */
+#define XM_TXF_LAT_COL 0x02b4 /* 32 bit r/o Tx Late Collision Counter */
+#define XM_TXF_DEF 0x02b8 /* 32 bit r/o Tx Deferred Frame Counter */
+#define XM_TXF_EX_DEF 0x02bc /* 32 bit r/o Tx Excessive Deferall Counter */
+#define XM_TXE_FIFO_UR 0x02c0 /* 32 bit r/o Tx FIFO Underrun Event Cnt */
+#define XM_TXE_CS_ERR 0x02c4 /* 32 bit r/o Tx Carrier Sense Error Cnt */
+#define XM_TXP_UTIL 0x02c8 /* 32 bit r/o Tx Utilization in % */
+ /* 0x02cc - 0x02ce: reserved */
+#define XM_TXF_64B 0x02d0 /* 32 bit r/o 64 Byte Tx Frame Counter */
+#define XM_TXF_127B 0x02d4 /* 32 bit r/o 65-127 Byte Tx Frame Counter */
+#define XM_TXF_255B 0x02d8 /* 32 bit r/o 128-255 Byte Tx Frame Counter */
+#define XM_TXF_511B 0x02dc /* 32 bit r/o 256-511 Byte Tx Frame Counter */
+#define XM_TXF_1023B 0x02e0 /* 32 bit r/o 512-1023 Byte Tx Frame Counter*/
+#define XM_TXF_MAX_SZ 0x02e4 /* 32 bit r/o 1024-MaxSize Byte Tx Frame Cnt*/
+ /* 0x02e8 - 0x02fe: reserved */
+#define XM_RXF_OK 0x0300 /* 32 bit r/o Frames Received OK */
+#define XM_RXO_OK_HI 0x0304 /* 32 bit r/o Octets Received OK High Cnt */
+#define XM_RXO_OK_LO 0x0308 /* 32 bit r/o Octets Received OK Low Counter*/
+#define XM_RXF_BC_OK 0x030c /* 32 bit r/o Broadcast Frames Received OK */
+#define XM_RXF_MC_OK 0x0310 /* 32 bit r/o Multicast Frames Received OK */
+#define XM_RXF_UC_OK 0x0314 /* 32 bit r/o Unicast Frames Received OK */
+#define XM_RXF_MPAUSE 0x0318 /* 32 bit r/o Rx Pause MAC Ctrl Frame Cnt */
+#define XM_RXF_MCTRL 0x031c /* 32 bit r/o Rx MAC Ctrl Frame Counter */
+#define XM_RXF_INV_MP 0x0320 /* 32 bit r/o Rx invalid Pause Frame Cnt */
+#define XM_RXF_INV_MOC 0x0324 /* 32 bit r/o Rx Frames with inv. MAC Opcode*/
+#define XM_RXE_BURST 0x0328 /* 32 bit r/o Rx Burst Event Counter */
+#define XM_RXE_FMISS 0x032c /* 32 bit r/o Rx Missed Frames Event Cnt */
+#define XM_RXF_FRA_ERR 0x0330 /* 32 bit r/o Rx Framing Error Counter */
+#define XM_RXE_FIFO_OV 0x0334 /* 32 bit r/o Rx FIFO overflow Event Cnt */
+#define XM_RXF_JAB_PKT 0x0338 /* 32 bit r/o Rx Jabber Packet Frame Cnt */
+#define XM_RXE_CAR_ERR 0x033c /* 32 bit r/o Rx Carrier Event Error Cnt */
+#define XM_RXF_LEN_ERR 0x0340 /* 32 bit r/o Rx in Range Length Error */
+#define XM_RXE_SYM_ERR 0x0344 /* 32 bit r/o Rx Symbol Error Counter */
+#define XM_RXE_SHT_ERR 0x0348 /* 32 bit r/o Rx Short Event Error Cnt */
+#define XM_RXE_RUNT 0x034c /* 32 bit r/o Rx Runt Event Counter */
+#define XM_RXF_LNG_ERR 0x0350 /* 32 bit r/o Rx Frame too Long Error Cnt */
+#define XM_RXF_FCS_ERR 0x0354 /* 32 bit r/o Rx Frame Check Seq. Error Cnt */
+ /* 0x0358 - 0x035a: reserved */
+#define XM_RXF_CEX_ERR 0x035c /* 32 bit r/o Rx Carrier Ext Error Frame Cnt*/
+#define XM_RXP_UTIL 0x0360 /* 32 bit r/o Rx Utilization in % */
+ /* 0x0364 - 0x0366: reserved */
+#define XM_RXF_64B 0x0368 /* 32 bit r/o 64 Byte Rx Frame Counter */
+#define XM_RXF_127B 0x036c /* 32 bit r/o 65-127 Byte Rx Frame Counter */
+#define XM_RXF_255B 0x0370 /* 32 bit r/o 128-255 Byte Rx Frame Counter */
+#define XM_RXF_511B 0x0374 /* 32 bit r/o 256-511 Byte Rx Frame Counter */
+#define XM_RXF_1023B 0x0378 /* 32 bit r/o 512-1023 Byte Rx Frame Counter*/
+#define XM_RXF_MAX_SZ 0x037c /* 32 bit r/o 1024-MaxSize Byte Rx Frame Cnt*/
+ /* 0x02e8 - 0x02fe: reserved */
+
+
+/*----------------------------------------------------------------------------*/
+/*
+ * XMAC Bit Definitions
+ *
+ * If the bit access behaviour differs from the register access behaviour
+ * (r/w, r/o) this is documented after the bit number.
+ * The following bit access behaviours are used:
+ * (sc) self clearing
+ * (ro) read only
+ */
+
+/* XM_MMU_CMD 16 bit r/w MMU Command Register */
+ /* Bit 15..13: reserved */
+#define XM_MMU_PHY_RDY (1<<12) /* Bit 12: PHY Read Ready */
+#define XM_MMU_PHY_BUSY (1<<11) /* Bit 11: PHY Busy */
+#define XM_MMU_IGN_PF (1<<10) /* Bit 10: Ignore Pause Frame */
+#define XM_MMU_MAC_LB (1<<9) /* Bit 9: Enable MAC Loopback */
+ /* Bit 8: reserved */
+#define XM_MMU_FRC_COL (1<<7) /* Bit 7: Force Collision */
+#define XM_MMU_SIM_COL (1<<6) /* Bit 6: Simulate Collision */
+#define XM_MMU_NO_PRE (1<<5) /* Bit 5: No MDIO Preamble */
+#define XM_MMU_GMII_FD (1<<4) /* Bit 4: GMII uses Full Duplex */
+#define XM_MMU_RAT_CTRL (1<<3) /* Bit 3: Enable Rate Control */
+#define XM_MMU_GMII_LOOP (1<<2) /* Bit 2: PHY is in Loopback Mode */
+#define XM_MMU_ENA_RX (1<<1) /* Bit 1: Enable Receiver */
+#define XM_MMU_ENA_TX (1<<0) /* Bit 0: Enable Transmitter */
+
+
+/* XM_TX_CMD 16 bit r/w Transmit Command Register */
+ /* Bit 15..7: reserved */
+#define XM_TX_BK2BK (1<<6) /* Bit 6: Ignor Carrier Sense (Tx Bk2Bk)*/
+#define XM_TX_ENC_BYP (1<<5) /* Bit 5: Set Encoder in Bypass Mode */
+#define XM_TX_SAM_LINE (1<<4) /* Bit 4: (sc) Start utilization calculation */
+#define XM_TX_NO_GIG_MD (1<<3) /* Bit 3: Disable Carrier Extension */
+#define XM_TX_NO_PRE (1<<2) /* Bit 2: Disable Preamble Generation */
+#define XM_TX_NO_CRC (1<<1) /* Bit 1: Disable CRC Generation */
+#define XM_TX_AUTO_PAD (1<<0) /* Bit 0: Enable Automatic Padding */
+
+
+/* XM_TX_RT_LIM 16 bit r/w Transmit Retry Limit Register */
+ /* Bit 15..5: reserved */
+#define XM_RT_LIM_MSK 0x1f /* Bit 4..0: Tx Retry Limit */
+
+
+/* XM_TX_STIME 16 bit r/w Transmit Slottime Register */
+ /* Bit 15..7: reserved */
+#define XM_STIME_MSK 0x7f /* Bit 6..0: Tx Slottime bits */
+
+
+/* XM_TX_IPG 16 bit r/w Transmit Inter Packet Gap */
+ /* Bit 15..8: reserved */
+#define XM_IPG_MSK 0xff /* Bit 7..0: IPG value bits */
+
+
+/* XM_RX_CMD 16 bit r/w Receive Command Register */
+ /* Bit 15..9: reserved */
+#define XM_RX_LENERR_OK (1<<8) /* Bit 8 don't set Rx Err bit for */
+ /* inrange error packets */
+#define XM_RX_BIG_PK_OK (1<<7) /* Bit 7 don't set Rx Err bit for */
+ /* jumbo packets */
+#define XM_RX_IPG_CAP (1<<6) /* Bit 6 repl. type field with IPG */
+#define XM_RX_TP_MD (1<<5) /* Bit 5: Enable transparent Mode */
+#define XM_RX_STRIP_FCS (1<<4) /* Bit 4: Enable FCS Stripping */
+#define XM_RX_SELF_RX (1<<3) /* Bit 3: Enable Rx of own packets */
+#define XM_RX_SAM_LINE (1<<2) /* Bit 2: (sc) Start utilization calculation */
+#define XM_RX_STRIP_PAD (1<<1) /* Bit 1: Strip pad bytes of Rx frames */
+#define XM_RX_DIS_CEXT (1<<0) /* Bit 0: Disable carrier ext. check */
+
+
+/* XM_PHY_ADDR 16 bit r/w PHY Address Register */
+ /* Bit 15..5: reserved */
+#define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */
+
+
+/* XM_GP_PORT 32 bit r/w General Purpose Port Register */
+ /* Bit 31..7: reserved */
+#define XM_GP_ANIP (1L<<6) /* Bit 6: (ro) Auto-Neg. in progress */
+#define XM_GP_FRC_INT (1L<<5) /* Bit 5: (sc) Force Interrupt */
+ /* Bit 4: reserved */
+#define XM_GP_RES_MAC (1L<<3) /* Bit 3: (sc) Reset MAC and FIFOs */
+#define XM_GP_RES_STAT (1L<<2) /* Bit 2: (sc) Reset the statistics module */
+ /* Bit 1: reserved */
+#define XM_GP_INP_ASS (1L<<0) /* Bit 0: (ro) GP Input Pin asserted */
+
+
+/* XM_IMSK 16 bit r/w Interrupt Mask Register */
+/* XM_ISRC 16 bit r/o Interrupt Status Register */
+ /* Bit 15: reserved */
+#define XM_IS_LNK_AE (1<<14) /* Bit 14: Link Asynchronous Event */
+#define XM_IS_TX_ABORT (1<<13) /* Bit 13: Transmit Abort, late Col. etc */
+#define XM_IS_FRC_INT (1<<12) /* Bit 12: Force INT bit set in GP */
+#define XM_IS_INP_ASS (1<<11) /* Bit 11: Input Asserted, GP bit 0 set */
+#define XM_IS_LIPA_RC (1<<10) /* Bit 10: Link Partner requests config */
+#define XM_IS_RX_PAGE (1<<9) /* Bit 9: Page Received */
+#define XM_IS_TX_PAGE (1<<8) /* Bit 8: Next Page Loaded for Transmit */
+#define XM_IS_AND (1<<7) /* Bit 7: Auto-Negotiation Done */
+#define XM_IS_TSC_OV (1<<6) /* Bit 6: Time Stamp Counter Overflow */
+#define XM_IS_RXC_OV (1<<5) /* Bit 5: Rx Counter Event Overflow */
+#define XM_IS_TXC_OV (1<<4) /* Bit 4: Tx Counter Event Overflow */
+#define XM_IS_RXF_OV (1<<3) /* Bit 3: Receive FIFO Overflow */
+#define XM_IS_TXF_UR (1<<2) /* Bit 2: Transmit FIFO Underrun */
+#define XM_IS_TX_COMP (1<<1) /* Bit 1: Frame Tx Complete */
+#define XM_IS_RX_COMP (1<<0) /* Bit 0: Frame Rx Complete */
+
+#define XM_DEF_MSK (~(XM_IS_INP_ASS | XM_IS_LIPA_RC | XM_IS_RX_PAGE |\
+ XM_IS_AND | XM_IS_RXC_OV | XM_IS_TXC_OV | XM_IS_TXF_UR))
+
+
+/* XM_HW_CFG 16 bit r/w Hardware Config Register */
+ /* Bit 15.. 4: reserved */
+#define XM_HW_GEN_EOP (1<<3) /* Bit 3: generate End of Packet pulse */
+#define XM_HW_COM4SIG (1<<2) /* Bit 2: use Comma Detect for Sig. Det.*/
+ /* Bit 1: reserved */
+#define XM_HW_GMII_MD (1<<0) /* Bit 0: GMII Interface selected */
+
+
+/* XM_TX_LO_WM 16 bit r/w Tx FIFO Low Water Mark */
+/* XM_TX_HI_WM 16 bit r/w Tx FIFO High Water Mark */
+ /* Bit 15..10 reserved */
+#define XM_TX_WM_MSK 0x01ff /* Bit 9.. 0 Tx FIFO Watermark bits */
+
+/* XM_TX_THR 16 bit r/w Tx Request Threshold */
+/* XM_HT_THR 16 bit r/w Host Request Threshold */
+/* XM_RX_THR 16 bit r/w Rx Request Threshold */
+ /* Bit 15..11 reserved */
+#define XM_THR_MSK 0x03ff /* Bit 10.. 0 Rx/Tx Request Threshold bits */
+
+
+/* XM_TX_STAT 32 bit r/o Tx Status LIFO Register */
+#define XM_ST_VALID (1UL<<31) /* Bit 31: Status Valid */
+#define XM_ST_BYTE_CNT (0x3fffL<<17) /* Bit 30..17: Tx frame Length */
+#define XM_ST_RETRY_CNT (0x1fL<<12) /* Bit 16..12: Retry Count */
+#define XM_ST_EX_COL (1L<<11) /* Bit 11: Excessive Collisions */
+#define XM_ST_EX_DEF (1L<<10) /* Bit 10: Excessive Deferral */
+#define XM_ST_BURST (1L<<9) /* Bit 9: p. xmitted in burst md*/
+#define XM_ST_DEFER (1L<<8) /* Bit 8: packet was defered */
+#define XM_ST_BC (1L<<7) /* Bit 7: Broadcast packet */
+#define XM_ST_MC (1L<<6) /* Bit 6: Multicast packet */
+#define XM_ST_UC (1L<<5) /* Bit 5: Unicast packet */
+#define XM_ST_TX_UR (1L<<4) /* Bit 4: FIFO Underrun occured */
+#define XM_ST_CS_ERR (1L<<3) /* Bit 3: Carrier Sense Error */
+#define XM_ST_LAT_COL (1L<<2) /* Bit 2: Late Collision Error */
+#define XM_ST_MUL_COL (1L<<1) /* Bit 1: Multiple Collisions */
+#define XM_ST_SGN_COL (1L<<0) /* Bit 0: Single Collision */
+
+/* XM_RX_LO_WM 16 bit r/w Receive Low Water Mark */
+/* XM_RX_HI_WM 16 bit r/w Receive High Water Mark */
+ /* Bit 15..11: reserved */
+#define XM_RX_WM_MSK 0x03ff /* Bit 11.. 0: Rx FIFO Watermark bits */
+
+
+/* XM_DEV_ID 32 bit r/o Device ID Register */
+#define XM_DEV_OUI (0x00ffffffUL<<8) /* Bit 31..8: Device OUI */
+#define XM_DEV_REV (0x07L << 5) /* Bit 7..5: Chip Rev Num */
+
+
+/* XM_MODE 32 bit r/w Mode Register */
+ /* Bit 31..27: reserved */
+#define XM_MD_ENA_REJ (1L<<26) /* Bit 26: Enable Frame Reject */
+#define XM_MD_SPOE_E (1L<<25) /* Bit 25: Send Pause on Edge */
+ /* extern generated */
+#define XM_MD_TX_REP (1L<<24) /* Bit 24: Transmit Repeater Mode */
+#define XM_MD_SPOFF_I (1L<<23) /* Bit 23: Send Pause on FIFO full */
+ /* intern generated */
+#define XM_MD_LE_STW (1L<<22) /* Bit 22: Rx Stat Word in Little Endian */
+#define XM_MD_TX_CONT (1L<<21) /* Bit 21: Send Continuous */
+#define XM_MD_TX_PAUSE (1L<<20) /* Bit 20: (sc) Send Pause Frame */
+#define XM_MD_ATS (1L<<19) /* Bit 19: Append Time Stamp */
+#define XM_MD_SPOL_I (1L<<18) /* Bit 18: Send Pause on Low */
+ /* intern generated */
+#define XM_MD_SPOH_I (1L<<17) /* Bit 17: Send Pause on High */
+ /* intern generated */
+#define XM_MD_CAP (1L<<16) /* Bit 16: Check Address Pair */
+#define XM_MD_ENA_HASH (1L<<15) /* Bit 15: Enable Hashing */
+#define XM_MD_CSA (1L<<14) /* Bit 14: Check Station Address */
+#define XM_MD_CAA (1L<<13) /* Bit 13: Check Address Array */
+#define XM_MD_RX_MCTRL (1L<<12) /* Bit 12: Rx MAC Control Frame */
+#define XM_MD_RX_RUNT (1L<<11) /* Bit 11: Rx Runt Frames */
+#define XM_MD_RX_IRLE (1L<<10) /* Bit 10: Rx in Range Len Err Frame */
+#define XM_MD_RX_LONG (1L<<9) /* Bit 9: Rx Long Frame */
+#define XM_MD_RX_CRCE (1L<<8) /* Bit 8: Rx CRC Error Frame */
+#define XM_MD_RX_ERR (1L<<7) /* Bit 7: Rx Error Frame */
+#define XM_MD_DIS_UC (1L<<6) /* Bit 6: Disable Rx Unicast */
+#define XM_MD_DIS_MC (1L<<5) /* Bit 5: Disable Rx Multicast */
+#define XM_MD_DIS_BC (1L<<4) /* Bit 4: Disable Rx Broadcast */
+#define XM_MD_ENA_PROM (1L<<3) /* Bit 3: Enable Promiscuous */
+#define XM_MD_ENA_BE (1L<<2) /* Bit 2: Enable Big Endian */
+#define XM_MD_FTF (1L<<1) /* Bit 1: (sc) Flush Tx FIFO */
+#define XM_MD_FRF (1L<<0) /* Bit 0: (sc) Flush Rx FIFO */
+
+#define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I)
+#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\
+ XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA)
+
+/* XM_STAT_CMD 16 bit r/w Statistics Command Register */
+ /* Bit 16..6: reserved */
+#define XM_SC_SNP_RXC (1<<5) /* Bit 5: (sc) Snap Rx Counters */
+#define XM_SC_SNP_TXC (1<<4) /* Bit 4: (sc) Snap Tx Counters */
+#define XM_SC_CP_RXC (1<<3) /* Bit 3: Copy Rx Counters Continuously */
+#define XM_SC_CP_TXC (1<<2) /* Bit 2: Copy Tx Counters Continuously */
+#define XM_SC_CLR_RXC (1<<1) /* Bit 1: (sc) Clear Rx Counters */
+#define XM_SC_CLR_TXC (1<<0) /* Bit 0: (sc) Clear Tx Counters */
+
+
+/* XM_RX_CNT_EV 32 bit r/o Rx Counter Event Register */
+/* XM_RX_EV_MSK 32 bit r/w Rx Counter Event Mask */
+#define XMR_MAX_SZ_OV (1UL<<31) /* Bit 31: 1024-MaxSize Rx Cnt Ov*/
+#define XMR_1023B_OV (1L<<30) /* Bit 30: 512-1023Byte Rx Cnt Ov*/
+#define XMR_511B_OV (1L<<29) /* Bit 29: 256-511 Byte Rx Cnt Ov*/
+#define XMR_255B_OV (1L<<28) /* Bit 28: 128-255 Byte Rx Cnt Ov*/
+#define XMR_127B_OV (1L<<27) /* Bit 27: 65-127 Byte Rx Cnt Ov */
+#define XMR_64B_OV (1L<<26) /* Bit 26: 64 Byte Rx Cnt Ov */
+#define XMR_UTIL_OV (1L<<25) /* Bit 25: Rx Util Cnt Overflow */
+#define XMR_UTIL_UR (1L<<24) /* Bit 24: Rx Util Cnt Underrun */
+#define XMR_CEX_ERR_OV (1L<<23) /* Bit 23: CEXT Err Cnt Ov */
+ /* Bit 22: reserved */
+#define XMR_FCS_ERR_OV (1L<<21) /* Bit 21: Rx FCS Error Cnt Ov */
+#define XMR_LNG_ERR_OV (1L<<20) /* Bit 20: Rx too Long Err Cnt Ov*/
+#define XMR_RUNT_OV (1L<<19) /* Bit 19: Runt Event Cnt Ov */
+#define XMR_SHT_ERR_OV (1L<<18) /* Bit 18: Rx Short Ev Err Cnt Ov*/
+#define XMR_SYM_ERR_OV (1L<<17) /* Bit 17: Rx Sym Err Cnt Ov */
+ /* Bit 16: reserved */
+#define XMR_CAR_ERR_OV (1L<<15) /* Bit 15: Rx Carr Ev Err Cnt Ov */
+#define XMR_JAB_PKT_OV (1L<<14) /* Bit 14: Rx Jabb Packet Cnt Ov */
+#define XMR_FIFO_OV (1L<<13) /* Bit 13: Rx FIFO Ov Ev Cnt Ov */
+#define XMR_FRA_ERR_OV (1L<<12) /* Bit 12: Rx Framing Err Cnt Ov */
+#define XMR_FMISS_OV (1L<<11) /* Bit 11: Rx Missed Ev Cnt Ov */
+#define XMR_BURST (1L<<10) /* Bit 10: Rx Burst Event Cnt Ov */
+#define XMR_INV_MOC (1L<<9) /* Bit 9: Rx with inv. MAC OC Ov*/
+#define XMR_INV_MP (1L<<8) /* Bit 8: Rx inv Pause Frame Ov */
+#define XMR_MCTRL_OV (1L<<7) /* Bit 7: Rx MAC Ctrl-F Cnt Ov */
+#define XMR_MPAUSE_OV (1L<<6) /* Bit 6: Rx Pause MAC Ctrl-F Ov*/
+#define XMR_UC_OK_OV (1L<<5) /* Bit 5: Rx Unicast Frame CntOv*/
+#define XMR_MC_OK_OV (1L<<4) /* Bit 4: Rx Multicast Cnt Ov */
+#define XMR_BC_OK_OV (1L<<3) /* Bit 3: Rx Broadcast Cnt Ov */
+#define XMR_OK_LO_OV (1L<<2) /* Bit 2: Octets Rx OK Low CntOv*/
+#define XMR_OK_HI_OV (1L<<1) /* Bit 1: Octets Rx OK Hi Cnt Ov*/
+#define XMR_OK_OV (1L<<0) /* Bit 0: Frames Received Ok Ov */
+
+#define XMR_DEF_MSK (XMR_OK_LO_OV | XMR_OK_HI_OV)
+
+/* XM_TX_CNT_EV 32 bit r/o Tx Counter Event Register */
+/* XM_TX_EV_MSK 32 bit r/w Tx Counter Event Mask */
+ /* Bit 31..26: reserved */
+#define XMT_MAX_SZ_OV (1L<<25) /* Bit 25: 1024-MaxSize Tx Cnt Ov*/
+#define XMT_1023B_OV (1L<<24) /* Bit 24: 512-1023Byte Tx Cnt Ov*/
+#define XMT_511B_OV (1L<<23) /* Bit 23: 256-511 Byte Tx Cnt Ov*/
+#define XMT_255B_OV (1L<<22) /* Bit 22: 128-255 Byte Tx Cnt Ov*/
+#define XMT_127B_OV (1L<<21) /* Bit 21: 65-127 Byte Tx Cnt Ov */
+#define XMT_64B_OV (1L<<20) /* Bit 20: 64 Byte Tx Cnt Ov */
+#define XMT_UTIL_OV (1L<<19) /* Bit 19: Tx Util Cnt Overflow */
+#define XMT_UTIL_UR (1L<<18) /* Bit 18: Tx Util Cnt Underrun */
+#define XMT_CS_ERR_OV (1L<<17) /* Bit 17: Tx Carr Sen Err Cnt Ov*/
+#define XMT_FIFO_UR_OV (1L<<16) /* Bit 16: Tx FIFO Ur Ev Cnt Ov */
+#define XMT_EX_DEF_OV (1L<<15) /* Bit 15: Tx Ex Deferall Cnt Ov */
+#define XMT_DEF (1L<<14) /* Bit 14: Tx Deferred Cnt Ov */
+#define XMT_LAT_COL_OV (1L<<13) /* Bit 13: Tx Late Col Cnt Ov */
+#define XMT_ABO_COL_OV (1L<<12) /* Bit 12: Tx abo dueto Ex Col Ov*/
+#define XMT_MUL_COL_OV (1L<<11) /* Bit 11: Tx Mult Col Cnt Ov */
+#define XMT_SNG_COL (1L<<10) /* Bit 10: Tx Single Col Cnt Ov */
+#define XMT_MCTRL_OV (1L<<9) /* Bit 9: Tx MAC Ctrl Counter Ov*/
+#define XMT_MPAUSE (1L<<8) /* Bit 8: Tx Pause MAC Ctrl-F Ov*/
+#define XMT_BURST (1L<<7) /* Bit 7: Tx Burst Event Cnt Ov */
+#define XMT_LONG (1L<<6) /* Bit 6: Tx Long Frame Cnt Ov */
+#define XMT_UC_OK_OV (1L<<5) /* Bit 5: Tx Unicast Cnt Ov */
+#define XMT_MC_OK_OV (1L<<4) /* Bit 4: Tx Multicast Cnt Ov */
+#define XMT_BC_OK_OV (1L<<3) /* Bit 3: Tx Broadcast Cnt Ov */
+#define XMT_OK_LO_OV (1L<<2) /* Bit 2: Octets Tx OK Low CntOv*/
+#define XMT_OK_HI_OV (1L<<1) /* Bit 1: Octets Tx OK Hi Cnt Ov*/
+#define XMT_OK_OV (1L<<0) /* Bit 0: Frames Tx Ok Ov */
+
+#define XMT_DEF_MSK (XMT_OK_LO_OV | XMT_OK_HI_OV)
+
+/*
+ * Receive Frame Status Encoding
+ */
+#define XMR_FS_LEN (0x3fffUL<<18) /* Bit 31..18: Rx Frame Length */
+#define XMR_FS_2L_VLAN (1L<<17) /* Bit 17: tagged wh 2Lev VLAN ID*/
+#define XMR_FS_1L_VLAN (1L<<16) /* Bit 16: tagged wh 1Lev VLAN ID*/
+#define XMR_FS_BC (1L<<15) /* Bit 15: Broadcast Frame */
+#define XMR_FS_MC (1L<<14) /* Bit 14: Multicast Frame */
+#define XMR_FS_UC (1L<<13) /* Bit 13: Unicast Frame */
+ /* Bit 12: reserved */
+#define XMR_FS_BURST (1L<<11) /* Bit 11: Burst Mode */
+#define XMR_FS_CEX_ERR (1L<<10) /* Bit 10: Carrier Ext. Error */
+#define XMR_FS_802_3 (1L<<9) /* Bit 9: 802.3 Frame */
+#define XMR_FS_COL_ERR (1L<<8) /* Bit 8: Collision Error */
+#define XMR_FS_CAR_ERR (1L<<7) /* Bit 7: Carrier Event Error */
+#define XMR_FS_LEN_ERR (1L<<6) /* Bit 6: In-Range Length Error */
+#define XMR_FS_FRA_ERR (1L<<5) /* Bit 5: Framing Error */
+#define XMR_FS_RUNT (1L<<4) /* Bit 4: Runt Frame */
+#define XMR_FS_LNG_ERR (1L<<3) /* Bit 3: Giant (Jumbo) Frame */
+#define XMR_FS_FCS_ERR (1L<<2) /* Bit 2: Frame Check Sequ Err */
+#define XMR_FS_ERR (1L<<1) /* Bit 1: Frame Error */
+#define XMR_FS_MCTRL (1L<<0) /* Bit 0: MAC Control Packet */
+
+/*
+ * XMR_FS_ERR will be set if
+ * XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT,
+ * XMR_FS_FRA_ERR, XMR_FS_LEN_ERR, or XMR_FS_CEX_ERR
+ * is set. XMR_FS_LNG_ERR and XMR_FS_LEN_ERR will issue
+ * XMR_FS_ERR unless the corresponding bit in the Receive Command
+ * Register is set.
+ */
+#define XMR_FS_ANY_ERR XMR_FS_ERR
+
+/*----------------------------------------------------------------------------*/
+/*
+ * XMAC-PHY Registers, indirect addressed over the XMAC
+ */
+#define PHY_XMAC_CTRL 0x00 /* 16 bit r/w PHY Control Register */
+#define PHY_XMAC_STAT 0x01 /* 16 bit r/w PHY Status Register */
+#define PHY_XMAC_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
+#define PHY_XMAC_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
+#define PHY_XMAC_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
+#define PHY_XMAC_AUNE_LP 0x05 /* 16 bit r/o Link Partner Abi Reg */
+#define PHY_XMAC_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
+#define PHY_XMAC_NEPG 0x07 /* 16 bit r/w Next Page Register */
+#define PHY_XMAC_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
+ /* 0x09 - 0x0e: reserved */
+#define PHY_XMAC_EXT_STAT 0x0f /* 16 bit r/o Ext Status Register */
+#define PHY_XMAC_RES_ABI 0x10 /* 16 bit r/o PHY Resolved Ability */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Broadcom-PHY Registers, indirect addressed over XMAC
+ */
+#define PHY_BCOM_CTRL 0x00 /* 16 bit r/w PHY Control Register */
+#define PHY_BCOM_STAT 0x01 /* 16 bit r/o PHY Status Register */
+#define PHY_BCOM_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
+#define PHY_BCOM_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
+#define PHY_BCOM_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
+#define PHY_BCOM_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
+#define PHY_BCOM_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
+#define PHY_BCOM_NEPG 0x07 /* 16 bit r/w Next Page Register */
+#define PHY_BCOM_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
+ /* Broadcom-specific registers */
+#define PHY_BCOM_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */
+#define PHY_BCOM_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
+ /* 0x0b - 0x0e: reserved */
+#define PHY_BCOM_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
+#define PHY_BCOM_P_EXT_CTRL 0x10 /* 16 bit r/w PHY Extended Ctrl Reg */
+#define PHY_BCOM_P_EXT_STAT 0x11 /* 16 bit r/o PHY Extended Stat Reg */
+#define PHY_BCOM_RE_CTR 0x12 /* 16 bit r/w Receive Error Counter */
+#define PHY_BCOM_FC_CTR 0x13 /* 16 bit r/w False Carrier Sense Cnt */
+#define PHY_BCOM_RNO_CTR 0x14 /* 16 bit r/w Receiver NOT_OK Cnt */
+ /* 0x15 - 0x17: reserved */
+#define PHY_BCOM_AUX_CTRL 0x18 /* 16 bit r/w Auxiliary Control Reg */
+#define PHY_BCOM_AUX_STAT 0x19 /* 16 bit r/o Auxiliary Stat Summary */
+#define PHY_BCOM_INT_STAT 0x1a /* 16 bit r/o Interrupt Status Reg */
+#define PHY_BCOM_INT_MASK 0x1b /* 16 bit r/w Interrupt Mask Reg */
+ /* 0x1c: reserved */
+ /* 0x1d - 0x1f: test registers */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Marvel-PHY Registers, indirect addressed over GMAC
+ */
+#define PHY_MARV_CTRL 0x00 /* 16 bit r/w PHY Control Register */
+#define PHY_MARV_STAT 0x01 /* 16 bit r/o PHY Status Register */
+#define PHY_MARV_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
+#define PHY_MARV_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
+#define PHY_MARV_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
+#define PHY_MARV_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
+#define PHY_MARV_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
+#define PHY_MARV_NEPG 0x07 /* 16 bit r/w Next Page Register */
+#define PHY_MARV_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
+ /* Marvel-specific registers */
+#define PHY_MARV_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */
+#define PHY_MARV_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
+ /* 0x0b - 0x0e: reserved */
+#define PHY_MARV_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
+#define PHY_MARV_PHY_CTRL 0x10 /* 16 bit r/w PHY Specific Ctrl Reg */
+#define PHY_MARV_PHY_STAT 0x11 /* 16 bit r/o PHY Specific Stat Reg */
+#define PHY_MARV_INT_MASK 0x12 /* 16 bit r/w Interrupt Mask Reg */
+#define PHY_MARV_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */
+#define PHY_MARV_EXT_CTRL 0x14 /* 16 bit r/w Ext. PHY Specific Ctrl */
+#define PHY_MARV_RXE_CNT 0x15 /* 16 bit r/w Receive Error Counter */
+#define PHY_MARV_EXT_ADR 0x16 /* 16 bit r/w Ext. Ad. for Cable Diag. */
+ /* 0x17: reserved */
+#define PHY_MARV_LED_CTRL 0x18 /* 16 bit r/w LED Control Reg */
+#define PHY_MARV_LED_OVER 0x19 /* 16 bit r/w Manual LED Override Reg */
+#define PHY_MARV_EXT_CTRL_2 0x1a /* 16 bit r/w Ext. PHY Specific Ctrl 2 */
+#define PHY_MARV_EXT_P_STAT 0x1b /* 16 bit r/w Ext. PHY Spec. Stat Reg */
+#define PHY_MARV_CABLE_DIAG 0x1c /* 16 bit r/o Cable Diagnostic Reg */
+ /* 0x1d - 0x1f: reserved */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * Level One-PHY Registers, indirect addressed over XMAC
+ */
+#define PHY_LONE_CTRL 0x00 /* 16 bit r/w PHY Control Register */
+#define PHY_LONE_STAT 0x01 /* 16 bit r/o PHY Status Register */
+#define PHY_LONE_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
+#define PHY_LONE_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
+#define PHY_LONE_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
+#define PHY_LONE_AUNE_LP 0x05 /* 16 bit r/o Link Part Ability Reg */
+#define PHY_LONE_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
+#define PHY_LONE_NEPG 0x07 /* 16 bit r/w Next Page Register */
+#define PHY_LONE_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */
+ /* Level One-specific registers */
+#define PHY_LONE_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg*/
+#define PHY_LONE_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
+ /* 0x0b -0x0e: reserved */
+#define PHY_LONE_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */
+#define PHY_LONE_PORT_CFG 0x10 /* 16 bit r/w Port Configuration Reg*/
+#define PHY_LONE_Q_STAT 0x11 /* 16 bit r/o Quick Status Reg */
+#define PHY_LONE_INT_ENAB 0x12 /* 16 bit r/w Interrupt Enable Reg */
+#define PHY_LONE_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */
+#define PHY_LONE_LED_CFG 0x14 /* 16 bit r/w LED Configuration Reg */
+#define PHY_LONE_PORT_CTRL 0x15 /* 16 bit r/w Port Control Reg */
+#define PHY_LONE_CIM 0x16 /* 16 bit r/o CIM Reg */
+ /* 0x17 -0x1c: reserved */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * National-PHY Registers, indirect addressed over XMAC
+ */
+#define PHY_NAT_CTRL 0x00 /* 16 bit r/w PHY Control Register */
+#define PHY_NAT_STAT 0x01 /* 16 bit r/w PHY Status Register */
+#define PHY_NAT_ID0 0x02 /* 16 bit r/o PHY ID0 Register */
+#define PHY_NAT_ID1 0x03 /* 16 bit r/o PHY ID1 Register */
+#define PHY_NAT_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */
+#define PHY_NAT_AUNE_LP 0x05 /* 16 bit r/o Link Partner Ability Reg */
+#define PHY_NAT_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */
+#define PHY_NAT_NEPG 0x07 /* 16 bit r/w Next Page Register */
+#define PHY_NAT_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner Reg */
+ /* National-specific registers */
+#define PHY_NAT_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg */
+#define PHY_NAT_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */
+ /* 0x0b -0x0e: reserved */
+#define PHY_NAT_EXT_STAT 0x0f /* 16 bit r/o Extended Status Register */
+#define PHY_NAT_EXT_CTRL1 0x10 /* 16 bit r/o Extended Control Reg1 */
+#define PHY_NAT_Q_STAT1 0x11 /* 16 bit r/o Quick Status Reg1 */
+#define PHY_NAT_10B_OP 0x12 /* 16 bit r/o 10Base-T Operations Reg */
+#define PHY_NAT_EXT_CTRL2 0x13 /* 16 bit r/o Extended Control Reg1 */
+#define PHY_NAT_Q_STAT2 0x14 /* 16 bit r/o Quick Status Reg2 */
+ /* 0x15 -0x18: reserved */
+#define PHY_NAT_PHY_ADDR 0x19 /* 16 bit r/o PHY Address Register */
+
+
+/*----------------------------------------------------------------------------*/
+
+/*
+ * PHY bit definitions
+ * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are
+ * XMAC/Broadcom/LevelOne/National/Marvell-specific.
+ * All other are general.
+ */
+
+/***** PHY_XMAC_CTRL 16 bit r/w PHY Control Register *****/
+/***** PHY_BCOM_CTRL 16 bit r/w PHY Control Register *****/
+/***** PHY_MARV_CTRL 16 bit r/w PHY Status Register *****/
+/***** PHY_LONE_CTRL 16 bit r/w PHY Control Register *****/
+#define PHY_CT_RESET (1<<15) /* Bit 15: (sc) clear all PHY related regs */
+#define PHY_CT_LOOP (1<<14) /* Bit 14: enable Loopback over PHY */
+#define PHY_CT_SPS_LSB (1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */
+#define PHY_CT_ANE (1<<12) /* Bit 12: Auto-Negotiation Enabled */
+#define PHY_CT_PDOWN (1<<11) /* Bit 11: (BC,L1) Power Down Mode */
+#define PHY_CT_ISOL (1<<10) /* Bit 10: (BC,L1) Isolate Mode */
+#define PHY_CT_RE_CFG (1<<9) /* Bit 9: (sc) Restart Auto-Negotiation */
+#define PHY_CT_DUP_MD (1<<8) /* Bit 8: Duplex Mode */
+#define PHY_CT_COL_TST (1<<7) /* Bit 7: (BC,L1) Collision Test enabled */
+#define PHY_CT_SPS_MSB (1<<6) /* Bit 6: (BC,L1) Speed select, upper bit */
+ /* Bit 5..0: reserved */
+
+#define PHY_CT_SP1000 PHY_CT_SPS_MSB /* enable speed of 1000 Mbps */
+#define PHY_CT_SP100 PHY_CT_SPS_LSB /* enable speed of 100 Mbps */
+#define PHY_CT_SP10 (0) /* enable speed of 10 Mbps */
+
+
+/***** PHY_XMAC_STAT 16 bit r/w PHY Status Register *****/
+/***** PHY_BCOM_STAT 16 bit r/w PHY Status Register *****/
+/***** PHY_MARV_STAT 16 bit r/w PHY Status Register *****/
+/***** PHY_LONE_STAT 16 bit r/w PHY Status Register *****/
+ /* Bit 15..9: reserved */
+ /* (BC/L1) 100/10 Mbps cap bits ignored*/
+#define PHY_ST_EXT_ST (1<<8) /* Bit 8: Extended Status Present */
+ /* Bit 7: reserved */
+#define PHY_ST_PRE_SUP (1<<6) /* Bit 6: (BC/L1) preamble suppression */
+#define PHY_ST_AN_OVER (1<<5) /* Bit 5: Auto-Negotiation Over */
+#define PHY_ST_REM_FLT (1<<4) /* Bit 4: Remote Fault Condition Occured */
+#define PHY_ST_AN_CAP (1<<3) /* Bit 3: Auto-Negotiation Capability */
+#define PHY_ST_LSYNC (1<<2) /* Bit 2: Link Synchronized */
+#define PHY_ST_JAB_DET (1<<1) /* Bit 1: (BC/L1) Jabber Detected */
+#define PHY_ST_EXT_REG (1<<0) /* Bit 0: Extended Register available */
+
+
+/***** PHY_XMAC_ID1 16 bit r/o PHY ID1 Register */
+/***** PHY_BCOM_ID1 16 bit r/o PHY ID1 Register */
+/***** PHY_MARV_ID1 16 bit r/o PHY ID1 Register */
+/***** PHY_LONE_ID1 16 bit r/o PHY ID1 Register */
+#define PHY_I1_OUI_MSK (0x3f<<10) /* Bit 15..10: Organization Unique ID */
+#define PHY_I1_MOD_NUM (0x3f<<4) /* Bit 9.. 4: Model Number */
+#define PHY_I1_REV_MSK 0x0f /* Bit 3.. 0: Revision Number */
+
+/* different Broadcom PHY Ids */
+#define PHY_BCOM_ID1_A1 0x6041
+#define PHY_BCOM_ID1_B2 0x6043
+#define PHY_BCOM_ID1_C0 0x6044
+#define PHY_BCOM_ID1_C5 0x6047
+
+
+/***** PHY_XMAC_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
+/***** PHY_XMAC_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
+#define PHY_AN_NXT_PG (1<<15) /* Bit 15: Request Next Page */
+#define PHY_X_AN_ACK (1<<14) /* Bit 14: (ro) Acknowledge Received */
+#define PHY_X_AN_RFB (3<<12) /* Bit 13..12: Remote Fault Bits */
+ /* Bit 11.. 9: reserved */
+#define PHY_X_AN_PAUSE (3<<7) /* Bit 8.. 7: Pause Bits */
+#define PHY_X_AN_HD (1<<6) /* Bit 6: Half Duplex */
+#define PHY_X_AN_FD (1<<5) /* Bit 5: Full Duplex */
+ /* Bit 4.. 0: reserved */
+
+/***** PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
+/***** PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
+/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
+ /* Bit 14: reserved */
+#define PHY_B_AN_RF (1<<13) /* Bit 13: Remote Fault */
+ /* Bit 12: reserved */
+#define PHY_B_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */
+#define PHY_B_AN_PC (1<<10) /* Bit 10: Pause Capable */
+ /* Bit 9..5: 100/10 BT cap bits ingnored */
+#define PHY_B_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
+
+/***** PHY_LONE_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
+/***** PHY_LONE_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
+/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
+ /* Bit 14: reserved */
+#define PHY_L_AN_RF (1<<13) /* Bit 13: Remote Fault */
+ /* Bit 12: reserved */
+#define PHY_L_AN_ASP (1<<11) /* Bit 11: Asymmetric Pause */
+#define PHY_L_AN_PC (1<<10) /* Bit 10: Pause Capable */
+ /* Bit 9..5: 100/10 BT cap bits ingnored */
+#define PHY_L_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
+
+/***** PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
+/***** PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/
+/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */
+ /* Bit 14: reserved */
+#define PHY_N_AN_RF (1<<13) /* Bit 13: Remote Fault */
+ /* Bit 12: reserved */
+#define PHY_N_AN_100F (1<<11) /* Bit 11: 100Base-T2 FD Support */
+#define PHY_N_AN_100H (1<<10) /* Bit 10: 100Base-T2 HD Support */
+ /* Bit 9..5: 100/10 BT cap bits ingnored */
+#define PHY_N_AN_SEL 0x1f /* Bit 4..0: Selector Field, 00001=Ethernet*/
+
+/* field type definition for PHY_x_AN_SEL */
+#define PHY_SEL_TYPE 0x01 /* 00001 = Ethernet */
+
+/***** PHY_XMAC_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
+ /* Bit 15..4: reserved */
+#define PHY_ANE_LP_NP (1<<3) /* Bit 3: Link Partner can Next Page */
+#define PHY_ANE_LOC_NP (1<<2) /* Bit 2: Local PHY can Next Page */
+#define PHY_ANE_RX_PG (1<<1) /* Bit 1: Page Received */
+ /* Bit 0: reserved */
+
+/***** PHY_BCOM_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
+/***** PHY_LONE_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
+/***** PHY_MARV_AUNE_EXP 16 bit r/o Auto-Negotiation Expansion Reg *****/
+ /* Bit 15..5: reserved */
+#define PHY_ANE_PAR_DF (1<<4) /* Bit 4: Parallel Detection Fault */
+/* PHY_ANE_LP_NP (see XMAC) Bit 3: Link Partner can Next Page */
+/* PHY_ANE_LOC_NP (see XMAC) Bit 2: Local PHY can Next Page */
+/* PHY_ANE_RX_PG (see XMAC) Bit 1: Page Received */
+#define PHY_ANE_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Cap. */
+
+/***** PHY_XMAC_NEPG 16 bit r/w Next Page Register *****/
+/***** PHY_BCOM_NEPG 16 bit r/w Next Page Register *****/
+/***** PHY_LONE_NEPG 16 bit r/w Next Page Register *****/
+/***** PHY_XMAC_NEPG_LP 16 bit r/o Next Page Link Partner *****/
+/***** PHY_BCOM_NEPG_LP 16 bit r/o Next Page Link Partner *****/
+/***** PHY_LONE_NEPG_LP 16 bit r/o Next Page Link Partner *****/
+#define PHY_NP_MORE (1<<15) /* Bit 15: More, Next Pages to follow */
+#define PHY_NP_ACK1 (1<<14) /* Bit 14: (ro) Ack1, for receiving a message */
+#define PHY_NP_MSG_VAL (1<<13) /* Bit 13: Message Page valid */
+#define PHY_NP_ACK2 (1<<12) /* Bit 12: Ack2, comply with msg content */
+#define PHY_NP_TOG (1<<11) /* Bit 11: Toggle Bit, ensure sync */
+#define PHY_NP_MSG 0x07ff /* Bit 10..0: Message from/to Link Partner */
+
+/*
+ * XMAC-Specific
+ */
+/***** PHY_XMAC_EXT_STAT 16 bit r/w Extended Status Register *****/
+#define PHY_X_EX_FD (1<<15) /* Bit 15: Device Supports Full Duplex */
+#define PHY_X_EX_HD (1<<14) /* Bit 14: Device Supports Half Duplex */
+ /* Bit 13..0: reserved */
+
+/***** PHY_XMAC_RES_ABI 16 bit r/o PHY Resolved Ability *****/
+ /* Bit 15..9: reserved */
+#define PHY_X_RS_PAUSE (3<<7) /* Bit 8..7: selected Pause Mode */
+#define PHY_X_RS_HD (1<<6) /* Bit 6: Half Duplex Mode selected */
+#define PHY_X_RS_FD (1<<5) /* Bit 5: Full Duplex Mode selected */
+#define PHY_X_RS_ABLMIS (1<<4) /* Bit 4: duplex or pause cap mismatch */
+#define PHY_X_RS_PAUMIS (1<<3) /* Bit 3: pause capability mismatch */
+ /* Bit 2..0: reserved */
+/*
+ * Remote Fault Bits (PHY_X_AN_RFB) encoding
+ */
+#define X_RFB_OK (0<<12) /* Bit 13..12 No errors, Link OK */
+#define X_RFB_LF (1<<12) /* Bit 13..12 Link Failure */
+#define X_RFB_OFF (2<<12) /* Bit 13..12 Offline */
+#define X_RFB_AN_ERR (3<<12) /* Bit 13..12 Auto-Negotiation Error */
+
+/*
+ * Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding
+ */
+#define PHY_X_P_NO_PAUSE (0<<7) /* Bit 8..7: no Pause Mode */
+#define PHY_X_P_SYM_MD (1<<7) /* Bit 8..7: symmetric Pause Mode */
+#define PHY_X_P_ASYM_MD (2<<7) /* Bit 8..7: asymmetric Pause Mode */
+#define PHY_X_P_BOTH_MD (3<<7) /* Bit 8..7: both Pause Mode */
+
+
+/*
+ * Broadcom-Specific
+ */
+/***** PHY_BCOM_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
+#define PHY_B_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
+#define PHY_B_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
+#define PHY_B_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
+#define PHY_B_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
+#define PHY_B_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
+#define PHY_B_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
+ /* Bit 7..0: reserved */
+
+/***** PHY_BCOM_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
+/***** PHY_MARV_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
+#define PHY_B_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
+#define PHY_B_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
+#define PHY_B_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
+#define PHY_B_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */
+#define PHY_B_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
+#define PHY_B_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
+ /* Bit 9..8: reserved */
+#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
+
+/***** PHY_BCOM_EXT_STAT 16 bit r/o Extended Status Register *****/
+#define PHY_B_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
+#define PHY_B_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
+#define PHY_B_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
+#define PHY_B_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
+ /* Bit 11..0: reserved */
+
+/***** PHY_BCOM_P_EXT_CTRL 16 bit r/w PHY Extended Control Reg *****/
+#define PHY_B_PEC_MAC_PHY (1<<15) /* Bit 15: 10BIT/GMI-Interface */
+#define PHY_B_PEC_DIS_CROSS (1<<14) /* Bit 14: Disable MDI Crossover */
+#define PHY_B_PEC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */
+#define PHY_B_PEC_INT_DIS (1<<12) /* Bit 12: Interrupts Disabled */
+#define PHY_B_PEC_F_INT (1<<11) /* Bit 11: Force Interrupt */
+#define PHY_B_PEC_BY_45 (1<<10) /* Bit 10: Bypass 4B5B-Decoder */
+#define PHY_B_PEC_BY_SCR (1<<9) /* Bit 9: Bypass Scrambler */
+#define PHY_B_PEC_BY_MLT3 (1<<8) /* Bit 8: Bypass MLT3 Encoder */
+#define PHY_B_PEC_BY_RXA (1<<7) /* Bit 7: Bypass Rx Alignm. */
+#define PHY_B_PEC_RES_SCR (1<<6) /* Bit 6: Reset Scrambler */
+#define PHY_B_PEC_EN_LTR (1<<5) /* Bit 5: Ena LED Traffic Mode */
+#define PHY_B_PEC_LED_ON (1<<4) /* Bit 4: Force LED's on */
+#define PHY_B_PEC_LED_OFF (1<<3) /* Bit 3: Force LED's off */
+#define PHY_B_PEC_EX_IPG (1<<2) /* Bit 2: Extend Tx IPG Mode */
+#define PHY_B_PEC_3_LED (1<<1) /* Bit 1: Three Link LED mode */
+#define PHY_B_PEC_HIGH_LA (1<<0) /* Bit 0: GMII FIFO Elasticy */
+
+/***** PHY_BCOM_P_EXT_STAT 16 bit r/o PHY Extended Status Reg *****/
+ /* Bit 15..14: reserved */
+#define PHY_B_PES_CROSS_STAT (1<<13) /* Bit 13: MDI Crossover Status */
+#define PHY_B_PES_INT_STAT (1<<12) /* Bit 12: Interrupt Status */
+#define PHY_B_PES_RRS (1<<11) /* Bit 11: Remote Receiver Stat. */
+#define PHY_B_PES_LRS (1<<10) /* Bit 10: Local Receiver Stat. */
+#define PHY_B_PES_LOCKED (1<<9) /* Bit 9: Locked */
+#define PHY_B_PES_LS (1<<8) /* Bit 8: Link Status */
+#define PHY_B_PES_RF (1<<7) /* Bit 7: Remote Fault */
+#define PHY_B_PES_CE_ER (1<<6) /* Bit 6: Carrier Ext Error */
+#define PHY_B_PES_BAD_SSD (1<<5) /* Bit 5: Bad SSD */
+#define PHY_B_PES_BAD_ESD (1<<4) /* Bit 4: Bad ESD */
+#define PHY_B_PES_RX_ER (1<<3) /* Bit 3: Receive Error */
+#define PHY_B_PES_TX_ER (1<<2) /* Bit 2: Transmit Error */
+#define PHY_B_PES_LOCK_ER (1<<1) /* Bit 1: Lock Error */
+#define PHY_B_PES_MLT3_ER (1<<0) /* Bit 0: MLT3 code Error */
+
+/***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/
+ /* Bit 15..8: reserved */
+#define PHY_B_FC_CTR 0xff /* Bit 7..0: False Carrier Counter */
+
+/***** PHY_BCOM_RNO_CTR 16 bit r/w Receive NOT_OK Counter *****/
+#define PHY_B_RC_LOC_MSK 0xff00 /* Bit 15..8: Local Rx NOT_OK cnt */
+#define PHY_B_RC_REM_MSK 0x00ff /* Bit 7..0: Remote Rx NOT_OK cnt */
+
+/***** PHY_BCOM_AUX_CTRL 16 bit r/w Auxiliary Control Reg *****/
+#define PHY_B_AC_L_SQE (1<<15) /* Bit 15: Low Squelch */
+#define PHY_B_AC_LONG_PACK (1<<14) /* Bit 14: Rx Long Packets */
+#define PHY_B_AC_ER_CTRL (3<<12) /* Bit 13..12: Edgerate Control */
+ /* Bit 11: reserved */
+#define PHY_B_AC_TX_TST (1<<10) /* Bit 10: Tx test bit, always 1 */
+ /* Bit 9.. 8: reserved */
+#define PHY_B_AC_DIS_PRF (1<<7) /* Bit 7: dis part resp filter */
+ /* Bit 6: reserved */
+#define PHY_B_AC_DIS_PM (1<<5) /* Bit 5: dis power management */
+ /* Bit 4: reserved */
+#define PHY_B_AC_DIAG (1<<3) /* Bit 3: Diagnostic Mode */
+ /* Bit 2.. 0: reserved */
+
+/***** PHY_BCOM_AUX_STAT 16 bit r/o Auxiliary Status Reg *****/
+#define PHY_B_AS_AN_C (1<<15) /* Bit 15: AutoNeg complete */
+#define PHY_B_AS_AN_CA (1<<14) /* Bit 14: AN Complete Ack */
+#define PHY_B_AS_ANACK_D (1<<13) /* Bit 13: AN Ack Detect */
+#define PHY_B_AS_ANAB_D (1<<12) /* Bit 12: AN Ability Detect */
+#define PHY_B_AS_NPW (1<<11) /* Bit 11: AN Next Page Wait */
+#define PHY_B_AS_AN_RES_MSK (7<<8) /* Bit 10..8: AN HDC */
+#define PHY_B_AS_PDF (1<<7) /* Bit 7: Parallel Detect. Fault */
+#define PHY_B_AS_RF (1<<6) /* Bit 6: Remote Fault */
+#define PHY_B_AS_ANP_R (1<<5) /* Bit 5: AN Page Received */
+#define PHY_B_AS_LP_ANAB (1<<4) /* Bit 4: LP AN Ability */
+#define PHY_B_AS_LP_NPAB (1<<3) /* Bit 3: LP Next Page Ability */
+#define PHY_B_AS_LS (1<<2) /* Bit 2: Link Status */
+#define PHY_B_AS_PRR (1<<1) /* Bit 1: Pause Resolution-Rx */
+#define PHY_B_AS_PRT (1<<0) /* Bit 0: Pause Resolution-Tx */
+
+#define PHY_B_AS_PAUSE_MSK (PHY_B_AS_PRR | PHY_B_AS_PRT)
+
+/***** PHY_BCOM_INT_STAT 16 bit r/o Interrupt Status Reg *****/
+/***** PHY_BCOM_INT_MASK 16 bit r/w Interrupt Mask Reg *****/
+ /* Bit 15: reserved */
+#define PHY_B_IS_PSE (1<<14) /* Bit 14: Pair Swap Error */
+#define PHY_B_IS_MDXI_SC (1<<13) /* Bit 13: MDIX Status Change */
+#define PHY_B_IS_HCT (1<<12) /* Bit 12: counter above 32k */
+#define PHY_B_IS_LCT (1<<11) /* Bit 11: counter above 128 */
+#define PHY_B_IS_AN_PR (1<<10) /* Bit 10: Page Received */
+#define PHY_B_IS_NO_HDCL (1<<9) /* Bit 9: No HCD Link */
+#define PHY_B_IS_NO_HDC (1<<8) /* Bit 8: No HCD */
+#define PHY_B_IS_NEG_USHDC (1<<7) /* Bit 7: Negotiated Unsup. HCD */
+#define PHY_B_IS_SCR_S_ER (1<<6) /* Bit 6: Scrambler Sync Error */
+#define PHY_B_IS_RRS_CHANGE (1<<5) /* Bit 5: Remote Rx Stat Change */
+#define PHY_B_IS_LRS_CHANGE (1<<4) /* Bit 4: Local Rx Stat Change */
+#define PHY_B_IS_DUP_CHANGE (1<<3) /* Bit 3: Duplex Mode Change */
+#define PHY_B_IS_LSP_CHANGE (1<<2) /* Bit 2: Link Speed Change */
+#define PHY_B_IS_LST_CHANGE (1<<1) /* Bit 1: Link Status Changed */
+#define PHY_B_IS_CRC_ER (1<<0) /* Bit 0: CRC Error */
+
+#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE))
+
+/* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */
+#define PHY_B_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */
+#define PHY_B_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */
+#define PHY_B_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */
+#define PHY_B_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */
+
+/*
+ * Resolved Duplex mode and Capabilities (Aux Status Summary Reg)
+ */
+#define PHY_B_RES_1000FD (7<<8) /* Bit 10..8: 1000Base-T Full Dup. */
+#define PHY_B_RES_1000HD (6<<8) /* Bit 10..8: 1000Base-T Half Dup. */
+/* others: 100/10: invalid for us */
+
+/*
+ * Level One-Specific
+ */
+/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
+#define PHY_L_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
+#define PHY_L_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
+#define PHY_L_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
+#define PHY_L_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
+#define PHY_L_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
+#define PHY_L_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
+ /* Bit 7..0: reserved */
+
+/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
+#define PHY_L_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
+#define PHY_L_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
+#define PHY_L_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
+#define PHY_L_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status */
+#define PHY_L_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
+#define PHY_L_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
+ /* Bit 9..8: reserved */
+#define PHY_B_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
+
+/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/
+#define PHY_L_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
+#define PHY_L_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
+#define PHY_L_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
+#define PHY_L_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
+ /* Bit 11..0: reserved */
+
+/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/
+#define PHY_L_PC_REP_MODE (1<<15) /* Bit 15: Repeater Mode */
+ /* Bit 14: reserved */
+#define PHY_L_PC_TX_DIS (1<<13) /* Bit 13: Tx output Disabled */
+#define PHY_L_PC_BY_SCR (1<<12) /* Bit 12: Bypass Scrambler */
+#define PHY_L_PC_BY_45 (1<<11) /* Bit 11: Bypass 4B5B-Decoder */
+#define PHY_L_PC_JAB_DIS (1<<10) /* Bit 10: Jabber Disabled */
+#define PHY_L_PC_SQE (1<<9) /* Bit 9: Enable Heartbeat */
+#define PHY_L_PC_TP_LOOP (1<<8) /* Bit 8: TP Loopback */
+#define PHY_L_PC_SSS (1<<7) /* Bit 7: Smart Speed Selection */
+#define PHY_L_PC_FIFO_SIZE (1<<6) /* Bit 6: FIFO Size */
+#define PHY_L_PC_PRE_EN (1<<5) /* Bit 5: Preamble Enable */
+#define PHY_L_PC_CIM (1<<4) /* Bit 4: Carrier Integrity Mon */
+#define PHY_L_PC_10_SER (1<<3) /* Bit 3: Use Serial Output */
+#define PHY_L_PC_ANISOL (1<<2) /* Bit 2: Unisolate Port */
+#define PHY_L_PC_TEN_BIT (1<<1) /* Bit 1: 10bit iface mode on */
+#define PHY_L_PC_ALTCLOCK (1<<0) /* Bit 0: (ro) ALTCLOCK Mode on */
+
+/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/
+#define PHY_L_QS_D_RATE (3<<14) /* Bit 15..14: Data Rate */
+#define PHY_L_QS_TX_STAT (1<<13) /* Bit 13: Transmitting */
+#define PHY_L_QS_RX_STAT (1<<12) /* Bit 12: Receiving */
+#define PHY_L_QS_COL_STAT (1<<11) /* Bit 11: Collision */
+#define PHY_L_QS_L_STAT (1<<10) /* Bit 10: Link is up */
+#define PHY_L_QS_DUP_MOD (1<<9) /* Bit 9: Full/Half Duplex */
+#define PHY_L_QS_AN (1<<8) /* Bit 8: AutoNeg is On */
+#define PHY_L_QS_AN_C (1<<7) /* Bit 7: AN is Complete */
+#define PHY_L_QS_LLE (7<<4) /* Bit 6: Line Length Estim. */
+#define PHY_L_QS_PAUSE (1<<3) /* Bit 3: LP advertised Pause */
+#define PHY_L_QS_AS_PAUSE (1<<2) /* Bit 2: LP adv. asym. Pause */
+#define PHY_L_QS_ISOLATE (1<<1) /* Bit 1: CIM Isolated */
+#define PHY_L_QS_EVENT (1<<0) /* Bit 0: Event has occurred */
+
+/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/
+/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/
+ /* Bit 15..14: reserved */
+#define PHY_L_IS_AN_F (1<<13) /* Bit 13: Auto-Negotiation fault */
+ /* Bit 12: not described */
+#define PHY_L_IS_CROSS (1<<11) /* Bit 11: Crossover used */
+#define PHY_L_IS_POL (1<<10) /* Bit 10: Polarity correct. used */
+#define PHY_L_IS_SS (1<<9) /* Bit 9: Smart Speed Downgrade */
+#define PHY_L_IS_CFULL (1<<8) /* Bit 8: Counter Full */
+#define PHY_L_IS_AN_C (1<<7) /* Bit 7: AutoNeg Complete */
+#define PHY_L_IS_SPEED (1<<6) /* Bit 6: Speed Changed */
+#define PHY_L_IS_DUP (1<<5) /* Bit 5: Duplex Changed */
+#define PHY_L_IS_LS (1<<4) /* Bit 4: Link Status Changed */
+#define PHY_L_IS_ISOL (1<<3) /* Bit 3: Isolate Occured */
+#define PHY_L_IS_MDINT (1<<2) /* Bit 2: (ro) STAT: MII Int Pending */
+#define PHY_L_IS_INTEN (1<<1) /* Bit 1: ENAB: Enable IRQs */
+#define PHY_L_IS_FORCE (1<<0) /* Bit 0: ENAB: Force Interrupt */
+
+/* int. mask */
+#define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN)
+
+/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/
+#define PHY_L_LC_LEDC (3<<14) /* Bit 15..14: Col/Blink/On/Off */
+#define PHY_L_LC_LEDR (3<<12) /* Bit 13..12: Rx/Blink/On/Off */
+#define PHY_L_LC_LEDT (3<<10) /* Bit 11..10: Tx/Blink/On/Off */
+#define PHY_L_LC_LEDG (3<<8) /* Bit 9..8: Giga/Blink/On/Off */
+#define PHY_L_LC_LEDS (3<<6) /* Bit 7..6: 10-100/Blink/On/Off */
+#define PHY_L_LC_LEDL (3<<4) /* Bit 5..4: Link/Blink/On/Off */
+#define PHY_L_LC_LEDF (3<<2) /* Bit 3..2: Duplex/Blink/On/Off */
+#define PHY_L_LC_PSTRECH (1<<1) /* Bit 1: Strech LED Pulses */
+#define PHY_L_LC_FREQ (1<<0) /* Bit 0: 30/100 ms */
+
+/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/
+#define PHY_L_PC_TX_TCLK (1<<15) /* Bit 15: Enable TX_TCLK */
+ /* Bit 14: reserved */
+#define PHY_L_PC_ALT_NP (1<<13) /* Bit 14: Alternate Next Page */
+#define PHY_L_PC_GMII_ALT (1<<12) /* Bit 13: Alternate GMII driver */
+ /* Bit 11: reserved */
+#define PHY_L_PC_TEN_CRS (1<<10) /* Bit 10: Extend CRS*/
+ /* Bit 9..0: not described */
+
+/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/
+#define PHY_L_CIM_ISOL (255<<8)/* Bit 15..8: Isolate Count */
+#define PHY_L_CIM_FALSE_CAR (255<<0)/* Bit 7..0: False Carrier Count */
+
+
+/*
+ * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding
+ */
+#define PHY_L_P_NO_PAUSE (0<<10) /* Bit 11..10: no Pause Mode */
+#define PHY_L_P_SYM_MD (1<<10) /* Bit 11..10: symmetric Pause Mode */
+#define PHY_L_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */
+#define PHY_L_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */
+
+
+/*
+ * National-Specific
+ */
+/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
+#define PHY_N_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
+#define PHY_N_1000C_MSE (1<<12) /* Bit 12: Master/Slave Enable */
+#define PHY_N_1000C_MSC (1<<11) /* Bit 11: M/S Configuration */
+#define PHY_N_1000C_RD (1<<10) /* Bit 10: Repeater/DTE */
+#define PHY_N_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
+#define PHY_N_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
+#define PHY_N_1000C_APC (1<<7) /* Bit 7: Asymmetric Pause Cap. */
+ /* Bit 6..0: reserved */
+
+/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/
+#define PHY_N_1000S_MSF (1<<15) /* Bit 15: Master/Slave Fault */
+#define PHY_N_1000S_MSR (1<<14) /* Bit 14: Master/Slave Result */
+#define PHY_N_1000S_LRS (1<<13) /* Bit 13: Local Receiver Status */
+#define PHY_N_1000S_RRS (1<<12) /* Bit 12: Remote Receiver Status*/
+#define PHY_N_1000S_LP_FD (1<<11) /* Bit 11: Link Partner can FD */
+#define PHY_N_1000S_LP_HD (1<<10) /* Bit 10: Link Partner can HD */
+#define PHY_N_1000C_LP_APC (1<<9) /* Bit 9: LP Asym. Pause Cap. */
+ /* Bit 8: reserved */
+#define PHY_N_1000S_IEC 0xff /* Bit 7..0: Idle Error Count */
+
+/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/
+#define PHY_N_ES_X_FD_CAP (1<<15) /* Bit 15: 1000Base-X FD capable */
+#define PHY_N_ES_X_HD_CAP (1<<14) /* Bit 14: 1000Base-X HD capable */
+#define PHY_N_ES_T_FD_CAP (1<<13) /* Bit 13: 1000Base-T FD capable */
+#define PHY_N_ES_T_HD_CAP (1<<12) /* Bit 12: 1000Base-T HD capable */
+ /* Bit 11..0: reserved */
+
+/* todo: those are still missing */
+/***** PHY_NAT_EXT_CTRL1 16 bit r/o Extended Control Reg1 *****/
+/***** PHY_NAT_Q_STAT1 16 bit r/o Quick Status Reg1 *****/
+/***** PHY_NAT_10B_OP 16 bit r/o 10Base-T Operations Reg *****/
+/***** PHY_NAT_EXT_CTRL2 16 bit r/o Extended Control Reg1 *****/
+/***** PHY_NAT_Q_STAT2 16 bit r/o Quick Status Reg2 *****/
+/***** PHY_NAT_PHY_ADDR 16 bit r/o PHY Address Register *****/
+
+/*
+ * Marvell-Specific
+ */
+/***** PHY_MARV_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/
+/***** PHY_MARV_AUNE_LP 16 bit r/w Link Part Ability Reg *****/
+#define PHY_M_AN_NXT_PG BIT_15 /* Request Next Page */
+#define PHY_M_AN_ACK BIT_14 /* (ro) Acknowledge Received */
+#define PHY_M_AN_RF BIT_13 /* Remote Fault */
+ /* Bit 12: reserved */
+#define PHY_M_AN_ASP BIT_11 /* Asymmetric Pause */
+#define PHY_M_AN_PC BIT_10 /* MAC Pause implemented */
+#define PHY_M_AN_100_FD BIT_8 /* Advertise 100Base-TX Full Duplex */
+#define PHY_M_AN_100_HD BIT_7 /* Advertise 100Base-TX Half Duplex */
+#define PHY_M_AN_10_FD BIT_6 /* Advertise 10Base-TX Full Duplex */
+#define PHY_M_AN_10_HD BIT_5 /* Advertise 10Base-TX Half Duplex */
+
+/* special defines for FIBER (88E1011S only) */
+#define PHY_M_AN_ASP_X BIT_8 /* Asymmetric Pause */
+#define PHY_M_AN_PC_X BIT_7 /* MAC Pause implemented */
+#define PHY_M_AN_1000X_AHD BIT_6 /* Advertise 10000Base-X Half Duplex */
+#define PHY_M_AN_1000X_AFD BIT_5 /* Advertise 10000Base-X Full Duplex */
+
+/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
+#define PHY_M_P_NO_PAUSE_X (0<<7) /* Bit 8.. 7: no Pause Mode */
+#define PHY_M_P_SYM_MD_X (1<<7) /* Bit 8.. 7: symmetric Pause Mode */
+#define PHY_M_P_ASYM_MD_X (2<<7) /* Bit 8.. 7: asymmetric Pause Mode */
+#define PHY_M_P_BOTH_MD_X (3<<7) /* Bit 8.. 7: both Pause Mode */
+
+/***** PHY_MARV_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/
+#define PHY_M_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */
+#define PHY_M_1000C_MSE (1<<12) /* Bit 12: Manual Master/Slave Enable */
+#define PHY_M_1000C_MSC (1<<11) /* Bit 11: M/S Configuration (1=Master) */
+#define PHY_M_1000C_MPD (1<<10) /* Bit 10: Multi-Port Device */
+#define PHY_M_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */
+#define PHY_M_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */
+ /* Bit 7..0: reserved */
+
+/***** PHY_MARV_PHY_CTRL 16 bit r/w PHY Specific Ctrl Reg *****/
+#define PHY_M_PC_TX_FFD_MSK (3<<14) /* Bit 15..14: Tx FIFO Depth Mask */
+#define PHY_M_PC_RX_FFD_MSK (3<<12) /* Bit 13..12: Rx FIFO Depth Mask */
+#define PHY_M_PC_ASS_CRS_TX (1<<11) /* Bit 11: Assert CRS on Transmit */
+#define PHY_M_PC_FL_GOOD (1<<10) /* Bit 10: Force Link Good */
+#define PHY_M_PC_EN_DET_MSK (3<<8) /* Bit 9.. 8: Energy Detect Mask */
+#define PHY_M_PC_ENA_EXT_D (1<<7) /* Bit 7: Enable Ext. Distance (10BT) */
+#define PHY_M_PC_MDIX_MSK (3<<5) /* Bit 6.. 5: MDI/MDIX Config. Mask */
+#define PHY_M_PC_DIS_125CLK (1<<4) /* Bit 4: Disable 125 CLK */
+#define PHY_M_PC_MAC_POW_UP (1<<3) /* Bit 3: MAC Power up */
+#define PHY_M_PC_SQE_T_ENA (1<<2) /* Bit 2: SQE Test Enabled */
+#define PHY_M_PC_POL_R_DIS (1<<1) /* Bit 1: Polarity Reversal Disabled */
+#define PHY_M_PC_DIS_JABBER (1<<0) /* Bit 0: Disable Jabber */
+
+#define PHY_M_PC_EN_DET SHIFT8(2) /* Energy Detect (Mode 1) */
+#define PHY_M_PC_EN_DET_PLUS SHIFT8(3) /* Energy Detect Plus (Mode 2) */
+
+#define PHY_M_PC_MDI_XMODE(x) SHIFT5(x)
+#define PHY_M_PC_MAN_MDI 0 /* 00 = Manual MDI configuration */
+#define PHY_M_PC_MAN_MDIX 1 /* 01 = Manual MDIX configuration */
+#define PHY_M_PC_ENA_AUTO 3 /* 11 = Enable Automatic Crossover */
+
+/***** PHY_MARV_PHY_STAT 16 bit r/o PHY Specific Status Reg *****/
+#define PHY_M_PS_SPEED_MSK (3<<14) /* Bit 15..14: Speed Mask */
+#define PHY_M_PS_SPEED_1000 (1<<15) /* 10 = 1000 Mbps */
+#define PHY_M_PS_SPEED_100 (1<<14) /* 01 = 100 Mbps */
+#define PHY_M_PS_SPEED_10 0 /* 00 = 10 Mbps */
+#define PHY_M_PS_FULL_DUP (1<<13) /* Bit 13: Full Duplex */
+#define PHY_M_PS_PAGE_REC (1<<12) /* Bit 12: Page Received */
+#define PHY_M_PS_SPDUP_RES (1<<11) /* Bit 11: Speed & Duplex Resolved */
+#define PHY_M_PS_LINK_UP (1<<10) /* Bit 10: Link Up */
+#define PHY_M_PS_CABLE_MSK (3<<7) /* Bit 9.. 7: Cable Length Mask */
+#define PHY_M_PS_MDI_X_STAT (1<<6) /* Bit 6: MDI Crossover Stat (1=MDIX) */
+#define PHY_M_PS_DOWNS_STAT (1<<5) /* Bit 5: Downshift Status (1=downsh.) */
+#define PHY_M_PS_ENDET_STAT (1<<4) /* Bit 4: Energy Detect Status (1=act) */
+#define PHY_M_PS_TX_P_EN (1<<3) /* Bit 3: Tx Pause Enabled */
+#define PHY_M_PS_RX_P_EN (1<<2) /* Bit 2: Rx Pause Enabled */
+#define PHY_M_PS_POL_REV (1<<1) /* Bit 1: Polarity Reversed */
+#define PHY_M_PC_JABBER (1<<0) /* Bit 0: Jabber */
+
+#define PHY_M_PS_PAUSE_MSK (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
+
+/***** PHY_MARV_INT_MASK 16 bit r/w Interrupt Mask Reg *****/
+/***** PHY_MARV_INT_STAT 16 bit r/o Interrupt Status Reg *****/
+#define PHY_M_IS_AN_ERROR (1<<15) /* Bit 15: Auto-Negotiation Error */
+#define PHY_M_IS_LSP_CHANGE (1<<14) /* Bit 14: Link Speed Changed */
+#define PHY_M_IS_DUP_CHANGE (1<<13) /* Bit 13: Duplex Mode Changed */
+#define PHY_M_IS_AN_PR (1<<12) /* Bit 12: Page Received */
+#define PHY_M_IS_AN_COMPL (1<<11) /* Bit 11: Auto-Negotiation Completed */
+#define PHY_M_IS_LST_CHANGE (1<<10) /* Bit 10: Link Status Changed */
+#define PHY_M_IS_SYMB_ERROR (1<<9) /* Bit 9: Symbol Error */
+#define PHY_M_IS_FALSE_CARR (1<<8) /* Bit 8: False Carrier */
+#define PHY_M_IS_FIFO_ERROR (1<<7) /* Bit 7: FIFO Overflow/Underrun Error */
+#define PHY_M_IS_MDI_CHANGE (1<<6) /* Bit 6: MDI Crossover Changed */
+#define PHY_M_IS_DOWNSH_DET (1<<5) /* Bit 5: Downshift Detected */
+#define PHY_M_IS_END_CHANGE (1<<4) /* Bit 4: Energy Detect Changed */
+ /* Bit 3..2: reserved */
+#define PHY_M_IS_POL_CHANGE (1<<1) /* Bit 1: Polarity Changed */
+#define PHY_M_IS_JABBER (1<<0) /* Bit 0: Jabber */
+
+#define PHY_M_DEF_MSK (PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \
+ PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR)
+
+/***** PHY_MARV_EXT_CTRL 16 bit r/w Ext. PHY Specific Ctrl *****/
+#define PHY_M_EC_M_DSC_MSK (3<<10) /* Bit 11..10: Master downshift counter */
+#define PHY_M_EC_S_DSC_MSK (3<<8) /* Bit 9.. 8: Slave downshift counter */
+#define PHY_M_EC_MAC_S_MSK (7<<4) /* Bit 6.. 4: Def. MAC interface speed */
+#define PHY_M_EC_FIB_AN_ENA (1<<3) /* Bit 3: Fiber Auto-Neg. Enable */
+
+#define PHY_M_EC_M_DSC(x) SHIFT10(x) /* 00=1x; 01=2x; 10=3x; 11=4x */
+#define PHY_M_EC_S_DSC(x) SHIFT8(x) /* 00=dis; 01=1x; 10=2x; 11=3x */
+#define PHY_M_EC_MAC_S(x) SHIFT4(x) /* 01X=0; 110=2.5; 111=25 (MHz) */
+
+#define MAC_TX_CLK_0_MHZ 2
+#define MAC_TX_CLK_2_5_MHZ 6
+#define MAC_TX_CLK_25_MHZ 7
+
+/***** PHY_MARV_LED_CTRL 16 bit r/w LED Control Reg *****/
+#define PHY_M_LEDC_DIS_LED (1<<15) /* Bit 15: Disable LED */
+#define PHY_M_LEDC_PULS_MSK (7<<12) /* Bit 14..12: Pulse Stretch Mask */
+#define PHY_M_LEDC_F_INT (1<<11) /* Bit 11: Force Interrupt */
+#define PHY_M_LEDC_BL_R_MSK (7<<8) /* Bit 10.. 8: Blink Rate Mask */
+ /* Bit 7.. 5: reserved */
+#define PHY_M_LEDC_LINK_MSK (3<<3) /* Bit 4.. 3: Link Control Mask */
+#define PHY_M_LEDC_DP_CTRL (1<<2) /* Bit 2: Duplex Control */
+#define PHY_M_LEDC_RX_CTRL (1<<1) /* Bit 1: Rx activity / Link */
+#define PHY_M_LEDC_TX_CTRL (1<<0) /* Bit 0: Tx activity / Link */
+
+#define PHY_M_LED_PULS_DUR(x) SHIFT12(x) /* Pulse Stretch Duration */
+
+#define PULS_NO_STR 0 /* no pulse stretching */
+#define PULS_21MS 1 /* 21 ms to 42 ms */
+#define PULS_42MS 2 /* 42 ms to 84 ms */
+#define PULS_84MS 3 /* 84 ms to 170 ms */
+#define PULS_170MS 4 /* 170 ms to 340 ms */
+#define PULS_340MS 5 /* 340 ms to 670 ms */
+#define PULS_670MS 6 /* 670 ms to 1.3 s */
+#define PULS_1300MS 7 /* 1.3 s to 2.7 s */
+
+#define PHY_M_LED_BLINK_RT(x) SHIFT8(x) /* Blink Rate */
+
+#define BLINK_42MS 0 /* 42 ms */
+#define BLINK_84MS 1 /* 84 ms */
+#define BLINK_170MS 2 /* 170 ms */
+#define BLINK_340MS 3 /* 340 ms */
+#define BLINK_670MS 4 /* 670 ms */
+ /* values 5 - 7: reserved */
+
+/***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/
+#define PHY_M_LED_MO_DUP(x) SHIFT10(x) /* Bit 11..10: Duplex */
+#define PHY_M_LED_MO_10(x) SHIFT8(x) /* Bit 9.. 8: Link 10 */
+#define PHY_M_LED_MO_100(x) SHIFT6(x) /* Bit 7.. 6: Link 100 */
+#define PHY_M_LED_MO_1000(x) SHIFT4(x) /* Bit 5.. 4: Link 1000 */
+#define PHY_M_LED_MO_RX(x) SHIFT2(x) /* Bit 3.. 2: Rx */
+#define PHY_M_LED_MO_TX(x) SHIFT0(x) /* Bit 1.. 0: Tx */
+
+#define MO_LED_NORM 0
+#define MO_LED_BLINK 1
+#define MO_LED_OFF 2
+#define MO_LED_ON 3
+
+/***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/
+ /* Bit 15.. 7: reserved */
+#define PHY_M_EC2_FI_IMPED (1<<6) /* Bit 6: Fiber Input Impedance */
+#define PHY_M_EC2_FO_IMPED (1<<5) /* Bit 5: Fiber Output Impedance */
+#define PHY_M_EC2_FO_M_CLK (1<<4) /* Bit 4: Fiber Mode Clock Enable */
+#define PHY_M_EC2_FO_BOOST (1<<3) /* Bit 3: Fiber Output Boost */
+#define PHY_M_EC2_FO_AM_MSK 7 /* Bit 2.. 0: Fiber Output Amplitude */
+
+/***** PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/
+#define PHY_M_FC_AUTO_SEL (1<<15) /* Bit 15: Fiber/Copper Auto Sel. dis. */
+#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14: Fiber/Copper Autoneg. reg acc */
+#define PHY_M_FC_RESULUTION (1<<13) /* Bit 13: Fiber/Copper Resulution */
+#define PHY_M_SER_IF_AN_BP (1<<12) /* Bit 12: Ser IF autoneg. bypass enable */
+#define PHY_M_SER_IF_BP_ST (1<<11) /* Bit 11: Ser IF autoneg. bypass status */
+#define PHY_M_IRQ_POLARITY (1<<10) /* Bit 10: IRQ polarity */
+ /* Bit 9..4: reserved */
+#define PHY_M_UNDOC1 (1<< 7) /* undocumented bit !! */
+#define PHY_M_MODE_MASK (0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */
+
+
+/***** PHY_MARV_CABLE_DIAG 16 bit r/o Cable Diagnostic Reg *****/
+#define PHY_M_CABD_ENA_TEST (1<<15) /* Bit 15: Enable Test */
+#define PHY_M_CABD_STAT_MSK (3<<13) /* Bit 14..13: Status */
+ /* Bit 12.. 8: reserved */
+#define PHY_M_CABD_DIST_MSK 0xff /* Bit 7.. 0: Distance */
+
+/* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */
+#define CABD_STAT_NORMAL 0
+#define CABD_STAT_SHORT 1
+#define CABD_STAT_OPEN 2
+#define CABD_STAT_FAIL 3
+
+
+/*
+ * GMAC registers
+ *
+ * The GMAC registers are 16 or 32 bits wide.
+ * The GMACs host processor interface is 16 bits wide,
+ * therefore ALL registers will be addressed with 16 bit accesses.
+ *
+ * The following macros are provided to access the GMAC registers
+ * GM_IN16(), GM_OUT16, GM_IN32(), GM_OUT32(), GM_INADR(), GM_OUTADR(),
+ * GM_INHASH(), and GM_OUTHASH().
+ * The macros are defined in SkGeHw.h.
+ *
+ * Note: NA reg = Network Address e.g DA, SA etc.
+ *
+ */
+
+/* Port Registers */
+#define GM_GP_STAT 0x0000 /* 16 bit r/o General Purpose Status */
+#define GM_GP_CTRL 0x0004 /* 16 bit r/w General Purpose Control */
+#define GM_TX_CTRL 0x0008 /* 16 bit r/w Transmit Control Reg. */
+#define GM_RX_CTRL 0x000c /* 16 bit r/w Receive Control Reg. */
+#define GM_TX_FLOW_CTRL 0x0010 /* 16 bit r/w Transmit Flow-Control */
+#define GM_TX_PARAM 0x0014 /* 16 bit r/w Transmit Parameter Reg. */
+#define GM_SERIAL_MODE 0x0018 /* 16 bit r/w Serial Mode Register */
+
+/* Source Address Registers */
+#define GM_SRC_ADDR_1L 0x001c /* 16 bit r/w Source Address 1 (low) */
+#define GM_SRC_ADDR_1M 0x0020 /* 16 bit r/w Source Address 1 (middle) */
+#define GM_SRC_ADDR_1H 0x0024 /* 16 bit r/w Source Address 1 (high) */
+#define GM_SRC_ADDR_2L 0x0028 /* 16 bit r/w Source Address 2 (low) */
+#define GM_SRC_ADDR_2M 0x002c /* 16 bit r/w Source Address 2 (middle) */
+#define GM_SRC_ADDR_2H 0x0030 /* 16 bit r/w Source Address 2 (high) */
+
+/* Multicast Address Hash Registers */
+#define GM_MC_ADDR_H1 0x0034 /* 16 bit r/w Multicast Address Hash 1 */
+#define GM_MC_ADDR_H2 0x0038 /* 16 bit r/w Multicast Address Hash 2 */
+#define GM_MC_ADDR_H3 0x003c /* 16 bit r/w Multicast Address Hash 3 */
+#define GM_MC_ADDR_H4 0x0040 /* 16 bit r/w Multicast Address Hash 4 */
+
+/* Interrupt Source Registers */
+#define GM_TX_IRQ_SRC 0x0044 /* 16 bit r/o Tx Overflow IRQ Source */
+#define GM_RX_IRQ_SRC 0x0048 /* 16 bit r/o Rx Overflow IRQ Source */
+#define GM_TR_IRQ_SRC 0x004c /* 16 bit r/o Tx/Rx Over. IRQ Source */
+
+/* Interrupt Mask Registers */
+#define GM_TX_IRQ_MSK 0x0050 /* 16 bit r/w Tx Overflow IRQ Mask */
+#define GM_RX_IRQ_MSK 0x0054 /* 16 bit r/w Rx Overflow IRQ Mask */
+#define GM_TR_IRQ_MSK 0x0058 /* 16 bit r/w Tx/Rx Over. IRQ Mask */
+
+/* Serial Management Interface (SMI) Registers */
+#define GM_SMI_CTRL 0x0080 /* 16 bit r/w SMI Control Register */
+#define GM_SMI_DATA 0x0084 /* 16 bit r/w SMI Data Register */
+#define GM_PHY_ADDR 0x0088 /* 16 bit r/w GPHY Address Register */
+
+/* MIB Counters */
+#define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */
+#define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */
+
+/*
+ * MIB Counters base address definitions (low word) -
+ * use offset 4 for access to high word (32 bit r/o)
+ */
+#define GM_RXF_UC_OK \
+ (GM_MIB_CNT_BASE + 0) /* Unicast Frames Received OK */
+#define GM_RXF_BC_OK \
+ (GM_MIB_CNT_BASE + 8) /* Broadcast Frames Received OK */
+#define GM_RXF_MPAUSE \
+ (GM_MIB_CNT_BASE + 16) /* Pause MAC Ctrl Frames Received */
+#define GM_RXF_MC_OK \
+ (GM_MIB_CNT_BASE + 24) /* Multicast Frames Received OK */
+#define GM_RXF_FCS_ERR \
+ (GM_MIB_CNT_BASE + 32) /* Rx Frame Check Seq. Error */
+ /* GM_MIB_CNT_BASE + 40: reserved */
+#define GM_RXO_OK_LO \
+ (GM_MIB_CNT_BASE + 48) /* Octets Received OK Low */
+#define GM_RXO_OK_HI \
+ (GM_MIB_CNT_BASE + 56) /* Octets Received OK High */
+#define GM_RXO_ERR_LO \
+ (GM_MIB_CNT_BASE + 64) /* Octets Received Invalid Low */
+#define GM_RXO_ERR_HI \
+ (GM_MIB_CNT_BASE + 72) /* Octets Received Invalid High */
+#define GM_RXF_SHT \
+ (GM_MIB_CNT_BASE + 80) /* Frames <64 Byte Received OK */
+#define GM_RXE_FRAG \
+ (GM_MIB_CNT_BASE + 88) /* Frames <64 Byte Received with FCS Err */
+#define GM_RXF_64B \
+ (GM_MIB_CNT_BASE + 96) /* 64 Byte Rx Frame */
+#define GM_RXF_127B \
+ (GM_MIB_CNT_BASE + 104) /* 65-127 Byte Rx Frame */
+#define GM_RXF_255B \
+ (GM_MIB_CNT_BASE + 112) /* 128-255 Byte Rx Frame */
+#define GM_RXF_511B \
+ (GM_MIB_CNT_BASE + 120) /* 256-511 Byte Rx Frame */
+#define GM_RXF_1023B \
+ (GM_MIB_CNT_BASE + 128) /* 512-1023 Byte Rx Frame */
+#define GM_RXF_1518B \
+ (GM_MIB_CNT_BASE + 136) /* 1024-1518 Byte Rx Frame */
+#define GM_RXF_MAX_SZ \
+ (GM_MIB_CNT_BASE + 144) /* 1519-MaxSize Byte Rx Frame */
+#define GM_RXF_LNG_ERR \
+ (GM_MIB_CNT_BASE + 152) /* Rx Frame too Long Error */
+#define GM_RXF_JAB_PKT \
+ (GM_MIB_CNT_BASE + 160) /* Rx Jabber Packet Frame */
+ /* GM_MIB_CNT_BASE + 168: reserved */
+#define GM_RXE_FIFO_OV \
+ (GM_MIB_CNT_BASE + 176) /* Rx FIFO overflow Event */
+ /* GM_MIB_CNT_BASE + 184: reserved */
+#define GM_TXF_UC_OK \
+ (GM_MIB_CNT_BASE + 192) /* Unicast Frames Xmitted OK */
+#define GM_TXF_BC_OK \
+ (GM_MIB_CNT_BASE + 200) /* Broadcast Frames Xmitted OK */
+#define GM_TXF_MPAUSE \
+ (GM_MIB_CNT_BASE + 208) /* Pause MAC Ctrl Frames Xmitted */
+#define GM_TXF_MC_OK \
+ (GM_MIB_CNT_BASE + 216) /* Multicast Frames Xmitted OK */
+#define GM_TXO_OK_LO \
+ (GM_MIB_CNT_BASE + 224) /* Octets Transmitted OK Low */
+#define GM_TXO_OK_HI \
+ (GM_MIB_CNT_BASE + 232) /* Octets Transmitted OK High */
+#define GM_TXF_64B \
+ (GM_MIB_CNT_BASE + 240) /* 64 Byte Tx Frame */
+#define GM_TXF_127B \
+ (GM_MIB_CNT_BASE + 248) /* 65-127 Byte Tx Frame */
+#define GM_TXF_255B \
+ (GM_MIB_CNT_BASE + 256) /* 128-255 Byte Tx Frame */
+#define GM_TXF_511B \
+ (GM_MIB_CNT_BASE + 264) /* 256-511 Byte Tx Frame */
+#define GM_TXF_1023B \
+ (GM_MIB_CNT_BASE + 272) /* 512-1023 Byte Tx Frame */
+#define GM_TXF_1518B \
+ (GM_MIB_CNT_BASE + 280) /* 1024-1518 Byte Tx Frame */
+#define GM_TXF_MAX_SZ \
+ (GM_MIB_CNT_BASE + 288) /* 1519-MaxSize Byte Tx Frame */
+ /* GM_MIB_CNT_BASE + 296: reserved */
+#define GM_TXF_COL \
+ (GM_MIB_CNT_BASE + 304) /* Tx Collision */
+#define GM_TXF_LAT_COL \
+ (GM_MIB_CNT_BASE + 312) /* Tx Late Collision */
+#define GM_TXF_ABO_COL \
+ (GM_MIB_CNT_BASE + 320) /* Tx aborted due to Exces. Col. */
+#define GM_TXF_MUL_COL \
+ (GM_MIB_CNT_BASE + 328) /* Tx Multiple Collision */
+#define GM_TXF_SNG_COL \
+ (GM_MIB_CNT_BASE + 336) /* Tx Single Collision */
+#define GM_TXE_FIFO_UR \
+ (GM_MIB_CNT_BASE + 344) /* Tx FIFO Underrun Event */
+
+/*----------------------------------------------------------------------------*/
+/*
+ * GMAC Bit Definitions
+ *
+ * If the bit access behaviour differs from the register access behaviour
+ * (r/w, r/o) this is documented after the bit number.
+ * The following bit access behaviours are used:
+ * (sc) self clearing
+ * (r/o) read only
+ */
+
+/* GM_GP_STAT 16 bit r/o General Purpose Status Register */
+#define GM_GPSR_SPEED (1<<15) /* Bit 15: Port Speed (1 = 100 Mbps) */
+#define GM_GPSR_DUPLEX (1<<14) /* Bit 14: Duplex Mode (1 = Full) */
+#define GM_GPSR_FC_TX_DIS (1<<13) /* Bit 13: Tx Flow-Control Mode Disabled */
+#define GM_GPSR_LINK_UP (1<<12) /* Bit 12: Link Up Status */
+#define GM_GPSR_PAUSE (1<<11) /* Bit 11: Pause State */
+#define GM_GPSR_TX_ACTIVE (1<<10) /* Bit 10: Tx in Progress */
+#define GM_GPSR_EXC_COL (1<<9) /* Bit 9: Excessive Collisions Occured */
+#define GM_GPSR_LAT_COL (1<<8) /* Bit 8: Late Collisions Occured */
+ /* Bit 7..6: reserved */
+#define GM_GPSR_PHY_ST_CH (1<<5) /* Bit 5: PHY Status Change */
+#define GM_GPSR_GIG_SPEED (1<<4) /* Bit 4: Gigabit Speed (1 = 1000 Mbps) */
+#define GM_GPSR_PART_MODE (1<<3) /* Bit 3: Partition mode */
+#define GM_GPSR_FC_RX_DIS (1<<2) /* Bit 2: Rx Flow-Control Mode Disabled */
+#define GM_GPSR_PROM_EN (1<<1) /* Bit 1: Promiscuous Mode Enabled */
+ /* Bit 0: reserved */
+
+/* GM_GP_CTRL 16 bit r/w General Purpose Control Register */
+ /* Bit 15: reserved */
+#define GM_GPCR_PROM_ENA (1<<14) /* Bit 14: Enable Promiscuous Mode */
+#define GM_GPCR_FC_TX_DIS (1<<13) /* Bit 13: Disable Tx Flow-Control Mode */
+#define GM_GPCR_TX_ENA (1<<12) /* Bit 12: Enable Transmit */
+#define GM_GPCR_RX_ENA (1<<11) /* Bit 11: Enable Receive */
+#define GM_GPCR_BURST_ENA (1<<10) /* Bit 10: Enable Burst Mode */
+#define GM_GPCR_LOOP_ENA (1<<9) /* Bit 9: Enable MAC Loopback Mode */
+#define GM_GPCR_PART_ENA (1<<8) /* Bit 8: Enable Partition Mode */
+#define GM_GPCR_GIGS_ENA (1<<7) /* Bit 7: Gigabit Speed (1000 Mbps) */
+#define GM_GPCR_FL_PASS (1<<6) /* Bit 6: Force Link Pass */
+#define GM_GPCR_DUP_FULL (1<<5) /* Bit 5: Full Duplex Mode */
+#define GM_GPCR_FC_RX_DIS (1<<4) /* Bit 4: Disable Rx Flow-Control Mode */
+#define GM_GPCR_SPEED_100 (1<<3) /* Bit 3: Port Speed 100 Mbps */
+#define GM_GPCR_AU_DUP_DIS (1<<2) /* Bit 2: Disable Auto-Update Duplex */
+#define GM_GPCR_AU_FCT_DIS (1<<1) /* Bit 1: Disable Auto-Update Flow-C. */
+#define GM_GPCR_AU_SPD_DIS (1<<0) /* Bit 0: Disable Auto-Update Speed */
+
+#define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
+#define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\
+ GM_GPCR_AU_SPD_DIS)
+
+/* GM_TX_CTRL 16 bit r/w Transmit Control Register */
+#define GM_TXCR_FORCE_JAM (1<<15) /* Bit 15: Force Jam / Flow-Control */
+#define GM_TXCR_CRC_DIS (1<<14) /* Bit 14: Disable insertion of CRC */
+#define GM_TXCR_PAD_DIS (1<<13) /* Bit 13: Disable padding of packets */
+#define GM_TXCR_COL_THR_MSK (1<<10) /* Bit 12..10: Collision Threshold */
+
+#define TX_COL_THR(x) (SHIFT10(x) & GM_TXCR_COL_THR_MSK)
+
+#define TX_COL_DEF 0x04
+
+/* GM_RX_CTRL 16 bit r/w Receive Control Register */
+#define GM_RXCR_UCF_ENA (1<<15) /* Bit 15: Enable Unicast filtering */
+#define GM_RXCR_MCF_ENA (1<<14) /* Bit 14: Enable Multicast filtering */
+#define GM_RXCR_CRC_DIS (1<<13) /* Bit 13: Remove 4-byte CRC */
+#define GM_RXCR_PASS_FC (1<<12) /* Bit 12: Pass FC packets to FIFO */
+
+/* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */
+#define GM_TXPA_JAMLEN_MSK (0x03<<14) /* Bit 15..14: Jam Length */
+#define GM_TXPA_JAMIPG_MSK (0x1f<<9) /* Bit 13..9: Jam IPG */
+#define GM_TXPA_JAMDAT_MSK (0x1f<<4) /* Bit 8..4: IPG Jam to Data */
+ /* Bit 3..0: reserved */
+
+#define TX_JAM_LEN_VAL(x) (SHIFT14(x) & GM_TXPA_JAMLEN_MSK)
+#define TX_JAM_IPG_VAL(x) (SHIFT9(x) & GM_TXPA_JAMIPG_MSK)
+#define TX_IPG_JAM_DATA(x) (SHIFT4(x) & GM_TXPA_JAMDAT_MSK)
+
+#define TX_JAM_LEN_DEF 0x03
+#define TX_JAM_IPG_DEF 0x0b
+#define TX_IPG_JAM_DEF 0x1c
+
+/* GM_SERIAL_MODE 16 bit r/w Serial Mode Register */
+#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder (r/o) */
+#define GM_SMOD_LIMIT_4 (1<<10) /* Bit 10: 4 consecutive Tx trials */
+#define GM_SMOD_VLAN_ENA (1<<9) /* Bit 9: Enable VLAN (Max. Frame Len) */
+#define GM_SMOD_JUMBO_ENA (1<<8) /* Bit 8: Enable Jumbo (Max. Frame Len) */
+ /* Bit 7..5: reserved */
+#define GM_SMOD_IPG_MSK 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */
+
+#define DATA_BLIND_VAL(x) (SHIFT11(x) & GM_SMOD_DATABL_MSK)
+#define DATA_BLIND_DEF 0x04
+
+#define IPG_DATA_VAL(x) (x & GM_SMOD_IPG_MSK)
+#define IPG_DATA_DEF 0x1e
+
+/* GM_SMI_CTRL 16 bit r/w SMI Control Register */
+#define GM_SMI_CT_PHY_A_MSK (0x1f<<11) /* Bit 15..11: PHY Device Address */
+#define GM_SMI_CT_REG_A_MSK (0x1f<<6) /* Bit 10.. 6: PHY Register Address */
+#define GM_SMI_CT_OP_RD (1<<5) /* Bit 5: OpCode Read (0=Write)*/
+#define GM_SMI_CT_RD_VAL (1<<4) /* Bit 4: Read Valid (Read completed) */
+#define GM_SMI_CT_BUSY (1<<3) /* Bit 3: Busy (Operation in progress) */
+ /* Bit 2..0: reserved */
+
+#define GM_SMI_CT_PHY_AD(x) (SHIFT11(x) & GM_SMI_CT_PHY_A_MSK)
+#define GM_SMI_CT_REG_AD(x) (SHIFT6(x) & GM_SMI_CT_REG_A_MSK)
+
+ /* GM_PHY_ADDR 16 bit r/w GPHY Address Register */
+ /* Bit 15..6: reserved */
+#define GM_PAR_MIB_CLR (1<<5) /* Bit 5: Set MIB Clear Counter Mode */
+#define GM_PAR_MIB_TST (1<<4) /* Bit 4: MIB Load Counter (Test Mode) */
+ /* Bit 3..0: reserved */
+
+/* Receive Frame Status Encoding */
+#define GMR_FS_LEN (0xffffUL<<16) /* Bit 31..16: Rx Frame Length */
+ /* Bit 15..14: reserved */
+#define GMR_FS_VLAN (1L<<13) /* Bit 13: VLAN Packet */
+#define GMR_FS_JABBER (1L<<12) /* Bit 12: Jabber Packet */
+#define GMR_FS_UN_SIZE (1L<<11) /* Bit 11: Undersize Packet */
+#define GMR_FS_MC (1L<<10) /* Bit 10: Multicast Packet */
+#define GMR_FS_BC (1L<<9) /* Bit 9: Broadcast Packet */
+#define GMR_FS_RX_OK (1L<<8) /* Bit 8: Receive OK (Good Packet) */
+#define GMR_FS_GOOD_FC (1L<<7) /* Bit 7: Good Flow-Control Packet */
+#define GMR_FS_BAD_FC (1L<<6) /* Bit 6: Bad Flow-Control Packet */
+#define GMR_FS_MII_ERR (1L<<5) /* Bit 5: MII Error */
+#define GMR_FS_LONG_ERR (1L<<4) /* Bit 4: Too Long Packet */
+#define GMR_FS_FRAGMENT (1L<<3) /* Bit 3: Fragment */
+ /* Bit 2: reserved */
+#define GMR_FS_CRC_ERR (1L<<1) /* Bit 1: CRC Error */
+#define GMR_FS_RX_FF_OV (1L<<0) /* Bit 0: Rx FIFO Overflow */
+
+/*
+ * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR)
+ */
+#define GMR_FS_ANY_ERR (GMR_FS_CRC_ERR | \
+ GMR_FS_LONG_ERR | \
+ GMR_FS_MII_ERR | \
+ GMR_FS_BAD_FC | \
+ GMR_FS_GOOD_FC | \
+ GMR_FS_JABBER)
+
+/* Rx GMAC FIFO Flush Mask (default) */
+#define RX_FF_FL_DEF_MSK (GMR_FS_CRC_ERR | \
+ GMR_FS_RX_FF_OV | \
+ GMR_FS_MII_ERR | \
+ GMR_FS_BAD_FC | \
+ GMR_FS_GOOD_FC | \
+ GMR_FS_UN_SIZE | \
+ GMR_FS_JABBER)
+
+/* typedefs *******************************************************************/
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __INC_XMAC_H */
diff --git a/drivers/net/sk98lin/skaddr.c b/drivers/net/sk98lin/skaddr.c
new file mode 100644
index 000000000000..a7e25edc7fc4
--- /dev/null
+++ b/drivers/net/sk98lin/skaddr.c
@@ -0,0 +1,1773 @@
+/******************************************************************************
+ *
+ * Name: skaddr.c
+ * Project: Gigabit Ethernet Adapters, ADDR-Module
+ * Version: $Revision: 1.52 $
+ * Date: $Date: 2003/06/02 13:46:15 $
+ * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This module is intended to manage multicast addresses, address override,
+ * and promiscuous mode on GEnesis and Yukon adapters.
+ *
+ * Address Layout:
+ * port address: physical MAC address
+ * 1st exact match: logical MAC address (GEnesis only)
+ * 2nd exact match: RLMT multicast (GEnesis only)
+ * exact match 3-13: OS-specific multicasts (GEnesis only)
+ *
+ * Include File Hierarchy:
+ *
+ * "skdrv1st.h"
+ * "skdrv2nd.h"
+ *
+ ******************************************************************************/
+
+#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
+static const char SysKonnectFileId[] =
+ "@(#) $Id: skaddr.c,v 1.52 2003/06/02 13:46:15 tschilli Exp $ (C) Marvell.";
+#endif /* DEBUG ||!LINT || !SK_SLIM */
+
+#define __SKADDR_C
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* cplusplus */
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+
+/* defines ********************************************************************/
+
+
+#define XMAC_POLY 0xEDB88320UL /* CRC32-Poly - XMAC: Little Endian */
+#define GMAC_POLY 0x04C11DB7L /* CRC16-Poly - GMAC: Little Endian */
+#define HASH_BITS 6 /* #bits in hash */
+#define SK_MC_BIT 0x01
+
+/* Error numbers and messages. */
+
+#define SKERR_ADDR_E001 (SK_ERRBASE_ADDR + 0)
+#define SKERR_ADDR_E001MSG "Bad Flags."
+#define SKERR_ADDR_E002 (SKERR_ADDR_E001 + 1)
+#define SKERR_ADDR_E002MSG "New Error."
+
+/* typedefs *******************************************************************/
+
+/* None. */
+
+/* global variables ***********************************************************/
+
+/* 64-bit hash values with all bits set. */
+
+static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
+
+/* local variables ************************************************************/
+
+#ifdef DEBUG
+static int Next0[SK_MAX_MACS] = {0};
+#endif /* DEBUG */
+
+/* functions ******************************************************************/
+
+/******************************************************************************
+ *
+ * SkAddrInit - initialize data, set state to init
+ *
+ * Description:
+ *
+ * SK_INIT_DATA
+ * ============
+ *
+ * This routine clears the multicast tables and resets promiscuous mode.
+ * Some entries are reserved for the "logical MAC address", the
+ * SK-RLMT multicast address, and the BPDU multicast address.
+ *
+ *
+ * SK_INIT_IO
+ * ==========
+ *
+ * All permanent MAC addresses are read from EPROM.
+ * If the current MAC addresses are not already set in software,
+ * they are set to the values of the permanent addresses.
+ * The current addresses are written to the corresponding MAC.
+ *
+ *
+ * SK_INIT_RUN
+ * ===========
+ *
+ * Nothing.
+ *
+ * Context:
+ * init, pageable
+ *
+ * Returns:
+ * SK_ADDR_SUCCESS
+ */
+int SkAddrInit(
+SK_AC *pAC, /* the adapter context */
+SK_IOC IoC, /* I/O context */
+int Level) /* initialization level */
+{
+ int j;
+ SK_U32 i;
+ SK_U8 *InAddr;
+ SK_U16 *OutAddr;
+ SK_ADDR_PORT *pAPort;
+
+ switch (Level) {
+ case SK_INIT_DATA:
+ SK_MEMSET((char *) &pAC->Addr, (SK_U8) 0,
+ (SK_U16) sizeof(SK_ADDR));
+
+ for (i = 0; i < SK_MAX_MACS; i++) {
+ pAPort = &pAC->Addr.Port[i];
+ pAPort->PromMode = SK_PROM_MODE_NONE;
+
+ pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
+ pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
+ pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
+ pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
+ }
+#ifdef xDEBUG
+ for (i = 0; i < SK_MAX_MACS; i++) {
+ if (pAC->Addr.Port[i].NextExactMatchRlmt <
+ SK_ADDR_FIRST_MATCH_RLMT) {
+ Next0[i] |= 4;
+ }
+ }
+#endif /* DEBUG */
+ /* pAC->Addr.InitDone = SK_INIT_DATA; */
+ break;
+
+ case SK_INIT_IO:
+#ifndef SK_NO_RLMT
+ for (i = 0; i < SK_MAX_NETS; i++) {
+ pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort;
+ }
+#endif /* !SK_NO_RLMT */
+#ifdef xDEBUG
+ for (i = 0; i < SK_MAX_MACS; i++) {
+ if (pAC->Addr.Port[i].NextExactMatchRlmt <
+ SK_ADDR_FIRST_MATCH_RLMT) {
+ Next0[i] |= 8;
+ }
+ }
+#endif /* DEBUG */
+
+ /* Read permanent logical MAC address from Control Register File. */
+ for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
+ InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j];
+ SK_IN8(IoC, B2_MAC_1 + j, InAddr);
+ }
+
+ if (!pAC->Addr.Net[0].CurrentMacAddressSet) {
+ /* Set the current logical MAC address to the permanent one. */
+ pAC->Addr.Net[0].CurrentMacAddress =
+ pAC->Addr.Net[0].PermanentMacAddress;
+ pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE;
+ }
+
+ /* Set the current logical MAC address. */
+ pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] =
+ pAC->Addr.Net[0].CurrentMacAddress;
+#if SK_MAX_NETS > 1
+ /* Set logical MAC address for net 2 to (log | 3). */
+ if (!pAC->Addr.Net[1].CurrentMacAddressSet) {
+ pAC->Addr.Net[1].PermanentMacAddress =
+ pAC->Addr.Net[0].PermanentMacAddress;
+ pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3;
+ /* Set the current logical MAC address to the permanent one. */
+ pAC->Addr.Net[1].CurrentMacAddress =
+ pAC->Addr.Net[1].PermanentMacAddress;
+ pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE;
+ }
+#endif /* SK_MAX_NETS > 1 */
+
+#ifdef DEBUG
+ for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+ SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
+ ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
+ i,
+ pAC->Addr.Net[i].PermanentMacAddress.a[0],
+ pAC->Addr.Net[i].PermanentMacAddress.a[1],
+ pAC->Addr.Net[i].PermanentMacAddress.a[2],
+ pAC->Addr.Net[i].PermanentMacAddress.a[3],
+ pAC->Addr.Net[i].PermanentMacAddress.a[4],
+ pAC->Addr.Net[i].PermanentMacAddress.a[5]))
+
+ SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
+ ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n",
+ i,
+ pAC->Addr.Net[i].CurrentMacAddress.a[0],
+ pAC->Addr.Net[i].CurrentMacAddress.a[1],
+ pAC->Addr.Net[i].CurrentMacAddress.a[2],
+ pAC->Addr.Net[i].CurrentMacAddress.a[3],
+ pAC->Addr.Net[i].CurrentMacAddress.a[4],
+ pAC->Addr.Net[i].CurrentMacAddress.a[5]))
+ }
+#endif /* DEBUG */
+
+ for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+ pAPort = &pAC->Addr.Port[i];
+
+ /* Read permanent port addresses from Control Register File. */
+ for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
+ InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j];
+ SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr);
+ }
+
+ if (!pAPort->CurrentMacAddressSet) {
+ /*
+ * Set the current and previous physical MAC address
+ * of this port to its permanent MAC address.
+ */
+ pAPort->CurrentMacAddress = pAPort->PermanentMacAddress;
+ pAPort->PreviousMacAddress = pAPort->PermanentMacAddress;
+ pAPort->CurrentMacAddressSet = SK_TRUE;
+ }
+
+ /* Set port's current physical MAC address. */
+ OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
+#ifdef GENESIS
+ if (pAC->GIni.GIGenesis) {
+ XM_OUTADDR(IoC, i, XM_SA, OutAddr);
+ }
+#endif /* GENESIS */
+#ifdef YUKON
+ if (!pAC->GIni.GIGenesis) {
+ GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr);
+ }
+#endif /* YUKON */
+#ifdef DEBUG
+ SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
+ ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+ pAPort->PermanentMacAddress.a[0],
+ pAPort->PermanentMacAddress.a[1],
+ pAPort->PermanentMacAddress.a[2],
+ pAPort->PermanentMacAddress.a[3],
+ pAPort->PermanentMacAddress.a[4],
+ pAPort->PermanentMacAddress.a[5]))
+
+ SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT,
+ ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+ pAPort->CurrentMacAddress.a[0],
+ pAPort->CurrentMacAddress.a[1],
+ pAPort->CurrentMacAddress.a[2],
+ pAPort->CurrentMacAddress.a[3],
+ pAPort->CurrentMacAddress.a[4],
+ pAPort->CurrentMacAddress.a[5]))
+#endif /* DEBUG */
+ }
+ /* pAC->Addr.InitDone = SK_INIT_IO; */
+ break;
+
+ case SK_INIT_RUN:
+#ifdef xDEBUG
+ for (i = 0; i < SK_MAX_MACS; i++) {
+ if (pAC->Addr.Port[i].NextExactMatchRlmt <
+ SK_ADDR_FIRST_MATCH_RLMT) {
+ Next0[i] |= 16;
+ }
+ }
+#endif /* DEBUG */
+
+ /* pAC->Addr.InitDone = SK_INIT_RUN; */
+ break;
+
+ default: /* error */
+ break;
+ }
+
+ return (SK_ADDR_SUCCESS);
+
+} /* SkAddrInit */
+
+#ifndef SK_SLIM
+
+/******************************************************************************
+ *
+ * SkAddrMcClear - clear the multicast table
+ *
+ * Description:
+ * This routine clears the multicast table.
+ *
+ * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
+ * immediately.
+ *
+ * It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according
+ * to the adapter in use. The real work is done there.
+ *
+ * Context:
+ * runtime, pageable
+ * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
+ * may be called after SK_INIT_IO without limitation
+ *
+ * Returns:
+ * SK_ADDR_SUCCESS
+ * SK_ADDR_ILLEGAL_PORT
+ */
+int SkAddrMcClear(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber, /* Index of affected port */
+int Flags) /* permanent/non-perm, sw-only */
+{
+ int ReturnCode;
+
+ if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+ return (SK_ADDR_ILLEGAL_PORT);
+ }
+
+ if (pAC->GIni.GIGenesis) {
+ ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags);
+ }
+ else {
+ ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags);
+ }
+
+ return (ReturnCode);
+
+} /* SkAddrMcClear */
+
+#endif /* !SK_SLIM */
+
+#ifndef SK_SLIM
+
+/******************************************************************************
+ *
+ * SkAddrXmacMcClear - clear the multicast table
+ *
+ * Description:
+ * This routine clears the multicast table
+ * (either entry 2 or entries 3-16 and InexactFilter) of the given port.
+ * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
+ * immediately.
+ *
+ * Context:
+ * runtime, pageable
+ * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
+ * may be called after SK_INIT_IO without limitation
+ *
+ * Returns:
+ * SK_ADDR_SUCCESS
+ * SK_ADDR_ILLEGAL_PORT
+ */
+int SkAddrXmacMcClear(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber, /* Index of affected port */
+int Flags) /* permanent/non-perm, sw-only */
+{
+ int i;
+
+ if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
+
+ /* Clear RLMT multicast addresses. */
+ pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
+ }
+ else { /* not permanent => DRV */
+
+ /* Clear InexactFilter */
+ for (i = 0; i < 8; i++) {
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
+ }
+
+ /* Clear DRV multicast addresses. */
+
+ pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
+ }
+
+ if (!(Flags & SK_MC_SW_ONLY)) {
+ (void) SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
+ }
+
+ return (SK_ADDR_SUCCESS);
+
+} /* SkAddrXmacMcClear */
+
+#endif /* !SK_SLIM */
+
+#ifndef SK_SLIM
+
+/******************************************************************************
+ *
+ * SkAddrGmacMcClear - clear the multicast table
+ *
+ * Description:
+ * This routine clears the multicast hashing table (InexactFilter)
+ * (either the RLMT or the driver bits) of the given port.
+ *
+ * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated
+ * immediately.
+ *
+ * Context:
+ * runtime, pageable
+ * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY
+ * may be called after SK_INIT_IO without limitation
+ *
+ * Returns:
+ * SK_ADDR_SUCCESS
+ * SK_ADDR_ILLEGAL_PORT
+ */
+int SkAddrGmacMcClear(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber, /* Index of affected port */
+int Flags) /* permanent/non-perm, sw-only */
+{
+ int i;
+
+#ifdef DEBUG
+ SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
+#endif /* DEBUG */
+
+ /* Clear InexactFilter */
+ for (i = 0; i < 8; i++) {
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
+ }
+
+ if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
+
+ /* Copy DRV bits to InexactFilter. */
+ for (i = 0; i < 8; i++) {
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
+ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
+
+ /* Clear InexactRlmtFilter. */
+ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0;
+
+ }
+ }
+ else { /* not permanent => DRV */
+
+ /* Copy RLMT bits to InexactFilter. */
+ for (i = 0; i < 8; i++) {
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
+ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
+
+ /* Clear InexactDrvFilter. */
+ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0;
+ }
+ }
+
+#ifdef DEBUG
+ SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n",
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6],
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]))
+#endif /* DEBUG */
+
+ if (!(Flags & SK_MC_SW_ONLY)) {
+ (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
+ }
+
+ return (SK_ADDR_SUCCESS);
+
+} /* SkAddrGmacMcClear */
+
+#ifndef SK_ADDR_CHEAT
+
+/******************************************************************************
+ *
+ * SkXmacMcHash - hash multicast address
+ *
+ * Description:
+ * This routine computes the hash value for a multicast address.
+ * A CRC32 algorithm is used.
+ *
+ * Notes:
+ * The code was adapted from the XaQti data sheet.
+ *
+ * Context:
+ * runtime, pageable
+ *
+ * Returns:
+ * Hash value of multicast address.
+ */
+SK_U32 SkXmacMcHash(
+unsigned char *pMc) /* Multicast address */
+{
+ SK_U32 Idx;
+ SK_U32 Bit;
+ SK_U32 Data;
+ SK_U32 Crc;
+
+ Crc = 0xFFFFFFFFUL;
+ for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) {
+ Data = *pMc++;
+ for (Bit = 0; Bit < 8; Bit++, Data >>= 1) {
+ Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0);
+ }
+ }
+
+ return (Crc & ((1 << HASH_BITS) - 1));
+
+} /* SkXmacMcHash */
+
+
+/******************************************************************************
+ *
+ * SkGmacMcHash - hash multicast address
+ *
+ * Description:
+ * This routine computes the hash value for a multicast address.
+ * A CRC16 algorithm is used.
+ *
+ * Notes:
+ *
+ *
+ * Context:
+ * runtime, pageable
+ *
+ * Returns:
+ * Hash value of multicast address.
+ */
+SK_U32 SkGmacMcHash(
+unsigned char *pMc) /* Multicast address */
+{
+ SK_U32 Data;
+ SK_U32 TmpData;
+ SK_U32 Crc;
+ int Byte;
+ int Bit;
+
+ Crc = 0xFFFFFFFFUL;
+ for (Byte = 0; Byte < 6; Byte++) {
+ /* Get next byte. */
+ Data = (SK_U32) pMc[Byte];
+
+ /* Change bit order in byte. */
+ TmpData = Data;
+ for (Bit = 0; Bit < 8; Bit++) {
+ if (TmpData & 1L) {
+ Data |= 1L << (7 - Bit);
+ }
+ else {
+ Data &= ~(1L << (7 - Bit));
+ }
+ TmpData >>= 1;
+ }
+
+ Crc ^= (Data << 24);
+ for (Bit = 0; Bit < 8; Bit++) {
+ if (Crc & 0x80000000) {
+ Crc = (Crc << 1) ^ GMAC_POLY;
+ }
+ else {
+ Crc <<= 1;
+ }
+ }
+ }
+
+ return (Crc & ((1 << HASH_BITS) - 1));
+
+} /* SkGmacMcHash */
+
+#endif /* !SK_ADDR_CHEAT */
+
+/******************************************************************************
+ *
+ * SkAddrMcAdd - add a multicast address to a port
+ *
+ * Description:
+ * This routine enables reception for a given address on the given port.
+ *
+ * It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the
+ * adapter in use. The real work is done there.
+ *
+ * Notes:
+ * The return code is only valid for SK_PROM_MODE_NONE.
+ *
+ * Context:
+ * runtime, pageable
+ * may be called after SK_INIT_DATA
+ *
+ * Returns:
+ * SK_MC_FILTERING_EXACT
+ * SK_MC_FILTERING_INEXACT
+ * SK_MC_ILLEGAL_ADDRESS
+ * SK_MC_ILLEGAL_PORT
+ * SK_MC_RLMT_OVERFLOW
+ */
+int SkAddrMcAdd(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber, /* Port Number */
+SK_MAC_ADDR *pMc, /* multicast address to be added */
+int Flags) /* permanent/non-permanent */
+{
+ int ReturnCode;
+
+ if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+ return (SK_ADDR_ILLEGAL_PORT);
+ }
+
+ if (pAC->GIni.GIGenesis) {
+ ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
+ }
+ else {
+ ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags);
+ }
+
+ return (ReturnCode);
+
+} /* SkAddrMcAdd */
+
+
+/******************************************************************************
+ *
+ * SkAddrXmacMcAdd - add a multicast address to a port
+ *
+ * Description:
+ * This routine enables reception for a given address on the given port.
+ *
+ * Notes:
+ * The return code is only valid for SK_PROM_MODE_NONE.
+ *
+ * The multicast bit is only checked if there are no free exact match
+ * entries.
+ *
+ * Context:
+ * runtime, pageable
+ * may be called after SK_INIT_DATA
+ *
+ * Returns:
+ * SK_MC_FILTERING_EXACT
+ * SK_MC_FILTERING_INEXACT
+ * SK_MC_ILLEGAL_ADDRESS
+ * SK_MC_RLMT_OVERFLOW
+ */
+int SkAddrXmacMcAdd(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber, /* Port Number */
+SK_MAC_ADDR *pMc, /* multicast address to be added */
+int Flags) /* permanent/non-permanent */
+{
+ int i;
+ SK_U8 Inexact;
+#ifndef SK_ADDR_CHEAT
+ SK_U32 HashBit;
+#endif /* !defined(SK_ADDR_CHEAT) */
+
+ if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
+#ifdef xDEBUG
+ if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt <
+ SK_ADDR_FIRST_MATCH_RLMT) {
+ Next0[PortNumber] |= 1;
+ return (SK_MC_RLMT_OVERFLOW);
+ }
+#endif /* DEBUG */
+
+ if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt >
+ SK_ADDR_LAST_MATCH_RLMT) {
+ return (SK_MC_RLMT_OVERFLOW);
+ }
+
+ /* Set a RLMT multicast address. */
+
+ pAC->Addr.Port[PortNumber].Exact[
+ pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc;
+
+ return (SK_MC_FILTERING_EXACT);
+ }
+
+#ifdef xDEBUG
+ if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <
+ SK_ADDR_FIRST_MATCH_DRV) {
+ Next0[PortNumber] |= 2;
+ return (SK_MC_RLMT_OVERFLOW);
+ }
+#endif /* DEBUG */
+
+ if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
+
+ /* Set exact match entry. */
+ pAC->Addr.Port[PortNumber].Exact[
+ pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc;
+
+ /* Clear InexactFilter */
+ for (i = 0; i < 8; i++) {
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0;
+ }
+ }
+ else {
+ if (!(pMc->a[0] & SK_MC_BIT)) {
+ /* Hashing only possible with multicast addresses */
+ return (SK_MC_ILLEGAL_ADDRESS);
+ }
+#ifndef SK_ADDR_CHEAT
+ /* Compute hash value of address. */
+ HashBit = 63 - SkXmacMcHash(&pMc->a[0]);
+
+ /* Add bit to InexactFilter. */
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |=
+ 1 << (HashBit % 8);
+#else /* SK_ADDR_CHEAT */
+ /* Set all bits in InexactFilter. */
+ for (i = 0; i < 8; i++) {
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
+ }
+#endif /* SK_ADDR_CHEAT */
+ }
+
+ for (Inexact = 0, i = 0; i < 8; i++) {
+ Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
+ }
+
+ if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) {
+ return (SK_MC_FILTERING_EXACT);
+ }
+ else {
+ return (SK_MC_FILTERING_INEXACT);
+ }
+
+} /* SkAddrXmacMcAdd */
+
+
+/******************************************************************************
+ *
+ * SkAddrGmacMcAdd - add a multicast address to a port
+ *
+ * Description:
+ * This routine enables reception for a given address on the given port.
+ *
+ * Notes:
+ * The return code is only valid for SK_PROM_MODE_NONE.
+ *
+ * Context:
+ * runtime, pageable
+ * may be called after SK_INIT_DATA
+ *
+ * Returns:
+ * SK_MC_FILTERING_INEXACT
+ * SK_MC_ILLEGAL_ADDRESS
+ */
+int SkAddrGmacMcAdd(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber, /* Port Number */
+SK_MAC_ADDR *pMc, /* multicast address to be added */
+int Flags) /* permanent/non-permanent */
+{
+ int i;
+#ifndef SK_ADDR_CHEAT
+ SK_U32 HashBit;
+#endif /* !defined(SK_ADDR_CHEAT) */
+
+ if (!(pMc->a[0] & SK_MC_BIT)) {
+ /* Hashing only possible with multicast addresses */
+ return (SK_MC_ILLEGAL_ADDRESS);
+ }
+
+#ifndef SK_ADDR_CHEAT
+
+ /* Compute hash value of address. */
+ HashBit = SkGmacMcHash(&pMc->a[0]);
+
+ if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */
+
+ /* Add bit to InexactRlmtFilter. */
+ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |=
+ 1 << (HashBit % 8);
+
+ /* Copy bit to InexactFilter. */
+ for (i = 0; i < 8; i++) {
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
+ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i];
+ }
+#ifdef DEBUG
+ SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
+ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[0],
+ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[1],
+ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[2],
+ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[3],
+ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4],
+ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5],
+ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6],
+ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7]))
+#endif /* DEBUG */
+ }
+ else { /* not permanent => DRV */
+
+ /* Add bit to InexactDrvFilter. */
+ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |=
+ 1 << (HashBit % 8);
+
+ /* Copy bit to InexactFilter. */
+ for (i = 0; i < 8; i++) {
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |=
+ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i];
+ }
+#ifdef DEBUG
+ SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n",
+ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[0],
+ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[1],
+ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[2],
+ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[3],
+ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4],
+ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5],
+ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6],
+ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7]))
+#endif /* DEBUG */
+ }
+
+#else /* SK_ADDR_CHEAT */
+
+ /* Set all bits in InexactFilter. */
+ for (i = 0; i < 8; i++) {
+ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF;
+ }
+#endif /* SK_ADDR_CHEAT */
+
+ return (SK_MC_FILTERING_INEXACT);
+
+} /* SkAddrGmacMcAdd */
+
+#endif /* !SK_SLIM */
+
+/******************************************************************************
+ *
+ * SkAddrMcUpdate - update the HW MC address table and set the MAC address
+ *
+ * Description:
+ * This routine enables reception of the addresses contained in a local
+ * table for a given port.
+ * It also programs the port's current physical MAC address.
+ *
+ * It calls either SkAddrXmacMcUpdate or SkAddrGmacMcUpdate, according
+ * to the adapter in use. The real work is done there.
+ *
+ * Notes:
+ * The return code is only valid for SK_PROM_MODE_NONE.
+ *
+ * Context:
+ * runtime, pageable
+ * may be called after SK_INIT_IO
+ *
+ * Returns:
+ * SK_MC_FILTERING_EXACT
+ * SK_MC_FILTERING_INEXACT
+ * SK_ADDR_ILLEGAL_PORT
+ */
+int SkAddrMcUpdate(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber) /* Port Number */
+{
+ int ReturnCode = 0;
+#if (!defined(SK_SLIM) || defined(DEBUG))
+ if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+ return (SK_ADDR_ILLEGAL_PORT);
+ }
+#endif /* !SK_SLIM || DEBUG */
+
+#ifdef GENESIS
+ if (pAC->GIni.GIGenesis) {
+ ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber);
+ }
+#endif /* GENESIS */
+#ifdef YUKON
+ if (!pAC->GIni.GIGenesis) {
+ ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber);
+ }
+#endif /* YUKON */
+ return (ReturnCode);
+
+} /* SkAddrMcUpdate */
+
+
+#ifdef GENESIS
+
+/******************************************************************************
+ *
+ * SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address
+ *
+ * Description:
+ * This routine enables reception of the addresses contained in a local
+ * table for a given port.
+ * It also programs the port's current physical MAC address.
+ *
+ * Notes:
+ * The return code is only valid for SK_PROM_MODE_NONE.
+ *
+ * Context:
+ * runtime, pageable
+ * may be called after SK_INIT_IO
+ *
+ * Returns:
+ * SK_MC_FILTERING_EXACT
+ * SK_MC_FILTERING_INEXACT
+ * SK_ADDR_ILLEGAL_PORT
+ */
+int SkAddrXmacMcUpdate(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber) /* Port Number */
+{
+ SK_U32 i;
+ SK_U8 Inexact;
+ SK_U16 *OutAddr;
+ SK_ADDR_PORT *pAPort;
+
+ SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber))
+
+ pAPort = &pAC->Addr.Port[PortNumber];
+
+#ifdef DEBUG
+ SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
+#endif /* DEBUG */
+
+ /* Start with 0 to also program the logical MAC address. */
+ for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
+ /* Set exact match address i on XMAC */
+ OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
+ XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
+ }
+
+ /* Clear other permanent exact match addresses on XMAC */
+ if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) {
+
+ SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt,
+ SK_ADDR_LAST_MATCH_RLMT);
+ }
+
+ for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) {
+ OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0];
+ XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr);
+ }
+
+ /* Clear other non-permanent exact match addresses on XMAC */
+ if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
+
+ SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv,
+ SK_ADDR_LAST_MATCH_DRV);
+ }
+
+ for (Inexact = 0, i = 0; i < 8; i++) {
+ Inexact |= pAPort->InexactFilter.Bytes[i];
+ }
+
+ if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
+
+ /* Set all bits in 64-bit hash register. */
+ XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
+
+ /* Enable Hashing */
+ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
+ }
+ else if (Inexact != 0) {
+
+ /* Set 64-bit hash register to InexactFilter. */
+ XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
+
+ /* Enable Hashing */
+ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
+ }
+ else {
+ /* Disable Hashing */
+ SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE);
+ }
+
+ if (pAPort->PromMode != SK_PROM_MODE_NONE) {
+ (void) SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
+ }
+
+ /* Set port's current physical MAC address. */
+ OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
+
+ XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
+
+#ifdef xDEBUG
+ for (i = 0; i < pAPort->NextExactMatchRlmt; i++) {
+ SK_U8 InAddr8[6];
+ SK_U16 *InAddr;
+
+ /* Get exact match address i from port PortNumber. */
+ InAddr = (SK_U16 *) &InAddr8[0];
+
+ XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr);
+
+ SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("SkAddrXmacMcUpdate: MC address %d on Port %u: ",
+ "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n",
+ i,
+ PortNumber,
+ InAddr8[0],
+ InAddr8[1],
+ InAddr8[2],
+ InAddr8[3],
+ InAddr8[4],
+ InAddr8[5],
+ pAPort->Exact[i].a[0],
+ pAPort->Exact[i].a[1],
+ pAPort->Exact[i].a[2],
+ pAPort->Exact[i].a[3],
+ pAPort->Exact[i].a[4],
+ pAPort->Exact[i].a[5]))
+ }
+#endif /* DEBUG */
+
+ /* Determine return value. */
+ if (Inexact == 0 && pAPort->PromMode == 0) {
+ return (SK_MC_FILTERING_EXACT);
+ }
+ else {
+ return (SK_MC_FILTERING_INEXACT);
+ }
+
+} /* SkAddrXmacMcUpdate */
+
+#endif /* GENESIS */
+
+#ifdef YUKON
+
+/******************************************************************************
+ *
+ * SkAddrGmacMcUpdate - update the HW MC address table and set the MAC address
+ *
+ * Description:
+ * This routine enables reception of the addresses contained in a local
+ * table for a given port.
+ * It also programs the port's current physical MAC address.
+ *
+ * Notes:
+ * The return code is only valid for SK_PROM_MODE_NONE.
+ *
+ * Context:
+ * runtime, pageable
+ * may be called after SK_INIT_IO
+ *
+ * Returns:
+ * SK_MC_FILTERING_EXACT
+ * SK_MC_FILTERING_INEXACT
+ * SK_ADDR_ILLEGAL_PORT
+ */
+int SkAddrGmacMcUpdate(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber) /* Port Number */
+{
+#ifndef SK_SLIM
+ SK_U32 i;
+ SK_U8 Inexact;
+#endif /* not SK_SLIM */
+ SK_U16 *OutAddr;
+ SK_ADDR_PORT *pAPort;
+
+ SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber))
+
+ pAPort = &pAC->Addr.Port[PortNumber];
+
+#ifdef DEBUG
+ SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber]))
+#endif /* DEBUG */
+
+#ifndef SK_SLIM
+ for (Inexact = 0, i = 0; i < 8; i++) {
+ Inexact |= pAPort->InexactFilter.Bytes[i];
+ }
+
+ /* Set 64-bit hash register to InexactFilter. */
+ GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
+ &pAPort->InexactFilter.Bytes[0]);
+
+ if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
+
+ /* Set all bits in 64-bit hash register. */
+ GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
+
+ /* Enable Hashing */
+ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
+ }
+ else {
+ /* Enable Hashing. */
+ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
+ }
+
+ if (pAPort->PromMode != SK_PROM_MODE_NONE) {
+ (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
+ }
+#else /* SK_SLIM */
+
+ /* Set all bits in 64-bit hash register. */
+ GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
+
+ /* Enable Hashing */
+ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
+
+ (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode);
+
+#endif /* SK_SLIM */
+
+ /* Set port's current physical MAC address. */
+ OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0];
+ GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
+
+ /* Set port's current logical MAC address. */
+ OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0];
+ GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr);
+
+#ifdef DEBUG
+ SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+ pAPort->Exact[0].a[0],
+ pAPort->Exact[0].a[1],
+ pAPort->Exact[0].a[2],
+ pAPort->Exact[0].a[3],
+ pAPort->Exact[0].a[4],
+ pAPort->Exact[0].a[5]))
+
+ SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+ pAPort->CurrentMacAddress.a[0],
+ pAPort->CurrentMacAddress.a[1],
+ pAPort->CurrentMacAddress.a[2],
+ pAPort->CurrentMacAddress.a[3],
+ pAPort->CurrentMacAddress.a[4],
+ pAPort->CurrentMacAddress.a[5]))
+#endif /* DEBUG */
+
+#ifndef SK_SLIM
+ /* Determine return value. */
+ if (Inexact == 0 && pAPort->PromMode == 0) {
+ return (SK_MC_FILTERING_EXACT);
+ }
+ else {
+ return (SK_MC_FILTERING_INEXACT);
+ }
+#else /* SK_SLIM */
+ return (SK_MC_FILTERING_INEXACT);
+#endif /* SK_SLIM */
+
+} /* SkAddrGmacMcUpdate */
+
+#endif /* YUKON */
+
+#ifndef SK_NO_MAO
+
+/******************************************************************************
+ *
+ * SkAddrOverride - override a port's MAC address
+ *
+ * Description:
+ * This routine overrides the MAC address of one port.
+ *
+ * Context:
+ * runtime, pageable
+ * may be called after SK_INIT_IO
+ *
+ * Returns:
+ * SK_ADDR_SUCCESS if successful.
+ * SK_ADDR_DUPLICATE_ADDRESS if duplicate MAC address.
+ * SK_ADDR_MULTICAST_ADDRESS if multicast or broadcast address.
+ * SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before.
+ */
+int SkAddrOverride(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber, /* Port Number */
+SK_MAC_ADDR SK_FAR *pNewAddr, /* new MAC address */
+int Flags) /* logical/physical MAC address */
+{
+#ifndef SK_NO_RLMT
+ SK_EVPARA Para;
+#endif /* !SK_NO_RLMT */
+ SK_U32 NetNumber;
+ SK_U32 i;
+ SK_U16 SK_FAR *OutAddr;
+
+#ifndef SK_NO_RLMT
+ NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber;
+#else
+ NetNumber = 0;
+#endif /* SK_NO_RLMT */
+#if (!defined(SK_SLIM) || defined(DEBUG))
+ if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+ return (SK_ADDR_ILLEGAL_PORT);
+ }
+#endif /* !SK_SLIM || DEBUG */
+ if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) {
+ return (SK_ADDR_MULTICAST_ADDRESS);
+ }
+
+ if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) {
+ return (SK_ADDR_TOO_EARLY);
+ }
+
+ if (Flags & SK_ADDR_SET_LOGICAL) { /* Activate logical MAC address. */
+ /* Parameter *pNewAddr is ignored. */
+ for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+ if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
+ return (SK_ADDR_TOO_EARLY);
+ }
+ }
+#ifndef SK_NO_RLMT
+ /* Set PortNumber to number of net's active port. */
+ PortNumber = pAC->Rlmt.Net[NetNumber].
+ Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
+#endif /* !SK_NO_RLMT */
+ pAC->Addr.Port[PortNumber].Exact[0] =
+ pAC->Addr.Net[NetNumber].CurrentMacAddress;
+
+ /* Write address to first exact match entry of active port. */
+ (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
+ }
+ else if (Flags & SK_ADDR_CLEAR_LOGICAL) {
+ /* Deactivate logical MAC address. */
+ /* Parameter *pNewAddr is ignored. */
+ for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+ if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
+ return (SK_ADDR_TOO_EARLY);
+ }
+ }
+#ifndef SK_NO_RLMT
+ /* Set PortNumber to number of net's active port. */
+ PortNumber = pAC->Rlmt.Net[NetNumber].
+ Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
+#endif /* !SK_NO_RLMT */
+ for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) {
+ pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0;
+ }
+
+ /* Write address to first exact match entry of active port. */
+ (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
+ }
+ else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical MAC address. */
+ if (SK_ADDR_EQUAL(pNewAddr->a,
+ pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
+ return (SK_ADDR_DUPLICATE_ADDRESS);
+ }
+
+ for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+ if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
+ return (SK_ADDR_TOO_EARLY);
+ }
+
+ if (SK_ADDR_EQUAL(pNewAddr->a,
+ pAC->Addr.Port[i].CurrentMacAddress.a)) {
+ if (i == PortNumber) {
+ return (SK_ADDR_SUCCESS);
+ }
+ else {
+ return (SK_ADDR_DUPLICATE_ADDRESS);
+ }
+ }
+ }
+
+ pAC->Addr.Port[PortNumber].PreviousMacAddress =
+ pAC->Addr.Port[PortNumber].CurrentMacAddress;
+ pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
+
+ /* Change port's physical MAC address. */
+ OutAddr = (SK_U16 SK_FAR *) pNewAddr;
+#ifdef GENESIS
+ if (pAC->GIni.GIGenesis) {
+ XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr);
+ }
+#endif /* GENESIS */
+#ifdef YUKON
+ if (!pAC->GIni.GIGenesis) {
+ GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr);
+ }
+#endif /* YUKON */
+
+#ifndef SK_NO_RLMT
+ /* Report address change to RLMT. */
+ Para.Para32[0] = PortNumber;
+ Para.Para32[0] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
+#endif /* !SK_NO_RLMT */
+ }
+ else { /* Logical MAC address. */
+ if (SK_ADDR_EQUAL(pNewAddr->a,
+ pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) {
+ return (SK_ADDR_SUCCESS);
+ }
+
+ for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) {
+ if (!pAC->Addr.Port[i].CurrentMacAddressSet) {
+ return (SK_ADDR_TOO_EARLY);
+ }
+
+ if (SK_ADDR_EQUAL(pNewAddr->a,
+ pAC->Addr.Port[i].CurrentMacAddress.a)) {
+ return (SK_ADDR_DUPLICATE_ADDRESS);
+ }
+ }
+
+ /*
+ * In case that the physical and the logical MAC addresses are equal
+ * we must also change the physical MAC address here.
+ * In this case we have an adapter which initially was programmed with
+ * two identical MAC addresses.
+ */
+ if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a,
+ pAC->Addr.Port[PortNumber].Exact[0].a)) {
+
+ pAC->Addr.Port[PortNumber].PreviousMacAddress =
+ pAC->Addr.Port[PortNumber].CurrentMacAddress;
+ pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr;
+
+#ifndef SK_NO_RLMT
+ /* Report address change to RLMT. */
+ Para.Para32[0] = PortNumber;
+ Para.Para32[0] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
+#endif /* !SK_NO_RLMT */
+ }
+
+#ifndef SK_NO_RLMT
+ /* Set PortNumber to number of net's active port. */
+ PortNumber = pAC->Rlmt.Net[NetNumber].
+ Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber;
+#endif /* !SK_NO_RLMT */
+ pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr;
+ pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr;
+#ifdef DEBUG
+ SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("SkAddrOverride: Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",
+ pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0],
+ pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1],
+ pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2],
+ pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3],
+ pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4],
+ pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5]))
+
+ SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL,
+ ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+ pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0],
+ pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1],
+ pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2],
+ pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3],
+ pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4],
+ pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5]))
+#endif /* DEBUG */
+
+ /* Write address to first exact match entry of active port. */
+ (void) SkAddrMcUpdate(pAC, IoC, PortNumber);
+ }
+
+ return (SK_ADDR_SUCCESS);
+
+} /* SkAddrOverride */
+
+
+#endif /* SK_NO_MAO */
+
+/******************************************************************************
+ *
+ * SkAddrPromiscuousChange - set promiscuous mode for given port
+ *
+ * Description:
+ * This routine manages promiscuous mode:
+ * - none
+ * - all LLC frames
+ * - all MC frames
+ *
+ * It calls either SkAddrXmacPromiscuousChange or
+ * SkAddrGmacPromiscuousChange, according to the adapter in use.
+ * The real work is done there.
+ *
+ * Context:
+ * runtime, pageable
+ * may be called after SK_INIT_IO
+ *
+ * Returns:
+ * SK_ADDR_SUCCESS
+ * SK_ADDR_ILLEGAL_PORT
+ */
+int SkAddrPromiscuousChange(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber, /* port whose promiscuous mode changes */
+int NewPromMode) /* new promiscuous mode */
+{
+ int ReturnCode = 0;
+#if (!defined(SK_SLIM) || defined(DEBUG))
+ if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+ return (SK_ADDR_ILLEGAL_PORT);
+ }
+#endif /* !SK_SLIM || DEBUG */
+
+#ifdef GENESIS
+ if (pAC->GIni.GIGenesis) {
+ ReturnCode =
+ SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
+ }
+#endif /* GENESIS */
+#ifdef YUKON
+ if (!pAC->GIni.GIGenesis) {
+ ReturnCode =
+ SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode);
+ }
+#endif /* YUKON */
+
+ return (ReturnCode);
+
+} /* SkAddrPromiscuousChange */
+
+#ifdef GENESIS
+
+/******************************************************************************
+ *
+ * SkAddrXmacPromiscuousChange - set promiscuous mode for given port
+ *
+ * Description:
+ * This routine manages promiscuous mode:
+ * - none
+ * - all LLC frames
+ * - all MC frames
+ *
+ * Context:
+ * runtime, pageable
+ * may be called after SK_INIT_IO
+ *
+ * Returns:
+ * SK_ADDR_SUCCESS
+ * SK_ADDR_ILLEGAL_PORT
+ */
+int SkAddrXmacPromiscuousChange(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber, /* port whose promiscuous mode changes */
+int NewPromMode) /* new promiscuous mode */
+{
+ int i;
+ SK_BOOL InexactModeBit;
+ SK_U8 Inexact;
+ SK_U8 HwInexact;
+ SK_FILTER64 HwInexactFilter;
+ SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Register. */
+ int CurPromMode = SK_PROM_MODE_NONE;
+
+ /* Read CurPromMode from Hardware. */
+ XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
+
+ if ((LoMode & XM_MD_ENA_PROM) != 0) {
+ /* Promiscuous mode! */
+ CurPromMode |= SK_PROM_MODE_LLC;
+ }
+
+ for (Inexact = 0xFF, i = 0; i < 8; i++) {
+ Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
+ }
+ if (Inexact == 0xFF) {
+ CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
+ }
+ else {
+ /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */
+ XM_IN16(IoC, PortNumber, XM_MODE, &LoMode);
+
+ InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0;
+
+ /* Read 64-bit hash register from XMAC */
+ XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]);
+
+ for (HwInexact = 0xFF, i = 0; i < 8; i++) {
+ HwInexact &= HwInexactFilter.Bytes[i];
+ }
+
+ if (InexactModeBit && (HwInexact == 0xFF)) {
+ CurPromMode |= SK_PROM_MODE_ALL_MC;
+ }
+ }
+
+ pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
+
+ if (NewPromMode == CurPromMode) {
+ return (SK_ADDR_SUCCESS);
+ }
+
+ if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
+ !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */
+
+ /* Set all bits in 64-bit hash register. */
+ XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash);
+
+ /* Enable Hashing */
+ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
+ }
+ else if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
+ !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */
+ for (Inexact = 0, i = 0; i < 8; i++) {
+ Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i];
+ }
+ if (Inexact == 0) {
+ /* Disable Hashing */
+ SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE);
+ }
+ else {
+ /* Set 64-bit hash register to InexactFilter. */
+ XM_OUTHASH(IoC, PortNumber, XM_HSM,
+ &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
+
+ /* Enable Hashing */
+ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
+ }
+ }
+
+ if ((NewPromMode & SK_PROM_MODE_LLC) &&
+ !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */
+ /* Set the MAC in Promiscuous Mode */
+ SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE);
+ }
+ else if ((CurPromMode & SK_PROM_MODE_LLC) &&
+ !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC. */
+ /* Clear Promiscuous Mode */
+ SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE);
+ }
+
+ return (SK_ADDR_SUCCESS);
+
+} /* SkAddrXmacPromiscuousChange */
+
+#endif /* GENESIS */
+
+#ifdef YUKON
+
+/******************************************************************************
+ *
+ * SkAddrGmacPromiscuousChange - set promiscuous mode for given port
+ *
+ * Description:
+ * This routine manages promiscuous mode:
+ * - none
+ * - all LLC frames
+ * - all MC frames
+ *
+ * Context:
+ * runtime, pageable
+ * may be called after SK_INIT_IO
+ *
+ * Returns:
+ * SK_ADDR_SUCCESS
+ * SK_ADDR_ILLEGAL_PORT
+ */
+int SkAddrGmacPromiscuousChange(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 PortNumber, /* port whose promiscuous mode changes */
+int NewPromMode) /* new promiscuous mode */
+{
+ SK_U16 ReceiveControl; /* GMAC Receive Control Register */
+ int CurPromMode = SK_PROM_MODE_NONE;
+
+ /* Read CurPromMode from Hardware. */
+ GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl);
+
+ if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) {
+ /* Promiscuous mode! */
+ CurPromMode |= SK_PROM_MODE_LLC;
+ }
+
+ if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) {
+ /* All Multicast mode! */
+ CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC);
+ }
+
+ pAC->Addr.Port[PortNumber].PromMode = NewPromMode;
+
+ if (NewPromMode == CurPromMode) {
+ return (SK_ADDR_SUCCESS);
+ }
+
+ if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
+ !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */
+
+ /* Set all bits in 64-bit hash register. */
+ GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash);
+
+ /* Enable Hashing */
+ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
+ }
+
+ if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
+ !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */
+
+ /* Set 64-bit hash register to InexactFilter. */
+ GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1,
+ &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]);
+
+ /* Enable Hashing. */
+ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE);
+ }
+
+ if ((NewPromMode & SK_PROM_MODE_LLC) &&
+ !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */
+
+ /* Set the MAC to Promiscuous Mode. */
+ SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE);
+ }
+ else if ((CurPromMode & SK_PROM_MODE_LLC) &&
+ !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC */
+
+ /* Clear Promiscuous Mode. */
+ SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE);
+ }
+
+ return (SK_ADDR_SUCCESS);
+
+} /* SkAddrGmacPromiscuousChange */
+
+#endif /* YUKON */
+
+#ifndef SK_SLIM
+
+/******************************************************************************
+ *
+ * SkAddrSwap - swap address info
+ *
+ * Description:
+ * This routine swaps address info of two ports.
+ *
+ * Context:
+ * runtime, pageable
+ * may be called after SK_INIT_IO
+ *
+ * Returns:
+ * SK_ADDR_SUCCESS
+ * SK_ADDR_ILLEGAL_PORT
+ */
+int SkAddrSwap(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC, /* I/O context */
+SK_U32 FromPortNumber, /* Port1 Index */
+SK_U32 ToPortNumber) /* Port2 Index */
+{
+ int i;
+ SK_U8 Byte;
+ SK_MAC_ADDR MacAddr;
+ SK_U32 DWord;
+
+ if (FromPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+ return (SK_ADDR_ILLEGAL_PORT);
+ }
+
+ if (ToPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) {
+ return (SK_ADDR_ILLEGAL_PORT);
+ }
+
+ if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) {
+ return (SK_ADDR_ILLEGAL_PORT);
+ }
+
+ /*
+ * Swap:
+ * - Exact Match Entries (GEnesis and Yukon)
+ * Yukon uses first entry for the logical MAC
+ * address (stored in the second GMAC register).
+ * - FirstExactMatchRlmt (GEnesis only)
+ * - NextExactMatchRlmt (GEnesis only)
+ * - FirstExactMatchDrv (GEnesis only)
+ * - NextExactMatchDrv (GEnesis only)
+ * - 64-bit filter (InexactFilter)
+ * - Promiscuous Mode
+ * of ports.
+ */
+
+ for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) {
+ MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i];
+ pAC->Addr.Port[FromPortNumber].Exact[i] =
+ pAC->Addr.Port[ToPortNumber].Exact[i];
+ pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr;
+ }
+
+ for (i = 0; i < 8; i++) {
+ Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i];
+ pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] =
+ pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i];
+ pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte;
+ }
+
+ i = pAC->Addr.Port[FromPortNumber].PromMode;
+ pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode;
+ pAC->Addr.Port[ToPortNumber].PromMode = i;
+
+ if (pAC->GIni.GIGenesis) {
+ DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt;
+ pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt =
+ pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt;
+ pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord;
+
+ DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt;
+ pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt =
+ pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt;
+ pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord;
+
+ DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv;
+ pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv =
+ pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv;
+ pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord;
+
+ DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv;
+ pAC->Addr.Port[FromPortNumber].NextExactMatchDrv =
+ pAC->Addr.Port[ToPortNumber].NextExactMatchDrv;
+ pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord;
+ }
+
+ /* CAUTION: Solution works if only ports of one adapter are in use. */
+ for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].
+ Net->NetNumber].NumPorts; i++) {
+ if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
+ Port[i]->PortNumber == ToPortNumber) {
+ pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber].
+ ActivePort = i;
+ /* 20001207 RA: Was "ToPortNumber;". */
+ }
+ }
+
+ (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber);
+ (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber);
+
+ return (SK_ADDR_SUCCESS);
+
+} /* SkAddrSwap */
+
+#endif /* !SK_SLIM */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
diff --git a/drivers/net/sk98lin/skcsum.c b/drivers/net/sk98lin/skcsum.c
new file mode 100644
index 000000000000..38a6e7a631f3
--- /dev/null
+++ b/drivers/net/sk98lin/skcsum.c
@@ -0,0 +1,871 @@
+/******************************************************************************
+ *
+ * Name: skcsum.c
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.12 $
+ * Date: $Date: 2003/08/20 13:55:53 $
+ * Purpose: Store/verify Internet checksum in send/receive packets.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2003 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.
+ *
+ ******************************************************************************/
+
+#ifdef SK_USE_CSUM /* Check if CSUM is to be used. */
+
+#ifndef lint
+static const char SysKonnectFileId[] =
+ "@(#) $Id: skcsum.c,v 1.12 2003/08/20 13:55:53 mschmid Exp $ (C) SysKonnect.";
+#endif /* !lint */
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This is the "GEnesis" common module "CSUM".
+ *
+ * This module contains the code necessary to calculate, store, and verify the
+ * Internet Checksum of IP, TCP, and UDP frames.
+ *
+ * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
+ * and is the code name of this SysKonnect project.
+ *
+ * Compilation Options:
+ *
+ * SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
+ * empty module.
+ *
+ * SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
+ * definitions. In this case, all SKCS_PROTO_xxx definitions must be made
+ * external.
+ *
+ * SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
+ * definitions. In this case, all SKCS_STATUS_xxx definitions must be made
+ * external.
+ *
+ * Include File Hierarchy:
+ *
+ * "h/skdrv1st.h"
+ * "h/skcsum.h"
+ * "h/sktypes.h"
+ * "h/skqueue.h"
+ * "h/skdrv2nd.h"
+ *
+ ******************************************************************************/
+
+#include "h/skdrv1st.h"
+#include "h/skcsum.h"
+#include "h/skdrv2nd.h"
+
+/* defines ********************************************************************/
+
+/* The size of an Ethernet MAC header. */
+#define SKCS_ETHERNET_MAC_HEADER_SIZE (6+6+2)
+
+/* The size of the used topology's MAC header. */
+#define SKCS_MAC_HEADER_SIZE SKCS_ETHERNET_MAC_HEADER_SIZE
+
+/* The size of the IP header without any option fields. */
+#define SKCS_IP_HEADER_SIZE 20
+
+/*
+ * Field offsets within the IP header.
+ */
+
+/* "Internet Header Version" and "Length". */
+#define SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH 0
+
+/* "Total Length". */
+#define SKCS_OFS_IP_TOTAL_LENGTH 2
+
+/* "Flags" "Fragment Offset". */
+#define SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET 6
+
+/* "Next Level Protocol" identifier. */
+#define SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL 9
+
+/* Source IP address. */
+#define SKCS_OFS_IP_SOURCE_ADDRESS 12
+
+/* Destination IP address. */
+#define SKCS_OFS_IP_DESTINATION_ADDRESS 16
+
+
+/*
+ * Field offsets within the UDP header.
+ */
+
+/* UDP checksum. */
+#define SKCS_OFS_UDP_CHECKSUM 6
+
+/* IP "Next Level Protocol" identifiers (see RFC 790). */
+#define SKCS_PROTO_ID_TCP 6 /* Transport Control Protocol */
+#define SKCS_PROTO_ID_UDP 17 /* User Datagram Protocol */
+
+/* IP "Don't Fragment" bit. */
+#define SKCS_IP_DONT_FRAGMENT SKCS_HTON16(0x4000)
+
+/* Add a byte offset to a pointer. */
+#define SKCS_IDX(pPtr, Ofs) ((void *) ((char *) (pPtr) + (Ofs)))
+
+/*
+ * Macros that convert host to network representation and vice versa, i.e.
+ * little/big endian conversion on little endian machines only.
+ */
+#ifdef SK_LITTLE_ENDIAN
+#define SKCS_HTON16(Val16) (((unsigned) (Val16) >> 8) | (((Val16) & 0xff) << 8))
+#endif /* SK_LITTLE_ENDIAN */
+#ifdef SK_BIG_ENDIAN
+#define SKCS_HTON16(Val16) (Val16)
+#endif /* SK_BIG_ENDIAN */
+#define SKCS_NTOH16(Val16) SKCS_HTON16(Val16)
+
+/* typedefs *******************************************************************/
+
+/* function prototypes ********************************************************/
+
+/******************************************************************************
+ *
+ * SkCsGetSendInfo - get checksum information for a send packet
+ *
+ * Description:
+ * Get all checksum information necessary to send a TCP or UDP packet. The
+ * function checks the IP header passed to it. If the high-level protocol
+ * is either TCP or UDP the pseudo header checksum is calculated and
+ * returned.
+ *
+ * The function returns the total length of the IP header (including any
+ * IP option fields), which is the same as the start offset of the IP data
+ * which in turn is the start offset of the TCP or UDP header.
+ *
+ * The function also returns the TCP or UDP pseudo header checksum, which
+ * should be used as the start value for the hardware checksum calculation.
+ * (Note that any actual pseudo header checksum can never calculate to
+ * zero.)
+ *
+ * Note:
+ * There is a bug in the GENESIS ASIC which may lead to wrong checksums.
+ *
+ * Arguments:
+ * pAc - A pointer to the adapter context struct.
+ *
+ * pIpHeader - Pointer to IP header. Must be at least the IP header *not*
+ * including any option fields, i.e. at least 20 bytes.
+ *
+ * Note: This pointer will be used to address 8-, 16-, and 32-bit
+ * variables with the respective alignment offsets relative to the pointer.
+ * Thus, the pointer should point to a 32-bit aligned address. If the
+ * target system cannot address 32-bit variables on non 32-bit aligned
+ * addresses, then the pointer *must* point to a 32-bit aligned address.
+ *
+ * pPacketInfo - A pointer to the packet information structure for this
+ * packet. Before calling this SkCsGetSendInfo(), the following field must
+ * be initialized:
+ *
+ * ProtocolFlags - Initialize with any combination of
+ * SKCS_PROTO_XXX bit flags. SkCsGetSendInfo() will only work on
+ * the protocols specified here. Any protocol(s) not specified
+ * here will be ignored.
+ *
+ * Note: Only one checksum can be calculated in hardware. Thus, if
+ * SKCS_PROTO_IP is specified in the 'ProtocolFlags',
+ * SkCsGetSendInfo() must calculate the IP header checksum in
+ * software. It might be a better idea to have the calling
+ * protocol stack calculate the IP header checksum.
+ *
+ * Returns: N/A
+ * On return, the following fields in 'pPacketInfo' may or may not have
+ * been filled with information, depending on the protocol(s) found in the
+ * packet:
+ *
+ * ProtocolFlags - Returns the SKCS_PROTO_XXX bit flags of the protocol(s)
+ * that were both requested by the caller and actually found in the packet.
+ * Protocol(s) not specified by the caller and/or not found in the packet
+ * will have their respective SKCS_PROTO_XXX bit flags reset.
+ *
+ * Note: For IP fragments, TCP and UDP packet information is ignored.
+ *
+ * IpHeaderLength - The total length in bytes of the complete IP header
+ * including any option fields is returned here. This is the start offset
+ * of the IP data, i.e. the TCP or UDP header if present.
+ *
+ * IpHeaderChecksum - If IP has been specified in the 'ProtocolFlags', the
+ * 16-bit Internet Checksum of the IP header is returned here. This value
+ * is to be stored into the packet's 'IP Header Checksum' field.
+ *
+ * PseudoHeaderChecksum - If this is a TCP or UDP packet and if TCP or UDP
+ * has been specified in the 'ProtocolFlags', the 16-bit Internet Checksum
+ * of the TCP or UDP pseudo header is returned here.
+ */
+void SkCsGetSendInfo(
+SK_AC *pAc, /* Adapter context struct. */
+void *pIpHeader, /* IP header. */
+SKCS_PACKET_INFO *pPacketInfo, /* Packet information struct. */
+int NetNumber) /* Net number */
+{
+ /* Internet Header Version found in IP header. */
+ unsigned InternetHeaderVersion;
+
+ /* Length of the IP header as found in IP header. */
+ unsigned IpHeaderLength;
+
+ /* Bit field specifiying the desired/found protocols. */
+ unsigned ProtocolFlags;
+
+ /* Next level protocol identifier found in IP header. */
+ unsigned NextLevelProtocol;
+
+ /* Length of IP data portion. */
+ unsigned IpDataLength;
+
+ /* TCP/UDP pseudo header checksum. */
+ unsigned long PseudoHeaderChecksum;
+
+ /* Pointer to next level protocol statistics structure. */
+ SKCS_PROTO_STATS *NextLevelProtoStats;
+
+ /* Temporary variable. */
+ unsigned Tmp;
+
+ Tmp = *(SK_U8 *)
+ SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);
+
+ /* Get the Internet Header Version (IHV). */
+ /* Note: The IHV is stored in the upper four bits. */
+
+ InternetHeaderVersion = Tmp >> 4;
+
+ /* Check the Internet Header Version. */
+ /* Note: We currently only support IP version 4. */
+
+ if (InternetHeaderVersion != 4) { /* IPv4? */
+ SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
+ ("Tx: Unknown Internet Header Version %u.\n",
+ InternetHeaderVersion));
+ pPacketInfo->ProtocolFlags = 0;
+ pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
+ return;
+ }
+
+ /* Get the IP header length (IHL). */
+ /*
+ * Note: The IHL is stored in the lower four bits as the number of
+ * 4-byte words.
+ */
+
+ IpHeaderLength = (Tmp & 0xf) * 4;
+ pPacketInfo->IpHeaderLength = IpHeaderLength;
+
+ /* Check the IP header length. */
+
+ /* 04-Aug-1998 sw - Really check the IHL? Necessary? */
+
+ if (IpHeaderLength < 5*4) {
+ SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
+ ("Tx: Invalid IP Header Length %u.\n", IpHeaderLength));
+ pPacketInfo->ProtocolFlags = 0;
+ pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
+ return;
+ }
+
+ /* This is an IPv4 frame with a header of valid length. */
+
+ pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxOkCts++;
+
+ /* Check if we should calculate the IP header checksum. */
+
+ ProtocolFlags = pPacketInfo->ProtocolFlags;
+
+ if (ProtocolFlags & SKCS_PROTO_IP) {
+ pPacketInfo->IpHeaderChecksum =
+ SkCsCalculateChecksum(pIpHeader, IpHeaderLength);
+ }
+
+ /* Get the next level protocol identifier. */
+
+ NextLevelProtocol =
+ *(SK_U8 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
+
+ /*
+ * Check if this is a TCP or UDP frame and if we should calculate the
+ * TCP/UDP pseudo header checksum.
+ *
+ * Also clear all protocol bit flags of protocols not present in the
+ * frame.
+ */
+
+ if ((ProtocolFlags & SKCS_PROTO_TCP) != 0 &&
+ NextLevelProtocol == SKCS_PROTO_ID_TCP) {
+ /* TCP/IP frame. */
+ ProtocolFlags &= SKCS_PROTO_TCP | SKCS_PROTO_IP;
+ NextLevelProtoStats =
+ &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
+ }
+ else if ((ProtocolFlags & SKCS_PROTO_UDP) != 0 &&
+ NextLevelProtocol == SKCS_PROTO_ID_UDP) {
+ /* UDP/IP frame. */
+ ProtocolFlags &= SKCS_PROTO_UDP | SKCS_PROTO_IP;
+ NextLevelProtoStats =
+ &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
+ }
+ else {
+ /*
+ * Either not a TCP or UDP frame and/or TCP/UDP processing not
+ * specified.
+ */
+ pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;
+ return;
+ }
+
+ /* Check if this is an IP fragment. */
+
+ /*
+ * Note: An IP fragment has a non-zero "Fragment Offset" field and/or
+ * the "More Fragments" bit set. Thus, if both the "Fragment Offset"
+ * and the "More Fragments" are zero, it is *not* a fragment. We can
+ * easily check both at the same time since they are in the same 16-bit
+ * word.
+ */
+
+ if ((*(SK_U16 *)
+ SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &
+ ~SKCS_IP_DONT_FRAGMENT) != 0) {
+ /* IP fragment; ignore all other protocols. */
+ pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;
+ NextLevelProtoStats->TxUnableCts++;
+ return;
+ }
+
+ /*
+ * Calculate the TCP/UDP pseudo header checksum.
+ */
+
+ /* Get total length of IP header and data. */
+
+ IpDataLength =
+ *(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);
+
+ /* Get length of IP data portion. */
+
+ IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;
+
+ /* Calculate the sum of all pseudo header fields (16-bit). */
+
+ PseudoHeaderChecksum =
+ (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+ SKCS_OFS_IP_SOURCE_ADDRESS + 0) +
+ (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+ SKCS_OFS_IP_SOURCE_ADDRESS + 2) +
+ (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+ SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
+ (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+ SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
+ (unsigned long) SKCS_HTON16(NextLevelProtocol) +
+ (unsigned long) SKCS_HTON16(IpDataLength);
+
+ /* Add-in any carries. */
+
+ SKCS_OC_ADD(PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
+
+ /* Add-in any new carry. */
+
+ SKCS_OC_ADD(pPacketInfo->PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
+
+ pPacketInfo->ProtocolFlags = ProtocolFlags;
+ NextLevelProtoStats->TxOkCts++; /* Success. */
+} /* SkCsGetSendInfo */
+
+
+/******************************************************************************
+ *
+ * SkCsGetReceiveInfo - verify checksum information for a received packet
+ *
+ * Description:
+ * Verify a received frame's checksum. The function returns a status code
+ * reflecting the result of the verification.
+ *
+ * Note:
+ * Before calling this function you have to verify that the frame is
+ * not padded and Checksum1 and Checksum2 are bigger than 1.
+ *
+ * Arguments:
+ * pAc - Pointer to adapter context struct.
+ *
+ * pIpHeader - Pointer to IP header. Must be at least the length in bytes
+ * of the received IP header including any option fields. For UDP packets,
+ * 8 additional bytes are needed to access the UDP checksum.
+ *
+ * Note: The actual length of the IP header is stored in the lower four
+ * bits of the first octet of the IP header as the number of 4-byte words,
+ * so it must be multiplied by four to get the length in bytes. Thus, the
+ * maximum IP header length is 15 * 4 = 60 bytes.
+ *
+ * Checksum1 - The first 16-bit Internet Checksum calculated by the
+ * hardware starting at the offset returned by SkCsSetReceiveFlags().
+ *
+ * Checksum2 - The second 16-bit Internet Checksum calculated by the
+ * hardware starting at the offset returned by SkCsSetReceiveFlags().
+ *
+ * Returns:
+ * SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
+ * SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
+ * SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
+ * SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
+ * SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
+ * SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
+ * SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
+ * SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
+ * SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
+ * SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
+ * SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
+ *
+ * Note: If SKCS_OVERWRITE_STATUS is defined, the SKCS_STATUS_XXX values
+ * returned here can be defined in some header file by the module using CSUM.
+ * In this way, the calling module can assign return values for its own needs,
+ * e.g. by assigning bit flags to the individual protocols.
+ */
+SKCS_STATUS SkCsGetReceiveInfo(
+SK_AC *pAc, /* Adapter context struct. */
+void *pIpHeader, /* IP header. */
+unsigned Checksum1, /* Hardware checksum 1. */
+unsigned Checksum2, /* Hardware checksum 2. */
+int NetNumber) /* Net number */
+{
+ /* Internet Header Version found in IP header. */
+ unsigned InternetHeaderVersion;
+
+ /* Length of the IP header as found in IP header. */
+ unsigned IpHeaderLength;
+
+ /* Length of IP data portion. */
+ unsigned IpDataLength;
+
+ /* IP header checksum. */
+ unsigned IpHeaderChecksum;
+
+ /* IP header options checksum, if any. */
+ unsigned IpOptionsChecksum;
+
+ /* IP data checksum, i.e. TCP/UDP checksum. */
+ unsigned IpDataChecksum;
+
+ /* Next level protocol identifier found in IP header. */
+ unsigned NextLevelProtocol;
+
+ /* The checksum of the "next level protocol", i.e. TCP or UDP. */
+ unsigned long NextLevelProtocolChecksum;
+
+ /* Pointer to next level protocol statistics structure. */
+ SKCS_PROTO_STATS *NextLevelProtoStats;
+
+ /* Temporary variable. */
+ unsigned Tmp;
+
+ Tmp = *(SK_U8 *)
+ SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);
+
+ /* Get the Internet Header Version (IHV). */
+ /* Note: The IHV is stored in the upper four bits. */
+
+ InternetHeaderVersion = Tmp >> 4;
+
+ /* Check the Internet Header Version. */
+ /* Note: We currently only support IP version 4. */
+
+ if (InternetHeaderVersion != 4) { /* IPv4? */
+ SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
+ ("Rx: Unknown Internet Header Version %u.\n",
+ InternetHeaderVersion));
+ pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxUnableCts++;
+ return (SKCS_STATUS_UNKNOWN_IP_VERSION);
+ }
+
+ /* Get the IP header length (IHL). */
+ /*
+ * Note: The IHL is stored in the lower four bits as the number of
+ * 4-byte words.
+ */
+
+ IpHeaderLength = (Tmp & 0xf) * 4;
+
+ /* Check the IP header length. */
+
+ /* 04-Aug-1998 sw - Really check the IHL? Necessary? */
+
+ if (IpHeaderLength < 5*4) {
+ SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
+ ("Rx: Invalid IP Header Length %u.\n", IpHeaderLength));
+ pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
+ return (SKCS_STATUS_IP_CSUM_ERROR);
+ }
+
+ /* This is an IPv4 frame with a header of valid length. */
+
+ /* Get the IP header and data checksum. */
+
+ IpDataChecksum = Checksum2;
+
+ /*
+ * The IP header checksum is calculated as follows:
+ *
+ * IpHeaderChecksum = Checksum1 - Checksum2
+ */
+
+ SKCS_OC_SUB(IpHeaderChecksum, Checksum1, Checksum2);
+
+ /* Check if any IP header options. */
+
+ if (IpHeaderLength > SKCS_IP_HEADER_SIZE) {
+
+ /* Get the IP options checksum. */
+
+ IpOptionsChecksum = SkCsCalculateChecksum(
+ SKCS_IDX(pIpHeader, SKCS_IP_HEADER_SIZE),
+ IpHeaderLength - SKCS_IP_HEADER_SIZE);
+
+ /* Adjust the IP header and IP data checksums. */
+
+ SKCS_OC_ADD(IpHeaderChecksum, IpHeaderChecksum, IpOptionsChecksum);
+
+ SKCS_OC_SUB(IpDataChecksum, IpDataChecksum, IpOptionsChecksum);
+ }
+
+ /*
+ * Check if the IP header checksum is ok.
+ *
+ * NOTE: We must check the IP header checksum even if the caller just wants
+ * us to check upper-layer checksums, because we cannot do any further
+ * processing of the packet without a valid IP checksum.
+ */
+
+ /* Get the next level protocol identifier. */
+
+ NextLevelProtocol = *(SK_U8 *)
+ SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
+
+ if (IpHeaderChecksum != 0xffff) {
+ pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
+ /* the NDIS tester wants to know the upper level protocol too */
+ if (NextLevelProtocol == SKCS_PROTO_ID_TCP) {
+ return(SKCS_STATUS_IP_CSUM_ERROR_TCP);
+ }
+ else if (NextLevelProtocol == SKCS_PROTO_ID_UDP) {
+ return(SKCS_STATUS_IP_CSUM_ERROR_UDP);
+ }
+ return (SKCS_STATUS_IP_CSUM_ERROR);
+ }
+
+ /*
+ * Check if this is a TCP or UDP frame and if we should calculate the
+ * TCP/UDP pseudo header checksum.
+ *
+ * Also clear all protocol bit flags of protocols not present in the
+ * frame.
+ */
+
+ if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_TCP) != 0 &&
+ NextLevelProtocol == SKCS_PROTO_ID_TCP) {
+ /* TCP/IP frame. */
+ NextLevelProtoStats =
+ &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
+ }
+ else if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_UDP) != 0 &&
+ NextLevelProtocol == SKCS_PROTO_ID_UDP) {
+ /* UDP/IP frame. */
+ NextLevelProtoStats =
+ &pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
+ }
+ else {
+ /*
+ * Either not a TCP or UDP frame and/or TCP/UDP processing not
+ * specified.
+ */
+ return (SKCS_STATUS_IP_CSUM_OK);
+ }
+
+ /* Check if this is an IP fragment. */
+
+ /*
+ * Note: An IP fragment has a non-zero "Fragment Offset" field and/or
+ * the "More Fragments" bit set. Thus, if both the "Fragment Offset"
+ * and the "More Fragments" are zero, it is *not* a fragment. We can
+ * easily check both at the same time since they are in the same 16-bit
+ * word.
+ */
+
+ if ((*(SK_U16 *)
+ SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &
+ ~SKCS_IP_DONT_FRAGMENT) != 0) {
+ /* IP fragment; ignore all other protocols. */
+ NextLevelProtoStats->RxUnableCts++;
+ return (SKCS_STATUS_IP_FRAGMENT);
+ }
+
+ /*
+ * 08-May-2000 ra
+ *
+ * From RFC 768 (UDP)
+ * If the computed checksum is zero, it is transmitted as all ones (the
+ * equivalent in one's complement arithmetic). An all zero transmitted
+ * checksum value means that the transmitter generated no checksum (for
+ * debugging or for higher level protocols that don't care).
+ */
+
+ if (NextLevelProtocol == SKCS_PROTO_ID_UDP &&
+ *(SK_U16*)SKCS_IDX(pIpHeader, IpHeaderLength + 6) == 0x0000) {
+
+ NextLevelProtoStats->RxOkCts++;
+
+ return (SKCS_STATUS_IP_CSUM_OK_NO_UDP);
+ }
+
+ /*
+ * Calculate the TCP/UDP checksum.
+ */
+
+ /* Get total length of IP header and data. */
+
+ IpDataLength =
+ *(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);
+
+ /* Get length of IP data portion. */
+
+ IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;
+
+ NextLevelProtocolChecksum =
+
+ /* Calculate the pseudo header checksum. */
+
+ (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+ SKCS_OFS_IP_SOURCE_ADDRESS + 0) +
+ (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+ SKCS_OFS_IP_SOURCE_ADDRESS + 2) +
+ (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+ SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
+ (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
+ SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
+ (unsigned long) SKCS_HTON16(NextLevelProtocol) +
+ (unsigned long) SKCS_HTON16(IpDataLength) +
+
+ /* Add the TCP/UDP header checksum. */
+
+ (unsigned long) IpDataChecksum;
+
+ /* Add-in any carries. */
+
+ SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);
+
+ /* Add-in any new carry. */
+
+ SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);
+
+ /* Check if the TCP/UDP checksum is ok. */
+
+ if ((unsigned) NextLevelProtocolChecksum == 0xffff) {
+
+ /* TCP/UDP checksum ok. */
+
+ NextLevelProtoStats->RxOkCts++;
+
+ return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
+ SKCS_STATUS_TCP_CSUM_OK : SKCS_STATUS_UDP_CSUM_OK);
+ }
+
+ /* TCP/UDP checksum error. */
+
+ NextLevelProtoStats->RxErrCts++;
+
+ return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
+ SKCS_STATUS_TCP_CSUM_ERROR : SKCS_STATUS_UDP_CSUM_ERROR);
+} /* SkCsGetReceiveInfo */
+
+
+/******************************************************************************
+ *
+ * SkCsSetReceiveFlags - set checksum receive flags
+ *
+ * Description:
+ * Use this function to set the various receive flags. According to the
+ * protocol flags set by the caller, the start offsets within received
+ * packets of the two hardware checksums are returned. These offsets must
+ * be stored in all receive descriptors.
+ *
+ * Arguments:
+ * pAc - Pointer to adapter context struct.
+ *
+ * ReceiveFlags - Any combination of SK_PROTO_XXX flags of the protocols
+ * for which the caller wants checksum information on received frames.
+ *
+ * pChecksum1Offset - The start offset of the first receive descriptor
+ * hardware checksum to be calculated for received frames is returned
+ * here.
+ *
+ * pChecksum2Offset - The start offset of the second receive descriptor
+ * hardware checksum to be calculated for received frames is returned
+ * here.
+ *
+ * Returns: N/A
+ * Returns the two hardware checksum start offsets.
+ */
+void SkCsSetReceiveFlags(
+SK_AC *pAc, /* Adapter context struct. */
+unsigned ReceiveFlags, /* New receive flags. */
+unsigned *pChecksum1Offset, /* Offset for hardware checksum 1. */
+unsigned *pChecksum2Offset, /* Offset for hardware checksum 2. */
+int NetNumber)
+{
+ /* Save the receive flags. */
+
+ pAc->Csum.ReceiveFlags[NetNumber] = ReceiveFlags;
+
+ /* First checksum start offset is the IP header. */
+ *pChecksum1Offset = SKCS_MAC_HEADER_SIZE;
+
+ /*
+ * Second checksum start offset is the IP data. Note that this may vary
+ * if there are any IP header options in the actual packet.
+ */
+ *pChecksum2Offset = SKCS_MAC_HEADER_SIZE + SKCS_IP_HEADER_SIZE;
+} /* SkCsSetReceiveFlags */
+
+#ifndef SK_CS_CALCULATE_CHECKSUM
+
+/******************************************************************************
+ *
+ * SkCsCalculateChecksum - calculate checksum for specified data
+ *
+ * Description:
+ * Calculate and return the 16-bit Internet Checksum for the specified
+ * data.
+ *
+ * Arguments:
+ * pData - Pointer to data for which the checksum shall be calculated.
+ * Note: The pointer should be aligned on a 16-bit boundary.
+ *
+ * Length - Length in bytes of data to checksum.
+ *
+ * Returns:
+ * The 16-bit Internet Checksum for the specified data.
+ *
+ * Note: The checksum is calculated in the machine's natural byte order,
+ * i.e. little vs. big endian. Thus, the resulting checksum is different
+ * for the same input data on little and big endian machines.
+ *
+ * However, when written back to the network packet, the byte order is
+ * always in correct network order.
+ */
+unsigned SkCsCalculateChecksum(
+void *pData, /* Data to checksum. */
+unsigned Length) /* Length of data. */
+{
+ SK_U16 *pU16; /* Pointer to the data as 16-bit words. */
+ unsigned long Checksum; /* Checksum; must be at least 32 bits. */
+
+ /* Sum up all 16-bit words. */
+
+ pU16 = (SK_U16 *) pData;
+ for (Checksum = 0; Length > 1; Length -= 2) {
+ Checksum += *pU16++;
+ }
+
+ /* If this is an odd number of bytes, add-in the last byte. */
+
+ if (Length > 0) {
+#ifdef SK_BIG_ENDIAN
+ /* Add the last byte as the high byte. */
+ Checksum += ((unsigned) *(SK_U8 *) pU16) << 8;
+#else /* !SK_BIG_ENDIAN */
+ /* Add the last byte as the low byte. */
+ Checksum += *(SK_U8 *) pU16;
+#endif /* !SK_BIG_ENDIAN */
+ }
+
+ /* Add-in any carries. */
+
+ SKCS_OC_ADD(Checksum, Checksum, 0);
+
+ /* Add-in any new carry. */
+
+ SKCS_OC_ADD(Checksum, Checksum, 0);
+
+ /* Note: All bits beyond the 16-bit limit are now zero. */
+
+ return ((unsigned) Checksum);
+} /* SkCsCalculateChecksum */
+
+#endif /* SK_CS_CALCULATE_CHECKSUM */
+
+/******************************************************************************
+ *
+ * SkCsEvent - the CSUM event dispatcher
+ *
+ * Description:
+ * This is the event handler for the CSUM module.
+ *
+ * Arguments:
+ * pAc - Pointer to adapter context.
+ *
+ * Ioc - I/O context.
+ *
+ * Event - Event id.
+ *
+ * Param - Event dependent parameter.
+ *
+ * Returns:
+ * The 16-bit Internet Checksum for the specified data.
+ *
+ * Note: The checksum is calculated in the machine's natural byte order,
+ * i.e. little vs. big endian. Thus, the resulting checksum is different
+ * for the same input data on little and big endian machines.
+ *
+ * However, when written back to the network packet, the byte order is
+ * always in correct network order.
+ */
+int SkCsEvent(
+SK_AC *pAc, /* Pointer to adapter context. */
+SK_IOC Ioc, /* I/O context. */
+SK_U32 Event, /* Event id. */
+SK_EVPARA Param) /* Event dependent parameter. */
+{
+ int ProtoIndex;
+ int NetNumber;
+
+ switch (Event) {
+ /*
+ * Clear protocol statistics.
+ *
+ * Param - Protocol index, or -1 for all protocols.
+ * - Net number.
+ */
+ case SK_CSUM_EVENT_CLEAR_PROTO_STATS:
+
+ ProtoIndex = (int)Param.Para32[1];
+ NetNumber = (int)Param.Para32[0];
+ if (ProtoIndex < 0) { /* Clear for all protocols. */
+ if (NetNumber >= 0) {
+ SK_MEMSET(&pAc->Csum.ProtoStats[NetNumber][0], 0,
+ sizeof(pAc->Csum.ProtoStats[NetNumber]));
+ }
+ }
+ else { /* Clear for individual protocol. */
+ SK_MEMSET(&pAc->Csum.ProtoStats[NetNumber][ProtoIndex], 0,
+ sizeof(pAc->Csum.ProtoStats[NetNumber][ProtoIndex]));
+ }
+ break;
+ default:
+ break;
+ }
+ return (0); /* Success. */
+} /* SkCsEvent */
+
+#endif /* SK_USE_CSUM */
diff --git a/drivers/net/sk98lin/skdim.c b/drivers/net/sk98lin/skdim.c
new file mode 100644
index 000000000000..0fddf61047b4
--- /dev/null
+++ b/drivers/net/sk98lin/skdim.c
@@ -0,0 +1,742 @@
+/******************************************************************************
+ *
+ * Name: skdim.c
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.5 $
+ * Date: $Date: 2003/11/28 12:55:40 $
+ * Purpose: All functions to maintain interrupt moderation
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This module is intended to manage the dynamic interrupt moderation on both
+ * GEnesis and Yukon adapters.
+ *
+ * Include File Hierarchy:
+ *
+ * "skdrv1st.h"
+ * "skdrv2nd.h"
+ *
+ ******************************************************************************/
+
+#ifndef lint
+static const char SysKonnectFileId[] =
+ "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";
+#endif
+
+#define __SKADDR_C
+
+#ifdef __cplusplus
+#error C++ is not yet supported.
+extern "C" {
+#endif
+
+/*******************************************************************************
+**
+** Includes
+**
+*******************************************************************************/
+
+#ifndef __INC_SKDRV1ST_H
+#include "h/skdrv1st.h"
+#endif
+
+#ifndef __INC_SKDRV2ND_H
+#include "h/skdrv2nd.h"
+#endif
+
+#include <linux/kernel_stat.h>
+
+/*******************************************************************************
+**
+** Defines
+**
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Typedefs
+**
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Local function prototypes
+**
+*******************************************************************************/
+
+static unsigned int GetCurrentSystemLoad(SK_AC *pAC);
+static SK_U64 GetIsrCalls(SK_AC *pAC);
+static SK_BOOL IsIntModEnabled(SK_AC *pAC);
+static void SetCurrIntCtr(SK_AC *pAC);
+static void EnableIntMod(SK_AC *pAC);
+static void DisableIntMod(SK_AC *pAC);
+static void ResizeDimTimerDuration(SK_AC *pAC);
+static void DisplaySelectedModerationType(SK_AC *pAC);
+static void DisplaySelectedModerationMask(SK_AC *pAC);
+static void DisplayDescrRatio(SK_AC *pAC);
+
+/*******************************************************************************
+**
+** Global variables
+**
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Local variables
+**
+*******************************************************************************/
+
+/*******************************************************************************
+**
+** Global functions
+**
+*******************************************************************************/
+
+/*******************************************************************************
+** Function : SkDimModerate
+** Description : Called in every ISR to check if moderation is to be applied
+** or not for the current number of interrupts
+** Programmer : Ralph Roesler
+** Last Modified: 22-mar-03
+** Returns : void (!)
+** Notes : -
+*******************************************************************************/
+
+void
+SkDimModerate(SK_AC *pAC) {
+ unsigned int CurrSysLoad = 0; /* expressed in percent */
+ unsigned int LoadIncrease = 0; /* expressed in percent */
+ SK_U64 ThresholdInts = 0;
+ SK_U64 IsrCallsPerSec = 0;
+
+#define M_DIMINFO pAC->DynIrqModInfo
+
+ if (!IsIntModEnabled(pAC)) {
+ if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+ CurrSysLoad = GetCurrentSystemLoad(pAC);
+ if (CurrSysLoad > 75) {
+ /*
+ ** More than 75% total system load! Enable the moderation
+ ** to shield the system against too many interrupts.
+ */
+ EnableIntMod(pAC);
+ } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) {
+ LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad);
+ if (LoadIncrease > ((M_DIMINFO.PrevSysLoad *
+ C_INT_MOD_ENABLE_PERCENTAGE) / 100)) {
+ if (CurrSysLoad > 10) {
+ /*
+ ** More than 50% increase with respect to the
+ ** previous load of the system. Most likely this
+ ** is due to our ISR-proc...
+ */
+ EnableIntMod(pAC);
+ }
+ }
+ } else {
+ /*
+ ** Neither too much system load at all nor too much increase
+ ** with respect to the previous system load. Hence, we can leave
+ ** the ISR-handling like it is without enabling moderation.
+ */
+ }
+ M_DIMINFO.PrevSysLoad = CurrSysLoad;
+ }
+ } else {
+ if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+ ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec *
+ C_INT_MOD_DISABLE_PERCENTAGE) / 100);
+ IsrCallsPerSec = GetIsrCalls(pAC);
+ if (IsrCallsPerSec <= ThresholdInts) {
+ /*
+ ** The number of interrupts within the last second is
+ ** lower than the disable_percentage of the desried
+ ** maxrate. Therefore we can disable the moderation.
+ */
+ DisableIntMod(pAC);
+ M_DIMINFO.MaxModIntsPerSec =
+ (M_DIMINFO.MaxModIntsPerSecUpperLimit +
+ M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2;
+ } else {
+ /*
+ ** The number of interrupts per sec is the same as expected.
+ ** Evalulate the descriptor-ratio. If it has changed, a resize
+ ** in the moderation timer might be usefull
+ */
+ if (M_DIMINFO.AutoSizing) {
+ ResizeDimTimerDuration(pAC);
+ }
+ }
+ }
+ }
+
+ /*
+ ** Some information to the log...
+ */
+ if (M_DIMINFO.DisplayStats) {
+ DisplaySelectedModerationType(pAC);
+ DisplaySelectedModerationMask(pAC);
+ DisplayDescrRatio(pAC);
+ }
+
+ M_DIMINFO.NbrProcessedDescr = 0;
+ SetCurrIntCtr(pAC);
+}
+
+/*******************************************************************************
+** Function : SkDimStartModerationTimer
+** Description : Starts the audit-timer for the dynamic interrupt moderation
+** Programmer : Ralph Roesler
+** Last Modified: 22-mar-03
+** Returns : void (!)
+** Notes : -
+*******************************************************************************/
+
+void
+SkDimStartModerationTimer(SK_AC *pAC) {
+ SK_EVPARA EventParam; /* Event struct for timer event */
+
+ SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
+ EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;
+ SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer,
+ SK_DRV_MODERATION_TIMER_LENGTH,
+ SKGE_DRV, SK_DRV_TIMER, EventParam);
+}
+
+/*******************************************************************************
+** Function : SkDimEnableModerationIfNeeded
+** Description : Either enables or disables moderation
+** Programmer : Ralph Roesler
+** Last Modified: 22-mar-03
+** Returns : void (!)
+** Notes : This function is called when a particular adapter is opened
+** There is no Disable function, because when all interrupts
+** might be disable, the moderation timer has no meaning at all
+******************************************************************************/
+
+void
+SkDimEnableModerationIfNeeded(SK_AC *pAC) {
+
+ if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {
+ EnableIntMod(pAC); /* notification print in this function */
+ } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+ SkDimStartModerationTimer(pAC);
+ if (M_DIMINFO.DisplayStats) {
+ printk("Dynamic moderation has been enabled\n");
+ }
+ } else {
+ if (M_DIMINFO.DisplayStats) {
+ printk("No moderation has been enabled\n");
+ }
+ }
+}
+
+/*******************************************************************************
+** Function : SkDimDisplayModerationSettings
+** Description : Displays the current settings regaring interrupt moderation
+** Programmer : Ralph Roesler
+** Last Modified: 22-mar-03
+** Returns : void (!)
+** Notes : -
+*******************************************************************************/
+
+void
+SkDimDisplayModerationSettings(SK_AC *pAC) {
+ DisplaySelectedModerationType(pAC);
+ DisplaySelectedModerationMask(pAC);
+}
+
+/*******************************************************************************
+**
+** Local functions
+**
+*******************************************************************************/
+
+/*******************************************************************************
+** Function : GetCurrentSystemLoad
+** Description : Retrieves the current system load of the system. This load
+** is evaluated for all processors within the system.
+** Programmer : Ralph Roesler
+** Last Modified: 22-mar-03
+** Returns : unsigned int: load expressed in percentage
+** Notes : The possible range being returned is from 0 up to 100.
+** Whereas 0 means 'no load at all' and 100 'system fully loaded'
+** It is impossible to determine what actually causes the system
+** to be in 100%, but maybe that is due to too much interrupts.
+*******************************************************************************/
+
+static unsigned int
+GetCurrentSystemLoad(SK_AC *pAC) {
+ unsigned long jif = jiffies;
+ unsigned int UserTime = 0;
+ unsigned int SystemTime = 0;
+ unsigned int NiceTime = 0;
+ unsigned int IdleTime = 0;
+ unsigned int TotalTime = 0;
+ unsigned int UsedTime = 0;
+ unsigned int SystemLoad = 0;
+
+ /* unsigned int NbrCpu = 0; */
+
+ /*
+ ** The following lines have been commented out, because
+ ** from kernel 2.5.44 onwards, the kernel-owned structure
+ **
+ ** struct kernel_stat kstat
+ **
+ ** is not marked as an exported symbol in the file
+ **
+ ** kernel/ksyms.c
+ **
+ ** As a consequence, using this driver as KLM is not possible
+ ** and any access of the structure kernel_stat via the
+ ** dedicated macros kstat_cpu(i).cpustat.xxx is to be avoided.
+ **
+ ** The kstat-information might be added again in future
+ ** versions of the 2.5.xx kernel, but for the time being,
+ ** number of interrupts will serve as indication how much
+ ** load we currently have...
+ **
+ ** for (NbrCpu = 0; NbrCpu < num_online_cpus(); NbrCpu++) {
+ ** UserTime = UserTime + kstat_cpu(NbrCpu).cpustat.user;
+ ** NiceTime = NiceTime + kstat_cpu(NbrCpu).cpustat.nice;
+ ** SystemTime = SystemTime + kstat_cpu(NbrCpu).cpustat.system;
+ ** }
+ */
+ SK_U64 ThresholdInts = 0;
+ SK_U64 IsrCallsPerSec = 0;
+
+ ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec *
+ C_INT_MOD_ENABLE_PERCENTAGE) + 100);
+ IsrCallsPerSec = GetIsrCalls(pAC);
+ if (IsrCallsPerSec >= ThresholdInts) {
+ /*
+ ** We do not know how much the real CPU-load is!
+ ** Return 80% as a default in order to activate DIM
+ */
+ SystemLoad = 80;
+ return (SystemLoad);
+ }
+
+ UsedTime = UserTime + NiceTime + SystemTime;
+
+ IdleTime = jif * num_online_cpus() - UsedTime;
+ TotalTime = UsedTime + IdleTime;
+
+ SystemLoad = ( 100 * (UsedTime - M_DIMINFO.PrevUsedTime) ) /
+ (TotalTime - M_DIMINFO.PrevTotalTime);
+
+ if (M_DIMINFO.DisplayStats) {
+ printk("Current system load is: %u\n", SystemLoad);
+ }
+
+ M_DIMINFO.PrevTotalTime = TotalTime;
+ M_DIMINFO.PrevUsedTime = UsedTime;
+
+ return (SystemLoad);
+}
+
+/*******************************************************************************
+** Function : GetIsrCalls
+** Description : Depending on the selected moderation mask, this function will
+** return the number of interrupts handled in the previous time-
+** frame. This evaluated number is based on the current number
+** of interrupts stored in PNMI-context and the previous stored
+** interrupts.
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : int: the number of interrupts being executed in the last
+** timeframe
+** Notes : It makes only sense to call this function, when dynamic
+** interrupt moderation is applied
+*******************************************************************************/
+
+static SK_U64
+GetIsrCalls(SK_AC *pAC) {
+ SK_U64 RxPort0IntDiff = 0;
+ SK_U64 RxPort1IntDiff = 0;
+ SK_U64 TxPort0IntDiff = 0;
+ SK_U64 TxPort1IntDiff = 0;
+
+ if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) {
+ if (pAC->GIni.GIMacsFound == 2) {
+ TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
+ pAC->DynIrqModInfo.PrevPort1TxIntrCts;
+ }
+ TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
+ pAC->DynIrqModInfo.PrevPort0TxIntrCts;
+ } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) {
+ if (pAC->GIni.GIMacsFound == 2) {
+ RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
+ pAC->DynIrqModInfo.PrevPort1RxIntrCts;
+ }
+ RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
+ pAC->DynIrqModInfo.PrevPort0RxIntrCts;
+ } else {
+ if (pAC->GIni.GIMacsFound == 2) {
+ RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
+ pAC->DynIrqModInfo.PrevPort1RxIntrCts;
+ TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -
+ pAC->DynIrqModInfo.PrevPort1TxIntrCts;
+ }
+ RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
+ pAC->DynIrqModInfo.PrevPort0RxIntrCts;
+ TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -
+ pAC->DynIrqModInfo.PrevPort0TxIntrCts;
+ }
+
+ return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff);
+}
+
+/*******************************************************************************
+** Function : GetRxCalls
+** Description : This function will return the number of times a receive inter-
+** rupt was processed. This is needed to evaluate any resizing
+** factor.
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : SK_U64: the number of RX-ints being processed
+** Notes : It makes only sense to call this function, when dynamic
+** interrupt moderation is applied
+*******************************************************************************/
+
+static SK_U64
+GetRxCalls(SK_AC *pAC) {
+ SK_U64 RxPort0IntDiff = 0;
+ SK_U64 RxPort1IntDiff = 0;
+
+ if (pAC->GIni.GIMacsFound == 2) {
+ RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts -
+ pAC->DynIrqModInfo.PrevPort1RxIntrCts;
+ }
+ RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts -
+ pAC->DynIrqModInfo.PrevPort0RxIntrCts;
+
+ return (RxPort0IntDiff + RxPort1IntDiff);
+}
+
+/*******************************************************************************
+** Function : SetCurrIntCtr
+** Description : Will store the current number orf occured interrupts in the
+** adapter context. This is needed to evaluated the number of
+** interrupts within a current timeframe.
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : void (!)
+** Notes : -
+*******************************************************************************/
+
+static void
+SetCurrIntCtr(SK_AC *pAC) {
+ if (pAC->GIni.GIMacsFound == 2) {
+ pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts;
+ pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts;
+ }
+ pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts;
+ pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts;
+}
+
+/*******************************************************************************
+** Function : IsIntModEnabled()
+** Description : Retrieves the current value of the interrupts moderation
+** command register. Its content determines whether any
+** moderation is running or not.
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : SK_TRUE : if mod timer running
+** SK_FALSE : if no moderation is being performed
+** Notes : -
+*******************************************************************************/
+
+static SK_BOOL
+IsIntModEnabled(SK_AC *pAC) {
+ unsigned long CtrCmd;
+
+ SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd);
+ if ((CtrCmd & TIM_START) == TIM_START) {
+ return SK_TRUE;
+ } else {
+ return SK_FALSE;
+ }
+}
+
+/*******************************************************************************
+** Function : EnableIntMod()
+** Description : Enables the interrupt moderation using the values stored in
+** in the pAC->DynIntMod data structure
+** Programmer : Ralph Roesler
+** Last Modified: 22-mar-03
+** Returns : -
+** Notes : -
+*******************************************************************************/
+
+static void
+EnableIntMod(SK_AC *pAC) {
+ unsigned long ModBase;
+
+ if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+ ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
+ } else {
+ ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
+ }
+
+ SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
+ SK_OUT32(pAC->IoBase, B2_IRQM_MSK, pAC->DynIrqModInfo.MaskIrqModeration);
+ SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START);
+ if (M_DIMINFO.DisplayStats) {
+ printk("Enabled interrupt moderation (%i ints/sec)\n",
+ M_DIMINFO.MaxModIntsPerSec);
+ }
+}
+
+/*******************************************************************************
+** Function : DisableIntMod()
+** Description : Disbles the interrupt moderation independent of what inter-
+** rupts are running or not
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : -
+** Notes : -
+*******************************************************************************/
+
+static void
+DisableIntMod(SK_AC *pAC) {
+
+ SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP);
+ if (M_DIMINFO.DisplayStats) {
+ printk("Disabled interrupt moderation\n");
+ }
+}
+
+/*******************************************************************************
+** Function : ResizeDimTimerDuration();
+** Description : Checks the current used descriptor ratio and resizes the
+** duration timer (longer/smaller) if possible.
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : -
+** Notes : There are both maximum and minimum timer duration value.
+** This function assumes that interrupt moderation is already
+** enabled!
+*******************************************************************************/
+
+static void
+ResizeDimTimerDuration(SK_AC *pAC) {
+ SK_BOOL IncreaseTimerDuration;
+ int TotalMaxNbrDescr;
+ int UsedDescrRatio;
+ int RatioDiffAbs;
+ int RatioDiffRel;
+ int NewMaxModIntsPerSec;
+ int ModAdjValue;
+ long ModBase;
+
+ /*
+ ** Check first if we are allowed to perform any modification
+ */
+ if (IsIntModEnabled(pAC)) {
+ if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) {
+ return;
+ } else {
+ if (M_DIMINFO.ModJustEnabled) {
+ M_DIMINFO.ModJustEnabled = SK_FALSE;
+ return;
+ }
+ }
+ }
+
+ /*
+ ** If we got until here, we have to evaluate the amount of the
+ ** descriptor ratio change...
+ */
+ TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
+ UsedDescrRatio = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr;
+
+ if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) {
+ RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio);
+ RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio;
+ M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
+ IncreaseTimerDuration = SK_FALSE; /* in other words: DECREASE */
+ } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) {
+ RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
+ RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
+ M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
+ IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */
+ } else {
+ RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio);
+ RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio;
+ M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio;
+ IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */
+ }
+
+ /*
+ ** Now we can determine the change in percent
+ */
+ if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) {
+ ModAdjValue = 1; /* 1% change - maybe some other value in future */
+ } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) {
+ ModAdjValue = 1; /* 1% change - maybe some other value in future */
+ } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) {
+ ModAdjValue = 1; /* 1% change - maybe some other value in future */
+ } else {
+ ModAdjValue = 1; /* 1% change - maybe some other value in future */
+ }
+
+ if (IncreaseTimerDuration) {
+ NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec +
+ (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
+ } else {
+ NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec -
+ (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100;
+ }
+
+ /*
+ ** Check if we exceed boundaries...
+ */
+ if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) ||
+ (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) {
+ if (M_DIMINFO.DisplayStats) {
+ printk("Cannot change ModTim from %i to %i ints/sec\n",
+ M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
+ }
+ return;
+ } else {
+ if (M_DIMINFO.DisplayStats) {
+ printk("Resized ModTim from %i to %i ints/sec\n",
+ M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec);
+ }
+ }
+
+ M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec;
+
+ if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+ ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec;
+ } else {
+ ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec;
+ }
+
+ /*
+ ** We do not need to touch any other registers
+ */
+ SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase);
+}
+
+/*******************************************************************************
+** Function : DisplaySelectedModerationType()
+** Description : Displays what type of moderation we have
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : void!
+** Notes : -
+*******************************************************************************/
+
+static void
+DisplaySelectedModerationType(SK_AC *pAC) {
+
+ if (pAC->DynIrqModInfo.DisplayStats) {
+ if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) {
+ printk("Static int moderation runs with %i INTS/sec\n",
+ pAC->DynIrqModInfo.MaxModIntsPerSec);
+ } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) {
+ if (IsIntModEnabled(pAC)) {
+ printk("Dynamic int moderation runs with %i INTS/sec\n",
+ pAC->DynIrqModInfo.MaxModIntsPerSec);
+ } else {
+ printk("Dynamic int moderation currently not applied\n");
+ }
+ } else {
+ printk("No interrupt moderation selected!\n");
+ }
+ }
+}
+
+/*******************************************************************************
+** Function : DisplaySelectedModerationMask()
+** Description : Displays what interrupts are moderated
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : void!
+** Notes : -
+*******************************************************************************/
+
+static void
+DisplaySelectedModerationMask(SK_AC *pAC) {
+
+ if (pAC->DynIrqModInfo.DisplayStats) {
+ if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) {
+ switch (pAC->DynIrqModInfo.MaskIrqModeration) {
+ case IRQ_MASK_TX_ONLY:
+ printk("Only Tx-interrupts are moderated\n");
+ break;
+ case IRQ_MASK_RX_ONLY:
+ printk("Only Rx-interrupts are moderated\n");
+ break;
+ case IRQ_MASK_SP_ONLY:
+ printk("Only special-interrupts are moderated\n");
+ break;
+ case IRQ_MASK_TX_RX:
+ printk("Tx- and Rx-interrupts are moderated\n");
+ break;
+ case IRQ_MASK_SP_RX:
+ printk("Special- and Rx-interrupts are moderated\n");
+ break;
+ case IRQ_MASK_SP_TX:
+ printk("Special- and Tx-interrupts are moderated\n");
+ break;
+ case IRQ_MASK_RX_TX_SP:
+ printk("All Rx-, Tx and special-interrupts are moderated\n");
+ break;
+ default:
+ printk("Don't know what is moderated\n");
+ break;
+ }
+ } else {
+ printk("No specific interrupts masked for moderation\n");
+ }
+ }
+}
+
+/*******************************************************************************
+** Function : DisplayDescrRatio
+** Description : Like the name states...
+** Programmer : Ralph Roesler
+** Last Modified: 23-mar-03
+** Returns : void!
+** Notes : -
+*******************************************************************************/
+
+static void
+DisplayDescrRatio(SK_AC *pAC) {
+ int TotalMaxNbrDescr = 0;
+
+ if (pAC->DynIrqModInfo.DisplayStats) {
+ TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC);
+ printk("Ratio descriptors: %i/%i\n",
+ M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr);
+ }
+}
+
+/*******************************************************************************
+**
+** End of file
+**
+*******************************************************************************/
diff --git a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c
new file mode 100644
index 000000000000..fb639959292b
--- /dev/null
+++ b/drivers/net/sk98lin/skethtool.c
@@ -0,0 +1,552 @@
+/******************************************************************************
+ *
+ * Name: skethtool.c
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.7 $
+ * Date: $Date: 2004/09/29 13:32:07 $
+ * Purpose: All functions regarding ethtool handling
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2004 Marvell.
+ *
+ * Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet
+ * Server Adapters.
+ *
+ * Author: Ralph Roesler (rroesler@syskonnect.de)
+ * Mirko Lindner (mlindner@syskonnect.de)
+ *
+ * Address all question to: linux@syskonnect.de
+ *
+ * The technical manual for the adapters is available from SysKonnect's
+ * web pages: www.syskonnect.com
+ *
+ * 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.
+ *
+ *****************************************************************************/
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+#include "h/skversion.h"
+
+#include <linux/ethtool.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+
+/******************************************************************************
+ *
+ * Defines
+ *
+ *****************************************************************************/
+
+#define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
+ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
+ SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \
+ SUPPORTED_TP)
+
+#define ADV_COPPER_ALL (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
+ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
+ ADVERTISED_1000baseT_Half| ADVERTISED_1000baseT_Full| \
+ ADVERTISED_TP)
+
+#define SUPP_FIBRE_ALL (SUPPORTED_1000baseT_Full | \
+ SUPPORTED_FIBRE | \
+ SUPPORTED_Autoneg)
+
+#define ADV_FIBRE_ALL (ADVERTISED_1000baseT_Full | \
+ ADVERTISED_FIBRE | \
+ ADVERTISED_Autoneg)
+
+
+/******************************************************************************
+ *
+ * Local Functions
+ *
+ *****************************************************************************/
+
+/*****************************************************************************
+ *
+ * getSettings - retrieves the current settings of the selected adapter
+ *
+ * Description:
+ * The current configuration of the selected adapter is returned.
+ * This configuration involves a)speed, b)duplex and c)autoneg plus
+ * a number of other variables.
+ *
+ * Returns: always 0
+ *
+ */
+static int getSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+ const DEV_NET *pNet = netdev_priv(dev);
+ int port = pNet->PortNr;
+ const SK_AC *pAC = pNet->pAC;
+ const SK_GEPORT *pPort = &pAC->GIni.GP[port];
+
+ static int DuplexAutoNegConfMap[9][3]= {
+ { -1 , -1 , -1 },
+ { 0 , -1 , -1 },
+ { SK_LMODE_HALF , DUPLEX_HALF, AUTONEG_DISABLE },
+ { SK_LMODE_FULL , DUPLEX_FULL, AUTONEG_DISABLE },
+ { SK_LMODE_AUTOHALF , DUPLEX_HALF, AUTONEG_ENABLE },
+ { SK_LMODE_AUTOFULL , DUPLEX_FULL, AUTONEG_ENABLE },
+ { SK_LMODE_AUTOBOTH , DUPLEX_FULL, AUTONEG_ENABLE },
+ { SK_LMODE_AUTOSENSE , -1 , -1 },
+ { SK_LMODE_INDETERMINATED, -1 , -1 }
+ };
+ static int SpeedConfMap[6][2] = {
+ { 0 , -1 },
+ { SK_LSPEED_AUTO , -1 },
+ { SK_LSPEED_10MBPS , SPEED_10 },
+ { SK_LSPEED_100MBPS , SPEED_100 },
+ { SK_LSPEED_1000MBPS , SPEED_1000 },
+ { SK_LSPEED_INDETERMINATED, -1 }
+ };
+ static int AdvSpeedMap[6][2] = {
+ { 0 , -1 },
+ { SK_LSPEED_AUTO , -1 },
+ { SK_LSPEED_10MBPS , ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full },
+ { SK_LSPEED_100MBPS , ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full },
+ { SK_LSPEED_1000MBPS , ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full},
+ { SK_LSPEED_INDETERMINATED, -1 }
+ };
+
+ ecmd->phy_address = port;
+ ecmd->speed = SpeedConfMap[pPort->PLinkSpeedUsed][1];
+ ecmd->duplex = DuplexAutoNegConfMap[pPort->PLinkModeStatus][1];
+ ecmd->autoneg = DuplexAutoNegConfMap[pPort->PLinkModeStatus][2];
+ ecmd->transceiver = XCVR_INTERNAL;
+
+ if (pAC->GIni.GICopperType) {
+ ecmd->port = PORT_TP;
+ ecmd->supported = (SUPP_COPPER_ALL|SUPPORTED_Autoneg);
+ if (pAC->GIni.GIGenesis) {
+ ecmd->supported &= ~(SUPPORTED_10baseT_Half);
+ ecmd->supported &= ~(SUPPORTED_10baseT_Full);
+ ecmd->supported &= ~(SUPPORTED_100baseT_Half);
+ ecmd->supported &= ~(SUPPORTED_100baseT_Full);
+ } else {
+ if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
+ ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
+ }
+#ifdef CHIP_ID_YUKON_FE
+ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) {
+ ecmd->supported &= ~(SUPPORTED_1000baseT_Half);
+ ecmd->supported &= ~(SUPPORTED_1000baseT_Full);
+ }
+#endif
+ }
+ if (pAC->GIni.GP[0].PLinkSpeed != SK_LSPEED_AUTO) {
+ ecmd->advertising = AdvSpeedMap[pPort->PLinkSpeed][1];
+ if (pAC->GIni.GIChipId == CHIP_ID_YUKON) {
+ ecmd->advertising &= ~(SUPPORTED_1000baseT_Half);
+ }
+ } else {
+ ecmd->advertising = ecmd->supported;
+ }
+
+ if (ecmd->autoneg == AUTONEG_ENABLE)
+ ecmd->advertising |= ADVERTISED_Autoneg;
+ } else {
+ ecmd->port = PORT_FIBRE;
+ ecmd->supported = SUPP_FIBRE_ALL;
+ ecmd->advertising = ADV_FIBRE_ALL;
+ }
+ return 0;
+}
+
+/*
+ * MIB infrastructure uses instance value starting at 1
+ * based on board and port.
+ */
+static inline u32 pnmiInstance(const DEV_NET *pNet)
+{
+ return 1 + (pNet->pAC->RlmtNets == 2) + pNet->PortNr;
+}
+
+/*****************************************************************************
+ *
+ * setSettings - configures the settings of a selected adapter
+ *
+ * Description:
+ * Possible settings that may be altered are a)speed, b)duplex or
+ * c)autonegotiation.
+ *
+ * Returns:
+ * 0: everything fine, no error
+ * <0: the return value is the error code of the failure
+ */
+static int setSettings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+ DEV_NET *pNet = netdev_priv(dev);
+ SK_AC *pAC = pNet->pAC;
+ u32 instance;
+ char buf[4];
+ int len = 1;
+
+ if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100
+ && ecmd->speed != SPEED_1000)
+ return -EINVAL;
+
+ if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
+ return -EINVAL;
+
+ if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
+ return -EINVAL;
+
+ if (ecmd->autoneg == AUTONEG_DISABLE)
+ *buf = (ecmd->duplex == DUPLEX_FULL)
+ ? SK_LMODE_FULL : SK_LMODE_HALF;
+ else
+ *buf = (ecmd->duplex == DUPLEX_FULL)
+ ? SK_LMODE_AUTOFULL : SK_LMODE_AUTOHALF;
+
+ instance = pnmiInstance(pNet);
+ if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE,
+ &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
+ return -EINVAL;
+
+ switch(ecmd->speed) {
+ case SPEED_1000:
+ *buf = SK_LSPEED_1000MBPS;
+ break;
+ case SPEED_100:
+ *buf = SK_LSPEED_100MBPS;
+ break;
+ case SPEED_10:
+ *buf = SK_LSPEED_10MBPS;
+ }
+
+ if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE,
+ &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK)
+ return -EINVAL;
+
+ return 0;
+}
+
+/*****************************************************************************
+ *
+ * getDriverInfo - returns generic driver and adapter information
+ *
+ * Description:
+ * Generic driver information is returned via this function, such as
+ * the name of the driver, its version and and firmware version.
+ * In addition to this, the location of the selected adapter is
+ * returned as a bus info string (e.g. '01:05.0').
+ *
+ * Returns: N/A
+ *
+ */
+static void getDriverInfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+ const DEV_NET *pNet = netdev_priv(dev);
+ const SK_AC *pAC = pNet->pAC;
+ char vers[32];
+
+ snprintf(vers, sizeof(vers)-1, VER_STRING "(v%d.%d)",
+ (pAC->GIni.GIPciHwRev >> 4) & 0xf, pAC->GIni.GIPciHwRev & 0xf);
+
+ strlcpy(info->driver, DRIVER_FILE_NAME, sizeof(info->driver));
+ strcpy(info->version, vers);
+ strcpy(info->fw_version, "N/A");
+ strlcpy(info->bus_info, pci_name(pAC->PciDev), ETHTOOL_BUSINFO_LEN);
+}
+
+/*
+ * Ethtool statistics support.
+ */
+static const char StringsStats[][ETH_GSTRING_LEN] = {
+ "rx_packets", "tx_packets",
+ "rx_bytes", "tx_bytes",
+ "rx_errors", "tx_errors",
+ "rx_dropped", "tx_dropped",
+ "multicasts", "collisions",
+ "rx_length_errors", "rx_buffer_overflow_errors",
+ "rx_crc_errors", "rx_frame_errors",
+ "rx_too_short_errors", "rx_too_long_errors",
+ "rx_carrier_extension_errors", "rx_symbol_errors",
+ "rx_llc_mac_size_errors", "rx_carrier_errors",
+ "rx_jabber_errors", "rx_missed_errors",
+ "tx_abort_collision_errors", "tx_carrier_errors",
+ "tx_buffer_underrun_errors", "tx_heartbeat_errors",
+ "tx_window_errors",
+};
+
+static int getStatsCount(struct net_device *dev)
+{
+ return ARRAY_SIZE(StringsStats);
+}
+
+static void getStrings(struct net_device *dev, u32 stringset, u8 *data)
+{
+ switch(stringset) {
+ case ETH_SS_STATS:
+ memcpy(data, *StringsStats, sizeof(StringsStats));
+ break;
+ }
+}
+
+static void getEthtoolStats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ const DEV_NET *pNet = netdev_priv(dev);
+ const SK_AC *pAC = pNet->pAC;
+ const SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct;
+
+ *data++ = pPnmiStruct->Stat[0].StatRxOkCts;
+ *data++ = pPnmiStruct->Stat[0].StatTxOkCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxOctetsOkCts;
+ *data++ = pPnmiStruct->Stat[0].StatTxOctetsOkCts;
+ *data++ = pPnmiStruct->InErrorsCts;
+ *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
+ *data++ = pPnmiStruct->RxNoBufCts;
+ *data++ = pPnmiStruct->TxNoBufCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxMulticastOkCts;
+ *data++ = pPnmiStruct->Stat[0].StatTxSingleCollisionCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxRuntCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxFifoOverflowCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxFcsCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxFramingCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxShortsCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxTooLongCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxCextCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxSymbolCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxIRLengthCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxCarrierCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxJabberCts;
+ *data++ = pPnmiStruct->Stat[0].StatRxMissedCts;
+ *data++ = pAC->stats.tx_aborted_errors;
+ *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
+ *data++ = pPnmiStruct->Stat[0].StatTxFifoUnderrunCts;
+ *data++ = pPnmiStruct->Stat[0].StatTxCarrierCts;
+ *data++ = pAC->stats.tx_window_errors;
+}
+
+
+/*****************************************************************************
+ *
+ * toggleLeds - Changes the LED state of an adapter
+ *
+ * Description:
+ * This function changes the current state of all LEDs of an adapter so
+ * that it can be located by a user.
+ *
+ * Returns: N/A
+ *
+ */
+static void toggleLeds(DEV_NET *pNet, int on)
+{
+ SK_AC *pAC = pNet->pAC;
+ int port = pNet->PortNr;
+ void __iomem *io = pAC->IoBase;
+
+ if (pAC->GIni.GIGenesis) {
+ SK_OUT8(io, MR_ADDR(port,LNK_LED_REG),
+ on ? SK_LNK_ON : SK_LNK_OFF);
+ SkGeYellowLED(pAC, io,
+ on ? (LED_ON >> 1) : (LED_OFF >> 1));
+ SkGeXmitLED(pAC, io, MR_ADDR(port,RX_LED_INI),
+ on ? SK_LED_TST : SK_LED_DIS);
+
+ if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM)
+ SkXmPhyWrite(pAC, io, port, PHY_BCOM_P_EXT_CTRL,
+ on ? PHY_B_PEC_LED_ON : PHY_B_PEC_LED_OFF);
+ else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE)
+ SkXmPhyWrite(pAC, io, port, PHY_LONE_LED_CFG,
+ on ? 0x0800 : PHY_L_LC_LEDT);
+ else
+ SkGeXmitLED(pAC, io, MR_ADDR(port,TX_LED_INI),
+ on ? SK_LED_TST : SK_LED_DIS);
+ } else {
+ const u16 YukLedOn = (PHY_M_LED_MO_DUP(MO_LED_ON) |
+ PHY_M_LED_MO_10(MO_LED_ON) |
+ PHY_M_LED_MO_100(MO_LED_ON) |
+ PHY_M_LED_MO_1000(MO_LED_ON) |
+ PHY_M_LED_MO_RX(MO_LED_ON));
+ const u16 YukLedOff = (PHY_M_LED_MO_DUP(MO_LED_OFF) |
+ PHY_M_LED_MO_10(MO_LED_OFF) |
+ PHY_M_LED_MO_100(MO_LED_OFF) |
+ PHY_M_LED_MO_1000(MO_LED_OFF) |
+ PHY_M_LED_MO_RX(MO_LED_OFF));
+
+
+ SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_CTRL,0);
+ SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_OVER,
+ on ? YukLedOn : YukLedOff);
+ }
+}
+
+/*****************************************************************************
+ *
+ * skGeBlinkTimer - Changes the LED state of an adapter
+ *
+ * Description:
+ * This function changes the current state of all LEDs of an adapter so
+ * that it can be located by a user. If the requested time interval for
+ * this test has elapsed, this function cleans up everything that was
+ * temporarily setup during the locate NIC test. This involves of course
+ * also closing or opening any adapter so that the initial board state
+ * is recovered.
+ *
+ * Returns: N/A
+ *
+ */
+void SkGeBlinkTimer(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *) data;
+ DEV_NET *pNet = netdev_priv(dev);
+ SK_AC *pAC = pNet->pAC;
+
+ toggleLeds(pNet, pAC->LedsOn);
+
+ pAC->LedsOn = !pAC->LedsOn;
+ mod_timer(&pAC->BlinkTimer, jiffies + HZ/4);
+}
+
+/*****************************************************************************
+ *
+ * locateDevice - start the locate NIC feature of the elected adapter
+ *
+ * Description:
+ * This function is used if the user want to locate a particular NIC.
+ * All LEDs are regularly switched on and off, so the NIC can easily
+ * be identified.
+ *
+ * Returns:
+ * ==0: everything fine, no error, locateNIC test was started
+ * !=0: one locateNIC test runs already
+ *
+ */
+static int locateDevice(struct net_device *dev, u32 data)
+{
+ DEV_NET *pNet = netdev_priv(dev);
+ SK_AC *pAC = pNet->pAC;
+
+ if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
+ data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
+
+ /* start blinking */
+ pAC->LedsOn = 0;
+ mod_timer(&pAC->BlinkTimer, jiffies);
+ msleep_interruptible(data * 1000);
+ del_timer_sync(&pAC->BlinkTimer);
+ toggleLeds(pNet, 0);
+
+ return 0;
+}
+
+/*****************************************************************************
+ *
+ * getPauseParams - retrieves the pause parameters
+ *
+ * Description:
+ * All current pause parameters of a selected adapter are placed
+ * in the passed ethtool_pauseparam structure and are returned.
+ *
+ * Returns: N/A
+ *
+ */
+static void getPauseParams(struct net_device *dev, struct ethtool_pauseparam *epause)
+{
+ DEV_NET *pNet = netdev_priv(dev);
+ SK_AC *pAC = pNet->pAC;
+ SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
+
+ epause->rx_pause = (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) ||
+ (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM);
+
+ epause->tx_pause = epause->rx_pause || (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND);
+ epause->autoneg = epause->rx_pause || epause->tx_pause;
+}
+
+/*****************************************************************************
+ *
+ * setPauseParams - configures the pause parameters of an adapter
+ *
+ * Description:
+ * This function sets the Rx or Tx pause parameters
+ *
+ * Returns:
+ * ==0: everything fine, no error
+ * !=0: the return value is the error code of the failure
+ */
+static int setPauseParams(struct net_device *dev , struct ethtool_pauseparam *epause)
+{
+ DEV_NET *pNet = netdev_priv(dev);
+ SK_AC *pAC = pNet->pAC;
+ SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr];
+ u32 instance = pnmiInstance(pNet);
+ struct ethtool_pauseparam old;
+ u8 oldspeed = pPort->PLinkSpeedUsed;
+ char buf[4];
+ int len = 1;
+ int ret;
+
+ /*
+ ** we have to determine the current settings to see if
+ ** the operator requested any modification of the flow
+ ** control parameters...
+ */
+ getPauseParams(dev, &old);
+
+ /*
+ ** perform modifications regarding the changes
+ ** requested by the operator
+ */
+ if (epause->autoneg != old.autoneg)
+ *buf = epause->autoneg ? SK_FLOW_MODE_NONE : SK_FLOW_MODE_SYMMETRIC;
+ else {
+ if (epause->rx_pause && epause->tx_pause)
+ *buf = SK_FLOW_MODE_SYMMETRIC;
+ else if (epause->rx_pause && !epause->tx_pause)
+ *buf = SK_FLOW_MODE_SYM_OR_REM;
+ else if (!epause->rx_pause && epause->tx_pause)
+ *buf = SK_FLOW_MODE_LOC_SEND;
+ else
+ *buf = SK_FLOW_MODE_NONE;
+ }
+
+ ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE,
+ &buf, &len, instance, pNet->NetNr);
+
+ if (ret != SK_PNMI_ERR_OK) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
+ ("ethtool (sk98lin): error changing rx/tx pause (%i)\n", ret));
+ goto err;
+ }
+
+ /*
+ ** It may be that autoneg has been disabled! Therefore
+ ** set the speed to the previously used value...
+ */
+ if (!epause->autoneg) {
+ len = 1;
+ ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE,
+ &oldspeed, &len, instance, pNet->NetNr);
+ if (ret != SK_PNMI_ERR_OK)
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL,
+ ("ethtool (sk98lin): error setting speed (%i)\n", ret));
+ }
+ err:
+ return ret ? -EIO : 0;
+}
+
+struct ethtool_ops SkGeEthtoolOps = {
+ .get_settings = getSettings,
+ .set_settings = setSettings,
+ .get_drvinfo = getDriverInfo,
+ .get_strings = getStrings,
+ .get_stats_count = getStatsCount,
+ .get_ethtool_stats = getEthtoolStats,
+ .phys_id = locateDevice,
+ .get_pauseparam = getPauseParams,
+ .set_pauseparam = setPauseParams,
+};
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
new file mode 100644
index 000000000000..05b827f79f54
--- /dev/null
+++ b/drivers/net/sk98lin/skge.c
@@ -0,0 +1,5186 @@
+/******************************************************************************
+ *
+ * Name: skge.c
+ * Project: GEnesis, PCI Gigabit Ethernet Adapter
+ * Version: $Revision: 1.45 $
+ * Date: $Date: 2004/02/12 14:41:02 $
+ * Purpose: The main driver source module
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * (C)Copyright 1998-2002 SysKonnect GmbH.
+ * (C)Copyright 2002-2003 Marvell.
+ *
+ * Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet
+ * Server Adapters.
+ *
+ * Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and
+ * SysKonnects GEnesis Solaris driver
+ * Author: Christoph Goos (cgoos@syskonnect.de)
+ * Mirko Lindner (mlindner@syskonnect.de)
+ *
+ * Address all question to: linux@syskonnect.de
+ *
+ * The technical manual for the adapters is available from SysKonnect's
+ * web pages: www.syskonnect.com
+ * Goto "Support" and search Knowledge Base for "manual".
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Possible compiler options (#define xxx / -Dxxx):
+ *
+ * debugging can be enable by changing SK_DEBUG_CHKMOD and
+ * SK_DEBUG_CHKCAT in makefile (described there).
+ *
+ ******************************************************************************/
+
+/******************************************************************************
+ *
+ * Description:
+ *
+ * This is the main module of the Linux GE driver.
+ *
+ * All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h
+ * are part of SysKonnect's COMMON MODULES for the SK-98xx adapters.
+ * Those are used for drivers on multiple OS', so some thing may seem
+ * unnecessary complicated on Linux. Please do not try to 'clean up'
+ * them without VERY good reasons, because this will make it more
+ * difficult to keep the Linux driver in synchronisation with the
+ * other versions.
+ *
+ * Include file hierarchy:
+ *
+ * <linux/module.h>
+ *
+ * "h/skdrv1st.h"
+ * <linux/types.h>
+ * <linux/kernel.h>
+ * <linux/string.h>
+ * <linux/errno.h>
+ * <linux/ioport.h>
+ * <linux/slab.h>
+ * <linux/interrupt.h>
+ * <linux/pci.h>
+ * <linux/bitops.h>
+ * <asm/byteorder.h>
+ * <asm/io.h>
+ * <linux/netdevice.h>
+ * <linux/etherdevice.h>
+ * <linux/skbuff.h>
+ * those three depending on kernel version used:
+ * <linux/bios32.h>
+ * <linux/init.h>
+ * <asm/uaccess.h>
+ * <net/checksum.h>
+ *
+ * "h/skerror.h"
+ * "h/skdebug.h"
+ * "h/sktypes.h"
+ * "h/lm80.h"
+ * "h/xmac_ii.h"
+ *
+ * "h/skdrv2nd.h"
+ * "h/skqueue.h"
+ * "h/skgehwt.h"
+ * "h/sktimer.h"
+ * "h/ski2c.h"
+ * "h/skgepnmi.h"
+ * "h/skvpd.h"
+ * "h/skgehw.h"
+ * "h/skgeinit.h"
+ * "h/skaddr.h"
+ * "h/skgesirq.h"
+ * "h/skcsum.h"
+ * "h/skrlmt.h"
+ *
+ ******************************************************************************/
+
+#include "h/skversion.h"
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+
+#include "h/skdrv1st.h"
+#include "h/skdrv2nd.h"
+
+/*******************************************************************************
+ *
+ * Defines
+ *
+ ******************************************************************************/
+
+/* for debuging on x86 only */
+/* #define BREAKPOINT() asm(" int $3"); */
+
+/* use the transmit hw checksum driver functionality */
+#define USE_SK_TX_CHECKSUM
+
+/* use the receive hw checksum driver functionality */
+#define USE_SK_RX_CHECKSUM
+
+/* use the scatter-gather functionality with sendfile() */
+#define SK_ZEROCOPY
+
+/* use of a transmit complete interrupt */
+#define USE_TX_COMPLETE
+
+/*
+ * threshold for copying small receive frames
+ * set to 0 to avoid copying, set to 9001 to copy all frames
+ */
+#define SK_COPY_THRESHOLD 50
+
+/* number of adapters that can be configured via command line params */
+#define SK_MAX_CARD_PARAM 16
+
+
+
+/*
+ * use those defines for a compile-in version of the driver instead
+ * of command line parameters
+ */
+// #define LINK_SPEED_A {"Auto", }
+// #define LINK_SPEED_B {"Auto", }
+// #define AUTO_NEG_A {"Sense", }
+// #define AUTO_NEG_B {"Sense", }
+// #define DUP_CAP_A {"Both", }
+// #define DUP_CAP_B {"Both", }
+// #define FLOW_CTRL_A {"SymOrRem", }
+// #define FLOW_CTRL_B {"SymOrRem", }
+// #define ROLE_A {"Auto", }
+// #define ROLE_B {"Auto", }
+// #define PREF_PORT {"A", }
+// #define CON_TYPE {"Auto", }
+// #define RLMT_MODE {"CheckLinkState", }
+
+#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb)
+#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb)
+#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb)
+
+
+/* Set blink mode*/
+#define OEM_CONFIG_VALUE ( SK_ACT_LED_BLINK | \
+ SK_DUP_LED_NORMAL | \
+ SK_LED_LINK100_ON)
+
+
+/* Isr return value */
+#define SkIsrRetVar irqreturn_t
+#define SkIsrRetNone IRQ_NONE
+#define SkIsrRetHandled IRQ_HANDLED
+
+
+/*******************************************************************************
+ *
+ * Local Function Prototypes
+ *
+ ******************************************************************************/
+
+static void FreeResources(struct SK_NET_DEVICE *dev);
+static int SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC);
+static SK_BOOL BoardAllocMem(SK_AC *pAC);
+static void BoardFreeMem(SK_AC *pAC);
+static void BoardInitMem(SK_AC *pAC);
+static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL);
+static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs);
+static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs);
+static int SkGeOpen(struct SK_NET_DEVICE *dev);
+static int SkGeClose(struct SK_NET_DEVICE *dev);
+static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev);
+static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p);
+static void SkGeSetRxMode(struct SK_NET_DEVICE *dev);
+static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
+static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
+static void GetConfiguration(SK_AC*);
+static void ProductStr(SK_AC*);
+static int XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
+static void FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
+static void FillRxRing(SK_AC*, RX_PORT*);
+static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*);
+static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL);
+static void ClearAndStartRx(SK_AC*, int);
+static void ClearTxIrq(SK_AC*, int, int);
+static void ClearRxRing(SK_AC*, RX_PORT*);
+static void ClearTxRing(SK_AC*, TX_PORT*);
+static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);
+static void PortReInitBmu(SK_AC*, int);
+static int SkGeIocMib(DEV_NET*, unsigned int, int);
+static int SkGeInitPCI(SK_AC *pAC);
+static void StartDrvCleanupTimer(SK_AC *pAC);
+static void StopDrvCleanupTimer(SK_AC *pAC);
+static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
+
+#ifdef SK_DIAG_SUPPORT
+static SK_U32 ParseDeviceNbrFromSlotName(const char *SlotName);
+static int SkDrvInitAdapter(SK_AC *pAC, int devNbr);
+static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr);
+#endif
+
+/*******************************************************************************
+ *
+ * Extern Function Prototypes
+ *
+ ******************************************************************************/
+static const char SKRootName[] = "sk98lin";
+static struct proc_dir_entry *pSkRootDir;
+extern struct file_operations sk_proc_fops;
+
+static inline void SkGeProcCreate(struct net_device *dev)
+{
+ struct proc_dir_entry *pe;
+
+ if (pSkRootDir &&
+ (pe = create_proc_entry(dev->name, S_IRUGO, pSkRootDir))) {
+ pe->proc_fops = &sk_proc_fops;
+ pe->data = dev;
+ pe->owner = THIS_MODULE;
+ }
+}
+
+static inline void SkGeProcRemove(struct net_device *dev)
+{
+ if (pSkRootDir)
+ remove_proc_entry(dev->name, pSkRootDir);
+}
+
+extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);
+extern void SkDimDisplayModerationSettings(SK_AC *pAC);
+extern void SkDimStartModerationTimer(SK_AC *pAC);
+extern void SkDimModerate(SK_AC *pAC);
+extern void SkGeBlinkTimer(unsigned long data);
+
+#ifdef DEBUG
+static void DumpMsg(struct sk_buff*, char*);
+static void DumpData(char*, int);
+static void DumpLong(char*, int);
+#endif
+
+/* global variables *********************************************************/
+static SK_BOOL DoPrintInterfaceChange = SK_TRUE;
+extern struct ethtool_ops SkGeEthtoolOps;
+
+/* local variables **********************************************************/
+static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}};
+static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480};
+
+/*****************************************************************************
+ *
+ * SkGeInitPCI - Init the PCI resources
+ *
+ * Description:
+ * This function initialize the PCI resources and IO
+ *
+ * Returns: N/A
+ *
+ */
+int SkGeInitPCI(SK_AC *pAC)
+{
+ struct SK_NET_DEVICE *dev = pAC->dev[0];
+ struct pci_dev *pdev = pAC->PciDev;
+ int retval;
+
+ if (pci_enable_device(pdev) != 0) {
+ return 1;
+ }
+
+ dev->mem_start = pci_resource_start (pdev, 0);
+ pci_set_master(pdev);
+
+ if (pci_request_regions(pdev, pAC->Name) != 0) {
+ retval = 2;
+ goto out_disable;
+ }
+
+#ifdef SK_BIG_ENDIAN
+ /*
+ * On big endian machines, we use the adapter's aibility of
+ * reading the descriptors as big endian.
+ */
+ {
+ SK_U32 our2;
+ SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
+ our2 |= PCI_REV_DESC;
+ SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
+ }
+#endif
+
+ /*
+ * Remap the regs into kernel space.
+ */
+ pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000);
+
+ if (!pAC->IoBase){
+ retval = 3;
+ goto out_release;
+ }
+
+ return 0;
+
+ out_release:
+ pci_release_regions(pdev);
+ out_disable:
+ pci_disable_device(pdev);
+ return retval;
+}
+
+
+/*****************************************************************************
+ *
+ * FreeResources - release resources allocated for adapter
+ *
+ * Description:
+ * This function releases the IRQ, unmaps the IO and
+ * frees the desriptor ring.
+ *
+ * Returns: N/A
+ *
+ */
+static void FreeResources(struct SK_NET_DEVICE *dev)
+{
+SK_U32 AllocFlag;
+DEV_NET *pNet;
+SK_AC *pAC;
+
+ pNet = netdev_priv(dev);
+ pAC = pNet->pAC;
+ AllocFlag = pAC->AllocFlag;
+ if (pAC->PciDev) {
+ pci_release_regions(pAC->PciDev);
+ }
+ if (AllocFlag & SK_ALLOC_IRQ) {
+ free_irq(dev->irq, dev);
+ }
+ if (pAC->IoBase) {
+ iounmap(pAC->IoBase);
+ }
+ if (pAC->pDescrMem) {
+ BoardFreeMem(pAC);
+ }
+
+} /* FreeResources */
+
+MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
+MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");
+MODULE_LICENSE("GPL");
+
+#ifdef LINK_SPEED_A
+static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED;
+#else
+static char *Speed_A[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef LINK_SPEED_B
+static char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED;
+#else
+static char *Speed_B[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef AUTO_NEG_A
+static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A;
+#else
+static char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef DUP_CAP_A
+static char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A;
+#else
+static char *DupCap_A[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef FLOW_CTRL_A
+static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A;
+#else
+static char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef ROLE_A
+static char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A;
+#else
+static char *Role_A[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef AUTO_NEG_B
+static char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B;
+#else
+static char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef DUP_CAP_B
+static char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B;
+#else
+static char *DupCap_B[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef FLOW_CTRL_B
+static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B;
+#else
+static char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef ROLE_B
+static char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B;
+#else
+static char *Role_B[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef CON_TYPE
+static char *ConType[SK_MAX_CARD_PARAM] = CON_TYPE;
+#else
+static char *ConType[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef PREF_PORT
+static char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT;
+#else
+static char *PrefPort[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+#ifdef RLMT_MODE
+static char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE;
+#else
+static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };
+#endif
+
+static int IntsPerSec[SK_MAX_CARD_PARAM];
+static char *Moderation[SK_MAX_CARD_PARAM];
+static char *ModerationMask[SK_MAX_CARD_PARAM];
+static char *AutoSizing[SK_MAX_CARD_PARAM];
+static char *Stats[SK_MAX_CARD_PARAM];
+
+module_param_array(Speed_A, charp, NULL, 0);
+module_param_array(Speed_B, charp, NULL, 0);
+module_param_array(AutoNeg_A, charp, NULL, 0);
+module_param_array(AutoNeg_B, charp, NULL, 0);
+module_param_array(DupCap_A, charp, NULL, 0);
+module_param_array(DupCap_B, charp, NULL, 0);
+module_param_array(FlowCtrl_A, charp, NULL, 0);
+module_param_array(FlowCtrl_B, charp, NULL, 0);
+module_param_array(Role_A, charp, NULL, 0);
+module_param_array(Role_B, charp, NULL, 0);
+module_param_array(ConType, charp, NULL, 0);
+module_param_array(PrefPort, charp, NULL, 0);
+module_param_array(RlmtMode, charp, NULL, 0);
+/* used for interrupt moderation */
+module_param_array(IntsPerSec, int, NULL, 0);
+module_param_array(Moderation, charp, NULL, 0);
+module_param_array(Stats, charp, NULL, 0);
+module_param_array(ModerationMask, charp, NULL, 0);
+module_param_array(AutoSizing, charp, NULL, 0);
+
+/*****************************************************************************
+ *
+ * SkGeBoardInit - do level 0 and 1 initialization
+ *
+ * Description:
+ * This function prepares the board hardware for running. The desriptor
+ * ring is set up, the IRQ is allocated and the configuration settings
+ * are examined.
+ *
+ * Returns:
+ * 0, if everything is ok
+ * !=0, on error
+ */
+static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
+{
+short i;
+unsigned long Flags;
+char *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */
+char *VerStr = VER_STRING;
+int Ret; /* return code of request_irq */
+SK_BOOL DualNet;
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("IoBase: %08lX\n", (unsigned long)pAC->IoBase));
+ for (i=0; i<SK_MAX_MACS; i++) {
+ pAC->TxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0];
+ pAC->TxPort[i][0].PortIndex = i;
+ pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i];
+ pAC->RxPort[i].PortIndex = i;
+ }
+
+ /* Initialize the mutexes */
+ for (i=0; i<SK_MAX_MACS; i++) {
+ spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock);
+ spin_lock_init(&pAC->RxPort[i].RxDesRingLock);
+ }
+ spin_lock_init(&pAC->SlowPathLock);
+
+ /* setup phy_id blink timer */
+ pAC->BlinkTimer.function = SkGeBlinkTimer;
+ pAC->BlinkTimer.data = (unsigned long) dev;
+ init_timer(&pAC->BlinkTimer);
+
+ /* level 0 init common modules here */
+
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+ /* Does a RESET on board ...*/
+ if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) {
+ printk("HWInit (0) failed.\n");
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+ return(-EAGAIN);
+ }
+ SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA);
+ SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA);
+ SkPnmiInit( pAC, pAC->IoBase, SK_INIT_DATA);
+ SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA);
+ SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA);
+ SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA);
+
+ pAC->BoardLevel = SK_INIT_DATA;
+ pAC->RxBufSize = ETH_BUF_SIZE;
+
+ SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString);
+ SK_PNMI_SET_DRIVER_VER(pAC, VerStr);
+
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+ /* level 1 init common modules here (HW init) */
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+ if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
+ printk("sk98lin: HWInit (1) failed.\n");
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+ return(-EAGAIN);
+ }
+ SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
+ SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
+ SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
+ SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
+ SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
+ SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
+
+ /* Set chipset type support */
+ pAC->ChipsetType = 0;
+ if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) ||
+ (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) {
+ pAC->ChipsetType = 1;
+ }
+
+ GetConfiguration(pAC);
+ if (pAC->RlmtNets == 2) {
+ pAC->GIni.GIPortUsage = SK_MUL_LINK;
+ }
+
+ pAC->BoardLevel = SK_INIT_IO;
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+ if (pAC->GIni.GIMacsFound == 2) {
+ Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+ } else if (pAC->GIni.GIMacsFound == 1) {
+ Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
+ pAC->Name, dev);
+ } else {
+ printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
+ pAC->GIni.GIMacsFound);
+ return -EAGAIN;
+ }
+
+ if (Ret) {
+ printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
+ dev->irq);
+ return -EAGAIN;
+ }
+ pAC->AllocFlag |= SK_ALLOC_IRQ;
+
+ /* Alloc memory for this board (Mem for RxD/TxD) : */
+ if(!BoardAllocMem(pAC)) {
+ printk("No memory for descriptor rings.\n");
+ return(-EAGAIN);
+ }
+
+ SkCsSetReceiveFlags(pAC,
+ SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP,
+ &pAC->CsOfs1, &pAC->CsOfs2, 0);
+ pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;
+
+ BoardInitMem(pAC);
+ /* tschilling: New common function with minimum size check. */
+ DualNet = SK_FALSE;
+ if (pAC->RlmtNets == 2) {
+ DualNet = SK_TRUE;
+ }
+
+ if (SkGeInitAssignRamToQueues(
+ pAC,
+ pAC->ActivePort,
+ DualNet)) {
+ BoardFreeMem(pAC);
+ printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
+ return(-EAGAIN);
+ }
+
+ return (0);
+} /* SkGeBoardInit */
+
+
+/*****************************************************************************
+ *
+ * BoardAllocMem - allocate the memory for the descriptor rings
+ *
+ * Description:
+ * This function allocates the memory for all descriptor rings.
+ * Each ring is aligned for the desriptor alignment and no ring
+ * has a 4 GByte boundary in it (because the upper 32 bit must
+ * be constant for all descriptiors in one rings).
+ *
+ * Returns:
+ * SK_TRUE, if all memory could be allocated
+ * SK_FALSE, if not
+ */
+static SK_BOOL BoardAllocMem(
+SK_AC *pAC)
+{
+caddr_t pDescrMem; /* pointer to descriptor memory area */
+size_t AllocLength; /* length of complete descriptor area */
+int i; /* loop counter */
+unsigned long BusAddr;
+
+
+ /* rings plus one for alignment (do not cross 4 GB boundary) */
+ /* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */
+#if (BITS_PER_LONG == 32)
+ AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
+#else
+ AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
+ + RX_RING_SIZE + 8;
+#endif
+
+ pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength,
+ &pAC->pDescrMemDMA);
+
+ if (pDescrMem == NULL) {
+ return (SK_FALSE);
+ }
+ pAC->pDescrMem = pDescrMem;
+ BusAddr = (unsigned long) pAC->pDescrMemDMA;
+
+ /* Descriptors need 8 byte alignment, and this is ensured
+ * by pci_alloc_consistent.
+ */
+ for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+ ("TX%d/A: pDescrMem: %lX, PhysDescrMem: %lX\n",
+ i, (unsigned long) pDescrMem,
+ BusAddr));
+ pAC->TxPort[i][0].pTxDescrRing = pDescrMem;
+ pAC->TxPort[i][0].VTxDescrRing = BusAddr;
+ pDescrMem += TX_RING_SIZE;
+ BusAddr += TX_RING_SIZE;
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+ ("RX%d: pDescrMem: %lX, PhysDescrMem: %lX\n",
+ i, (unsigned long) pDescrMem,
+ (unsigned long)BusAddr));
+ pAC->RxPort[i].pRxDescrRing = pDescrMem;
+ pAC->RxPort[i].VRxDescrRing = BusAddr;
+ pDescrMem += RX_RING_SIZE;
+ BusAddr += RX_RING_SIZE;
+ } /* for */
+
+ return (SK_TRUE);
+} /* BoardAllocMem */
+
+
+/****************************************************************************
+ *
+ * BoardFreeMem - reverse of BoardAllocMem
+ *
+ * Description:
+ * Free all memory allocated in BoardAllocMem: adapter context,
+ * descriptor rings, locks.
+ *
+ * Returns: N/A
+ */
+static void BoardFreeMem(
+SK_AC *pAC)
+{
+size_t AllocLength; /* length of complete descriptor area */
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("BoardFreeMem\n"));
+#if (BITS_PER_LONG == 32)
+ AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;
+#else
+ AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound
+ + RX_RING_SIZE + 8;
+#endif
+
+ pci_free_consistent(pAC->PciDev, AllocLength,
+ pAC->pDescrMem, pAC->pDescrMemDMA);
+ pAC->pDescrMem = NULL;
+} /* BoardFreeMem */
+
+
+/*****************************************************************************
+ *
+ * BoardInitMem - initiate the descriptor rings
+ *
+ * Description:
+ * This function sets the descriptor rings up in memory.
+ * The adapter is initialized with the descriptor start addresses.
+ *
+ * Returns: N/A
+ */
+static void BoardInitMem(
+SK_AC *pAC) /* pointer to adapter context */
+{
+int i; /* loop counter */
+int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/
+int TxDescrSize; /* the size of a tx descriptor rounded up to alignment*/
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("BoardInitMem\n"));
+
+ RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
+ pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize;
+ TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN;
+ pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize;
+
+ for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ SetupRing(
+ pAC,
+ pAC->TxPort[i][0].pTxDescrRing,
+ pAC->TxPort[i][0].VTxDescrRing,
+ (RXD**)&pAC->TxPort[i][0].pTxdRingHead,
+ (RXD**)&pAC->TxPort[i][0].pTxdRingTail,
+ (RXD**)&pAC->TxPort[i][0].pTxdRingPrev,
+ &pAC->TxPort[i][0].TxdRingFree,
+ SK_TRUE);
+ SetupRing(
+ pAC,
+ pAC->RxPort[i].pRxDescrRing,
+ pAC->RxPort[i].VRxDescrRing,
+ &pAC->RxPort[i].pRxdRingHead,
+ &pAC->RxPort[i].pRxdRingTail,
+ &pAC->RxPort[i].pRxdRingPrev,
+ &pAC->RxPort[i].RxdRingFree,
+ SK_FALSE);
+ }
+} /* BoardInitMem */
+
+
+/*****************************************************************************
+ *
+ * SetupRing - create one descriptor ring
+ *
+ * Description:
+ * This function creates one descriptor ring in the given memory area.
+ * The head, tail and number of free descriptors in the ring are set.
+ *
+ * Returns:
+ * none
+ */
+static void SetupRing(
+SK_AC *pAC,
+void *pMemArea, /* a pointer to the memory area for the ring */
+uintptr_t VMemArea, /* the virtual bus address of the memory area */
+RXD **ppRingHead, /* address where the head should be written */
+RXD **ppRingTail, /* address where the tail should be written */
+RXD **ppRingPrev, /* address where the tail should be written */
+int *pRingFree, /* address where the # of free descr. goes */
+SK_BOOL IsTx) /* flag: is this a tx ring */
+{
+int i; /* loop counter */
+int DescrSize; /* the size of a descriptor rounded up to alignment*/
+int DescrNum; /* number of descriptors per ring */
+RXD *pDescr; /* pointer to a descriptor (receive or transmit) */
+RXD *pNextDescr; /* pointer to the next descriptor */
+RXD *pPrevDescr; /* pointer to the previous descriptor */
+uintptr_t VNextDescr; /* the virtual bus address of the next descriptor */
+
+ if (IsTx == SK_TRUE) {
+ DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) *
+ DESCR_ALIGN;
+ DescrNum = TX_RING_SIZE / DescrSize;
+ } else {
+ DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) *
+ DESCR_ALIGN;
+ DescrNum = RX_RING_SIZE / DescrSize;
+ }
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS,
+ ("Descriptor size: %d Descriptor Number: %d\n",
+ DescrSize,DescrNum));
+
+ pDescr = (RXD*) pMemArea;
+ pPrevDescr = NULL;
+ pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
+ VNextDescr = VMemArea + DescrSize;
+ for(i=0; i<DescrNum; i++) {
+ /* set the pointers right */
+ pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
+ pDescr->pNextRxd = pNextDescr;
+ pDescr->TcpSumStarts = pAC->CsOfs;
+
+ /* advance one step */
+ pPrevDescr = pDescr;
+ pDescr = pNextDescr;
+ pNextDescr = (RXD*) (((char*)pDescr) + DescrSize);
+ VNextDescr += DescrSize;
+ }
+ pPrevDescr->pNextRxd = (RXD*) pMemArea;
+ pPrevDescr->VNextRxd = VMemArea;
+ pDescr = (RXD*) pMemArea;
+ *ppRingHead = (RXD*) pMemArea;
+ *ppRingTail = *ppRingHead;
+ *ppRingPrev = pPrevDescr;
+ *pRingFree = DescrNum;
+} /* SetupRing */
+
+
+/*****************************************************************************
+ *
+ * PortReInitBmu - re-initiate the descriptor rings for one port
+ *
+ * Description:
+ * This function reinitializes the descriptor rings of one port
+ * in memory. The port must be stopped before.
+ * The HW is initialized with the descriptor start addresses.
+ *
+ * Returns:
+ * none
+ */
+static void PortReInitBmu(
+SK_AC *pAC, /* pointer to adapter context */
+int PortIndex) /* index of the port for which to re-init */
+{
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("PortReInitBmu "));
+
+ /* set address of first descriptor of ring in BMU */
+ SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_L,
+ (uint32_t)(((caddr_t)
+ (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
+ pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
+ pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) &
+ 0xFFFFFFFF));
+ SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_H,
+ (uint32_t)(((caddr_t)
+ (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) -
+ pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing +
+ pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32));
+ SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_L,
+ (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
+ pAC->RxPort[PortIndex].pRxDescrRing +
+ pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF));
+ SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_H,
+ (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) -
+ pAC->RxPort[PortIndex].pRxDescrRing +
+ pAC->RxPort[PortIndex].VRxDescrRing) >> 32));
+} /* PortReInitBmu */
+
+
+/****************************************************************************
+ *
+ * SkGeIsr - handle adapter interrupts
+ *
+ * Description:
+ * The interrupt routine is called when the network adapter
+ * generates an interrupt. It may also be called if another device
+ * shares this interrupt vector with the driver.
+ *
+ * Returns: N/A
+ *
+ */
+static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs)
+{
+struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
+DEV_NET *pNet;
+SK_AC *pAC;
+SK_U32 IntSrc; /* interrupts source register contents */
+
+ pNet = netdev_priv(dev);
+ pAC = pNet->pAC;
+
+ /*
+ * Check and process if its our interrupt
+ */
+ SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
+ if (IntSrc == 0) {
+ return SkIsrRetNone;
+ }
+
+ while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
+#if 0 /* software irq currently not used */
+ if (IntSrc & IS_IRQ_SW) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_INT_SRC,
+ ("Software IRQ\n"));
+ }
+#endif
+ if (IntSrc & IS_R1_F) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_INT_SRC,
+ ("EOF RX1 IRQ\n"));
+ ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
+ SK_PNMI_CNT_RX_INTR(pAC, 0);
+ }
+ if (IntSrc & IS_R2_F) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_INT_SRC,
+ ("EOF RX2 IRQ\n"));
+ ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
+ SK_PNMI_CNT_RX_INTR(pAC, 1);
+ }
+#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+ if (IntSrc & IS_XA1_F) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_INT_SRC,
+ ("EOF AS TX1 IRQ\n"));
+ SK_PNMI_CNT_TX_INTR(pAC, 0);
+ spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
+ FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
+ spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
+ }
+ if (IntSrc & IS_XA2_F) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_INT_SRC,
+ ("EOF AS TX2 IRQ\n"));
+ SK_PNMI_CNT_TX_INTR(pAC, 1);
+ spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
+ FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]);
+ spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock);
+ }
+#if 0 /* only if sync. queues used */
+ if (IntSrc & IS_XS1_F) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_INT_SRC,
+ ("EOF SY TX1 IRQ\n"));
+ SK_PNMI_CNT_TX_INTR(pAC, 1);
+ spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
+ FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
+ spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
+ ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
+ }
+ if (IntSrc & IS_XS2_F) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_INT_SRC,
+ ("EOF SY TX2 IRQ\n"));
+ SK_PNMI_CNT_TX_INTR(pAC, 1);
+ spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
+ FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH);
+ spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock);
+ ClearTxIrq(pAC, 1, TX_PRIO_HIGH);
+ }
+#endif
+#endif
+
+ /* do all IO at once */
+ if (IntSrc & IS_R1_F)
+ ClearAndStartRx(pAC, 0);
+ if (IntSrc & IS_R2_F)
+ ClearAndStartRx(pAC, 1);
+#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+ if (IntSrc & IS_XA1_F)
+ ClearTxIrq(pAC, 0, TX_PRIO_LOW);
+ if (IntSrc & IS_XA2_F)
+ ClearTxIrq(pAC, 1, TX_PRIO_LOW);
+#endif
+ SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
+ } /* while (IntSrc & IRQ_MASK != 0) */
+
+ IntSrc &= pAC->GIni.GIValIrqMask;
+ if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+ ("SPECIAL IRQ DP-Cards => %x\n", IntSrc));
+ pAC->CheckQueue = SK_FALSE;
+ spin_lock(&pAC->SlowPathLock);
+ if (IntSrc & SPECIAL_IRQS)
+ SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
+
+ SkEventDispatcher(pAC, pAC->IoBase);
+ spin_unlock(&pAC->SlowPathLock);
+ }
+ /*
+ * do it all again is case we cleared an interrupt that
+ * came in after handling the ring (OUTs may be delayed
+ * in hardware buffers, but are through after IN)
+ *
+ * rroesler: has been commented out and shifted to
+ * SkGeDrvEvent(), because it is timer
+ * guarded now
+ *
+ ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
+ ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE);
+ */
+
+ if (pAC->CheckQueue) {
+ pAC->CheckQueue = SK_FALSE;
+ spin_lock(&pAC->SlowPathLock);
+ SkEventDispatcher(pAC, pAC->IoBase);
+ spin_unlock(&pAC->SlowPathLock);
+ }
+
+ /* IRQ is processed - Enable IRQs again*/
+ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
+
+ return SkIsrRetHandled;
+} /* SkGeIsr */
+
+
+/****************************************************************************
+ *
+ * SkGeIsrOnePort - handle adapter interrupts for single port adapter
+ *
+ * Description:
+ * The interrupt routine is called when the network adapter
+ * generates an interrupt. It may also be called if another device
+ * shares this interrupt vector with the driver.
+ * This is the same as above, but handles only one port.
+ *
+ * Returns: N/A
+ *
+ */
+static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs)
+{
+struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
+DEV_NET *pNet;
+SK_AC *pAC;
+SK_U32 IntSrc; /* interrupts source register contents */
+
+ pNet = netdev_priv(dev);
+ pAC = pNet->pAC;
+
+ /*
+ * Check and process if its our interrupt
+ */
+ SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc);
+ if (IntSrc == 0) {
+ return SkIsrRetNone;
+ }
+
+ while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) {
+#if 0 /* software irq currently not used */
+ if (IntSrc & IS_IRQ_SW) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_INT_SRC,
+ ("Software IRQ\n"));
+ }
+#endif
+ if (IntSrc & IS_R1_F) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_INT_SRC,
+ ("EOF RX1 IRQ\n"));
+ ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
+ SK_PNMI_CNT_RX_INTR(pAC, 0);
+ }
+#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+ if (IntSrc & IS_XA1_F) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_INT_SRC,
+ ("EOF AS TX1 IRQ\n"));
+ SK_PNMI_CNT_TX_INTR(pAC, 0);
+ spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
+ FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]);
+ spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock);
+ }
+#if 0 /* only if sync. queues used */
+ if (IntSrc & IS_XS1_F) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_INT_SRC,
+ ("EOF SY TX1 IRQ\n"));
+ SK_PNMI_CNT_TX_INTR(pAC, 0);
+ spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
+ FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH);
+ spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock);
+ ClearTxIrq(pAC, 0, TX_PRIO_HIGH);
+ }
+#endif
+#endif
+
+ /* do all IO at once */
+ if (IntSrc & IS_R1_F)
+ ClearAndStartRx(pAC, 0);
+#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */
+ if (IntSrc & IS_XA1_F)
+ ClearTxIrq(pAC, 0, TX_PRIO_LOW);
+#endif
+ SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc);
+ } /* while (IntSrc & IRQ_MASK != 0) */
+
+ IntSrc &= pAC->GIni.GIValIrqMask;
+ if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC,
+ ("SPECIAL IRQ SP-Cards => %x\n", IntSrc));
+ pAC->CheckQueue = SK_FALSE;
+ spin_lock(&pAC->SlowPathLock);
+ if (IntSrc & SPECIAL_IRQS)
+ SkGeSirqIsr(pAC, pAC->IoBase, IntSrc);
+
+ SkEventDispatcher(pAC, pAC->IoBase);
+ spin_unlock(&pAC->SlowPathLock);
+ }
+ /*
+ * do it all again is case we cleared an interrupt that
+ * came in after handling the ring (OUTs may be delayed
+ * in hardware buffers, but are through after IN)
+ *
+ * rroesler: has been commented out and shifted to
+ * SkGeDrvEvent(), because it is timer
+ * guarded now
+ *
+ ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE);
+ */
+
+ /* IRQ is processed - Enable IRQs again*/
+ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
+
+ return SkIsrRetHandled;
+} /* SkGeIsrOnePort */
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/****************************************************************************
+ *
+ * SkGePollController - polling receive, for netconsole
+ *
+ * Description:
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ *
+ * Returns: N/A
+ */
+static void SkGePollController(struct net_device *dev)
+{
+ disable_irq(dev->irq);
+ SkGeIsr(dev->irq, dev, NULL);
+ enable_irq(dev->irq);
+}
+#endif
+
+/****************************************************************************
+ *
+ * SkGeOpen - handle start of initialized adapter
+ *
+ * Description:
+ * This function starts the initialized adapter.
+ * The board level variable is set and the adapter is
+ * brought to full functionality.
+ * The device flags are set for operation.
+ * Do all necessary level 2 initialization, enable interrupts and
+ * give start command to RLMT.
+ *
+ * Returns:
+ * 0 on success
+ * != 0 on error
+ */
+static int SkGeOpen(
+struct SK_NET_DEVICE *dev)
+{
+ DEV_NET *pNet;
+ SK_AC *pAC;
+ unsigned long Flags; /* for spin lock */
+ int i;
+ SK_EVPARA EvPara; /* an event parameter union */
+
+ pNet = netdev_priv(dev);
+ pAC = pNet->pAC;
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC));
+
+#ifdef SK_DIAG_SUPPORT
+ if (pAC->DiagModeActive == DIAG_ACTIVE) {
+ if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
+ return (-1); /* still in use by diag; deny actions */
+ }
+ }
+#endif
+
+ /* Set blink mode */
+ if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab ))
+ pAC->GIni.GILedBlinkCtrl = OEM_CONFIG_VALUE;
+
+ if (pAC->BoardLevel == SK_INIT_DATA) {
+ /* level 1 init common modules here */
+ if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
+ printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name);
+ return (-1);
+ }
+ SkI2cInit (pAC, pAC->IoBase, SK_INIT_IO);
+ SkEventInit (pAC, pAC->IoBase, SK_INIT_IO);
+ SkPnmiInit (pAC, pAC->IoBase, SK_INIT_IO);
+ SkAddrInit (pAC, pAC->IoBase, SK_INIT_IO);
+ SkRlmtInit (pAC, pAC->IoBase, SK_INIT_IO);
+ SkTimerInit (pAC, pAC->IoBase, SK_INIT_IO);
+ pAC->BoardLevel = SK_INIT_IO;
+ }
+
+ if (pAC->BoardLevel != SK_INIT_RUN) {
+ /* tschilling: Level 2 init modules here, check return value. */
+ if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) {
+ printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name);
+ return (-1);
+ }
+ SkI2cInit (pAC, pAC->IoBase, SK_INIT_RUN);
+ SkEventInit (pAC, pAC->IoBase, SK_INIT_RUN);
+ SkPnmiInit (pAC, pAC->IoBase, SK_INIT_RUN);
+ SkAddrInit (pAC, pAC->IoBase, SK_INIT_RUN);
+ SkRlmtInit (pAC, pAC->IoBase, SK_INIT_RUN);
+ SkTimerInit (pAC, pAC->IoBase, SK_INIT_RUN);
+ pAC->BoardLevel = SK_INIT_RUN;
+ }
+
+ for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ /* Enable transmit descriptor polling. */
+ SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
+ FillRxRing(pAC, &pAC->RxPort[i]);
+ }
+ SkGeYellowLED(pAC, pAC->IoBase, 1);
+
+ StartDrvCleanupTimer(pAC);
+ SkDimEnableModerationIfNeeded(pAC);
+ SkDimDisplayModerationSettings(pAC);
+
+ pAC->GIni.GIValIrqMask &= IRQ_MASK;
+
+ /* enable Interrupts */
+ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
+ SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
+
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+
+ if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) {
+ EvPara.Para32[0] = pAC->RlmtNets;
+ EvPara.Para32[1] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS,
+ EvPara);
+ EvPara.Para32[0] = pAC->RlmtMode;
+ EvPara.Para32[1] = 0;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE,
+ EvPara);
+ }
+
+ EvPara.Para32[0] = pNet->NetNr;
+ EvPara.Para32[1] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+ SkEventDispatcher(pAC, pAC->IoBase);
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+ pAC->MaxPorts++;
+ pNet->Up = 1;
+
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("SkGeOpen suceeded\n"));
+
+ return (0);
+} /* SkGeOpen */
+
+
+/****************************************************************************
+ *
+ * SkGeClose - Stop initialized adapter
+ *
+ * Description:
+ * Close initialized adapter.
+ *
+ * Returns:
+ * 0 - on success
+ * error code - on error
+ */
+static int SkGeClose(
+struct SK_NET_DEVICE *dev)
+{
+ DEV_NET *pNet;
+ DEV_NET *newPtrNet;
+ SK_AC *pAC;
+
+ unsigned long Flags; /* for spin lock */
+ int i;
+ int PortIdx;
+ SK_EVPARA EvPara;
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC));
+
+ pNet = netdev_priv(dev);
+ pAC = pNet->pAC;
+
+#ifdef SK_DIAG_SUPPORT
+ if (pAC->DiagModeActive == DIAG_ACTIVE) {
+ if (pAC->DiagFlowCtrl == SK_FALSE) {
+ /*
+ ** notify that the interface which has been closed
+ ** by operator interaction must not be started up
+ ** again when the DIAG has finished.
+ */
+ newPtrNet = netdev_priv(pAC->dev[0]);
+ if (newPtrNet == pNet) {
+ pAC->WasIfUp[0] = SK_FALSE;
+ } else {
+ pAC->WasIfUp[1] = SK_FALSE;
+ }
+ return 0; /* return to system everything is fine... */
+ } else {
+ pAC->DiagFlowCtrl = SK_FALSE;
+ }
+ }
+#endif
+
+ netif_stop_queue(dev);
+
+ if (pAC->RlmtNets == 1)
+ PortIdx = pAC->ActivePort;
+ else
+ PortIdx = pNet->NetNr;
+
+ StopDrvCleanupTimer(pAC);
+
+ /*
+ * Clear multicast table, promiscuous mode ....
+ */
+ SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
+ SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
+ SK_PROM_MODE_NONE);
+
+ if (pAC->MaxPorts == 1) {
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+ /* disable interrupts */
+ SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+ EvPara.Para32[0] = pNet->NetNr;
+ EvPara.Para32[1] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+ SkEventDispatcher(pAC, pAC->IoBase);
+ SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+ /* stop the hardware */
+ SkGeDeInit(pAC, pAC->IoBase);
+ pAC->BoardLevel = SK_INIT_DATA;
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+ } else {
+
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+ EvPara.Para32[0] = pNet->NetNr;
+ EvPara.Para32[1] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+ SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara);
+ SkEventDispatcher(pAC, pAC->IoBase);
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+ /* Stop port */
+ spin_lock_irqsave(&pAC->TxPort[pNet->PortNr]
+ [TX_PRIO_LOW].TxDesRingLock, Flags);
+ SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr,
+ SK_STOP_ALL, SK_HARD_RST);
+ spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr]
+ [TX_PRIO_LOW].TxDesRingLock, Flags);
+ }
+
+ if (pAC->RlmtNets == 1) {
+ /* clear all descriptor rings */
+ for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
+ ClearRxRing(pAC, &pAC->RxPort[i]);
+ ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]);
+ }
+ } else {
+ /* clear port descriptor rings */
+ ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE);
+ ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]);
+ ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]);
+ }
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("SkGeClose: done "));
+
+ SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA));
+ SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct),
+ sizeof(SK_PNMI_STRUCT_DATA));
+
+ pAC->MaxPorts--;
+ pNet->Up = 0;
+
+ return (0);
+} /* SkGeClose */
+
+
+/*****************************************************************************
+ *
+ * SkGeXmit - Linux frame transmit function
+ *
+ * Description:
+ * The system calls this function to send frames onto the wire.
+ * It puts the frame in the tx descriptor ring. If the ring is
+ * full then, the 'tbusy' flag is set.
+ *
+ * Returns:
+ * 0, if everything is ok
+ * !=0, on error
+ * WARNING: returning 1 in 'tbusy' case caused system crashes (double
+ * allocated skb's) !!!
+ */
+static int SkGeXmit(struct sk_buff *skb, struct SK_NET_DEVICE *dev)
+{
+DEV_NET *pNet;
+SK_AC *pAC;
+int Rc; /* return code of XmitFrame */
+
+ pNet = netdev_priv(dev);
+ pAC = pNet->pAC;
+
+ if ((!skb_shinfo(skb)->nr_frags) ||
+ (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) {
+ /* Don't activate scatter-gather and hardware checksum */
+
+ if (pAC->RlmtNets == 2)
+ Rc = XmitFrame(
+ pAC,
+ &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
+ skb);
+ else
+ Rc = XmitFrame(
+ pAC,
+ &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
+ skb);
+ } else {
+ /* scatter-gather and hardware TCP checksumming anabled*/
+ if (pAC->RlmtNets == 2)
+ Rc = XmitFrameSG(
+ pAC,
+ &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW],
+ skb);
+ else
+ Rc = XmitFrameSG(
+ pAC,
+ &pAC->TxPort[pAC->ActivePort][TX_PRIO_LOW],
+ skb);
+ }
+
+ /* Transmitter out of resources? */
+ if (Rc <= 0) {
+ netif_stop_queue(dev);
+ }
+
+ /* If not taken, give buffer ownership back to the
+ * queueing layer.
+ */
+ if (Rc < 0)
+ return (1);
+
+ dev->trans_start = jiffies;
+ return (0);
+} /* SkGeXmit */
+
+
+/*****************************************************************************
+ *
+ * XmitFrame - fill one socket buffer into the transmit ring
+ *
+ * Description:
+ * This function puts a message into the transmit descriptor ring
+ * if there is a descriptors left.
+ * Linux skb's consist of only one continuous buffer.
+ * The first step locks the ring. It is held locked
+ * all time to avoid problems with SWITCH_../PORT_RESET.
+ * Then the descriptoris allocated.
+ * The second part is linking the buffer to the descriptor.
+ * At the very last, the Control field of the descriptor
+ * is made valid for the BMU and a start TX command is given
+ * if necessary.
+ *
+ * Returns:
+ * > 0 - on succes: the number of bytes in the message
+ * = 0 - on resource shortage: this frame sent or dropped, now
+ * the ring is full ( -> set tbusy)
+ * < 0 - on failure: other problems ( -> return failure to upper layers)
+ */
+static int XmitFrame(
+SK_AC *pAC, /* pointer to adapter context */
+TX_PORT *pTxPort, /* pointer to struct of port to send to */
+struct sk_buff *pMessage) /* pointer to send-message */
+{
+ TXD *pTxd; /* the rxd to fill */
+ TXD *pOldTxd;
+ unsigned long Flags;
+ SK_U64 PhysAddr;
+ int Protocol;
+ int IpHeaderLength;
+ int BytesSend = pMessage->len;
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("X"));
+
+ spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
+#ifndef USE_TX_COMPLETE
+ FreeTxDescriptors(pAC, pTxPort);
+#endif
+ if (pTxPort->TxdRingFree == 0) {
+ /*
+ ** no enough free descriptors in ring at the moment.
+ ** Maybe free'ing some old one help?
+ */
+ FreeTxDescriptors(pAC, pTxPort);
+ if (pTxPort->TxdRingFree == 0) {
+ spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
+ SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_TX_PROGRESS,
+ ("XmitFrame failed\n"));
+ /*
+ ** the desired message can not be sent
+ ** Because tbusy seems to be set, the message
+ ** should not be freed here. It will be used
+ ** by the scheduler of the ethernet handler
+ */
+ return (-1);
+ }
+ }
+
+ /*
+ ** If the passed socket buffer is of smaller MTU-size than 60,
+ ** copy everything into new buffer and fill all bytes between
+ ** the original packet end and the new packet end of 60 with 0x00.
+ ** This is to resolve faulty padding by the HW with 0xaa bytes.
+ */
+ if (BytesSend < C_LEN_ETHERNET_MINSIZE) {
+ if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) {
+ spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
+ return 0;
+ }
+ pMessage->len = C_LEN_ETHERNET_MINSIZE;
+ }
+
+ /*
+ ** advance head counter behind descriptor needed for this frame,
+ ** so that needed descriptor is reserved from that on. The next
+ ** action will be to add the passed buffer to the TX-descriptor
+ */
+ pTxd = pTxPort->pTxdRingHead;
+ pTxPort->pTxdRingHead = pTxd->pNextTxd;
+ pTxPort->TxdRingFree--;
+
+#ifdef SK_DUMP_TX
+ DumpMsg(pMessage, "XmitFrame");
+#endif
+
+ /*
+ ** First step is to map the data to be sent via the adapter onto
+ ** the DMA memory. Kernel 2.2 uses virt_to_bus(), but kernels 2.4
+ ** and 2.6 need to use pci_map_page() for that mapping.
+ */
+ PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
+ virt_to_page(pMessage->data),
+ ((unsigned long) pMessage->data & ~PAGE_MASK),
+ pMessage->len,
+ PCI_DMA_TODEVICE);
+ pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
+ pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
+ pTxd->pMBuf = pMessage;
+
+ if (pMessage->ip_summed == CHECKSUM_HW) {
+ Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff);
+ if ((Protocol == C_PROTO_ID_UDP) &&
+ (pAC->GIni.GIChipRev == 0) &&
+ (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
+ pTxd->TBControl = BMU_TCP_CHECK;
+ } else {
+ pTxd->TBControl = BMU_UDP_CHECK;
+ }
+
+ IpHeaderLength = (SK_U8)pMessage->data[C_OFFSET_IPHEADER];
+ IpHeaderLength = (IpHeaderLength & 0xf) * 4;
+ pTxd->TcpSumOfs = 0; /* PH-Checksum already calculated */
+ pTxd->TcpSumSt = C_LEN_ETHERMAC_HEADER + IpHeaderLength +
+ (Protocol == C_PROTO_ID_UDP ?
+ C_OFFSET_UDPHEADER_UDPCS :
+ C_OFFSET_TCPHEADER_TCPCS);
+ pTxd->TcpSumWr = C_LEN_ETHERMAC_HEADER + IpHeaderLength;
+
+ pTxd->TBControl |= BMU_OWN | BMU_STF |
+ BMU_SW | BMU_EOF |
+#ifdef USE_TX_COMPLETE
+ BMU_IRQ_EOF |
+#endif
+ pMessage->len;
+ } else {
+ pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK |
+ BMU_SW | BMU_EOF |
+#ifdef USE_TX_COMPLETE
+ BMU_IRQ_EOF |
+#endif
+ pMessage->len;
+ }
+
+ /*
+ ** If previous descriptor already done, give TX start cmd
+ */
+ pOldTxd = xchg(&pTxPort->pTxdRingPrev, pTxd);
+ if ((pOldTxd->TBControl & BMU_OWN) == 0) {
+ SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
+ }
+
+ /*
+ ** after releasing the lock, the skb may immediately be free'd
+ */
+ spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
+ if (pTxPort->TxdRingFree != 0) {
+ return (BytesSend);
+ } else {
+ return (0);
+ }
+
+} /* XmitFrame */
+
+/*****************************************************************************
+ *
+ * XmitFrameSG - fill one socket buffer into the transmit ring
+ * (use SG and TCP/UDP hardware checksumming)
+ *
+ * Description:
+ * This function puts a message into the transmit descriptor ring
+ * if there is a descriptors left.
+ *
+ * Returns:
+ * > 0 - on succes: the number of bytes in the message
+ * = 0 - on resource shortage: this frame sent or dropped, now
+ * the ring is full ( -> set tbusy)
+ * < 0 - on failure: other problems ( -> return failure to upper layers)
+ */
+static int XmitFrameSG(
+SK_AC *pAC, /* pointer to adapter context */
+TX_PORT *pTxPort, /* pointer to struct of port to send to */
+struct sk_buff *pMessage) /* pointer to send-message */
+{
+
+ TXD *pTxd;
+ TXD *pTxdFst;
+ TXD *pTxdLst;
+ int CurrFrag;
+ int BytesSend;
+ int IpHeaderLength;
+ int Protocol;
+ skb_frag_t *sk_frag;
+ SK_U64 PhysAddr;
+ unsigned long Flags;
+
+ spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
+#ifndef USE_TX_COMPLETE
+ FreeTxDescriptors(pAC, pTxPort);
+#endif
+ if ((skb_shinfo(pMessage)->nr_frags +1) > pTxPort->TxdRingFree) {
+ FreeTxDescriptors(pAC, pTxPort);
+ if ((skb_shinfo(pMessage)->nr_frags + 1) > pTxPort->TxdRingFree) {
+ spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
+ SK_PNMI_CNT_NO_TX_BUF(pAC, pTxPort->PortIndex);
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_TX_PROGRESS,
+ ("XmitFrameSG failed - Ring full\n"));
+ /* this message can not be sent now */
+ return(-1);
+ }
+ }
+
+ pTxd = pTxPort->pTxdRingHead;
+ pTxdFst = pTxd;
+ pTxdLst = pTxd;
+ BytesSend = 0;
+ Protocol = 0;
+
+ /*
+ ** Map the first fragment (header) into the DMA-space
+ */
+ PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
+ virt_to_page(pMessage->data),
+ ((unsigned long) pMessage->data & ~PAGE_MASK),
+ skb_headlen(pMessage),
+ PCI_DMA_TODEVICE);
+
+ pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
+ pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
+
+ /*
+ ** Does the HW need to evaluate checksum for TCP or UDP packets?
+ */
+ if (pMessage->ip_summed == CHECKSUM_HW) {
+ pTxd->TBControl = BMU_STF | BMU_STFWD | skb_headlen(pMessage);
+ /*
+ ** We have to use the opcode for tcp here, because the
+ ** opcode for udp is not working in the hardware yet
+ ** (Revision 2.0)
+ */
+ Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff);
+ if ((Protocol == C_PROTO_ID_UDP) &&
+ (pAC->GIni.GIChipRev == 0) &&
+ (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
+ pTxd->TBControl |= BMU_TCP_CHECK;
+ } else {
+ pTxd->TBControl |= BMU_UDP_CHECK;
+ }
+
+ IpHeaderLength = ((SK_U8)pMessage->data[C_OFFSET_IPHEADER] & 0xf)*4;
+ pTxd->TcpSumOfs = 0; /* PH-Checksum already claculated */
+ pTxd->TcpSumSt = C_LEN_ETHERMAC_HEADER + IpHeaderLength +
+ (Protocol == C_PROTO_ID_UDP ?
+ C_OFFSET_UDPHEADER_UDPCS :
+ C_OFFSET_TCPHEADER_TCPCS);
+ pTxd->TcpSumWr = C_LEN_ETHERMAC_HEADER + IpHeaderLength;
+ } else {
+ pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_STF |
+ skb_headlen(pMessage);
+ }
+
+ pTxd = pTxd->pNextTxd;
+ pTxPort->TxdRingFree--;
+ BytesSend += skb_headlen(pMessage);
+
+ /*
+ ** Browse over all SG fragments and map each of them into the DMA space
+ */
+ for (CurrFrag = 0; CurrFrag < skb_shinfo(pMessage)->nr_frags; CurrFrag++) {
+ sk_frag = &skb_shinfo(pMessage)->frags[CurrFrag];
+ /*
+ ** we already have the proper value in entry
+ */
+ PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
+ sk_frag->page,
+ sk_frag->page_offset,
+ sk_frag->size,
+ PCI_DMA_TODEVICE);
+
+ pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
+ pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
+ pTxd->pMBuf = pMessage;
+
+ /*
+ ** Does the HW need to evaluate checksum for TCP or UDP packets?
+ */
+ if (pMessage->ip_summed == CHECKSUM_HW) {
+ pTxd->TBControl = BMU_OWN | BMU_SW | BMU_STFWD;
+ /*
+ ** We have to use the opcode for tcp here because the
+ ** opcode for udp is not working in the hardware yet
+ ** (revision 2.0)
+ */
+ if ((Protocol == C_PROTO_ID_UDP) &&
+ (pAC->GIni.GIChipRev == 0) &&
+ (pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
+ pTxd->TBControl |= BMU_TCP_CHECK;
+ } else {
+ pTxd->TBControl |= BMU_UDP_CHECK;
+ }
+ } else {
+ pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_OWN;
+ }
+
+ /*
+ ** Do we have the last fragment?
+ */
+ if( (CurrFrag+1) == skb_shinfo(pMessage)->nr_frags ) {
+#ifdef USE_TX_COMPLETE
+ pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF | sk_frag->size;
+#else
+ pTxd->TBControl |= BMU_EOF | sk_frag->size;
+#endif
+ pTxdFst->TBControl |= BMU_OWN | BMU_SW;
+
+ } else {
+ pTxd->TBControl |= sk_frag->size;
+ }
+ pTxdLst = pTxd;
+ pTxd = pTxd->pNextTxd;
+ pTxPort->TxdRingFree--;
+ BytesSend += sk_frag->size;
+ }
+
+ /*
+ ** If previous descriptor already done, give TX start cmd
+ */
+ if ((pTxPort->pTxdRingPrev->TBControl & BMU_OWN) == 0) {
+ SK_OUT8(pTxPort->HwAddr, Q_CSR, CSR_START);
+ }
+
+ pTxPort->pTxdRingPrev = pTxdLst;
+ pTxPort->pTxdRingHead = pTxd;
+
+ spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
+
+ if (pTxPort->TxdRingFree > 0) {
+ return (BytesSend);
+ } else {
+ return (0);
+ }
+}
+
+/*****************************************************************************
+ *
+ * FreeTxDescriptors - release descriptors from the descriptor ring
+ *
+ * Description:
+ * This function releases descriptors from a transmit ring if they
+ * have been sent by the BMU.
+ * If a descriptors is sent, it can be freed and the message can
+ * be freed, too.
+ * The SOFTWARE controllable bit is used to prevent running around a
+ * completely free ring for ever. If this bit is no set in the
+ * frame (by XmitFrame), this frame has never been sent or is
+ * already freed.
+ * The Tx descriptor ring lock must be held while calling this function !!!
+ *
+ * Returns:
+ * none
+ */
+static void FreeTxDescriptors(
+SK_AC *pAC, /* pointer to the adapter context */
+TX_PORT *pTxPort) /* pointer to destination port structure */
+{
+TXD *pTxd; /* pointer to the checked descriptor */
+TXD *pNewTail; /* pointer to 'end' of the ring */
+SK_U32 Control; /* TBControl field of descriptor */
+SK_U64 PhysAddr; /* address of DMA mapping */
+
+ pNewTail = pTxPort->pTxdRingTail;
+ pTxd = pNewTail;
+ /*
+ ** loop forever; exits if BMU_SW bit not set in start frame
+ ** or BMU_OWN bit set in any frame
+ */
+ while (1) {
+ Control = pTxd->TBControl;
+ if ((Control & BMU_SW) == 0) {
+ /*
+ ** software controllable bit is set in first
+ ** fragment when given to BMU. Not set means that
+ ** this fragment was never sent or is already
+ ** freed ( -> ring completely free now).
+ */
+ pTxPort->pTxdRingTail = pTxd;
+ netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
+ return;
+ }
+ if (Control & BMU_OWN) {
+ pTxPort->pTxdRingTail = pTxd;
+ if (pTxPort->TxdRingFree > 0) {
+ netif_wake_queue(pAC->dev[pTxPort->PortIndex]);
+ }
+ return;
+ }
+
+ /*
+ ** release the DMA mapping, because until not unmapped
+ ** this buffer is considered being under control of the
+ ** adapter card!
+ */
+ PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32;
+ PhysAddr |= (SK_U64) pTxd->VDataLow;
+ pci_unmap_page(pAC->PciDev, PhysAddr,
+ pTxd->pMBuf->len,
+ PCI_DMA_TODEVICE);
+
+ if (Control & BMU_EOF)
+ DEV_KFREE_SKB_ANY(pTxd->pMBuf); /* free message */
+
+ pTxPort->TxdRingFree++;
+ pTxd->TBControl &= ~BMU_SW;
+ pTxd = pTxd->pNextTxd; /* point behind fragment with EOF */
+ } /* while(forever) */
+} /* FreeTxDescriptors */
+
+/*****************************************************************************
+ *
+ * FillRxRing - fill the receive ring with valid descriptors
+ *
+ * Description:
+ * This function fills the receive ring descriptors with data
+ * segments and makes them valid for the BMU.
+ * The active ring is filled completely, if possible.
+ * The non-active ring is filled only partial to save memory.
+ *
+ * Description of rx ring structure:
+ * head - points to the descriptor which will be used next by the BMU
+ * tail - points to the next descriptor to give to the BMU
+ *
+ * Returns: N/A
+ */
+static void FillRxRing(
+SK_AC *pAC, /* pointer to the adapter context */
+RX_PORT *pRxPort) /* ptr to port struct for which the ring
+ should be filled */
+{
+unsigned long Flags;
+
+ spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
+ while (pRxPort->RxdRingFree > pRxPort->RxFillLimit) {
+ if(!FillRxDescriptor(pAC, pRxPort))
+ break;
+ }
+ spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
+} /* FillRxRing */
+
+
+/*****************************************************************************
+ *
+ * FillRxDescriptor - fill one buffer into the receive ring
+ *
+ * Description:
+ * The function allocates a new receive buffer and
+ * puts it into the next descriptor.
+ *
+ * Returns:
+ * SK_TRUE - a buffer was added to the ring
+ * SK_FALSE - a buffer could not be added
+ */
+static SK_BOOL FillRxDescriptor(
+SK_AC *pAC, /* pointer to the adapter context struct */
+RX_PORT *pRxPort) /* ptr to port struct of ring to fill */
+{
+struct sk_buff *pMsgBlock; /* pointer to a new message block */
+RXD *pRxd; /* the rxd to fill */
+SK_U16 Length; /* data fragment length */
+SK_U64 PhysAddr; /* physical address of a rx buffer */
+
+ pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC);
+ if (pMsgBlock == NULL) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_ENTRY,
+ ("%s: Allocation of rx buffer failed !\n",
+ pAC->dev[pRxPort->PortIndex]->name));
+ SK_PNMI_CNT_NO_RX_BUF(pAC, pRxPort->PortIndex);
+ return(SK_FALSE);
+ }
+ skb_reserve(pMsgBlock, 2); /* to align IP frames */
+ /* skb allocated ok, so add buffer */
+ pRxd = pRxPort->pRxdRingTail;
+ pRxPort->pRxdRingTail = pRxd->pNextRxd;
+ pRxPort->RxdRingFree--;
+ Length = pAC->RxBufSize;
+ PhysAddr = (SK_U64) pci_map_page(pAC->PciDev,
+ virt_to_page(pMsgBlock->data),
+ ((unsigned long) pMsgBlock->data &
+ ~PAGE_MASK),
+ pAC->RxBufSize - 2,
+ PCI_DMA_FROMDEVICE);
+
+ pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff);
+ pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
+ pRxd->pMBuf = pMsgBlock;
+ pRxd->RBControl = BMU_OWN |
+ BMU_STF |
+ BMU_IRQ_EOF |
+ BMU_TCP_CHECK |
+ Length;
+ return (SK_TRUE);
+
+} /* FillRxDescriptor */
+
+
+/*****************************************************************************
+ *
+ * ReQueueRxBuffer - fill one buffer back into the receive ring
+ *
+ * Description:
+ * Fill a given buffer back into the rx ring. The buffer
+ * has been previously allocated and aligned, and its phys.
+ * address calculated, so this is no more necessary.
+ *
+ * Returns: N/A
+ */
+static void ReQueueRxBuffer(
+SK_AC *pAC, /* pointer to the adapter context struct */
+RX_PORT *pRxPort, /* ptr to port struct of ring to fill */
+struct sk_buff *pMsg, /* pointer to the buffer */
+SK_U32 PhysHigh, /* phys address high dword */
+SK_U32 PhysLow) /* phys address low dword */
+{
+RXD *pRxd; /* the rxd to fill */
+SK_U16 Length; /* data fragment length */
+
+ pRxd = pRxPort->pRxdRingTail;
+ pRxPort->pRxdRingTail = pRxd->pNextRxd;
+ pRxPort->RxdRingFree--;
+ Length = pAC->RxBufSize;
+
+ pRxd->VDataLow = PhysLow;
+ pRxd->VDataHigh = PhysHigh;
+ pRxd->pMBuf = pMsg;
+ pRxd->RBControl = BMU_OWN |
+ BMU_STF |
+ BMU_IRQ_EOF |
+ BMU_TCP_CHECK |
+ Length;
+ return;
+} /* ReQueueRxBuffer */
+
+/*****************************************************************************
+ *
+ * ReceiveIrq - handle a receive IRQ
+ *
+ * Description:
+ * This function is called when a receive IRQ is set.
+ * It walks the receive descriptor ring and sends up all
+ * frames that are complete.
+ *
+ * Returns: N/A
+ */
+static void ReceiveIrq(
+ SK_AC *pAC, /* pointer to adapter context */
+ RX_PORT *pRxPort, /* pointer to receive port struct */
+ SK_BOOL SlowPathLock) /* indicates if SlowPathLock is needed */
+{
+RXD *pRxd; /* pointer to receive descriptors */
+SK_U32 Control; /* control field of descriptor */
+struct sk_buff *pMsg; /* pointer to message holding frame */
+struct sk_buff *pNewMsg; /* pointer to a new message for copying frame */
+int FrameLength; /* total length of received frame */
+int IpFrameLength;
+SK_MBUF *pRlmtMbuf; /* ptr to a buffer for giving a frame to rlmt */
+SK_EVPARA EvPara; /* an event parameter union */
+unsigned long Flags; /* for spin lock */
+int PortIndex = pRxPort->PortIndex;
+unsigned int Offset;
+unsigned int NumBytes;
+unsigned int ForRlmt;
+SK_BOOL IsBc;
+SK_BOOL IsMc;
+SK_BOOL IsBadFrame; /* Bad frame */
+
+SK_U32 FrameStat;
+unsigned short Csum1;
+unsigned short Csum2;
+unsigned short Type;
+int Result;
+SK_U64 PhysAddr;
+
+rx_start:
+ /* do forever; exit if BMU_OWN found */
+ for ( pRxd = pRxPort->pRxdRingHead ;
+ pRxPort->RxdRingFree < pAC->RxDescrPerRing ;
+ pRxd = pRxd->pNextRxd,
+ pRxPort->pRxdRingHead = pRxd,
+ pRxPort->RxdRingFree ++) {
+
+ /*
+ * For a better understanding of this loop
+ * Go through every descriptor beginning at the head
+ * Please note: the ring might be completely received so the OWN bit
+ * set is not a good crirteria to leave that loop.
+ * Therefore the RingFree counter is used.
+ * On entry of this loop pRxd is a pointer to the Rxd that needs
+ * to be checked next.
+ */
+
+ Control = pRxd->RBControl;
+
+ /* check if this descriptor is ready */
+ if ((Control & BMU_OWN) != 0) {
+ /* this descriptor is not yet ready */
+ /* This is the usual end of the loop */
+ /* We don't need to start the ring again */
+ FillRxRing(pAC, pRxPort);
+ return;
+ }
+ pAC->DynIrqModInfo.NbrProcessedDescr++;
+
+ /* get length of frame and check it */
+ FrameLength = Control & BMU_BBC;
+ if (FrameLength > pAC->RxBufSize) {
+ goto rx_failed;
+ }
+
+ /* check for STF and EOF */
+ if ((Control & (BMU_STF | BMU_EOF)) != (BMU_STF | BMU_EOF)) {
+ goto rx_failed;
+ }
+
+ /* here we have a complete frame in the ring */
+ pMsg = pRxd->pMBuf;
+
+ FrameStat = pRxd->FrameStat;
+
+ /* check for frame length mismatch */
+#define XMR_FS_LEN_SHIFT 18
+#define GMR_FS_LEN_SHIFT 16
+ if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+ if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_RX_PROGRESS,
+ ("skge: Frame length mismatch (%u/%u).\n",
+ FrameLength,
+ (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
+ goto rx_failed;
+ }
+ }
+ else {
+ if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_RX_PROGRESS,
+ ("skge: Frame length mismatch (%u/%u).\n",
+ FrameLength,
+ (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)));
+ goto rx_failed;
+ }
+ }
+
+ /* Set Rx Status */
+ if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) {
+ IsBc = (FrameStat & XMR_FS_BC) != 0;
+ IsMc = (FrameStat & XMR_FS_MC) != 0;
+ IsBadFrame = (FrameStat &
+ (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0;
+ } else {
+ IsBc = (FrameStat & GMR_FS_BC) != 0;
+ IsMc = (FrameStat & GMR_FS_MC) != 0;
+ IsBadFrame = (((FrameStat & GMR_FS_ANY_ERR) != 0) ||
+ ((FrameStat & GMR_FS_RX_OK) == 0));
+ }
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
+ ("Received frame of length %d on port %d\n",
+ FrameLength, PortIndex));
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 0,
+ ("Number of free rx descriptors: %d\n",
+ pRxPort->RxdRingFree));
+/* DumpMsg(pMsg, "Rx"); */
+
+ if ((Control & BMU_STAT_VAL) != BMU_STAT_VAL || (IsBadFrame)) {
+#if 0
+ (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) {
+#endif
+ /* there is a receive error in this frame */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_RX_PROGRESS,
+ ("skge: Error in received frame, dropped!\n"
+ "Control: %x\nRxStat: %x\n",
+ Control, FrameStat));
+
+ ReQueueRxBuffer(pAC, pRxPort, pMsg,
+ pRxd->VDataHigh, pRxd->VDataLow);
+
+ continue;
+ }
+
+ /*
+ * if short frame then copy data to reduce memory waste
+ */
+ if ((FrameLength < SK_COPY_THRESHOLD) &&
+ ((pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC)) != NULL)) {
+ /*
+ * Short frame detected and allocation successfull
+ */
+ /* use new skb and copy data */
+ skb_reserve(pNewMsg, 2);
+ skb_put(pNewMsg, FrameLength);
+ PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+ PhysAddr |= (SK_U64) pRxd->VDataLow;
+
+ pci_dma_sync_single_for_cpu(pAC->PciDev,
+ (dma_addr_t) PhysAddr,
+ FrameLength,
+ PCI_DMA_FROMDEVICE);
+ eth_copy_and_sum(pNewMsg, pMsg->data,
+ FrameLength, 0);
+ pci_dma_sync_single_for_device(pAC->PciDev,
+ (dma_addr_t) PhysAddr,
+ FrameLength,
+ PCI_DMA_FROMDEVICE);
+ ReQueueRxBuffer(pAC, pRxPort, pMsg,
+ pRxd->VDataHigh, pRxd->VDataLow);
+
+ pMsg = pNewMsg;
+
+ }
+ else {
+ /*
+ * if large frame, or SKB allocation failed, pass
+ * the SKB directly to the networking
+ */
+
+ PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+ PhysAddr |= (SK_U64) pRxd->VDataLow;
+
+ /* release the DMA mapping */
+ pci_unmap_single(pAC->PciDev,
+ PhysAddr,
+ pAC->RxBufSize - 2,
+ PCI_DMA_FROMDEVICE);
+
+ /* set length in message */
+ skb_put(pMsg, FrameLength);
+ /* hardware checksum */
+ Type = ntohs(*((short*)&pMsg->data[12]));
+
+#ifdef USE_SK_RX_CHECKSUM
+ if (Type == 0x800) {
+ Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff);
+ Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff);
+ IpFrameLength = (int) ntohs((unsigned short)
+ ((unsigned short *) pMsg->data)[8]);
+
+ /*
+ * Test: If frame is padded, a check is not possible!
+ * Frame not padded? Length difference must be 14 (0xe)!
+ */
+ if ((FrameLength - IpFrameLength) != 0xe) {
+ /* Frame padded => TCP offload not possible! */
+ pMsg->ip_summed = CHECKSUM_NONE;
+ } else {
+ /* Frame not padded => TCP offload! */
+ if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) &&
+ (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) ||
+ (pAC->ChipsetType)) {
+ Result = SkCsGetReceiveInfo(pAC,
+ &pMsg->data[14],
+ Csum1, Csum2, pRxPort->PortIndex);
+ if (Result ==
+ SKCS_STATUS_IP_FRAGMENT ||
+ Result ==
+ SKCS_STATUS_IP_CSUM_OK ||
+ Result ==
+ SKCS_STATUS_TCP_CSUM_OK ||
+ Result ==
+ SKCS_STATUS_UDP_CSUM_OK) {
+ pMsg->ip_summed =
+ CHECKSUM_UNNECESSARY;
+ }
+ else if (Result ==
+ SKCS_STATUS_TCP_CSUM_ERROR ||
+ Result ==
+ SKCS_STATUS_UDP_CSUM_ERROR ||
+ Result ==
+ SKCS_STATUS_IP_CSUM_ERROR_UDP ||
+ Result ==
+ SKCS_STATUS_IP_CSUM_ERROR_TCP ||
+ Result ==
+ SKCS_STATUS_IP_CSUM_ERROR ) {
+ /* HW Checksum error */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_RX_PROGRESS,
+ ("skge: CRC error. Frame dropped!\n"));
+ goto rx_failed;
+ } else {
+ pMsg->ip_summed =
+ CHECKSUM_NONE;
+ }
+ }/* checksumControl calculation valid */
+ } /* Frame length check */
+ } /* IP frame */
+#else
+ pMsg->ip_summed = CHECKSUM_NONE;
+#endif
+ } /* frame > SK_COPY_TRESHOLD */
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V"));
+ ForRlmt = SK_RLMT_RX_PROTOCOL;
+#if 0
+ IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC;
+#endif
+ SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength,
+ IsBc, &Offset, &NumBytes);
+ if (NumBytes != 0) {
+#if 0
+ IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC;
+#endif
+ SK_RLMT_LOOKAHEAD(pAC, PortIndex,
+ &pMsg->data[Offset],
+ IsBc, IsMc, &ForRlmt);
+ }
+ if (ForRlmt == SK_RLMT_RX_PROTOCOL) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W"));
+ /* send up only frames from active port */
+ if ((PortIndex == pAC->ActivePort) ||
+ (pAC->RlmtNets == 2)) {
+ /* frame for upper layer */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U"));
+#ifdef xDEBUG
+ DumpMsg(pMsg, "Rx");
+#endif
+ SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,
+ FrameLength, pRxPort->PortIndex);
+
+ pMsg->dev = pAC->dev[pRxPort->PortIndex];
+ pMsg->protocol = eth_type_trans(pMsg,
+ pAC->dev[pRxPort->PortIndex]);
+ netif_rx(pMsg);
+ pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
+ }
+ else {
+ /* drop frame */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_RX_PROGRESS,
+ ("D"));
+ DEV_KFREE_SKB(pMsg);
+ }
+
+ } /* if not for rlmt */
+ else {
+ /* packet for rlmt */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_RX_PROGRESS, ("R"));
+ pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC,
+ pAC->IoBase, FrameLength);
+ if (pRlmtMbuf != NULL) {
+ pRlmtMbuf->pNext = NULL;
+ pRlmtMbuf->Length = FrameLength;
+ pRlmtMbuf->PortIdx = PortIndex;
+ EvPara.pParaPtr = pRlmtMbuf;
+ memcpy((char*)(pRlmtMbuf->pData),
+ (char*)(pMsg->data),
+ FrameLength);
+
+ /* SlowPathLock needed? */
+ if (SlowPathLock == SK_TRUE) {
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+ SkEventQueue(pAC, SKGE_RLMT,
+ SK_RLMT_PACKET_RECEIVED,
+ EvPara);
+ pAC->CheckQueue = SK_TRUE;
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+ } else {
+ SkEventQueue(pAC, SKGE_RLMT,
+ SK_RLMT_PACKET_RECEIVED,
+ EvPara);
+ pAC->CheckQueue = SK_TRUE;
+ }
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
+ SK_DBGCAT_DRV_RX_PROGRESS,
+ ("Q"));
+ }
+ if ((pAC->dev[pRxPort->PortIndex]->flags &
+ (IFF_PROMISC | IFF_ALLMULTI)) != 0 ||
+ (ForRlmt & SK_RLMT_RX_PROTOCOL) ==
+ SK_RLMT_RX_PROTOCOL) {
+ pMsg->dev = pAC->dev[pRxPort->PortIndex];
+ pMsg->protocol = eth_type_trans(pMsg,
+ pAC->dev[pRxPort->PortIndex]);
+ netif_rx(pMsg);
+ pAC->dev[pRxPort->PortIndex]->last_rx = jiffies;
+ }
+ else {
+ DEV_KFREE_SKB(pMsg);
+ }
+
+ } /* if packet for rlmt */
+ } /* for ... scanning the RXD ring */
+
+ /* RXD ring is empty -> fill and restart */
+ FillRxRing(pAC, pRxPort);
+ /* do not start if called from Close */
+ if (pAC->BoardLevel > SK_INIT_DATA) {
+ ClearAndStartRx(pAC, PortIndex);
+ }
+ return;
+
+rx_failed:
+ /* remove error frame */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
+ ("Schrottdescriptor, length: 0x%x\n", FrameLength));
+
+ /* release the DMA mapping */
+
+ PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+ PhysAddr |= (SK_U64) pRxd->VDataLow;
+ pci_unmap_page(pAC->PciDev,
+ PhysAddr,
+ pAC->RxBufSize - 2,
+ PCI_DMA_FROMDEVICE);
+ DEV_KFREE_SKB_IRQ(pRxd->pMBuf);
+ pRxd->pMBuf = NULL;
+ pRxPort->RxdRingFree++;
+ pRxPort->pRxdRingHead = pRxd->pNextRxd;
+ goto rx_start;
+
+} /* ReceiveIrq */
+
+
+/*****************************************************************************
+ *
+ * ClearAndStartRx - give a start receive command to BMU, clear IRQ
+ *
+ * Description:
+ * This function sends a start command and a clear interrupt
+ * command for one receive queue to the BMU.
+ *
+ * Returns: N/A
+ * none
+ */
+static void ClearAndStartRx(
+SK_AC *pAC, /* pointer to the adapter context */
+int PortIndex) /* index of the receive port (XMAC) */
+{
+ SK_OUT8(pAC->IoBase,
+ RxQueueAddr[PortIndex]+Q_CSR,
+ CSR_START | CSR_IRQ_CL_F);
+} /* ClearAndStartRx */
+
+
+/*****************************************************************************
+ *
+ * ClearTxIrq - give a clear transmit IRQ command to BMU
+ *
+ * Description:
+ * This function sends a clear tx IRQ command for one
+ * transmit queue to the BMU.
+ *
+ * Returns: N/A
+ */
+static void ClearTxIrq(
+SK_AC *pAC, /* pointer to the adapter context */
+int PortIndex, /* index of the transmit port (XMAC) */
+int Prio) /* priority or normal queue */
+{
+ SK_OUT8(pAC->IoBase,
+ TxQueueAddr[PortIndex][Prio]+Q_CSR,
+ CSR_IRQ_CL_F);
+} /* ClearTxIrq */
+
+
+/*****************************************************************************
+ *
+ * ClearRxRing - remove all buffers from the receive ring
+ *
+ * Description:
+ * This function removes all receive buffers from the ring.
+ * The receive BMU must be stopped before calling this function.
+ *
+ * Returns: N/A
+ */
+static void ClearRxRing(
+SK_AC *pAC, /* pointer to adapter context */
+RX_PORT *pRxPort) /* pointer to rx port struct */
+{
+RXD *pRxd; /* pointer to the current descriptor */
+unsigned long Flags;
+SK_U64 PhysAddr;
+
+ if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) {
+ return;
+ }
+ spin_lock_irqsave(&pRxPort->RxDesRingLock, Flags);
+ pRxd = pRxPort->pRxdRingHead;
+ do {
+ if (pRxd->pMBuf != NULL) {
+
+ PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32;
+ PhysAddr |= (SK_U64) pRxd->VDataLow;
+ pci_unmap_page(pAC->PciDev,
+ PhysAddr,
+ pAC->RxBufSize - 2,
+ PCI_DMA_FROMDEVICE);
+ DEV_KFREE_SKB(pRxd->pMBuf);
+ pRxd->pMBuf = NULL;
+ }
+ pRxd->RBControl &= BMU_OWN;
+ pRxd = pRxd->pNextRxd;
+ pRxPort->RxdRingFree++;
+ } while (pRxd != pRxPort->pRxdRingTail);
+ pRxPort->pRxdRingTail = pRxPort->pRxdRingHead;
+ spin_unlock_irqrestore(&pRxPort->RxDesRingLock, Flags);
+} /* ClearRxRing */
+
+/*****************************************************************************
+ *
+ * ClearTxRing - remove all buffers from the transmit ring
+ *
+ * Description:
+ * This function removes all transmit buffers from the ring.
+ * The transmit BMU must be stopped before calling this function
+ * and transmitting at the upper level must be disabled.
+ * The BMU own bit of all descriptors is cleared, the rest is
+ * done by calling FreeTxDescriptors.
+ *
+ * Returns: N/A
+ */
+static void ClearTxRing(
+SK_AC *pAC, /* pointer to adapter context */
+TX_PORT *pTxPort) /* pointer to tx prt struct */
+{
+TXD *pTxd; /* pointer to the current descriptor */
+int i;
+unsigned long Flags;
+
+ spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
+ pTxd = pTxPort->pTxdRingHead;
+ for (i=0; i<pAC->TxDescrPerRing; i++) {
+ pTxd->TBControl &= ~BMU_OWN;
+ pTxd = pTxd->pNextTxd;
+ }
+ FreeTxDescriptors(pAC, pTxPort);
+ spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
+} /* ClearTxRing */
+
+/*****************************************************************************
+ *
+ * SkGeSetMacAddr - Set the hardware MAC address
+ *
+ * Description:
+ * This function sets the MAC address used by the adapter.
+ *
+ * Returns:
+ * 0, if everything is ok
+ * !=0, on error
+ */
+static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p)
+{
+
+DEV_NET *pNet = netdev_priv(dev);
+SK_AC *pAC = pNet->pAC;
+
+struct sockaddr *addr = p;
+unsigned long Flags;
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("SkGeSetMacAddr starts now...\n"));
+ if(netif_running(dev))
+ return -EBUSY;
+
+ memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
+
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+
+ if (pAC->RlmtNets == 2)
+ SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr,
+ (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
+ else
+ SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort,
+ (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS);
+
+
+
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+ return 0;
+} /* SkGeSetMacAddr */
+
+
+/*****************************************************************************
+ *
+ * SkGeSetRxMode - set receive mode
+ *
+ * Description:
+ * This function sets the receive mode of an adapter. The adapter
+ * supports promiscuous mode, allmulticast mode and a number of
+ * multicast addresses. If more multicast addresses the available
+ * are selected, a hash function in the hardware is used.
+ *
+ * Returns:
+ * 0, if everything is ok
+ * !=0, on error
+ */
+static void SkGeSetRxMode(struct SK_NET_DEVICE *dev)
+{
+
+DEV_NET *pNet;
+SK_AC *pAC;
+
+struct dev_mc_list *pMcList;
+int i;
+int PortIdx;
+unsigned long Flags;
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("SkGeSetRxMode starts now... "));
+
+ pNet = netdev_priv(dev);
+ pAC = pNet->pAC;
+ if (pAC->RlmtNets == 1)
+ PortIdx = pAC->ActivePort;
+ else
+ PortIdx = pNet->NetNr;
+
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+ if (dev->flags & IFF_PROMISC) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("PROMISCUOUS mode\n"));
+ SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
+ SK_PROM_MODE_LLC);
+ } else if (dev->flags & IFF_ALLMULTI) {
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("ALLMULTI mode\n"));
+ SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
+ SK_PROM_MODE_ALL_MC);
+ } else {
+ SkAddrPromiscuousChange(pAC, pAC->IoBase, PortIdx,
+ SK_PROM_MODE_NONE);
+ SkAddrMcClear(pAC, pAC->IoBase, PortIdx, 0);
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("Number of MC entries: %d ", dev->mc_count));
+
+ pMcList = dev->mc_list;
+ for (i=0; i<dev->mc_count; i++, pMcList = pMcList->next) {
+ SkAddrMcAdd(pAC, pAC->IoBase, PortIdx,
+ (SK_MAC_ADDR*)pMcList->dmi_addr, 0);
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MCA,
+ ("%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pMcList->dmi_addr[0],
+ pMcList->dmi_addr[1],
+ pMcList->dmi_addr[2],
+ pMcList->dmi_addr[3],
+ pMcList->dmi_addr[4],
+ pMcList->dmi_addr[5]));
+ }
+ SkAddrMcUpdate(pAC, pAC->IoBase, PortIdx);
+ }
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+ return;
+} /* SkGeSetRxMode */
+
+
+/*****************************************************************************
+ *
+ * SkGeChangeMtu - set the MTU to another value
+ *
+ * Description:
+ * This function sets is called whenever the MTU size is changed
+ * (ifconfig mtu xxx dev ethX). If the MTU is bigger than standard
+ * ethernet MTU size, long frame support is activated.
+ *
+ * Returns:
+ * 0, if everything is ok
+ * !=0, on error
+ */
+static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
+{
+DEV_NET *pNet;
+DEV_NET *pOtherNet;
+SK_AC *pAC;
+unsigned long Flags;
+int i;
+SK_EVPARA EvPara;
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("SkGeChangeMtu starts now...\n"));
+
+ pNet = netdev_priv(dev);
+ pAC = pNet->pAC;
+
+ if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) {
+ return -EINVAL;
+ }
+
+ if(pAC->BoardLevel != SK_INIT_RUN) {
+ return -EINVAL;
+ }
+
+#ifdef SK_DIAG_SUPPORT
+ if (pAC->DiagModeActive == DIAG_ACTIVE) {
+ if (pAC->DiagFlowCtrl == SK_FALSE) {
+ return -1; /* still in use, deny any actions of MTU */
+ } else {
+ pAC->DiagFlowCtrl = SK_FALSE;
+ }
+ }
+#endif
+
+ pNet->Mtu = NewMtu;
+ pOtherNet = netdev_priv(pAC->dev[1 - pNet->NetNr]);
+ if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
+ return(0);
+ }
+
+ pAC->RxBufSize = NewMtu + 32;
+ dev->mtu = NewMtu;
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("New MTU: %d\n", NewMtu));
+
+ /*
+ ** Prevent any reconfiguration while changing the MTU
+ ** by disabling any interrupts
+ */
+ SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+
+ /*
+ ** Notify RLMT that any ports are to be stopped
+ */
+ EvPara.Para32[0] = 0;
+ EvPara.Para32[1] = -1;
+ if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+ EvPara.Para32[0] = 1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+ } else {
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara);
+ }
+
+ /*
+ ** After calling the SkEventDispatcher(), RLMT is aware about
+ ** the stopped ports -> configuration can take place!
+ */
+ SkEventDispatcher(pAC, pAC->IoBase);
+
+ for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
+ netif_stop_queue(pAC->dev[i]);
+
+ }
+
+ /*
+ ** Depending on the desired MTU size change, a different number of
+ ** RX buffers need to be allocated
+ */
+ if (NewMtu > 1500) {
+ /*
+ ** Use less rx buffers
+ */
+ for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+ pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
+ (pAC->RxDescrPerRing / 4);
+ } else {
+ if (i == pAC->ActivePort) {
+ pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
+ (pAC->RxDescrPerRing / 4);
+ } else {
+ pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
+ (pAC->RxDescrPerRing / 10);
+ }
+ }
+ }
+ } else {
+ /*
+ ** Use the normal amount of rx buffers
+ */
+ for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+ pAC->RxPort[i].RxFillLimit = 1;
+ } else {
+ if (i == pAC->ActivePort) {
+ pAC->RxPort[i].RxFillLimit = 1;
+ } else {
+ pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing -
+ (pAC->RxDescrPerRing / 4);
+ }
+ }
+ }
+ }
+
+ SkGeDeInit(pAC, pAC->IoBase);
+
+ /*
+ ** enable/disable hardware support for long frames
+ */
+ if (NewMtu > 1500) {
+// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */
+ pAC->GIni.GIPortUsage = SK_JUMBO_LINK;
+ } else {
+ if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+ pAC->GIni.GIPortUsage = SK_MUL_LINK;
+ } else {
+ pAC->GIni.GIPortUsage = SK_RED_LINK;
+ }
+ }
+
+ SkGeInit( pAC, pAC->IoBase, SK_INIT_IO);
+ SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
+ SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
+ SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO);
+ SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO);
+ SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO);
+ SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);
+
+ /*
+ ** tschilling:
+ ** Speed and others are set back to default in level 1 init!
+ */
+ GetConfiguration(pAC);
+
+ SkGeInit( pAC, pAC->IoBase, SK_INIT_RUN);
+ SkI2cInit( pAC, pAC->IoBase, SK_INIT_RUN);
+ SkEventInit(pAC, pAC->IoBase, SK_INIT_RUN);
+ SkPnmiInit( pAC, pAC->IoBase, SK_INIT_RUN);
+ SkAddrInit( pAC, pAC->IoBase, SK_INIT_RUN);
+ SkRlmtInit( pAC, pAC->IoBase, SK_INIT_RUN);
+ SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN);
+
+ /*
+ ** clear and reinit the rx rings here
+ */
+ for (i=0; i<pAC->GIni.GIMacsFound; i++) {
+ ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE);
+ ClearRxRing(pAC, &pAC->RxPort[i]);
+ FillRxRing(pAC, &pAC->RxPort[i]);
+
+ /*
+ ** Enable transmit descriptor polling
+ */
+ SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE);
+ FillRxRing(pAC, &pAC->RxPort[i]);
+ };
+
+ SkGeYellowLED(pAC, pAC->IoBase, 1);
+ SkDimEnableModerationIfNeeded(pAC);
+ SkDimDisplayModerationSettings(pAC);
+
+ netif_start_queue(pAC->dev[pNet->PortNr]);
+ for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) {
+ spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock);
+ }
+
+ /*
+ ** Enable Interrupts again
+ */
+ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask);
+ SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK);
+
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+ SkEventDispatcher(pAC, pAC->IoBase);
+
+ /*
+ ** Notify RLMT about the changing and restarting one (or more) ports
+ */
+ if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
+ EvPara.Para32[0] = pAC->RlmtNets;
+ EvPara.Para32[1] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, EvPara);
+ EvPara.Para32[0] = pNet->PortNr;
+ EvPara.Para32[1] = -1;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+
+ if (pOtherNet->Up) {
+ EvPara.Para32[0] = pOtherNet->PortNr;
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+ }
+ } else {
+ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
+ }
+
+ SkEventDispatcher(pAC, pAC->IoBase);
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+
+ /*
+ ** While testing this driver with latest kernel 2.5 (2.5.70), it
+ ** seems as if upper layers have a problem to handle a successful
+ ** return value of '0'. If such a zero is returned, the complete
+ ** system hangs for several minutes (!), which is in acceptable.
+ **
+ ** Currently it is not clear, what the exact reason for this problem
+ ** is. The implemented workaround for 2.5 is to return the desired
+ ** new MTU size if all needed changes for the new MTU size where
+ ** performed. In kernels 2.2 and 2.4, a zero value is returned,
+ ** which indicates the successful change of the mtu-size.
+ */
+ return NewMtu;
+
+} /* SkGeChangeMtu */
+
+
+/*****************************************************************************
+ *
+ * SkGeStats - return ethernet device statistics
+ *
+ * Description:
+ * This function return statistic data about the ethernet device
+ * to the operating system.
+ *
+ * Returns:
+ * pointer to the statistic structure.
+ */
+static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev)
+{
+DEV_NET *pNet = netdev_priv(dev);
+SK_AC *pAC = pNet->pAC;
+SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */
+SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */
+SK_PNMI_CONF *pPnmiConf; /* pointer to virtual link config. */
+unsigned int Size; /* size of pnmi struct */
+unsigned long Flags; /* for spin lock */
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("SkGeStats starts now...\n"));
+ pPnmiStruct = &pAC->PnmiStruct;
+
+#ifdef SK_DIAG_SUPPORT
+ if ((pAC->DiagModeActive == DIAG_NOTACTIVE) &&
+ (pAC->BoardLevel == SK_INIT_RUN)) {
+#endif
+ SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA));
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+ Size = SK_PNMI_STRUCT_SIZE;
+ SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr);
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+#ifdef SK_DIAG_SUPPORT
+ }
+#endif
+
+ pPnmiStat = &pPnmiStruct->Stat[0];
+ pPnmiConf = &pPnmiStruct->Conf[0];
+
+ pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF;
+ pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF;
+ pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
+ pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
+
+ if (pNet->Mtu <= 1500) {
+ pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
+ } else {
+ pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
+ pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF);
+ }
+
+
+ if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12)
+ pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts;
+
+ pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
+ pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF;
+ pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF;
+ pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF;
+ pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF;
+
+ /* detailed rx_errors: */
+ pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF;
+ pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
+ pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF;
+ pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF;
+ pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF;
+ pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF;
+
+ /* detailed tx_errors */
+ pAC->stats.tx_aborted_errors = (SK_U32) 0;
+ pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
+ pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF;
+ pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF;
+ pAC->stats.tx_window_errors = (SK_U32) 0;
+
+ return(&pAC->stats);
+} /* SkGeStats */
+
+
+/*****************************************************************************
+ *
+ * SkGeIoctl - IO-control function
+ *
+ * Description:
+ * This function is called if an ioctl is issued on the device.
+ * There are three subfunction for reading, writing and test-writing
+ * the private MIB data structure (usefull for SysKonnect-internal tools).
+ *
+ * Returns:
+ * 0, if everything is ok
+ * !=0, on error
+ */
+static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd)
+{
+DEV_NET *pNet;
+SK_AC *pAC;
+void *pMemBuf;
+struct pci_dev *pdev = NULL;
+SK_GE_IOCTL Ioctl;
+unsigned int Err = 0;
+int Size = 0;
+int Ret = 0;
+unsigned int Length = 0;
+int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32);
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("SkGeIoctl starts now...\n"));
+
+ pNet = netdev_priv(dev);
+ pAC = pNet->pAC;
+
+ if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) {
+ return -EFAULT;
+ }
+
+ switch(cmd) {
+ case SK_IOCTL_SETMIB:
+ case SK_IOCTL_PRESETMIB:
+ if (!capable(CAP_NET_ADMIN)) return -EPERM;
+ case SK_IOCTL_GETMIB:
+ if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData,
+ Ioctl.Len<sizeof(pAC->PnmiStruct)?
+ Ioctl.Len : sizeof(pAC->PnmiStruct))) {
+ return -EFAULT;
+ }
+ Size = SkGeIocMib(pNet, Ioctl.Len, cmd);
+ if(copy_to_user(Ioctl.pData, &pAC->PnmiStruct,
+ Ioctl.Len<Size? Ioctl.Len : Size)) {
+ return -EFAULT;
+ }
+ Ioctl.Len = Size;
+ if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
+ return -EFAULT;
+ }
+ break;
+ case SK_IOCTL_GEN:
+ if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
+ Length = Ioctl.Len;
+ } else {
+ Length = sizeof(pAC->PnmiStruct) + HeaderLength;
+ }
+ if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
+ return -ENOMEM;
+ }
+ if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
+ Err = -EFAULT;
+ goto fault_gen;
+ }
+ if ((Ret = SkPnmiGenIoctl(pAC, pAC->IoBase, pMemBuf, &Length, 0)) < 0) {
+ Err = -EFAULT;
+ goto fault_gen;
+ }
+ if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
+ Err = -EFAULT;
+ goto fault_gen;
+ }
+ Ioctl.Len = Length;
+ if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
+ Err = -EFAULT;
+ goto fault_gen;
+ }
+fault_gen:
+ kfree(pMemBuf); /* cleanup everything */
+ break;
+#ifdef SK_DIAG_SUPPORT
+ case SK_IOCTL_DIAG:
+ if (!capable(CAP_NET_ADMIN)) return -EPERM;
+ if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) {
+ Length = Ioctl.Len;
+ } else {
+ Length = sizeof(pAC->PnmiStruct) + HeaderLength;
+ }
+ if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
+ return -ENOMEM;
+ }
+ if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
+ Err = -EFAULT;
+ goto fault_diag;
+ }
+ pdev = pAC->PciDev;
+ Length = 3 * sizeof(SK_U32); /* Error, Bus and Device */
+ /*
+ ** While coding this new IOCTL interface, only a few lines of code
+ ** are to to be added. Therefore no dedicated function has been
+ ** added. If more functionality is added, a separate function
+ ** should be used...
+ */
+ * ((SK_U32 *)pMemBuf) = 0;
+ * ((SK_U32 *)pMemBuf + 1) = pdev->bus->number;
+ * ((SK_U32 *)pMemBuf + 2) = ParseDeviceNbrFromSlotName(pci_name(pdev));
+ if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
+ Err = -EFAULT;
+ goto fault_diag;
+ }
+ Ioctl.Len = Length;
+ if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
+ Err = -EFAULT;
+ goto fault_diag;
+ }
+fault_diag:
+ kfree(pMemBuf); /* cleanup everything */
+ break;
+#endif
+ default:
+ Err = -EOPNOTSUPP;
+ }
+
+ return(Err);
+
+} /* SkGeIoctl */
+
+
+/*****************************************************************************
+ *
+ * SkGeIocMib - handle a GetMib, SetMib- or PresetMib-ioctl message
+ *
+ * Description:
+ * This function reads/writes the MIB data using PNMI (Private Network
+ * Management Interface).
+ * The destination for the data must be provided with the
+ * ioctl call and is given to the driver in the form of
+ * a user space address.
+ * Copying from the user-provided data area into kernel messages
+ * and back is done by copy_from_user and copy_to_user calls in
+ * SkGeIoctl.
+ *
+ * Returns:
+ * returned size from PNMI call
+ */
+static int SkGeIocMib(
+DEV_NET *pNet, /* pointer to the adapter context */
+unsigned int Size, /* length of ioctl data */
+int mode) /* flag for set/preset */
+{
+unsigned long Flags; /* for spin lock */
+SK_AC *pAC;
+
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("SkGeIocMib starts now...\n"));
+ pAC = pNet->pAC;
+ /* access MIB */
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+ switch(mode) {
+ case SK_IOCTL_GETMIB:
+ SkPnmiGetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
+ pNet->NetNr);
+ break;
+ case SK_IOCTL_PRESETMIB:
+ SkPnmiPreSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
+ pNet->NetNr);
+ break;
+ case SK_IOCTL_SETMIB:
+ SkPnmiSetStruct(pAC, pAC->IoBase, &pAC->PnmiStruct, &Size,
+ pNet->NetNr);
+ break;
+ default:
+ break;
+ }
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
+ ("MIB data access succeeded\n"));
+ return (Size);
+} /* SkGeIocMib */
+
+
+/*****************************************************************************
+ *
+ * GetConfiguration - read configuration information
+ *
+ * Description:
+ * This function reads per-adapter configuration information from
+ * the options provided on the command line.
+ *
+ * Returns:
+ * none
+ */
+static void GetConfiguration(
+SK_AC *pAC) /* pointer to the adapter context structure */
+{
+SK_I32 Port; /* preferred port */
+SK_BOOL AutoSet;
+SK_BOOL DupSet;
+int LinkSpeed = SK_LSPEED_AUTO; /* Link speed */
+int AutoNeg = 1; /* autoneg off (0) or on (1) */
+int DuplexCap = 0; /* 0=both,1=full,2=half */
+int FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; /* FlowControl */
+int MSMode = SK_MS_MODE_AUTO; /* master/slave mode */
+
+SK_BOOL IsConTypeDefined = SK_TRUE;
+SK_BOOL IsLinkSpeedDefined = SK_TRUE;
+SK_BOOL IsFlowCtrlDefined = SK_TRUE;
+SK_BOOL IsRoleDefined = SK_TRUE;
+SK_BOOL IsModeDefined = SK_TRUE;
+/*
+ * The two parameters AutoNeg. and DuplexCap. map to one configuration
+ * parameter. The mapping is described by this table:
+ * DuplexCap -> | both | full | half |
+ * AutoNeg | | | |
+ * -----------------------------------------------------------------
+ * Off | illegal | Full | Half |
+ * -----------------------------------------------------------------
+ * On | AutoBoth | AutoFull | AutoHalf |
+ * -----------------------------------------------------------------
+ * Sense | AutoSense | AutoSense | AutoSense |
+ */
+int Capabilities[3][3] =
+ { { -1, SK_LMODE_FULL , SK_LMODE_HALF },
+ {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF },
+ {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} };
+
+#define DC_BOTH 0
+#define DC_FULL 1
+#define DC_HALF 2
+#define AN_OFF 0
+#define AN_ON 1
+#define AN_SENS 2
+#define M_CurrPort pAC->GIni.GP[Port]
+
+
+ /*
+ ** Set the default values first for both ports!
+ */
+ for (Port = 0; Port < SK_MAX_MACS; Port++) {
+ M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
+ M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
+ M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
+ M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO;
+ }
+
+ /*
+ ** Check merged parameter ConType. If it has not been used,
+ ** verify any other parameter (e.g. AutoNeg) and use default values.
+ **
+ ** Stating both ConType and other lowlevel link parameters is also
+ ** possible. If this is the case, the passed ConType-parameter is
+ ** overwritten by the lowlevel link parameter.
+ **
+ ** The following settings are used for a merged ConType-parameter:
+ **
+ ** ConType DupCap AutoNeg FlowCtrl Role Speed
+ ** ------- ------ ------- -------- ---------- -----
+ ** Auto Both On SymOrRem Auto Auto
+ ** 100FD Full Off None <ignored> 100
+ ** 100HD Half Off None <ignored> 100
+ ** 10FD Full Off None <ignored> 10
+ ** 10HD Half Off None <ignored> 10
+ **
+ ** This ConType parameter is used for all ports of the adapter!
+ */
+ if ( (ConType != NULL) &&
+ (pAC->Index < SK_MAX_CARD_PARAM) &&
+ (ConType[pAC->Index] != NULL) ) {
+
+ /* Check chipset family */
+ if ((!pAC->ChipsetType) &&
+ (strcmp(ConType[pAC->Index],"Auto")!=0) &&
+ (strcmp(ConType[pAC->Index],"")!=0)) {
+ /* Set the speed parameter back */
+ printk("sk98lin: Illegal value \"%s\" "
+ "for ConType."
+ " Using Auto.\n",
+ ConType[pAC->Index]);
+
+ sprintf(ConType[pAC->Index], "Auto");
+ }
+
+ if (strcmp(ConType[pAC->Index],"")==0) {
+ IsConTypeDefined = SK_FALSE; /* No ConType defined */
+ } else if (strcmp(ConType[pAC->Index],"Auto")==0) {
+ for (Port = 0; Port < SK_MAX_MACS; Port++) {
+ M_CurrPort.PLinkModeConf = Capabilities[AN_ON][DC_BOTH];
+ M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_SYM_OR_REM;
+ M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
+ M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO;
+ }
+ } else if (strcmp(ConType[pAC->Index],"100FD")==0) {
+ for (Port = 0; Port < SK_MAX_MACS; Port++) {
+ M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
+ M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
+ M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
+ M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS;
+ }
+ } else if (strcmp(ConType[pAC->Index],"100HD")==0) {
+ for (Port = 0; Port < SK_MAX_MACS; Port++) {
+ M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
+ M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
+ M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
+ M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS;
+ }
+ } else if (strcmp(ConType[pAC->Index],"10FD")==0) {
+ for (Port = 0; Port < SK_MAX_MACS; Port++) {
+ M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL];
+ M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
+ M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
+ M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS;
+ }
+ } else if (strcmp(ConType[pAC->Index],"10HD")==0) {
+ for (Port = 0; Port < SK_MAX_MACS; Port++) {
+ M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF];
+ M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE;
+ M_CurrPort.PMSMode = SK_MS_MODE_AUTO;
+ M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS;
+ }
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for ConType\n",
+ ConType[pAC->Index]);
+ IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */
+ }
+ } else {
+ IsConTypeDefined = SK_FALSE; /* No ConType defined */
+ }
+
+ /*
+ ** Parse any parameter settings for port A:
+ ** a) any LinkSpeed stated?
+ */
+ if (Speed_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+ Speed_A[pAC->Index] != NULL) {
+ if (strcmp(Speed_A[pAC->Index],"")==0) {
+ IsLinkSpeedDefined = SK_FALSE;
+ } else if (strcmp(Speed_A[pAC->Index],"Auto")==0) {
+ LinkSpeed = SK_LSPEED_AUTO;
+ } else if (strcmp(Speed_A[pAC->Index],"10")==0) {
+ LinkSpeed = SK_LSPEED_10MBPS;
+ } else if (strcmp(Speed_A[pAC->Index],"100")==0) {
+ LinkSpeed = SK_LSPEED_100MBPS;
+ } else if (strcmp(Speed_A[pAC->Index],"1000")==0) {
+ LinkSpeed = SK_LSPEED_1000MBPS;
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for Speed_A\n",
+ Speed_A[pAC->Index]);
+ IsLinkSpeedDefined = SK_FALSE;
+ }
+ } else {
+ IsLinkSpeedDefined = SK_FALSE;
+ }
+
+ /*
+ ** Check speed parameter:
+ ** Only copper type adapter and GE V2 cards
+ */
+ if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
+ ((LinkSpeed != SK_LSPEED_AUTO) &&
+ (LinkSpeed != SK_LSPEED_1000MBPS))) {
+ printk("sk98lin: Illegal value for Speed_A. "
+ "Not a copper card or GE V2 card\n Using "
+ "speed 1000\n");
+ LinkSpeed = SK_LSPEED_1000MBPS;
+ }
+
+ /*
+ ** Decide whether to set new config value if somethig valid has
+ ** been received.
+ */
+ if (IsLinkSpeedDefined) {
+ pAC->GIni.GP[0].PLinkSpeed = LinkSpeed;
+ }
+
+ /*
+ ** b) Any Autonegotiation and DuplexCapabilities set?
+ ** Please note that both belong together...
+ */
+ AutoNeg = AN_ON; /* tschilling: Default: Autonegotiation on! */
+ AutoSet = SK_FALSE;
+ if (AutoNeg_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+ AutoNeg_A[pAC->Index] != NULL) {
+ AutoSet = SK_TRUE;
+ if (strcmp(AutoNeg_A[pAC->Index],"")==0) {
+ AutoSet = SK_FALSE;
+ } else if (strcmp(AutoNeg_A[pAC->Index],"On")==0) {
+ AutoNeg = AN_ON;
+ } else if (strcmp(AutoNeg_A[pAC->Index],"Off")==0) {
+ AutoNeg = AN_OFF;
+ } else if (strcmp(AutoNeg_A[pAC->Index],"Sense")==0) {
+ AutoNeg = AN_SENS;
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for AutoNeg_A\n",
+ AutoNeg_A[pAC->Index]);
+ }
+ }
+
+ DuplexCap = DC_BOTH;
+ DupSet = SK_FALSE;
+ if (DupCap_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+ DupCap_A[pAC->Index] != NULL) {
+ DupSet = SK_TRUE;
+ if (strcmp(DupCap_A[pAC->Index],"")==0) {
+ DupSet = SK_FALSE;
+ } else if (strcmp(DupCap_A[pAC->Index],"Both")==0) {
+ DuplexCap = DC_BOTH;
+ } else if (strcmp(DupCap_A[pAC->Index],"Full")==0) {
+ DuplexCap = DC_FULL;
+ } else if (strcmp(DupCap_A[pAC->Index],"Half")==0) {
+ DuplexCap = DC_HALF;
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for DupCap_A\n",
+ DupCap_A[pAC->Index]);
+ }
+ }
+
+ /*
+ ** Check for illegal combinations
+ */
+ if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
+ ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
+ (DuplexCap == SK_LMODE_STAT_HALF)) &&
+ (pAC->ChipsetType)) {
+ printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
+ " Using Full Duplex.\n");
+ DuplexCap = DC_FULL;
+ }
+
+ if ( AutoSet && AutoNeg==AN_SENS && DupSet) {
+ printk("sk98lin, Port A: DuplexCapabilities"
+ " ignored using Sense mode\n");
+ }
+
+ if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
+ printk("sk98lin: Port A: Illegal combination"
+ " of values AutoNeg. and DuplexCap.\n Using "
+ "Full Duplex\n");
+ DuplexCap = DC_FULL;
+ }
+
+ if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
+ DuplexCap = DC_FULL;
+ }
+
+ if (!AutoSet && DupSet) {
+ printk("sk98lin: Port A: Duplex setting not"
+ " possible in\n default AutoNegotiation mode"
+ " (Sense).\n Using AutoNegotiation On\n");
+ AutoNeg = AN_ON;
+ }
+
+ /*
+ ** set the desired mode
+ */
+ if (AutoSet || DupSet) {
+ pAC->GIni.GP[0].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
+ }
+
+ /*
+ ** c) Any Flowcontrol-parameter set?
+ */
+ if (FlowCtrl_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+ FlowCtrl_A[pAC->Index] != NULL) {
+ if (strcmp(FlowCtrl_A[pAC->Index],"") == 0) {
+ IsFlowCtrlDefined = SK_FALSE;
+ } else if (strcmp(FlowCtrl_A[pAC->Index],"SymOrRem") == 0) {
+ FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
+ } else if (strcmp(FlowCtrl_A[pAC->Index],"Sym")==0) {
+ FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
+ } else if (strcmp(FlowCtrl_A[pAC->Index],"LocSend")==0) {
+ FlowCtrl = SK_FLOW_MODE_LOC_SEND;
+ } else if (strcmp(FlowCtrl_A[pAC->Index],"None")==0) {
+ FlowCtrl = SK_FLOW_MODE_NONE;
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n",
+ FlowCtrl_A[pAC->Index]);
+ IsFlowCtrlDefined = SK_FALSE;
+ }
+ } else {
+ IsFlowCtrlDefined = SK_FALSE;
+ }
+
+ if (IsFlowCtrlDefined) {
+ if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
+ printk("sk98lin: Port A: FlowControl"
+ " impossible without AutoNegotiation,"
+ " disabled\n");
+ FlowCtrl = SK_FLOW_MODE_NONE;
+ }
+ pAC->GIni.GP[0].PFlowCtrlMode = FlowCtrl;
+ }
+
+ /*
+ ** d) What is with the RoleParameter?
+ */
+ if (Role_A != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+ Role_A[pAC->Index] != NULL) {
+ if (strcmp(Role_A[pAC->Index],"")==0) {
+ IsRoleDefined = SK_FALSE;
+ } else if (strcmp(Role_A[pAC->Index],"Auto")==0) {
+ MSMode = SK_MS_MODE_AUTO;
+ } else if (strcmp(Role_A[pAC->Index],"Master")==0) {
+ MSMode = SK_MS_MODE_MASTER;
+ } else if (strcmp(Role_A[pAC->Index],"Slave")==0) {
+ MSMode = SK_MS_MODE_SLAVE;
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for Role_A\n",
+ Role_A[pAC->Index]);
+ IsRoleDefined = SK_FALSE;
+ }
+ } else {
+ IsRoleDefined = SK_FALSE;
+ }
+
+ if (IsRoleDefined == SK_TRUE) {
+ pAC->GIni.GP[0].PMSMode = MSMode;
+ }
+
+
+
+ /*
+ ** Parse any parameter settings for port B:
+ ** a) any LinkSpeed stated?
+ */
+ IsConTypeDefined = SK_TRUE;
+ IsLinkSpeedDefined = SK_TRUE;
+ IsFlowCtrlDefined = SK_TRUE;
+ IsModeDefined = SK_TRUE;
+
+ if (Speed_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+ Speed_B[pAC->Index] != NULL) {
+ if (strcmp(Speed_B[pAC->Index],"")==0) {
+ IsLinkSpeedDefined = SK_FALSE;
+ } else if (strcmp(Speed_B[pAC->Index],"Auto")==0) {
+ LinkSpeed = SK_LSPEED_AUTO;
+ } else if (strcmp(Speed_B[pAC->Index],"10")==0) {
+ LinkSpeed = SK_LSPEED_10MBPS;
+ } else if (strcmp(Speed_B[pAC->Index],"100")==0) {
+ LinkSpeed = SK_LSPEED_100MBPS;
+ } else if (strcmp(Speed_B[pAC->Index],"1000")==0) {
+ LinkSpeed = SK_LSPEED_1000MBPS;
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for Speed_B\n",
+ Speed_B[pAC->Index]);
+ IsLinkSpeedDefined = SK_FALSE;
+ }
+ } else {
+ IsLinkSpeedDefined = SK_FALSE;
+ }
+
+ /*
+ ** Check speed parameter:
+ ** Only copper type adapter and GE V2 cards
+ */
+ if (((!pAC->ChipsetType) || (pAC->GIni.GICopperType != SK_TRUE)) &&
+ ((LinkSpeed != SK_LSPEED_AUTO) &&
+ (LinkSpeed != SK_LSPEED_1000MBPS))) {
+ printk("sk98lin: Illegal value for Speed_B. "
+ "Not a copper card or GE V2 card\n Using "
+ "speed 1000\n");
+ LinkSpeed = SK_LSPEED_1000MBPS;
+ }
+
+ /*
+ ** Decide whether to set new config value if somethig valid has
+ ** been received.
+ */
+ if (IsLinkSpeedDefined) {
+ pAC->GIni.GP[1].PLinkSpeed = LinkSpeed;
+ }
+
+ /*
+ ** b) Any Autonegotiation and DuplexCapabilities set?
+ ** Please note that both belong together...
+ */
+ AutoNeg = AN_SENS; /* default: do auto Sense */
+ AutoSet = SK_FALSE;
+ if (AutoNeg_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+ AutoNeg_B[pAC->Index] != NULL) {
+ AutoSet = SK_TRUE;
+ if (strcmp(AutoNeg_B[pAC->Index],"")==0) {
+ AutoSet = SK_FALSE;
+ } else if (strcmp(AutoNeg_B[pAC->Index],"On")==0) {
+ AutoNeg = AN_ON;
+ } else if (strcmp(AutoNeg_B[pAC->Index],"Off")==0) {
+ AutoNeg = AN_OFF;
+ } else if (strcmp(AutoNeg_B[pAC->Index],"Sense")==0) {
+ AutoNeg = AN_SENS;
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for AutoNeg_B\n",
+ AutoNeg_B[pAC->Index]);
+ }
+ }
+
+ DuplexCap = DC_BOTH;
+ DupSet = SK_FALSE;
+ if (DupCap_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+ DupCap_B[pAC->Index] != NULL) {
+ DupSet = SK_TRUE;
+ if (strcmp(DupCap_B[pAC->Index],"")==0) {
+ DupSet = SK_FALSE;
+ } else if (strcmp(DupCap_B[pAC->Index],"Both")==0) {
+ DuplexCap = DC_BOTH;
+ } else if (strcmp(DupCap_B[pAC->Index],"Full")==0) {
+ DuplexCap = DC_FULL;
+ } else if (strcmp(DupCap_B[pAC->Index],"Half")==0) {
+ DuplexCap = DC_HALF;
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for DupCap_B\n",
+ DupCap_B[pAC->Index]);
+ }
+ }
+
+
+ /*
+ ** Check for illegal combinations
+ */
+ if ((LinkSpeed == SK_LSPEED_1000MBPS) &&
+ ((DuplexCap == SK_LMODE_STAT_AUTOHALF) ||
+ (DuplexCap == SK_LMODE_STAT_HALF)) &&
+ (pAC->ChipsetType)) {
+ printk("sk98lin: Half Duplex not possible with Gigabit speed!\n"
+ " Using Full Duplex.\n");
+ DuplexCap = DC_FULL;
+ }
+
+ if (AutoSet && AutoNeg==AN_SENS && DupSet) {
+ printk("sk98lin, Port B: DuplexCapabilities"
+ " ignored using Sense mode\n");
+ }
+
+ if (AutoSet && AutoNeg==AN_OFF && DupSet && DuplexCap==DC_BOTH){
+ printk("sk98lin: Port B: Illegal combination"
+ " of values AutoNeg. and DuplexCap.\n Using "
+ "Full Duplex\n");
+ DuplexCap = DC_FULL;
+ }
+
+ if (AutoSet && AutoNeg==AN_OFF && !DupSet) {
+ DuplexCap = DC_FULL;
+ }
+
+ if (!AutoSet && DupSet) {
+ printk("sk98lin: Port B: Duplex setting not"
+ " possible in\n default AutoNegotiation mode"
+ " (Sense).\n Using AutoNegotiation On\n");
+ AutoNeg = AN_ON;
+ }
+
+ /*
+ ** set the desired mode
+ */
+ if (AutoSet || DupSet) {
+ pAC->GIni.GP[1].PLinkModeConf = Capabilities[AutoNeg][DuplexCap];
+ }
+
+ /*
+ ** c) Any FlowCtrl parameter set?
+ */
+ if (FlowCtrl_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+ FlowCtrl_B[pAC->Index] != NULL) {
+ if (strcmp(FlowCtrl_B[pAC->Index],"") == 0) {
+ IsFlowCtrlDefined = SK_FALSE;
+ } else if (strcmp(FlowCtrl_B[pAC->Index],"SymOrRem") == 0) {
+ FlowCtrl = SK_FLOW_MODE_SYM_OR_REM;
+ } else if (strcmp(FlowCtrl_B[pAC->Index],"Sym")==0) {
+ FlowCtrl = SK_FLOW_MODE_SYMMETRIC;
+ } else if (strcmp(FlowCtrl_B[pAC->Index],"LocSend")==0) {
+ FlowCtrl = SK_FLOW_MODE_LOC_SEND;
+ } else if (strcmp(FlowCtrl_B[pAC->Index],"None")==0) {
+ FlowCtrl = SK_FLOW_MODE_NONE;
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for FlowCtrl_B\n",
+ FlowCtrl_B[pAC->Index]);
+ IsFlowCtrlDefined = SK_FALSE;
+ }
+ } else {
+ IsFlowCtrlDefined = SK_FALSE;
+ }
+
+ if (IsFlowCtrlDefined) {
+ if ((AutoNeg == AN_OFF) && (FlowCtrl != SK_FLOW_MODE_NONE)) {
+ printk("sk98lin: Port B: FlowControl"
+ " impossible without AutoNegotiation,"
+ " disabled\n");
+ FlowCtrl = SK_FLOW_MODE_NONE;
+ }
+ pAC->GIni.GP[1].PFlowCtrlMode = FlowCtrl;
+ }
+
+ /*
+ ** d) What is the RoleParameter?
+ */
+ if (Role_B != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+ Role_B[pAC->Index] != NULL) {
+ if (strcmp(Role_B[pAC->Index],"")==0) {
+ IsRoleDefined = SK_FALSE;
+ } else if (strcmp(Role_B[pAC->Index],"Auto")==0) {
+ MSMode = SK_MS_MODE_AUTO;
+ } else if (strcmp(Role_B[pAC->Index],"Master")==0) {
+ MSMode = SK_MS_MODE_MASTER;
+ } else if (strcmp(Role_B[pAC->Index],"Slave")==0) {
+ MSMode = SK_MS_MODE_SLAVE;
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for Role_B\n",
+ Role_B[pAC->Index]);
+ IsRoleDefined = SK_FALSE;
+ }
+ } else {
+ IsRoleDefined = SK_FALSE;
+ }
+
+ if (IsRoleDefined) {
+ pAC->GIni.GP[1].PMSMode = MSMode;
+ }
+
+ /*
+ ** Evaluate settings for both ports
+ */
+ pAC->ActivePort = 0;
+ if (PrefPort != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+ PrefPort[pAC->Index] != NULL) {
+ if (strcmp(PrefPort[pAC->Index],"") == 0) { /* Auto */
+ pAC->ActivePort = 0;
+ pAC->Rlmt.Net[0].Preference = -1; /* auto */
+ pAC->Rlmt.Net[0].PrefPort = 0;
+ } else if (strcmp(PrefPort[pAC->Index],"A") == 0) {
+ /*
+ ** do not set ActivePort here, thus a port
+ ** switch is issued after net up.
+ */
+ Port = 0;
+ pAC->Rlmt.Net[0].Preference = Port;
+ pAC->Rlmt.Net[0].PrefPort = Port;
+ } else if (strcmp(PrefPort[pAC->Index],"B") == 0) {
+ /*
+ ** do not set ActivePort here, thus a port
+ ** switch is issued after net up.
+ */
+ if (pAC->GIni.GIMacsFound == 1) {
+ printk("sk98lin: Illegal value \"B\" for PrefPort.\n"
+ " Port B not available on single port adapters.\n");
+
+ pAC->ActivePort = 0;
+ pAC->Rlmt.Net[0].Preference = -1; /* auto */
+ pAC->Rlmt.Net[0].PrefPort = 0;
+ } else {
+ Port = 1;
+ pAC->Rlmt.Net[0].Preference = Port;
+ pAC->Rlmt.Net[0].PrefPort = Port;
+ }
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for PrefPort\n",
+ PrefPort[pAC->Index]);
+ }
+ }
+
+ pAC->RlmtNets = 1;
+
+ if (RlmtMode != NULL && pAC->Index<SK_MAX_CARD_PARAM &&
+ RlmtMode[pAC->Index] != NULL) {
+ if (strcmp(RlmtMode[pAC->Index], "") == 0) {
+ pAC->RlmtMode = 0;
+ } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) {
+ pAC->RlmtMode = SK_RLMT_CHECK_LINK;
+ } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) {
+ pAC->RlmtMode = SK_RLMT_CHECK_LINK |
+ SK_RLMT_CHECK_LOC_LINK;
+ } else if (strcmp(RlmtMode[pAC->Index], "CheckSeg") == 0) {
+ pAC->RlmtMode = SK_RLMT_CHECK_LINK |
+ SK_RLMT_CHECK_LOC_LINK |
+ SK_RLMT_CHECK_SEG;
+ } else if ((strcmp(RlmtMode[pAC->Index], "DualNet") == 0) &&
+ (pAC->GIni.GIMacsFound == 2)) {
+ pAC->RlmtMode = SK_RLMT_CHECK_LINK;
+ pAC->RlmtNets = 2;
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for"
+ " RlmtMode, using default\n",
+ RlmtMode[pAC->Index]);
+ pAC->RlmtMode = 0;
+ }
+ } else {
+ pAC->RlmtMode = 0;
+ }
+
+ /*
+ ** Check the interrupt moderation parameters
+ */
+ if (Moderation[pAC->Index] != NULL) {
+ if (strcmp(Moderation[pAC->Index], "") == 0) {
+ pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+ } else if (strcmp(Moderation[pAC->Index], "Static") == 0) {
+ pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC;
+ } else if (strcmp(Moderation[pAC->Index], "Dynamic") == 0) {
+ pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_DYNAMIC;
+ } else if (strcmp(Moderation[pAC->Index], "None") == 0) {
+ pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+ } else {
+ printk("sk98lin: Illegal value \"%s\" for Moderation.\n"
+ " Disable interrupt moderation.\n",
+ Moderation[pAC->Index]);
+ pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+ }
+ } else {
+ pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE;
+ }
+
+ if (Stats[pAC->Index] != NULL) {
+ if (strcmp(Stats[pAC->Index], "Yes") == 0) {
+ pAC->DynIrqModInfo.DisplayStats = SK_TRUE;
+ } else {
+ pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
+ }
+ } else {
+ pAC->DynIrqModInfo.DisplayStats = SK_FALSE;
+ }
+
+ if (ModerationMask[pAC->Index] != NULL) {
+ if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
+ } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY;
+ } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY;
+ } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
+ } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX;
+ } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
+ } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
+ } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
+ } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX;
+ } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+ } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+ } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+ } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+ } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+ } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) {
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP;
+ } else { /* some rubbish */
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY;
+ }
+ } else { /* operator has stated nothing */
+ pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX;
+ }
+
+ if (AutoSizing[pAC->Index] != NULL) {
+ if (strcmp(AutoSizing[pAC->Index], "On") == 0) {
+ pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
+ } else {
+ pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
+ }
+ } else { /* operator has stated nothing */
+ pAC->DynIrqModInfo.AutoSizing = SK_FALSE;
+ }
+
+ if (IntsPerSec[pAC->Index] != 0) {
+ if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) ||
+ (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) {
+ printk("sk98lin: Illegal value \"%d\" for IntsPerSec. (Range: %d - %d)\n"
+ " Using default value of %i.\n",
+ IntsPerSec[pAC->Index],
+ C_INT_MOD_IPS_LOWER_RANGE,
+ C_INT_MOD_IPS_UPPER_RANGE,
+ C_INTS_PER_SEC_DEFAULT);
+ pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
+ } else {
+ pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
+ }
+ } else {
+ pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
+ }
+
+ /*
+ ** Evaluate upper and lower moderation threshold
+ */
+ pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit =
+ pAC->DynIrqModInfo.MaxModIntsPerSec +
+ (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
+
+ pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit =
+ pAC->DynIrqModInfo.MaxModIntsPerSec -
+ (pAC->DynIrqModInfo.MaxModIntsPerSec / 2);
+
+ pAC->DynIrqModInfo.PrevTimeVal = jiffies; /* initial value */
+
+
+} /* GetConfiguration */
+
+
+/*****************************************************************************
+ *
+ * ProductStr - return a adapter identification string from vpd
+ *
+ * Description:
+ * This function reads the product name string from the vpd area
+ * and puts it the field pAC->DeviceString.
+ *
+ * Returns: N/A
+ */
+static void ProductStr(
+SK_AC *pAC /* pointer to adapter context */
+)
+{
+int StrLen = 80; /* length of the string, defined in SK_AC */
+char Keyword[] = VPD_NAME; /* vpd productname identifier */
+int ReturnCode; /* return code from vpd_read */
+unsigned long Flags;
+
+ spin_lock_irqsave(&pAC->SlowPathLock, Flags);
+ ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, pAC->DeviceStr,
+ &StrLen);
+ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
+ if (ReturnCode != 0) {
+ /* there was an error reading the vpd data */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
+ ("Error reading VPD data: %d\n", ReturnCode));
+ pAC->DeviceStr[0] = '\0';
+ }
+} /* ProductStr */
+
+/*****************************************************************************
+ *
+ * StartDrvCleanupTimer - Start timer to check for descriptors which
+ * might be placed in descriptor ring, but
+ * havent been handled up to now
+ *
+ * Description:
+ * This function requests a HW-timer fo the Yukon card. The actions to
+ * perform when this timer expires, are located in the SkDrvEvent().
+ *
+ * Returns: N/A
+ */
+static void
+StartDrvCleanupTimer(SK_AC *pAC) {
+ SK_EVPARA EventParam; /* Event struct for timer event */
+
+ SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
+ EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER;
+ SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer,
+ SK_DRV_RX_CLEANUP_TIMER_LENGTH,
+ SKGE_DRV, SK_DRV_TIMER, EventParam);
+}
+
+/*****************************************************************************
+ *
+ * StopDrvCleanupTimer - Stop timer to check for descriptors
+ *
+ * Description:
+ * This function requests a HW-timer fo the Yukon card. The actions to
+ * perform when this timer expires, are located in the SkDrvEvent().
+ *
+ * Returns: N/A
+ */
+static void
+StopDrvCleanupTimer(SK_AC *pAC) {
+ SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer);
+ SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER));
+}
+
+/****************************************************************************/
+/* functions for common modules *********************************************/
+/****************************************************************************/
+
+
+/*****************************************************************************
+ *
+ * SkDrvAllocRlmtMbuf - allocate an RLMT mbuf
+ *
+ * Description:
+ * This routine returns an RLMT mbuf or NULL. The RLMT Mbuf structure
+ * is embedded into a socket buff data area.
+ *
+ * Context:
+ * runtime
+ *
+ * Returns:
+ * NULL or pointer to Mbuf.
+ */
+SK_MBUF *SkDrvAllocRlmtMbuf(
+SK_AC *pAC, /* pointer to adapter context */
+SK_IOC IoC, /* the IO-context */
+unsigned BufferSize) /* size of the requested buffer */
+{
+SK_MBUF *pRlmtMbuf; /* pointer to a new rlmt-mbuf structure */
+struct sk_buff *pMsgBlock; /* pointer to a new message block */
+
+ pMsgBlock = alloc_skb(BufferSize + sizeof(SK_MBUF), GFP_ATOMIC);
+ if (pMsgBlock == NULL) {
+ return (NULL);
+ }
+ pRlmtMbuf = (SK_MBUF*) pMsgBlock->data;
+ skb_reserve(pMsgBlock, sizeof(SK_MBUF));
+ pRlmtMbuf->pNext = NULL;
+ pRlmtMbuf->pOs = pMsgBlock;
+ pRlmtMbuf->pData = pMsgBlock->data; /* Data buffer. */
+ pRlmtMbuf->Size = BufferSize; /* Data buffer size. */
+ pRlmtMbuf->Length = 0; /* Length of packet (<= Size). */
+ return (pRlmtMbuf);
+
+} /* SkDrvAllocRlmtMbuf */
+
+
+/*****************************************************************************
+ *
+ * SkDrvFreeRlmtMbuf - free an RLMT mbuf
+ *
+ * Description:
+ * This routine frees one or more RLMT mbuf(s).
+ *
+ * Context:
+ * runtime
+ *
+ * Returns:
+ * Nothing
+ */
+void SkDrvFreeRlmtMbuf(
+SK_AC *pAC, /* pointer to adapter context */
+SK_IOC IoC, /* the IO-context */
+SK_MBUF *pMbuf) /* size of the requested buffer */
+{
+SK_MBUF *pFreeMbuf;
+SK_MBUF *pNextMbuf;
+
+ pFreeMbuf = pMbuf;
+ do {
+ pNextMbuf = pFreeMbuf->pNext;
+ DEV_KFREE_SKB_ANY(pFreeMbuf->pOs);
+ pFreeMbuf = pNextMbuf;
+ } while ( pFreeMbuf != NULL );
+} /* SkDrvFreeRlmtMbuf */
+
+
+/*****************************************************************************
+ *
+ * SkOsGetTime - provide a time value
+ *
+ * Description:
+ * This routine provides a time value. The unit is 1/HZ (defined by Linux).
+ * It is not used for absolute time, but only for time differences.
+ *
+ *
+ * Returns:
+ * Time value
+ */
+SK_U64 SkOsGetTime(SK_AC *pAC)
+{
+ SK_U64 PrivateJiffies;
+ SkOsGetTimeCurrent(pAC, &PrivateJiffies);
+ return PrivateJiffies;
+} /* SkOsGetTime */
+
+
+/*****************************************************************************
+ *
+ * SkPciReadCfgDWord - read a 32 bit value from pci config space
+ *
+ * Description:
+ * This routine reads a 32 bit value from the pci configuration
+ * space.
+ *
+ * Returns:
+ * 0 - indicate everything worked ok.
+ * != 0 - error indication
+ */
+int SkPciReadCfgDWord(
+SK_AC *pAC, /* Adapter Control structure pointer */
+int PciAddr, /* PCI register address */
+SK_U32 *pVal) /* pointer to store the read value */
+{
+ pci_read_config_dword(pAC->PciDev, PciAddr, pVal);
+ return(0);
+} /* SkPciReadCfgDWord */
+
+
+/*****************************************************************************
+ *
+ * SkPciReadCfgWord - read a 16 bit value from pci config space
+ *
+ * Description:
+ * This routine reads a 16 bit value from the pci configuration
+ * space.
+ *
+ * Returns:
+ * 0 - indicate everything worked ok.
+ * != 0 - error indication
+ */
+int SkPciReadCfgWord(
+SK_AC *pAC, /* Adapter Control structure pointer */
+int PciAddr, /* PCI register address */
+SK_U16 *pVal) /* pointer to store the read value */
+{
+ pci_read_config_word(pAC->PciDev, PciAddr, pVal);
+ return(0);
+} /* SkPciReadCfgWord */
+
+
+/*****************************************************************************
+ *
+ * SkPciReadCfgByte - read a 8 bit value from pci config space
+ *
+ * Description:
+ * This routine reads a 8 bit value from the pci configuration
+ * space.
+ *
+ * Returns:
+ * 0 - indicate everything worked ok.
+ * != 0 - error indication
+ */
+int SkPciReadCfgByte(
+SK_AC *pAC, /* Adapter Control structure pointer */
+int PciAddr, /* PCI register address */
+SK_U8 *pVal) /* pointer to store the read value */
+{
+ pci_read_config_byte(pAC->PciDev, PciAddr, pVal);
+ return(0);
+} /* SkPciReadCfgByte */
+
+
+/*****************************************************************************
+ *
+ * SkPciWriteCfgDWord - write a 32 bit value to pci config space
+ *
+ * Description:
+ * This routine writes a 32 bit value to the pci configuration
+ * space.
+ *
+ * Returns:
+ * 0 - indicate everything worked ok.
+ * != 0 - error indication
+ */
+int SkPciWriteCfgDWord(
+SK_AC *pAC, /* Adapter Control structure pointer */
+int PciAddr, /* PCI register address */
+SK_U32 Val) /* pointer to store the read value */
+{
+ pci_write_config_dword(pAC->PciDev, PciAddr, Val);
+ return(0);
+} /* SkPciWriteCfgDWord */
+
+
+/*****************************************************************************
+ *
+ * SkPciWriteCfgWord - write a 16 bit value to pci config space
+ *
+ * Description:
+ * This routine writes a 16 bit value to the pci configuration
+ * space. The flag PciConfigUp indicates whether the config space
+ * is accesible or must be set up first.
+ *
+ * Returns:
+ * 0 - indicate everything worked ok.
+ * != 0 - error indication
+ */
+int SkPciWriteCfgWord(
+SK_AC *pAC, /* Adapter Control structure pointer */
+int PciAddr, /* PCI register address */
+SK_U16 Val) /* pointer to store the read value */
+{
+ pci_write_config_word(pAC->PciDev, PciAddr, Val);
+ return(0);
+} /* SkPciWriteCfgWord */
+
+
+/*****************************************************************************
+ *
+ * SkPciWriteCfgWord - write a 8 bit value to pci config space
+ *
+ * Description:
+ * This routine writes a 8 bit value to the pci configuration
+ * space. The flag PciConfigUp indicates whether the config space
+ * is accesible or must be set up first.
+ *
+ * Returns:
+ * 0 - indicate everything worked ok.
+ * != 0 - error indication
+ */
+int SkPciWriteCfgByte(
+SK_AC *pAC, /* Adapter Control structure pointer */
+int PciAddr, /* PCI register address */
+SK_U8 Val) /* pointer to store the read value */
+{
+ pci_write_config_byte(pAC->PciDev, PciAddr, Val);
+ return(0);
+} /* SkPciWriteCfgByte */
+
+
+/*****************************************************************************
+ *
+ * SkDrvEvent - handle driver events
+ *
+ * Description:
+ * This function handles events from all modules directed to the driver
+ *
+ * Context:
+ * Is called under protection of slow path lock.
+ *
+ * Returns:
+ * 0 if everything ok
+ * < 0 on error
+ *
+ */
+int SkDrvEvent(
+SK_AC *pAC, /* pointer to adapter context */
+SK_IOC IoC, /* io-context */
+SK_U32 Event, /* event-id */
+SK_EVPARA Param) /* event-parameter */
+{
+SK_MBUF *pRlmtMbuf; /* pointer to a rlmt-mbuf structure */
+struct sk_buff *pMsg; /* pointer to a message block */
+int FromPort; /* the port from which we switch away */
+int ToPort; /* the port we switch to */
+SK_EVPARA NewPara; /* parameter for further events */
+int Stat;
+unsigned long Flags;
+SK_BOOL DualNet;
+
+ switch (Event) {
+ case SK_DRV_ADAP_FAIL:
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+ ("ADAPTER FAIL EVENT\n"));
+ printk("%s: Adapter failed.\n", pAC->dev[0]->name);
+ /* disable interrupts */
+ SK_OUT32(pAC->IoBase, B0_IMSK, 0);
+ /* cgoos */
+ break;
+ case SK_DRV_PORT_FAIL:
+ FromPort = Param.Para32[0];
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+ ("PORT FAIL EVENT, Port: %d\n", FromPort));
+ if (FromPort == 0) {
+ printk("%s: Port A failed.\n", pAC->dev[0]->name);
+ } else {
+ printk("%s: Port B failed.\n", pAC->dev[1]->name);
+ }
+ /* cgoos */
+ break;
+ case SK_DRV_PORT_RESET: /* SK_U32 PortIdx */
+ /* action list 4 */
+ FromPort = Param.Para32[0];
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+ ("PORT RESET EVENT, Port: %d ", FromPort));
+ NewPara.Para64 = FromPort;
+ SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
+ spin_lock_irqsave(
+ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+ Flags);
+
+ SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST);
+ pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING;
+ spin_unlock_irqrestore(
+ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+ Flags);
+
+ /* clear rx ring from received frames */
+ ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE);
+
+ ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
+ spin_lock_irqsave(
+ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+ Flags);
+
+ /* tschilling: Handling of return value inserted. */
+ if (SkGeInitPort(pAC, IoC, FromPort)) {
+ if (FromPort == 0) {
+ printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name);
+ } else {
+ printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name);
+ }
+ }
+ SkAddrMcUpdate(pAC,IoC, FromPort);
+ PortReInitBmu(pAC, FromPort);
+ SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
+ ClearAndStartRx(pAC, FromPort);
+ spin_unlock_irqrestore(
+ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+ Flags);
+ break;
+ case SK_DRV_NET_UP: /* SK_U32 PortIdx */
+ /* action list 5 */
+ FromPort = Param.Para32[0];
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+ ("NET UP EVENT, Port: %d ", Param.Para32[0]));
+ /* Mac update */
+ SkAddrMcUpdate(pAC,IoC, FromPort);
+
+ if (DoPrintInterfaceChange) {
+ printk("%s: network connection up using"
+ " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]);
+
+ /* tschilling: Values changed according to LinkSpeedUsed. */
+ Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed;
+ if (Stat == SK_LSPEED_STAT_10MBPS) {
+ printk(" speed: 10\n");
+ } else if (Stat == SK_LSPEED_STAT_100MBPS) {
+ printk(" speed: 100\n");
+ } else if (Stat == SK_LSPEED_STAT_1000MBPS) {
+ printk(" speed: 1000\n");
+ } else {
+ printk(" speed: unknown\n");
+ }
+
+
+ Stat = pAC->GIni.GP[FromPort].PLinkModeStatus;
+ if (Stat == SK_LMODE_STAT_AUTOHALF ||
+ Stat == SK_LMODE_STAT_AUTOFULL) {
+ printk(" autonegotiation: yes\n");
+ }
+ else {
+ printk(" autonegotiation: no\n");
+ }
+ if (Stat == SK_LMODE_STAT_AUTOHALF ||
+ Stat == SK_LMODE_STAT_HALF) {
+ printk(" duplex mode: half\n");
+ }
+ else {
+ printk(" duplex mode: full\n");
+ }
+ Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus;
+ if (Stat == SK_FLOW_STAT_REM_SEND ) {
+ printk(" flowctrl: remote send\n");
+ }
+ else if (Stat == SK_FLOW_STAT_LOC_SEND ){
+ printk(" flowctrl: local send\n");
+ }
+ else if (Stat == SK_FLOW_STAT_SYMMETRIC ){
+ printk(" flowctrl: symmetric\n");
+ }
+ else {
+ printk(" flowctrl: none\n");
+ }
+
+ /* tschilling: Check against CopperType now. */
+ if ((pAC->GIni.GICopperType == SK_TRUE) &&
+ (pAC->GIni.GP[FromPort].PLinkSpeedUsed ==
+ SK_LSPEED_STAT_1000MBPS)) {
+ Stat = pAC->GIni.GP[FromPort].PMSStatus;
+ if (Stat == SK_MS_STAT_MASTER ) {
+ printk(" role: master\n");
+ }
+ else if (Stat == SK_MS_STAT_SLAVE ) {
+ printk(" role: slave\n");
+ }
+ else {
+ printk(" role: ???\n");
+ }
+ }
+
+ /*
+ Display dim (dynamic interrupt moderation)
+ informations
+ */
+ if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC)
+ printk(" irq moderation: static (%d ints/sec)\n",
+ pAC->DynIrqModInfo.MaxModIntsPerSec);
+ else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC)
+ printk(" irq moderation: dynamic (%d ints/sec)\n",
+ pAC->DynIrqModInfo.MaxModIntsPerSec);
+ else
+ printk(" irq moderation: disabled\n");
+
+
+#ifdef SK_ZEROCOPY
+ if (pAC->ChipsetType)
+#ifdef USE_SK_TX_CHECKSUM
+ printk(" scatter-gather: enabled\n");
+#else
+ printk(" tx-checksum: disabled\n");
+#endif
+ else
+ printk(" scatter-gather: disabled\n");
+#else
+ printk(" scatter-gather: disabled\n");
+#endif
+
+#ifndef USE_SK_RX_CHECKSUM
+ printk(" rx-checksum: disabled\n");
+#endif
+
+ } else {
+ DoPrintInterfaceChange = SK_TRUE;
+ }
+
+ if ((Param.Para32[0] != pAC->ActivePort) &&
+ (pAC->RlmtNets == 1)) {
+ NewPara.Para32[0] = pAC->ActivePort;
+ NewPara.Para32[1] = Param.Para32[0];
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN,
+ NewPara);
+ }
+
+ /* Inform the world that link protocol is up. */
+ pAC->dev[Param.Para32[0]]->flags |= IFF_RUNNING;
+
+ break;
+ case SK_DRV_NET_DOWN: /* SK_U32 Reason */
+ /* action list 7 */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+ ("NET DOWN EVENT "));
+ if (DoPrintInterfaceChange) {
+ printk("%s: network connection down\n",
+ pAC->dev[Param.Para32[1]]->name);
+ } else {
+ DoPrintInterfaceChange = SK_TRUE;
+ }
+ pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING;
+ break;
+ case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+ ("PORT SWITCH HARD "));
+ case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
+ /* action list 6 */
+ printk("%s: switching to port %c\n", pAC->dev[0]->name,
+ 'A'+Param.Para32[1]);
+ case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */
+ FromPort = Param.Para32[0];
+ ToPort = Param.Para32[1];
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+ ("PORT SWITCH EVENT, From: %d To: %d (Pref %d) ",
+ FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort));
+ NewPara.Para64 = FromPort;
+ SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
+ NewPara.Para64 = ToPort;
+ SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara);
+ spin_lock_irqsave(
+ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+ Flags);
+ spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
+ SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST);
+ SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST);
+ spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
+ spin_unlock_irqrestore(
+ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+ Flags);
+
+ ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */
+ ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */
+
+ ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]);
+ ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]);
+ spin_lock_irqsave(
+ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+ Flags);
+ spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
+ pAC->ActivePort = ToPort;
+#if 0
+ SetQueueSizes(pAC);
+#else
+ /* tschilling: New common function with minimum size check. */
+ DualNet = SK_FALSE;
+ if (pAC->RlmtNets == 2) {
+ DualNet = SK_TRUE;
+ }
+
+ if (SkGeInitAssignRamToQueues(
+ pAC,
+ pAC->ActivePort,
+ DualNet)) {
+ spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
+ spin_unlock_irqrestore(
+ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+ Flags);
+ printk("SkGeInitAssignRamToQueues failed.\n");
+ break;
+ }
+#endif
+ /* tschilling: Handling of return values inserted. */
+ if (SkGeInitPort(pAC, IoC, FromPort) ||
+ SkGeInitPort(pAC, IoC, ToPort)) {
+ printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name);
+ }
+ if (Event == SK_DRV_SWITCH_SOFT) {
+ SkMacRxTxEnable(pAC, IoC, FromPort);
+ }
+ SkMacRxTxEnable(pAC, IoC, ToPort);
+ SkAddrSwap(pAC, IoC, FromPort, ToPort);
+ SkAddrMcUpdate(pAC, IoC, FromPort);
+ SkAddrMcUpdate(pAC, IoC, ToPort);
+ PortReInitBmu(pAC, FromPort);
+ PortReInitBmu(pAC, ToPort);
+ SkGePollTxD(pAC, IoC, FromPort, SK_TRUE);
+ SkGePollTxD(pAC, IoC, ToPort, SK_TRUE);
+ ClearAndStartRx(pAC, FromPort);
+ ClearAndStartRx(pAC, ToPort);
+ spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock);
+ spin_unlock_irqrestore(
+ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock,
+ Flags);
+ break;
+ case SK_DRV_RLMT_SEND: /* SK_MBUF *pMb */
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+ ("RLS "));
+ pRlmtMbuf = (SK_MBUF*) Param.pParaPtr;
+ pMsg = (struct sk_buff*) pRlmtMbuf->pOs;
+ skb_put(pMsg, pRlmtMbuf->Length);
+ if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW],
+ pMsg) < 0)
+
+ DEV_KFREE_SKB_ANY(pMsg);
+ break;
+ case SK_DRV_TIMER:
+ if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) {
+ /*
+ ** expiration of the moderation timer implies that
+ ** dynamic moderation is to be applied
+ */
+ SkDimStartModerationTimer(pAC);
+ SkDimModerate(pAC);
+ if (pAC->DynIrqModInfo.DisplayStats) {
+ SkDimDisplayModerationSettings(pAC);
+ }
+ } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) {
+ /*
+ ** check if we need to check for descriptors which
+ ** haven't been handled the last millisecs
+ */
+ StartDrvCleanupTimer(pAC);
+ if (pAC->GIni.GIMacsFound == 2) {
+ ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE);
+ }
+ ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE);
+ } else {
+ printk("Expiration of unknown timer\n");
+ }
+ break;
+ default:
+ break;
+ }
+ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
+ ("END EVENT "));
+