From ecd90054f374b3b98ccff52a3d6a2a880ab12d10 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20R=C4=99korajski?= Date: Tue, 7 Aug 2007 18:21:12 +0000 Subject: [PATCH] - new from http://www.skd.de/ Changed files: linux-2.6-sk98lin_v10.0.4.3.patch -> 1.1 --- linux-2.6-sk98lin_v10.0.4.3.patch | 60691 ++++++++++++++++++++++++++++ 1 file changed, 60691 insertions(+) create mode 100644 linux-2.6-sk98lin_v10.0.4.3.patch diff --git a/linux-2.6-sk98lin_v10.0.4.3.patch b/linux-2.6-sk98lin_v10.0.4.3.patch new file mode 100644 index 00000000..4e66fe3b --- /dev/null +++ b/linux-2.6-sk98lin_v10.0.4.3.patch @@ -0,0 +1,60691 @@ +diff -ruN linux/drivers/net/sk98lin/h/lm80.h linux-new/drivers/net/sk98lin/h/lm80.h +--- linux/drivers/net/sk98lin/h/lm80.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/lm80.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,8 +2,8 @@ + * + * Name: lm80.h + * Project: Gigabit Ethernet Adapters, Common Modules +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Contains all defines for the LM80 Chip + * (National Semiconductor). + * +@@ -11,6 +11,7 @@ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. + * +@@ -20,6 +21,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +diff -ruN linux/drivers/net/sk98lin/h/mvyexhw.h linux-new/drivers/net/sk98lin/h/mvyexhw.h +--- linux/drivers/net/sk98lin/h/mvyexhw.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/h/mvyexhw.h 2007-01-24 14:03:40.000000000 +0100 +@@ -0,0 +1,4399 @@ ++/****************************************************************************** ++ * ++ * Name: mvyexhw.h ++ * Project: Yukon Extreme, Common Modules ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Defines and Macros for the Yukon Extreme Gigabit Ethernet Adapters ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * (C)Copyright 2005 - 2006 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. ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * This file was automatically generated by reg.pl (Rev. 1.55) using ++ * Yukon_Extreme_Registers_Config.csv ++ * Yukon_Extreme_Registers_Control.csv ++ * Yukon_Extreme_Registers_GMAC.csv ++ * ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * Name: mvyexhw.h ++ * Project: Yukon Extreme, Common Modules ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Defines and Macros for the Yukon Extreme Gigabit Ethernet Adapters ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * (C)Copyright 2005 - 2006 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. ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * This file was automatically generated by reg.pl (Rev. 1.55) using ++ * Yukon_Extreme_Registers_Config.csv ++ * Yukon_Extreme_Registers_Control.csv ++ * Yukon_Extreme_Registers_GMAC.csv ++ * ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * History: ++ * $Log$ ++ * Revision 1.1.2.3 2006/11/17 14:39:31 malthoff ++ * Add defines for host control register CPU states. ++ * ++ * Revision 1.1.2.2 2006/09/15 15:33:22 drazinko ++ * Added a macsec register ++ * ++ * Revision 1.1.2.1 2006/08/25 13:49:55 malthoff ++ * Generated from register table v0.50. ++ * First Check-in. ++ * ++ * ++ */ ++ ++ ++#ifndef __INC_MVYEXHW_H ++#define __INC_MVYEXHW_H ++ ++#define PCI_VEN_ID 0x0000 /* 16 bit Vendor ID Register */ ++#define PCI_DEV_ID 0x0002 /* 16 bit Device ID Register */ ++#define PCI_CMD 0x0004 /* 16 bit Command Register */ ++#define PCI_STAT 0x0006 /* 16 bit Status Register */ ++//#define PCI_REV_ID 0x0008 /* 8 bit Revision ID Register */ ++#define PCI_PIF 0x0009 /* 8 bit Programming ++ * Interface ++ * Register, Lower ++ * Byte ++ */ ++#define PCI_SCC 0x000A /* 8 bit Sub-Class Register, ++ * Middle Byte ++ */ ++#define PCI_BCC 0x000B /* 8 bit Base-Class ++ * Register, Upper ++ * Byte ++ */ ++#define PCI_CLS 0x000C /* 8 bit Cache Line Size ++ * Register ++ */ ++//#define PCI_LAT_TIM 0x000D /* 8 bit Latency Timer ++// * Register ++// */ ++#define PCI_HDRTYP 0x000E /* 8 bit Header Type Register */ ++//#define PCI_BIST 0x000F /* 8 bit Built-in Self Test ++// * (BIST) Register ++// */ ++#define PCI_BAR1_LO 0x0010 /* 32 bit Base Address ++ * Register (1st), ++ * Lower Address ++ */ ++#define PCI_BAR1_HI 0x0014 /* 32 bit Base Address ++ * Register (1st), ++ * Upper Address ++ */ ++#define PCI_BAR2 0x0018 /* 32 bit Base Address ++ * Register (2nd) ++ */ ++#define PCI_SSVEN_ID 0x002C /* 16 bit Subsystem Vendor ID ++ * Register ++ */ ++#define PCI_SSDEV_ID 0x002E /* 16 bit Subsystem ID ++ * Register ++ */ ++#define PCI_ERBAR 0x0030 /* 32 bit Expansion Rom Base ++ * Address Register ++ */ ++#define PCI_NCAP_PTR 0x0034 /* 8 bit New Capabilities ++ * Pointer (New Cap ++ * Ptr) Register ++ */ ++#define PCI_INT_LINE 0x003C /* 8 bit Interrupt Line ++ * Register ++ */ ++#define PCI_INT_PIN 0x003D /* 8 bit Interrupt Pin ++ * Register ++ */ ++//#define PCI_MIN_GNT 0x003E /* 8 bit Min_Gnt Register */ ++//#define PCI_MAX_LAT 0x003F /* 8 bit Max_Lat Register */ ++#define PCI_OUR1 0x0040 /* 32 bit Our Register 1 */ ++#define PCI_OUR2 0x0044 /* 32 bit Our Register 2 */ ++//#define PCI_PM_CAP_ID 0x0048 /* 8 bit Power Management ++// * Capability ID ++// * Register (PM Cap ++// * ID) ++// */ ++#define PCI_PM_NXT_PTR 0x0049 /* 8 bit Power Management ++ * Next Item Pointer ++ * Register ++ */ ++#define PCI_PM_CAP 0x004A /* 16 bit Power Management ++ * Capabilities ++ * Register ++ */ ++#define PCI_PM_CSR 0x004C /* 16 bit Power Management ++ * Control/Status ++ * Register ++ */ ++#define PCI_PM_DATA 0x004F /* 8 bit Power Management ++ * Data Register ++ */ ++//#define PCI_VPD_CAP_ID 0x0050 /* 8 bit VPD Capability ID ++// * Register (VPD Cap ++// * ID) ++// */ ++#define PCI_VPD_NPTR 0x0051 /* 8 bit VPD Next Item ++ * Pointer Register ++ */ ++#define PCI_VPD_ADDR 0x0052 /* 16 bit VPD Address Register */ ++#define PCI_VPD_DATA 0x0054 /* 32 bit VPD Data Register */ ++#define PCI_LDR_CTRL 0x005A /* 16 bit TWSI EEPROM Loader ++ * Control Register ++ */ ++//#define PCI_MSI_CAP_ID 0x005C /* 8 bit MSI Capability ID ++// * Register (MSI Cap ++// * ID) ++// */ ++#define PCI_MSI_NPTR 0x005D /* 8 bit MSI Next Item ++ * Pointer Register ++ */ ++//#define PCI_MSI_CTRL 0x005E /* 16 bit MSI Message Control ++// * Register ++// */ ++#define PCI_MSI_ADDR_LO 0x0060 /* 32 bit MSI Message Address ++ * Register, Lower ++ * Address ++ */ ++#define PCI_MSI_ADDR_HI 0x0064 /* 32 bit MSI Message Address ++ * Register, Upper ++ * Address ++ */ ++//#define PCI_MSI_DATA 0x0068 /* 32 bit MSI Message Data ++// * Register ++// */ ++#define PCIE_STAT 0x0070 /* 32 bit PCI Express Status ++ * Register ++ */ ++#define PCIE_OUR_STAT 0x007C /* 32 bit Our Status Register */ ++#define PCIE_OUR3 0x0080 /* 32 bit Our Register 3 */ ++#define PCIE_OUR4 0x0084 /* 32 bit Our Register 4 */ ++#define PCIE_OUR5 0x0088 /* 32 bit Our Register 5 */ ++#define PCIE_ER_MASK 0x008C /* 32 bit Error Reporting ++ * Mask Register ++ */ ++#define CONFIG 0x0090 /* 32 bit Config Register */ ++#define PCIE_CAP_ID 0x00E0 /* 8 bit PE Capability ID ++ * Register (PM Cap ++ * ID) ++ */ ++#define PCIE_NPTR 0x00E1 /* 8 bit PE Next Item ++ * Pointer Register ++ */ ++#define PCIE_CAP 0x00E2 /* 16 bit PE Capabilities ++ * Register ++ */ ++#define DEVICE_CAPABILITIES_REGISTER 0x00E4 /* 32 bit Device Capabilities ++ * Register ++ */ ++#define PCIE_DEVCTRL 0x00E8 /* 16 bit Device Control ++ * Register ++ */ ++#define PCIE_DEVSTAT 0x00EA /* 16 bit Device Status ++ * Register ++ */ ++#define PCIE_LNKCAP 0x00EC /* 32 bit Link Capabilities ++ * Register ++ */ ++#define PCIE_LNKCTRL 0x00F0 /* 16 bit Link Control ++ * Register ++ */ ++#define PCIE_LNKSTAT 0x00F2 /* 16 bit Link Status Register */ ++#define PCIE_AE_CAP_HDR 0x0100 /* 32 bit Advanced Error ++ * Reporting ++ * Enhanced ++ * Capability Header ++ * Register ++ */ ++#define PCIE_UE_STAT 0x0104 /* 32 bit Uncorrectable Error ++ * Status Register ++ */ ++#define PCIE_UE_MASK 0x0108 /* 32 bit Uncorrectable Error ++ * Mask Register ++ */ ++#define PCIE_UE_SVRT 0x010C /* 32 bit Uncorrectable Error ++ * Severity Register ++ */ ++#define PCIE_CA_STAT 0x0110 /* 32 bit Correctable Error ++ * Status Register ++ */ ++#define PCIE_CA_MASK 0x0114 /* 32 bit Correctable Error ++ * Mask Register ++ */ ++#define PCIE_AE_CAPCTRL 0x0118 /* 32 bit Advanced Error ++ * Capabilities and ++ * Control Register ++ */ ++#define PCIE_HDRLOG 0x011C /* 13 bit Header Log Registers */ ++#define PCIE_TL_CTRL 0x0200 /* 32 bit Transaction Layer ++ * Control Register ++ */ ++#define PCIE_TL_STAT 0x0204 /* 32 bit Transaction Layer ++ * Status Register ++ */ ++#define PCIE_DL_CTRL 0x0208 /* 32 bit Data Link Layer ++ * Control Register ++ */ ++#define PCIE_DL_STAT 0x020C /* 32 bit Data Link Layer ++ * Status Register ++ */ ++#define PCIE_PL_CTRL 0x0210 /* 32 bit PE Physical Layer ++ * Control Register ++ */ ++#define PCIE_PL_STAT 0x0214 /* 32 bit PE Physical Layer ++ * Status Register ++ */ ++#define PCIE_CPLTO 0x0220 /* 32 bit PE Completion ++ * Timeout Register ++ */ ++#define PCIE_FC 0x0224 /* 32 bit PE Flow Control ++ * Register ++ */ ++#define PCIE_ACKTIM_X1 0x0228 /* 32 bit PE Ack Timer for 1x ++ * Link Register ++ */ ++ ++/* ++ * ++ * THE BIT DEFINES ++ * ++ */ ++/* PCI_VEN_ID 0x0000 Vendor ID Register */ ++#define PCI_VEN_ID_MSK SHIFT0(0xffffS) /* Vendor ID */ ++#define PCI_VEN_ID_BASE BIT_0S ++ ++/* PCI_DEV_ID 0x0002 Device ID Register */ ++#define PCI_DEV_ID_MSK SHIFT0(0xffffS) /* Device ID */ ++#define PCI_DEV_ID_BASE BIT_0S ++ ++/* PCI_CMD 0x0004 Command Register */ ++/* Bit(s) PCI_CMD_RSRV_4_0 reserved */ ++#define PCI_CMD_INT_DIS BIT_10S /* Interrupt Disable */ ++/* Bit(s) PCI_CMD_RSRV_ reserved */ ++#define PCI_CMD_SERR_ENA BIT_8S /* SERR Enable */ ++/* Bit(s) PCI_CMD_RSRV_ reserved */ ++#define PCI_CMD_PERREN BIT_6S /* PERREN */ ++/* Bit(s) PCI_CMD_RSRV_2_0 reserved */ ++#define PCI_CMD_BMEN BIT_2S /* BMEN */ ++#define PCI_CMD_MEMEN BIT_1S /* MEMEN */ ++#define PCI_CMD_IOEN BIT_0S /* IOEN */ ++ ++/* PCI_STAT 0x0006 Status Register */ ++#define PCI_STAT_PERR BIT_15S /* PERR */ ++#define PCI_STAT_SERR BIT_14S /* SERR */ ++#define PCI_STAT_RMABORT BIT_13S /* RMABORT */ ++#define PCI_STAT_RTABORT BIT_12S /* RTABORT */ ++/* Bit(s) PCI_STAT_RSRV_2_0 reserved */ ++#define PCI_STAT_DATAPERR BIT_8S /* DATAPERR */ ++/* Bit(s) PCI_STAT_RSRV_2_0 reserved */ ++#define PCI_STAT_NEWCAP BIT_4S /* NEWCAP */ ++#define PCI_STAT_INTSTA BIT_3S /* INTSTA */ ++/* Bit(s) PCI_STAT_RSRV_2_0 reserved */ ++ ++/* PCI_REV_ID 0x0008 Revision ID Register */ ++#define PCI_REV_ID_MSK SHIFT0(0xffS) /* Revision ID */ ++#define PCI_REV_ID_BASE BIT_0S ++ ++/* PCI_PIF 0x0009 Programming Interface Register, ++ * Lower Byte ++ */ ++#define PCI_PIF_MSK SHIFT0(0xffS) /* Prog IF */ ++#define PCI_PIF_BASE BIT_0S ++ ++/* PCI_SCC 0x000A Sub-Class Register, Middle Byte */ ++#define PCI_SCC_MSK SHIFT0(0xffS) /* Sub Class */ ++#define PCI_SCC_BASE BIT_0S ++ ++/* PCI_BCC 0x000B Base-Class Register, Upper Byte */ ++#define PCI_BCC_MSK SHIFT0(0xffS) /* Base Class */ ++#define PCI_BCC_BASE BIT_0S ++ ++/* PCI_CLS 0x000C Cache Line Size Register */ ++/* Bit(s) PCI_CLS_RSRV_7_0 reserved */ ++ ++/* PCI_LAT_TIM 0x000D Latency Timer Register */ ++/* Bit(s) PCI_LAT_TIM_RSRV_7_0 reserved */ ++ ++/* PCI_HDRTYP 0x000E Header Type Register */ ++/* Bit(s) PCI_HDRTYP_RSRV_7_0 reserved */ ++ ++/* PCI_BIST 0x000F Built-in Self Test (BIST) Register */ ++#define PCI_BIST_MSK SHIFT0(0xffS) /* */ ++#define PCI_BIST_BASE BIT_0S ++ ++/* PCI_BAR1_LO 0x0010 Base Address Register (1st), Lower ++ * Address ++ */ ++#define PCI_BAR1_LO_BASE_MSK SHIFT14(0x3ffff) /* Lower MEMBASE Address */ ++#define PCI_BAR1_LO_BASE_BASE BIT_14 ++#define PCI_BAR1_LO_SIZE_MSK SHIFT4(0x3ff) /* MEMSIZE */ ++#define PCI_BAR1_LO_SIZE_BASE BIT_4 ++#define PCI_BAR1_LO_PREFEN BIT_3 /* PREFEN */ ++#define PCI_BAR1_LO_TYPE_MSK SHIFT1(0x3) /* Memory Type */ ++#define PCI_BAR1_LO_TYPE_BASE BIT_1 ++#define PCI_BAR1_LO_IO_SPC BIT_0 /* MEMSPACE */ ++ ++/* PCI_BAR1_HI 0x0014 Base Address Register (1st), Upper ++ * Address ++ */ ++#define PCI_BAR1_HI_BASE_MSK SHIFT0(0xffffffff) /* Upper MEMBASE */ ++#define PCI_BAR1_HI_BASE_BASE BIT_0 ++ ++/* PCI_BAR2 0x0018 Base Address Register (2nd) */ ++#define PCI_BAR2_BASE_MSK SHIFT8(0xffffff) /* IOBASE */ ++#define PCI_BAR2_BASE_BASE BIT_8 ++#define PCI_BAR2_SIZE_MSK SHIFT2(0x3f) /* IOSIZE */ ++#define PCI_BAR2_SIZE_BASE BIT_2 ++/* Bit(s) PCI_BAR2_RSRV_ reserved */ ++#define PCI_BAR2_IO_SPC BIT_0 /* IOSPACE */ ++ ++/* PCI_SSVEN_ID 0x002C Subsystem Vendor ID Register */ ++#define PCI_SSVEN_ID_MSK SHIFT0(0xffffS) /* Subsystem Vendor ID */ ++#define PCI_SSVEN_ID_BASE BIT_0S ++ ++/* PCI_SSDEV_ID 0x002E Subsystem ID Register */ ++#define PCI_SSDEV_ID_MSK SHIFT0(0xffffS) /* Subsystem ID */ ++#define PCI_SSDEV_ID_BASE BIT_0S ++ ++/* PCI_ERBAR 0x0030 Expansion Rom Base Address Register */ ++#define PCI_ERBAR_BASE_MSK SHIFT17(0x7fff) /* Rombase */ ++#define PCI_ERBAR_BASE_BASE BIT_17 ++#define PCI_ERBAR_BASE_SIZE_MSK SHIFT14(0x7) /* Rombase/size */ ++#define PCI_ERBAR_BASE_SIZE_BASE BIT_14 ++#define PCI_ERBAR_SIZE_MSK SHIFT11(0x7) /* Romsize */ ++#define PCI_ERBAR_SIZE_BASE BIT_11 ++/* Bit(s) PCI_ERBAR_RSRV_9_0 reserved */ ++#define PCI_ERBAR_ENA BIT_0 /* ROMEN */ ++ ++/* PCI_NCAP_PTR 0x0034 New Capabilities Pointer (New Cap ++ * Ptr) Register ++ */ ++#define PCI_NCAP_PTR_MSK SHIFT0(0xffS) /* New Capabilities Pointer */ ++#define PCI_NCAP_PTR_BASE BIT_0S ++ ++/* PCI_INT_LINE 0x003C Interrupt Line Register */ ++#define PCI_INT_LINE_MSK SHIFT0(0xffS) /* Interrupt Line */ ++#define PCI_INT_LINE_BASE BIT_0S ++ ++/* PCI_INT_PIN 0x003D Interrupt Pin Register */ ++#define PCI_INT_PIN_MSK SHIFT0(0xffS) /* Interrupt Pin */ ++#define PCI_INT_PIN_BASE BIT_0S ++ ++/* PCI_MIN_GNT 0x003E Min_Gnt Register */ ++/* Bit(s) PCI_MIN_GNT_RSRV_7_0 reserved */ ++ ++/* PCI_MAX_LAT 0x003F Max_Lat Register */ ++/* Bit(s) PCI_MAX_LAT_RSRV_7_0 reserved */ ++ ++/* PCI_OUR1 0x0040 Our Register 1 */ ++#define PCI_OUR1_RUN_PIG BIT_31 /* Run_PiG */ ++#define PCI_OUR1_SW_POR BIT_30 /* SW POR */ ++/* Enable Gen Preset during SW POR */ ++#define PCI_OUR1_EN_GEN_PRSET BIT_29 ++#define PCI_OUR1_GP_COMA BIT_28 /* PHY Coma Mode */ ++#define PCI_OUR1_DIS_SPI_LOAD BIT_27 /* Disable SPI Loader */ ++#define PCI_OUR1_GP_PWD BIT_26 /* PHY Power Down Mode */ ++#define PCI_OUR1_DIS_VPD_LOAD BIT_25 /* Disable VPD Loader */ ++#define PCI_OUR1_ENBOOT BIT_24 /* En Boot */ ++#define PCI_OUR1_ENIOMAP BIT_23 /* En IO Mapping */ ++#define PCI_OUR1_ENEPROM BIT_22 /* En Eprom */ ++#define PCI_OUR1_PAGE_SIZ_MSK SHIFT20(0x3) /* Pagesize<1:0> */ ++#define PCI_OUR1_PAGE_SIZ_BASE BIT_20 ++/* Bit(s) PCI_OUR1_RSRV_ reserved */ ++#define PCI_OUR1_PAGE_SEL_MSK SHIFT16(0x7) /* Page Reg<2:0> */ ++#define PCI_OUR1_PAGE_SEL_BASE BIT_16 ++#define PCI_OUR1_DBG_PEX_PME BIT_15 /* DEBUG_PEX_PME */ ++/* Bit(s) PCI_OUR1_RSRV_4_0 reserved */ ++/* Timer for GPHY Link Trigger */ ++#define PCI_OUR1_GP_TRIG_TIM_MSK SHIFT8(0x3) ++#define PCI_OUR1_GP_TRIG_TIM_BASE BIT_8 ++#define PCI_OUR1_L1_EVT_ENA BIT_7 /* L1 Event Enable */ ++#define PCI_OUR1_GP_LNK_ENA BIT_6 /* Enable GPHY Link */ ++#define PCI_OUR1_FORCE_L1 BIT_5 /* Force to L1 */ ++/* Bit(s) PCI_OUR1_RSRV_4_0 reserved */ ++ ++/* PCI_OUR2 0x0044 Our Register 2 */ ++/* Bit(s) PCI_OUR2_RSRV_7_0 reserved */ ++#define PCI_OUR2_VPD_DEVSEL_MSK SHIFT17(0x7f) /* VPD Devsel */ ++#define PCI_OUR2_VPD_DEVSEL_BASE BIT_17 ++#define PCI_OUR2_VPD_ROMSIZE_MSK SHIFT14(0x7) /* VPD ROM Size */ ++#define PCI_OUR2_VPD_ROMSIZE_BASE BIT_14 ++/* Bit(s) PCI_OUR2_RSRV_13_0 reserved */ ++ ++/* PCI_PM_CAP_ID 0x0048 Power Management Capability ID ++ * Register (PM Cap ID) ++ */ ++#define PCI_PM_CAP_ID_MSK SHIFT0(0xffS) /* Cap ID */ ++#define PCI_PM_CAP_ID_BASE BIT_0S ++ ++/* PCI_PM_NXT_PTR 0x0049 Power Management Next Item Pointer ++ * Register ++ */ ++#define PCI_PM_NXT_PTR_MSK SHIFT0(0xffS) /* Next Item Ptr */ ++#define PCI_PM_NXT_PTR_BASE BIT_0S ++ ++/* PCI_PM_CAP 0x004A Power Management Capabilities ++ * Register ++ */ ++#define PCI_PM_CAP_D3C_ENA BIT_15S /* PME Support */ ++#define PCI_PM_CAP_D3H_ENA BIT_14S /* PME Support */ ++#define PCI_PM_CAP_D2_ENA BIT_13S /* PME Support */ ++#define PCI_PM_CAP_D1_ENA BIT_12S /* PME Support */ ++#define PCI_PM_CAP_D0_ENA BIT_11S /* PME Support */ ++#define PCI_PM_CAP_D2_SUP BIT_10S /* D2 Support */ ++#define PCI_PM_CAP_D1_SUP BIT_9S /* D1 Support */ ++/* Bit(s) PCI_PM_CAP_RSRV_2_0 reserved */ ++#define PCI_PM_CAP_DSI_ENA BIT_5S /* DSI */ ++/* Bit(s) PCI_PM_CAP_RSRV_1_0 reserved */ ++#define PCI_PM_CAP_VER_ID_MSK SHIFT0(0x7S) /* Version */ ++#define PCI_PM_CAP_VER_ID_BASE BIT_0S ++ ++/* PCI_PM_CSR 0x004C Power Management Control/Status ++ * Register ++ */ ++#define PCI_PM_CSR_PME_STAT BIT_15S /* PME Status */ ++#define PCI_PM_CSR_D_SCALE_MSK SHIFT13(0x3S) /* Data Scale */ ++#define PCI_PM_CSR_D_SCALE_BASE BIT_13S ++#define PCI_PM_CSR_D_SEL_MSK SHIFT9(0xfS) /* Data Select */ ++#define PCI_PM_CSR_D_SEL_BASE BIT_9S ++#define PCI_PM_CSR_PMEEN BIT_8S /* PME En */ ++/* Bit(s) PCI_PM_CSR_RSRV_5_0 reserved */ ++#define PCI_PM_CSR_PWST_MSK SHIFT0(0x3S) /* Power State */ ++#define PCI_PM_CSR_PWST_BASE BIT_0S ++ ++/* PCI_PM_DATA 0x004F Power Management Data Register */ ++#define PCI_PM_DATA_MSK SHIFT0(0xffS) /* Data */ ++#define PCI_PM_DATA_BASE BIT_0S ++ ++/* PCI_VPD_CAP_ID 0x0050 VPD Capability ID Register (VPD ++ * Cap ID) ++ */ ++#define PCI_VPD_CAP_ID_MSK SHIFT0(0xffS) /* Cap ID */ ++#define PCI_VPD_CAP_ID_BASE BIT_0S ++ ++/* PCI_VPD_NPTR 0x0051 VPD Next Item Pointer Register */ ++#define PCI_VPD_NPTR_MSK SHIFT0(0xffS) /* Next Item Ptr */ ++#define PCI_VPD_NPTR_BASE BIT_0S ++ ++/* PCI_VPD_ADDR 0x0052 VPD Address Register */ ++#define PCI_VPD_ADDR_FLAG BIT_15S /* Flag */ ++#define PCI_VPD_ADDR_MSK SHIFT0(0x7fffS) /* VPD Address */ ++#define PCI_VPD_ADDR_BASE BIT_0S ++ ++/* PCI_VPD_DATA 0x0054 VPD Data Register */ ++#define PCI_VPD_DATA_MSK SHIFT0(0xffffffff) /* VPD Data */ ++#define PCI_VPD_DATA_BASE BIT_0 ++ ++/* PCI_LDR_CTRL 0x005A TWSI EEPROM Loader Control Register */ ++#define PCI_LDR_CTRL_FLAG BIT_15S /* Flag */ ++#define PCI_LDR_CTRL_ADDR_MSK SHIFT0(0x7fffS) /* TWSI EEPROM Address */ ++#define PCI_LDR_CTRL_ADDR_BASE BIT_0S ++ ++/* PCI_MSI_CAP_ID 0x005C MSI Capability ID Register (MSI ++ * Cap ID) ++ */ ++#define PCI_MSI_CAP_ID_MSK SHIFT0(0xffS) /* Cap ID */ ++#define PCI_MSI_CAP_ID_BASE BIT_0S ++ ++/* PCI_MSI_NPTR 0x005D MSI Next Item Pointer Register */ ++#define PCI_MSI_NPTR_MSK SHIFT0(0xffS) /* Next Item Ptr */ ++#define PCI_MSI_NPTR_BASE BIT_0S ++ ++/* PCI_MSI_CTRL 0x005E MSI Message Control Register */ ++/* Bit(s) PCI_MSI_CTRL_RSRV_7_0 reserved */ ++#define PCI_MSI_CTRL_64CAP BIT_7S /* 64 Bit Addr capable */ ++#define PCI_MSI_CTRL_MM_ENA_MSK SHIFT4(0x7S) /* Multiple Message Enable */ ++#define PCI_MSI_CTRL_MM_ENA_BASE BIT_4S ++#define PCI_MSI_CTRL_MM_CAP_MSK SHIFT1(0x7S) /* Multiple Message Capable */ ++#define PCI_MSI_CTRL_MM_CAP_BASE BIT_1S ++#define PCI_MSI_CTRL_ENA BIT_0S /* MSI Enable */ ++ ++/* PCI_MSI_ADDR_LO 0x0060 MSI Message Address Register, ++ * Lower Address ++ */ ++/* MSI Message Address, Lower Address */ ++#define PCI_MSI_ADDR_LO_MSK SHIFT2(0x3fffffff) ++#define PCI_MSI_ADDR_LO_BASE BIT_2 ++/* Bit(s) PCI_MSI_ADDR_LO_RSRV_1_0 reserved */ ++ ++/* PCI_MSI_ADDR_HI 0x0064 MSI Message Address Register, ++ * Upper Address ++ */ ++/* MSI Message Address, Upper Address */ ++#define PCI_MSI_ADDR_HI_MSK SHIFT0(0xffffffff) ++#define PCI_MSI_ADDR_HI_BASE BIT_0 ++ ++/* PCI_MSI_DATA 0x0068 MSI Message Data Register */ ++/* Bit(s) PCI_MSI_DATA_RSRV_15_0 reserved */ ++#define PCI_MSI_DATA_MSK SHIFT0(0xffff) /* Message Data */ ++#define PCI_MSI_DATA_BASE BIT_0 ++ ++/* PCIE_STAT 0x0070 PCI Express Status Register */ ++/* Bit(s) PCIE_STAT_RSRV_1_0 reserved */ ++#define PCIE_STAT_FIX_MSK SHIFT16(0x3fff) /* Fixed value */ ++#define PCIE_STAT_FIX_BASE BIT_16 ++#define PCIE_STAT_BUS_NUM_MSK SHIFT8(0xff) /* Request ID (Bus Number) */ ++#define PCIE_STAT_BUS_NUM_BASE BIT_8 ++#define PCIE_STAT_DEV_NUM_MSK SHIFT3(0x1f) /* Request ID (Device Number) */ ++#define PCIE_STAT_DEV_NUM_BASE BIT_3 ++#define PCIE_STAT_FUN_NUM_MSK SHIFT0(0x7) /* Request ID (Function Number) */ ++#define PCIE_STAT_FUN_NUM_BASE BIT_0 ++ ++/* PCIE_OUR_STAT 0x007C Our Status Register */ ++/* Bit(s) PCIE_OUR_STAT_RSRV_5_0 reserved */ ++#define PCIE_OUR_STAT_DLL_ERR_MSK SHIFT24(0x3) /* DLL Err */ ++#define PCIE_OUR_STAT_DLL_ERR_BASE BIT_24 ++#define PCIE_OUR_STAT_DLL_ROW_MSK SHIFT20(0xf) /* DLL Row */ ++#define PCIE_OUR_STAT_DLL_ROW_BASE BIT_20 ++#define PCIE_OUR_STAT_DLL_COL_MSK SHIFT16(0xf) /* DLL Col */ ++#define PCIE_OUR_STAT_DLL_COL_BASE BIT_16 ++/* Bit(s) PCIE_OUR_STAT_RSRV_15_0 reserved */ ++ ++/* PCIE_OUR3 0x0080 Our Register 3 */ ++/* Mask L0 condition */ ++#define PCIE_OUR3_MASK_L0_COMMA BIT_31 ++/* Mask L0s condition */ ++#define PCIE_OUR3_MASK_L0S_COMMA BIT_30 ++/* Select MACSec clock */ ++#define PCIE_OUR3_MACSEC_CLK_SEL BIT_29 ++/* Bit(s) PCIE_OUR3_RSRV_9_0 reserved */ ++#define PCIE_OUR3_CLK_ASF_REGS_DIS BIT_18 /* disable clk_asf */ ++/* disable clk_macsec */ ++#define PCIE_OUR3_CLK_MACSEC_REGS_DIS BIT_17 ++/* disable clk_pci_regs_d0 */ ++#define PCIE_OUR3_CLK_PCI_REGS_DIS BIT_16 ++/* disable clk_core_ytb_arb */ ++#define PCIE_OUR3_CLK_CORE_YTB_ARB_DIS BIT_15 ++/* disable clk_mac_lnk1_d3 */ ++#define PCIE_OUR3_CLK_MAC_LNK1_D3_DIS BIT_14 ++/* disable clk_core_lnk1_d0 */ ++#define PCIE_OUR3_CLK_CORE_LNK1_D0_DIS BIT_13 ++/* disable clk_mac_lnk1_d0 */ ++#define PCIE_OUR3_CLK_MAC_LNK1_D0_DIS BIT_12 ++/* disable clk_core_lnk1_d3 */ ++#define PCIE_OUR3_CLK_CORE_LNK1_D3_DIS BIT_11 ++/* disable clk_pci_master_arb */ ++#define PCIE_OUR3_CLK_PCI_MST_ARB_DIS BIT_10 ++/* disable clk_core_regs_d3 */ ++#define PCIE_OUR3_CLK_CORE_REGS_D3_DIS BIT_9 ++/* disable clk_pci_regs_d3 */ ++#define PCIE_OUR3_CLK_PCI_REGS_D3_DIS BIT_8 ++/* disable clk_ref_lnk1_gmac */ ++#define PCIE_OUR3_CLK_REF_LNK1_GMAC_DIS BIT_7 ++/* disable clk_core_lnk1_gmac */ ++#define PCIE_OUR3_CLK_CORE_LNK1_GMAC_DIS BIT_6 ++/* disable clk_pci_common */ ++#define PCIE_OUR3_CLK_PCI_COM_DIS BIT_5 ++/* disable clk_core_common */ ++#define PCIE_OUR3_CLK_CORE_COM_DIS BIT_4 ++/* disable clk_pci_lnk1_bmu */ ++#define PCIE_OUR3_CLK_PCI_LNK1_BMU_DIS BIT_3 ++/* disable clk_core_lnk1_bmu */ ++#define PCIE_OUR3_CLK_CORE_LNK1_BMU_DIS BIT_2 ++/* disable pci_clk_biu */ ++#define PCIE_OUR3_PCI_CLK_BIU_DIS BIT_1 ++/* disable clk_core_biu */ ++#define PCIE_OUR3_CLK_CORE_BIU_DIS BIT_0 ++ ++/* PCIE_OUR4 0x0084 Our Register 4 */ ++/* PEXUNIT LTSSM State for Gating Core Clock */ ++#define PCIE_OUR4_PEX_LTSSM_STATE_MSK SHIFT25(0x7f) ++#define PCIE_OUR4_PEX_LTSSM_STATE_BASE BIT_25 ++#define PCIE_OUR4_GPHY_INT_ASPM BIT_24 /* GPHY get INT */ ++#define PCIE_OUR4_TIM_VAL_MSK SHIFT16(0xff) /* Timer Value */ ++#define PCIE_OUR4_TIM_VAL_BASE BIT_16 ++/* Force ASPM Request */ ++#define PCIE_OUR4_FORCE_ASPM_REQ BIT_15 ++#define PCIE_OUR4_GPHY_LNK_DOWN BIT_14 /* GPHY Link Down */ ++/* Internal FIFO Empty */ ++#define PCIE_OUR4_INT_FIFO_EMPTY BIT_13 ++#define PCIE_OUR4_CLKRUN_REQ BIT_12 /* Clkrun Request */ ++/* Enable EC SMBUS Pin mode */ ++#define PCIE_OUR4_EN_EC_SMBUS_PIN BIT_11 ++/* Enable PCIE RX Overflow status */ ++#define PCIE_OUR4_EN_PCIE_RX_OVERFLOW BIT_10 ++/* Enable ASPM at No-D0 mode */ ++#define PCIE_OUR4_EN_ASPM_NOND0 BIT_9 ++/* Enable PIN#63 as LED_LIN */ ++#define PCIE_OUR4_EN_LED_LINK_PIN63 BIT_8 ++/* Force ASPM L1 Enable */ ++#define PCIE_OUR4_FORCE_ASPM_L1_ENA BIT_7 ++/* Force ASPM L0s Enable */ ++#define PCIE_OUR4_FORCE_ASPM_L0S_ENA BIT_6 ++/* Force CLKREQn Pin Low */ ++#define PCIE_OUR4_FORCE_CLKREQN_PIN_LO BIT_5 ++/* Force CLKREQ Scheme Enable */ ++#define PCIE_OUR4_FORCE_CLKREQ_SCHEME_ENA BIT_4 ++/* CLKREQn PAD Control */ ++#define PCIE_OUR4_CLKREQN_PAD_CTRL BIT_3 ++#define PCIE_OUR4_A1_MODE_SEL BIT_2 /* A1 Mode Select */ ++/* Enable Gate Pexunit Clock */ ++#define PCIE_OUR4_GATE_PEXUNIT_CLK_ENA BIT_1 ++/* Enable Gate Root Core Clock */ ++#define PCIE_OUR4_GATE_ROOT_CORE_CLK_ENA BIT_0 ++ ++/* PCIE_OUR5 0x0088 Our Register 5 */ ++/* Divide Core Clock Enable */ ++#define PCIE_OUR5_DIV_CORE_CLK_ENA BIT_31 ++/* Soft Reset for Vmain_avlbl De-Glitch Logic */ ++#define PCIE_OUR5_SOFT_RST_VMAIN_DEGLITCH BIT_30 ++/* Bypass Enable for Vmain_avlbl De-Glitch */ ++#define PCIE_OUR5_BYPASS_VMAIN_DEGLITCH_ENA BIT_29 ++/* Timer of Vmain_avlbl De-Glitch */ ++#define PCIE_OUR5_TIM_VMAIN_DEGLITCH_MSK SHIFT27(0x3) ++#define PCIE_OUR5_TIM_VMAIN_DEGLITCH_BASE BIT_27 ++/* PCI-E Reset De-Asserted */ ++#define PCIE_OUR5_PCIE_RST_DEASS BIT_26 ++/* GPHY Received Packet */ ++#define PCIE_OUR5_GPHY_RX_PKT BIT_25 ++/* Internal FIFO Not Empty */ ++#define PCIE_OUR5_INT_FIFO_NOT_EMPTY BIT_24 ++/* Main Power is Available */ ++#define PCIE_OUR5_MAIN_PWR_AVL BIT_23 ++#define PCIE_OUR5_CLKRUN_REQ BIT_22 /* CLKRUN Request */ ++/* PCI-E Reset Asserted */ ++#define PCIE_OUR5_PCIE_RST_ASS BIT_21 ++#define PCIE_OUR5_PME_ASS BIT_20 /* PME Asserted */ ++/* PCI-E Exits L1 State */ ++#define PCIE_OUR5_PCIE_EX_L1_STATE BIT_19 ++/* EPROM Loader Not Finished */ ++#define PCIE_OUR5_EPROM_LDR_NOT_FIN BIT_18 ++/* PCI-E RX Exits ELEC IDLE */ ++#define PCIE_OUR5_PCIE_RX_EX_ELEC_IDLE BIT_17 ++#define PCIE_OUR5_GPHY_LNK_UP BIT_16 /* GPHY Link Up */ ++/* CPU Goes to Sleep */ ++#define PCIE_OUR5_CPU_SLEEP BIT_15 ++#define PCIE_OUR5_GPHY_INT BIT_14 /* GPHY get INT */ ++/* Bit(s) PCIE_OUR5_RSRV_ reserved */ ++#define PCIE_OUR5_GPHY_INT_EV BIT_12 /* GPHY get INT */ ++/* CPU Goes to Sleep and Events */ ++#define PCIE_OUR5_CPU_SLEEP_EV BIT_11 ++/* PCI-E Reset Asserted and Events */ ++#define PCIE_OUR5_PCIE_RST_ASS_EV BIT_10 ++/* GPHY Not Received Packet */ ++#define PCIE_OUR5_GPHY_NOT_RX_PKT BIT_9 ++/* Internal FIFO Empty */ ++#define PCIE_OUR5_INTERNAL_FIFO_EMPTY BIT_8 ++/* Main Power is Not Available */ ++#define PCIE_OUR5_MAIN_PWR_NOT_AVL BIT_7 ++/* CLKRUN Not Requested */ ++#define PCIE_OUR5_CLKRUN_NOT_REQ BIT_6 ++/* PCI-E Reset De-Asserted and Events */ ++#define PCIE_OUR5_PCIE_RST_DEASS_EV BIT_5 ++#define PCIE_OUR5_PME_DEASS BIT_4 /* PME De-Asserted */ ++/* PCI-E Goes to L1 State */ ++#define PCIE_OUR5_PCIE_GO_L1_STATE BIT_3 ++/* EPROM Loader Finished */ ++#define PCIE_OUR5_EPROM_LDR_FIN BIT_2 ++/* PCI-E Rx ELEC IDLE */ ++#define PCIE_OUR5_PCIE_RX_ELEC_IDLE BIT_1 ++#define PCIE_OUR5_GPHY_LNK_DOWN BIT_0 /* GPHY Link Down */ ++ ++/* PCIE_ER_MASK 0x008C Error Reporting Mask Register */ ++/* Enable the Device Feature Set SERR */ ++#define PCIE_ER_MASK_DEV_FEAT_SET_SERR_ENA BIT_31 ++/* Bit(s) PCIE_ER_MASK_RSRV_2_0 reserved */ ++/* Enable Uncorretable Error (UR Error) */ ++#define PCIE_ER_MASK_UR_ENA BIT_27 ++/* Enable Uncorretable Error (ECRC Error) */ ++#define PCIE_ER_MASK_ECRCERR_ENA BIT_26 ++/* Enable Uncorretable Error (Malformed TLP) */ ++#define PCIE_ER_MASK_MTLP_ENA BIT_25 ++/* Enable Uncorretable Error (RX Overflow) */ ++#define PCIE_ER_MASK_RCVOVFL_ENA BIT_24 ++/* Enable Uncorretable Error (Unexpected Completion) */ ++#define PCIE_ER_MASK_UNEXPCPL_ENA BIT_23 ++/* Enable Uncorretable Error (Completer Abort) */ ++#define PCIE_ER_MASK_CPLABRT_ENA BIT_22 ++/* Enable Uncorretable Error (Completion Timeout) */ ++#define PCIE_ER_MASK_CPLTO_ENA BIT_21 ++/* Enable Uncorretable Error (Flow Control Protocol Error) */ ++#define PCIE_ER_MASK_FCPROTERR_ENA BIT_20 ++/* Enable Uncorretable Error (Posioned TLP) */ ++#define PCIE_ER_MASK_PTLP_ENA BIT_19 ++/* Enable Uncorretable Error (Data Link Protocol Error) */ ++#define PCIE_ER_MASK_DLPRTERR_ENA BIT_18 ++/* Enable Uncorretable Error (Training Error) */ ++#define PCIE_ER_MASK_TRAINERR_ENA BIT_17 ++/* Bit(s) PCIE_ER_MASK_RSRV_ reserved */ ++/* Enable Uncorretable Error (UR Error) Send Error Message */ ++#define PCIE_ER_MASK_UR_SEND_ENA BIT_15 ++/* Enable Uncorretable Error (ECRC Error) Send Error Message */ ++#define PCIE_ER_MASK_ECRCERR_SEND_ENA BIT_14 ++/* Enable Uncorretable Error (Malformed TLP) Send Error Message */ ++#define PCIE_ER_MASK_MTLP_SEND_ENA BIT_13 ++/* Enable Uncorretable Error (RX Overflow) Send Error Message */ ++#define PCIE_ER_MASK_RCVOVFL_SEND_ENA BIT_12 ++/* Enable Uncorretable Error (Unexpected Completion) Send Error Message */ ++#define PCIE_ER_MASK_CPLUC_SEND_ENA BIT_11 ++/* Enable Uncorretable Error (Completer Abort) Send Error Message */ ++#define PCIE_ER_MASK_CPLABRT_SEND_ENA BIT_10 ++/* Enable Uncorretable Error (Completion Timeout) Send Error Message */ ++#define PCIE_ER_MASK_CPLTO_SEND_ENA BIT_9 ++/* Enable Uncorretable Error (Flow Control Protocol Error) Send Error Message */ ++#define PCIE_ER_MASK_FCPROTERR_SEND_ENA BIT_8 ++/* Enable Uncorretable Error (Posioned TLP) Send Error Message */ ++#define PCIE_ER_MASK_PTLP_SEND_ENA BIT_7 ++/* Enable Uncorretable Error (Data Link Protocol Error) Send Error Message */ ++#define PCIE_ER_MASK_DLPRTERR_SEND_ENA BIT_6 ++/* Enable Uncorretable Error (Training Error) Send Error Message */ ++#define PCIE_ER_MASK_TRAINERR_SEND_ENA BIT_5 ++/* Enable Corretable Error (Replay Timer Timeout) Send Error Message */ ++#define PCIE_ER_MASK_RPLYTO_SEND_ENA BIT_4 ++/* Enable Corretable Error (REPLAY_NUM RollOver) Send Error Message */ ++#define PCIE_ER_MASK_RPLYNUMRO_SEND_ENA BIT_3 ++/* Enable Corretable Error (Bad DLLP) Send Error Message */ ++#define PCIE_ER_MASK_BADDLLP_SEND_ENA BIT_2 ++/* Enable Corretable Error (Bad TLP) Send Error Message */ ++#define PCIE_ER_MASK_BADTLP_SEND_ENA BIT_1 ++/* Enable Corretable Error (RX Error) Send Error Message */ ++#define PCIE_ER_MASK_RXERR_SEND_ENA BIT_0 ++ ++/* CONFIG 0x0090 Config Register */ ++/* Bit(s) CONFIG_RSRV_30_0 reserved */ ++#define CONFIG_CPU_LOCK_VPD BIT_0 /* uC lock VPD */ ++ ++/* PCIE_CAP_ID 0x00E0 PE Capability ID Register (PM Cap ++ * ID) ++ */ ++#define PCIE_CAP_ID_MSK SHIFT0(0xffS) /* Cap ID */ ++#define PCIE_CAP_ID_BASE BIT_0S ++ ++/* PCIE_NPTR 0x00E1 PE Next Item Pointer Register */ ++#define PCIE_NPTR_MSK SHIFT0(0xffS) /* Next Item Ptr */ ++#define PCIE_NPTR_BASE BIT_0S ++ ++/* PCIE_CAP 0x00E2 PE Capabilities Register */ ++/* Bit(s) PCIE_CAP_RSRV_1_0 reserved */ ++#define PCIE_CAP_INTMSG_NUM_MSK SHIFT9(0x1fS) /* Interrupt Message Number */ ++#define PCIE_CAP_INTMSG_NUM_BASE BIT_9S ++/* Bit(s) PCIE_CAP_RSRV_ reserved */ ++#define PCIE_CAP_PORT_TYP_MSK SHIFT4(0xfS) /* Device/Port Type */ ++#define PCIE_CAP_PORT_TYP_BASE BIT_4S ++#define PCIE_CAP_CAP_VER_MSK SHIFT0(0xfS) /* Capability Version */ ++#define PCIE_CAP_CAP_VER_BASE BIT_0S ++ ++/* DEVICE_CAPABILITIES_REGISTER 0x00E4 Device Capabilities Register */ ++/* Bit(s) DEVICE_CAPABILITIES_REGISTER_RSRV_3_0 reserved */ ++/* Captured Slot Power Limit Scale */ ++#define DEVICE_CAPABILITIES_REGISTER_SPL_SCALE_MSK SHIFT26(0x3) ++#define DEVICE_CAPABILITIES_REGISTER_SPL_SCALE_BASE BIT_26 ++/* Captured Slot Power Limit Value */ ++#define DEVICE_CAPABILITIES_REGISTER_SPL_VAL_MSK SHIFT18(0xff) ++#define DEVICE_CAPABILITIES_REGISTER_SPL_VAL_BASE BIT_18 ++/* Bit(s) DEVICE_CAPABILITIES_REGISTER_RSRV_2_0 reserved */ ++/* Power Indicator Present */ ++#define DEVICE_CAPABILITIES_REGISTER_PI_PRS BIT_14 ++/* Attention Indicator Present */ ++#define DEVICE_CAPABILITIES_REGISTER_AI_PRS BIT_13 ++/* Attention Button Present */ ++#define DEVICE_CAPABILITIES_REGISTER_AB_PRS BIT_12 ++/* Endpoint L1 Acceptable Latency */ ++#define DEVICE_CAPABILITIES_REGISTER_L1_AC_LAT_MSK SHIFT9(0x7) ++#define DEVICE_CAPABILITIES_REGISTER_L1_AC_LAT_BASE BIT_9 ++/* Endpoint L0s Acceptable Latency */ ++#define DEVICE_CAPABILITIES_REGISTER_L0_AC_LAT_MSK SHIFT6(0x7) ++#define DEVICE_CAPABILITIES_REGISTER_L0_AC_LAT_BASE BIT_6 ++/* Extended Tag Field Supported */ ++#define DEVICE_CAPABILITIES_REGISTER_EXTTAG_SUP BIT_5 ++/* Phantom Functions Supported */ ++#define DEVICE_CAPABILITIES_REGISTER_PHANTOM_SUP_MSK SHIFT3(0x3) ++#define DEVICE_CAPABILITIES_REGISTER_PHANTOM_SUP_BASE BIT_3 ++/* Max_Payload_Size Supported */ ++#define DEVICE_CAPABILITIES_REGISTER_MAX_PLS_SUP_MSK SHIFT0(0x7) ++#define DEVICE_CAPABILITIES_REGISTER_MAX_PLS_SUP_BASE BIT_0 ++ ++/* PCIE_DEVCTRL 0x00E8 Device Control Register */ ++/* Bit(s) PCIE_DEVCTRL_RSRV_ reserved */ ++#define PCIE_DEVCTRL_MAX_RRS_MSK SHIFT12(0x7S) /* Max_Read_Request_Size */ ++#define PCIE_DEVCTRL_MAX_RRS_BASE BIT_12S ++#define PCIE_DEVCTRL_NOSNP_ENA BIT_11S /* Enable No Snoop */ ++/* Auxiliary (AUX) Power PM Enable */ ++#define PCIE_DEVCTRL_AUXPWR_ENA BIT_10S ++#define PCIE_DEVCTRL_PHANTOM__ENA BIT_9S /* Phantom Functions Enable */ ++/* Extended Tag Field Enable */ ++#define PCIE_DEVCTRL_EXTTAG_ENA BIT_8S ++#define PCIE_DEVCTRL_MAX_PLS_MSK SHIFT5(0x7S) /* Max_Payload_Size */ ++#define PCIE_DEVCTRL_MAX_PLS_BASE BIT_5S ++#define PCIE_DEVCTRL_REL_ORD_ENA BIT_4S /* Enable Relaxed Ordering */ ++/* Unsupported Request Reporting Enable */ ++#define PCIE_DEVCTRL_URR_ENA BIT_3S ++/* Fatal Error Reporting Enable */ ++#define PCIE_DEVCTRL_FERR_ENA BIT_2S ++/* Non-Fatal Error Reporting Enable */ ++#define PCIE_DEVCTRL_NFERR_ENA BIT_1S ++/* Correctable Error Reporting Enable */ ++#define PCIE_DEVCTRL_CERR_ENA BIT_0S ++ ++/* PCIE_DEVSTAT 0x00EA Device Status Register */ ++/* Bit(s) PCIE_DEVSTAT_RSRV_9_0 reserved */ ++#define PCIE_DEVSTAT_TRANS_PEND BIT_5S /* Transactions Pending */ ++#define PCIE_DEVSTAT_AUXPWR_DET BIT_4S /* AUX Power Detected */ ++/* Unsupported Request Detected */ ++#define PCIE_DEVSTAT_UR_DET BIT_3S ++#define PCIE_DEVSTAT_FERR_DET BIT_2S /* Fatal Error Detected */ ++#define PCIE_DEVSTAT_NFERR_DET BIT_1S /* Non-Fatal Error Detected */ ++/* Correctable Error Detected */ ++#define PCIE_DEVSTAT_CERR_DET BIT_0S ++ ++/* PCIE_LNKCAP 0x00EC Link Capabilities Register */ ++#define PCIE_LNKCAP_PORT_NUM_MSK SHIFT24(0xff) /* Port Number */ ++#define PCIE_LNKCAP_PORT_NUM_BASE BIT_24 ++/* Bit(s) PCIE_LNKCAP_RSRV_5_0 reserved */ ++#define PCIE_LNKCAP_L1_EXITLAT_MSK SHIFT15(0x7) /* L1 Exit Latency */ ++#define PCIE_LNKCAP_L1_EXITLAT_BASE BIT_15 ++#define PCIE_LNKCAP_LOS_EXITLAT_MSK SHIFT12(0x7) /* L0s Exit Latency */ ++#define PCIE_LNKCAP_LOS_EXITLAT_BASE BIT_12 ++/* Active State Link PM Support */ ++#define PCIE_LNKCAP_ASPM_SUP_MSK SHIFT10(0x3) ++#define PCIE_LNKCAP_ASPM_SUP_BASE BIT_10 ++#define PCIE_LNKCAP_MAX_LNKWID_MSK SHIFT4(0x3f) /* Maximum Link Width */ ++#define PCIE_LNKCAP_MAX_LNKWID_BASE BIT_4 ++#define PCIE_LNKCAP_MAX_LNKSPD_MSK SHIFT0(0xf) /* Maximum Link Speed */ ++#define PCIE_LNKCAP_MAX_LNKSPD_BASE BIT_0 ++ ++/* PCIE_LNKCTRL 0x00F0 Link Control Register */ ++/* Bit(s) PCIE_LNKCTRL_RSRV_7_0 reserved */ ++#define PCIE_LNKCTRL_EXTSYNC BIT_7S /* Extended Sync */ ++/* Bit(s) PCIE_LNKCTRL_RSRV_ reserved */ ++/* Bit(s) PCIE_LNKCTRL_RSRV_1_0 reserved */ ++/* Read Completion Boundary (RCB) */ ++#define PCIE_LNKCTRL_RCB_128B BIT_3S ++/* Bit(s) PCIE_LNKCTRL_RSRV_ reserved */ ++/* Active State Link PM Control */ ++#define PCIE_LNKCTRL_ASPM_CTRL_MSK SHIFT0(0x3S) ++#define PCIE_LNKCTRL_ASPM_CTRL_BASE BIT_0S ++ ++/* PCIE_LNKSTAT 0x00F2 Link Status Register */ ++/* Bit(s) PCIE_LNKSTAT_RSRV_2_0 reserved */ ++/* Slot Clock Configuration */ ++#define PCIE_LNKSTAT_SCLKCFG BIT_12S ++#define PCIE_LNKSTAT_LNKTRAIN BIT_11S /* Link Training */ ++#define PCIE_LNKSTAT_TRAINERR BIT_10S /* Training Error */ ++/* Negotiated Link Width */ ++#define PCIE_LNKSTAT_NEGLNKWID_MSK SHIFT4(0x3fS) ++#define PCIE_LNKSTAT_NEGLNKWID_BASE BIT_4S ++#define PCIE_LNKSTAT_LNKSPD_MSK SHIFT0(0xfS) /* Link Speed */ ++#define PCIE_LNKSTAT_LNKSPD_BASE BIT_0S ++ ++/* PCIE_AE_CAP_HDR 0x0100 Advanced Error Reporting Enhanced ++ * Capability Header Register ++ */ ++#define PCIE_AE_CAP_HDR_NPTR_MSK SHIFT20(0xfff) /* Next Capability Offset */ ++#define PCIE_AE_CAP_HDR_NPTR_BASE BIT_20 ++#define PCIE_AE_CAP_HDR_VER_ID_MSK SHIFT16(0xf) /* Capability Version */ ++#define PCIE_AE_CAP_HDR_VER_ID_BASE BIT_16 ++/* PCI Express Extended Capability ID */ ++#define PCIE_AE_CAP_HDR_CAP_ID_MSK SHIFT0(0xffff) ++#define PCIE_AE_CAP_HDR_CAP_ID_BASE BIT_0 ++ ++/* PCIE_UE_STAT 0x0104 Uncorrectable Error Status Register */ ++/* Bit(s) PCIE_UE_STAT_RSRV_10_0 reserved */ ++/* Unsupported Request Error */ ++#define PCIE_UE_STAT_UR BIT_20 ++#define PCIE_UE_STAT_ECRCERR BIT_19 /* ECRC Error */ ++#define PCIE_UE_STAT_MTLP BIT_18 /* Malformed TLP */ ++#define PCIE_UE_STAT_RCVOVFL BIT_17 /* Receiver Overflow */ ++#define PCIE_UE_STAT_UNEXPCPL BIT_16 /* Unexpected Completion */ ++#define PCIE_UE_STAT_CPLABORT BIT_15 /* Completer Abort */ ++#define PCIE_UE_STAT_CPLTO BIT_14 /* Completion Timeout */ ++/* Flow Control Protocol Error */ ++#define PCIE_UE_STAT_FCPROTERR BIT_13 ++#define PCIE_UE_STAT_PTLP BIT_12 /* Poisoned TLP */ ++/* Bit(s) PCIE_UE_STAT_RSRV_6_0 reserved */ ++#define PCIE_UE_STAT_DLPROTERR BIT_4 /* Data Link Protocol Error */ ++/* Bit(s) PCIE_UE_STAT_RSRV_2_0 reserved */ ++#define PCIE_UE_STAT_TRINERR BIT_0 /* Training Error */ ++ ++/* PCIE_UE_MASK 0x0108 Uncorrectable Error Mask Register */ ++/* Bit(s) PCIE_UE_MASK_RSRV_10_0 reserved */ ++/* Unsupported Request Error */ ++#define PCIE_UE_MASK_UR BIT_20 ++#define PCIE_UE_MASK_ECRCERR BIT_19 /* ECRC Error */ ++#define PCIE_UE_MASK_MTLP BIT_18 /* Malformed TLP */ ++#define PCIE_UE_MASK_RCVOVFL BIT_17 /* Receiver Overflow */ ++#define PCIE_UE_MASK_UNEXPCPL BIT_16 /* Unexpected Completion */ ++#define PCIE_UE_MASK_CPLABRT BIT_15 /* Completer Abort */ ++#define PCIE_UE_MASK_CPLTO BIT_14 /* Completion Timeout */ ++/* Flow Control Protocol Error */ ++#define PCIE_UE_MASK_FCPROTERR BIT_13 ++#define PCIE_UE_MASK_PTLP BIT_12 /* Poisoned TLP */ ++/* Bit(s) PCIE_UE_MASK_RSRV_6_0 reserved */ ++#define PCIE_UE_MASK_DLPROTERR BIT_4 /* Data Link Protocol Error */ ++/* Bit(s) PCIE_UE_MASK_RSRV_2_0 reserved */ ++#define PCIE_UE_MASK_TRAINERR BIT_0 /* Training Error */ ++ ++/* PCIE_UE_SVRT 0x010C Uncorrectable Error Severity ++ * Register ++ */ ++/* Bit(s) PCIE_UE_SVRT_RSRV_10_0 reserved */ ++/* Unsupported Request Error */ ++#define PCIE_UE_SVRT_UR BIT_20 ++#define PCIE_UE_SVRT_ECRCERR BIT_19 /* ECRC Error Severity */ ++#define PCIE_UE_SVRT_MTLP BIT_18 /* Malformed TLP */ ++#define PCIE_UE_SVRT_RCVOVFL BIT_17 /* Receiver Overflow */ ++#define PCIE_UE_SVRT_UNEXPCPL BIT_16 /* Unexpected Completion */ ++#define PCIE_UE_SVRT_CPLABRT BIT_15 /* Completer Abort */ ++#define PCIE_UE_SVRT_CPLTO BIT_14 /* Completion Timeout */ ++/* Flow Control Protocol Error */ ++#define PCIE_UE_SVRT_FCPROTERR BIT_13 ++#define PCIE_UE_SVRT_PTLP BIT_12 /* Poisoned TLP */ ++/* Bit(s) PCIE_UE_SVRT_RSRV_6_0 reserved */ ++#define PCIE_UE_SVRT_DLPROTERR BIT_4 /* Data Link Protocol Error */ ++/* Bit(s) PCIE_UE_SVRT_RSRV_2_0 reserved */ ++#define PCIE_UE_SVRT_TRAINERR BIT_0 /* Training Error */ ++ ++/* PCIE_CA_STAT 0x0110 Correctable Error Status Register */ ++/* Bit(s) PCIE_CA_STAT_RSRV_18_0 reserved */ ++/* Replay Timer Timeout */ ++#define PCIE_CA_STAT_RPLYTO BIT_12 ++/* Bit(s) PCIE_CA_STAT_RSRV_2_0 reserved */ ++/* REPLAY_NUM Rollover */ ++#define PCIE_CA_STAT_RPLYNUMRO BIT_8 ++#define PCIE_CA_STAT_BADDLLP BIT_7 /* Bad DLLP */ ++#define PCIE_CA_STAT_BADTLP BIT_6 /* Bad TLP */ ++/* Bit(s) PCIE_CA_STAT_RSRV_4_0 reserved */ ++/* Receiver Error */ ++#define PCIE_CA_STAT_RCVERR BIT_0 ++ ++/* PCIE_CA_MASK 0x0114 Correctable Error Mask Register */ ++/* Bit(s) PCIE_CA_MASK_RSRV_18_0 reserved */ ++/* Replay Timer Timeout */ ++#define PCIE_CA_MASK_RPLYTO BIT_12 ++/* Bit(s) PCIE_CA_MASK_RSRV_2_0 reserved */ ++/* REPLAY_NUM Rollover */ ++#define PCIE_CA_MASK_RPLYNUMRO BIT_8 ++#define PCIE_CA_MASK_BADDLLP BIT_7 /* Bad DLLP */ ++#define PCIE_CA_MASK_BADTLP BIT_6 /* Bad TLP */ ++/* Bit(s) PCIE_CA_MASK_RSRV_4_0 reserved */ ++/* Receiver Error */ ++#define PCIE_CA_MASK_RCVERR BIT_0 ++ ++/* PCIE_AE_CAPCTRL 0x0118 Advanced Error Capabilities and ++ * Control Register ++ */ ++/* Bit(s) PCIE_AE_CAPCTRL_RSRV_22_0 reserved */ ++/* ECRC Check Enable */ ++#define PCIE_AE_CAPCTRL_ECRCCHK_ENA BIT_8 ++/* ECRC Check Capable */ ++#define PCIE_AE_CAPCTRL_ECRCCHK_CAP BIT_7 ++/* ECRC Generation Enable */ ++#define PCIE_AE_CAPCTRL_ECRCGEN_ENA BIT_6 ++/* ECRC Generation Capable */ ++#define PCIE_AE_CAPCTRL_ECRCGEN_CAP BIT_5 ++/* First Error Pointer */ ++#define PCIE_AE_CAPCTRL_1ERR_PTR_MSK SHIFT0(0x1f) ++#define PCIE_AE_CAPCTRL_1ERR_PTR_BASE BIT_0 ++ ++/* PCIE_HDRLOG 0x011C Header Log Registers */ ++ ++/* PCIE_TL_CTRL 0x0200 Transaction Layer Control Register */ ++/* Bit(s) PCIE_TL_CTRL_RSRV_29_0 reserved */ ++#define PCIE_TL_CTRL_MAXOUTSTAND_MSK SHIFT0(0x3) /* Max_outstand */ ++#define PCIE_TL_CTRL_MAXOUTSTAND_BASE BIT_0 ++ ++/* PCIE_TL_STAT 0x0204 Transaction Layer Status Register */ ++/* Bit(s) PCIE_TL_STAT_RSRV_31_0 reserved */ ++ ++/* PCIE_DL_CTRL 0x0208 Data Link Layer Control Register */ ++/* Bit(s) PCIE_DL_CTRL_RSRV_31_0 reserved */ ++ ++/* PCIE_DL_STAT 0x020C Data Link Layer Status Register */ ++/* Bit(s) PCIE_DL_STAT_RSRV_31_0 reserved */ ++ ++/* PCIE_PL_CTRL 0x0210 PE Physical Layer Control Register */ ++/* Bit(s) PCIE_PL_CTRL_RSRV_15_0 reserved */ ++#define PCIE_PL_CTRL_N_FTS_MSK SHIFT8(0xff) /* N_FTS */ ++#define PCIE_PL_CTRL_N_FTS_BASE BIT_8 ++/* Bit(s) PCIE_PL_CTRL_RSRV_7_0 reserved */ ++ ++/* PCIE_PL_STAT 0x0214 PE Physical Layer Status Register */ ++/* Bit(s) PCIE_PL_STAT_RSRV_31_0 reserved */ ++ ++/* PCIE_CPLTO 0x0220 PE Completion Timeout Register */ ++/* Bit(s) PCIE_CPLTO_RSRV_15_0 reserved */ ++#define PCIE_CPLTO_MSK SHIFT0(0xffff) /* CmpTOThrshld */ ++#define PCIE_CPLTO_BASE BIT_0 ++ ++/* PCIE_FC 0x0224 PE Flow Control Register */ ++#define PCIE_FC_PH_INIT_MSK SHIFT24(0xff) /* PHInitFC */ ++#define PCIE_FC_PH_INIT_BASE BIT_24 ++#define PCIE_FC_NPH_INIT_MSK SHIFT16(0xff) /* NPHInitFC */ ++#define PCIE_FC_NPH_INIT_BASE BIT_16 ++#define PCIE_FC_CH_INIT_MSK SHIFT8(0xff) /* CHInitFC */ ++#define PCIE_FC_CH_INIT_BASE BIT_8 ++#define PCIE_FC_UPDATETO_MSK SHIFT0(0xff) /* FCUpdateTO */ ++#define PCIE_FC_UPDATETO_BASE BIT_0 ++ ++/* PCIE_ACKTIM_X1 0x0228 PE Ack Timer for 1x Link Register */ ++#define PCIE_ACKTIM_X1_RPLYTO_MSK SHIFT16(0xffff) /* AckRplyTOX1 */ ++#define PCIE_ACKTIM_X1_RPLYTO_BASE BIT_16 ++#define PCIE_ACKTIM_X1_LATTO_MSK SHIFT0(0xffff) /* AckLatTOX1 */ ++#define PCIE_ACKTIM_X1_LATTO_BASE BIT_0 ++ ++ ++ ++/* -------------------- */ ++ ++ ++ ++/* ++ * ++ * THE BASE ADDRESSES ++ * ++ */ ++ ++/* ++ * ++ * THE REGISTER DEFINES ++ * ++ */ ++#define GLB_RAP 0x0000 /* 32 bit Register Address Port (RAP) ++ * Register ++ */ ++#define GLB_CSR 0x0004 /* 24 bit Control/Status Register */ ++#define GLB_PCTRL 0x0007 /* 8 bit Power Control Register */ ++#define GLB_ISRC 0x0008 /* 32 bit Interrupt Source Register */ ++#define GLB_IMSK 0x000C /* 32 bit Interrupt Mask Register */ ++#define GLB_ISRC_HW 0x0010 /* 32 bit Interrupt HW Error Source ++ * Register ++ */ ++#define GLB_IMSK_HW 0x0014 /* 32 bit Interrupt HW Error Mask Register */ ++#define GLB_ISRC_SP1 0x0018 /* 32 bit Special Interrupt Source ++ * Register 1 ++ */ ++#define GLB_ISRC_SP2 0x001C /* 32 bit Special Interrupt Source ++ * Register 2 ++ */ ++#define GLB_ISRC_SP3 0x0020 /* 32 bit Special Interrupt Source ++ * Register 3 ++ */ ++#define GLB_EISR 0x0024 /* 32 bit Enter Interrupt Service Routine ++ * Register ++ */ ++#define GLB_LISR 0x0028 /* 32 bit Leave Interrupt Service Routine ++ * Register ++ */ ++#define GLB_ICTRL 0x002C /* 32 bit Interrupt Control Register */ ++#define SPI_CTRL 0x0060 /* 32 bit SPI Flash Memory Control ++ * Register ++ */ ++#define SPI_ADDR 0x0064 /* 32 bit SPI Flash Memory Address ++ * Register ++ */ ++#define SPI_DATA 0x0068 /* 32 bit SPI Flash Memory Data Register */ ++#define SPI_ID 0x006C /* 32 bit SPI Flash Memory Vendor/Device ++ * ID Register ++ */ ++#define SPI_LCFG 0x0070 /* 32 bit SPI Flash Memory Loader ++ * Configuration Register ++ */ ++#define SPI_VCFG 0x0074 /* 32 bit SPI Flash Memory VPD ++ * Configuration Register ++ */ ++#define SPI_OPC1 0x0078 /* 32 bit SPI Flash Memory Opcode 1 ++ * Register ++ */ ++#define SPI_OPC2 0x007C /* 32 bit SPI Flash Memory Opcode 2 ++ * Register ++ */ ++#define GLB_BWIN 0x0080 /* 32 bit Block Window Register */ ++#define L1_CFG_MADDR_HI 0x0100 /*32 bit Link1 MAC Address Register High */ ++#define M_CFG_MADDR_HI 0x0110 /*32 bit maintenance MAC Address Register High */ ++#define L1_CFG_MADDR_LO 0x0104 /*32 bit Link1 MAC Address Register Low */ ++#define M_CFG_MADDR_LO 0x0114 /*32 bit maintenance MAC Address Register Low */ ++#define CFG_IF 0x0118 /* 16 bit Interface Type Register (PMD ++ * Type and Connector Type) ++ */ ++#define CFG_CREV 0x011A /* 8 bit Chip Revision Register */ ++#define CFG_CID 0x011B /* 8 bit Chip ID Register */ ++#define CFG_CGATE 0x011C /* 16 bit Clock Gating Register */ ++#define CFG_AIR2 0x011E /* 8 bit Application Information ++ * Register 2 ++ */ ++#define CFG_AIR1 0x011F /* 8 bit Application Information ++ * Register 1 ++ */ ++#define CFG_CDIV 0x0120 /* 32 bit Clock Divider Register */ ++#define IRQ_TIM_INIT 0x0130 /* 32 bit Timer Init Value Register */ ++#define IRQ_TIM_CNT 0x0134 /* 32 bit Timer Register */ ++#define IRQ_TIM_TCTRL 0x0138 /* 32 bit Timer Control/Test Register */ ++#define MOD_TIM_INIT 0x0140 /* 32 bit IRQ Moderation Timer Init Value ++ * Register ++ */ ++#define MOD_TIM_CNT 0x0144 /* 32 bit IRQ Moderation Timer Register */ ++#define MOD_TIM_TCTRL 0x0148 /* 32 bit IRQ Moderation Timer ++ * Control/Test Register ++ */ ++#define MOD_TIM_MSK 0x014C /* 32 bit Interrupt Moderation Mask ++ * Register ++ */ ++#define MOD_TIM_MSK_HW 0x0150 /* 32 bit Interrupt Hardware Error ++ * Moderation Mask Register ++ */ ++#define GLB_TCTRL 0x0158 /* 32 bit Test Control Register 1 */ ++#define GLB_GPIO 0x015C /* 32 bit General Purpose I/O Register */ ++#define TWSI_CTRL 0x0160 /* 32 bit TWSI (HW) Control Register */ ++#define TWSI_DATA 0x0164 /* 32 bit TWSI (HW) Data Register */ ++#define TWSI_IRQ 0x0168 /* 32 bit TWSI (HW) IRQ Register */ ++#define TWSI_SW 0x016C /* 32 bit TWSI (SW) Register */ ++#define PCIE_PHY 0x0170 /* 32 bit PCI Express PHY Address Register */ ++#define RAM_ADDR 0x0180 /* 32 bit RAM Address Register */ ++#define RAM_DATA_LO 0x0184 /* 32 bit Data Port/Lower Dword Register */ ++#define RAM_DATA_HI 0x0188 /* 32 bit Data Port/Upper Dword Register */ ++#define ASF_TO 0x0190 /* 32 bit Timeout Register */ ++#define ASF_CTRL 0x01A0 /* 32 bit FIFO Interface Control */ ++#define RSS_KEY0 0x0220 /* 32 bit RSS Key 0 Register */ ++#define RSS_KEY1 0x0224 /* 32 bit RSS Key 1 Register */ ++#define RSS_KEY2 0x0228 /* 32 bit RSS Key 2 Register */ ++#define RSS_KEY3 0x022C /* 32 bit RSS Key 3 Register */ ++#define RSS_KEY4 0x0230 /* 32 bit RSS Key 4 Register */ ++#define RSS_KEY5 0x0234 /* 32 bit RSS Key 5 Register */ ++#define RSS_KEY6 0x0238 /* 32 bit RSS Key 6 Register */ ++#define RSS_KEY7 0x023C /* 32 bit RSS Key 7 Register */ ++#define RSS_KEY8 0x0240 /* 32 bit RSS Key 8 Register */ ++#define RSS_KEY9 0x0244 /* 32 bit RSS Key 9 Register */ ++#define RBMU_DESCR 0x0400 /* 32 bit Current Receive Descriptor ++ * Register ++ */ ++#define RBMU_HASH 0x0404 /* 32 bit RSS Hash Checksum Register */ ++#define RBMU_ADDR_HI 0x0408 /* 32 bit Receive Buffer Address Lo ++ * Register ++ */ ++#define RBMU_ADDR_LO 0x040C /* 32 bit Receive Buffer Address Hi ++ * Register ++ */ ++#define RBMU_RFSW 0x0410 /* 32 bit Receive Buffer Status Word ++ * Register ++ */ ++#define RBMU_TSP 0x0414 /* 32 bit Receive Timestamp Register */ ++#define RBMU_VLAN 0x0420 /* 32 bit VLAN Tag Register */ ++#define RBMU_DONE_IDX 0x0424 /* 32 bit Done Index Register */ ++#define RBMU_REQ_ADDR_LO 0x0428 /* 32 bit Request Address, Lower Register */ ++#define RBMU_REQ_ADDR_HI 0x042C /* 32 bit Request Address, Upper Register */ ++#define RBMU_REQ_CNT 0x0430 /* 32 bit Request Byte Count Register */ ++#define RBMU_CSR 0x0434 /* 32 bit BMU Control/Status Register */ ++#define RBMU_TEST 0x0438 /* 32 bit BMU Test Register */ ++#define RBMU_SM 0x043C /* 32 bit BMU Statemachine Register */ ++#define RBMU_FIFO_WM 0x0440 /* 16 bit FIFO Watermark Register */ ++#define RBMU_FIFO_AL 0x0442 /* 16 bit FIFO Alignment Register */ ++#define TBMU_DESC1 0x0680 /* 32 bit Current Transmit Descriptor ++ * Register 1 ++ */ ++#define TBMU_DESC2 0x0684 /* 16 bit Current Transmit Descriptor ++ * Register 2 ++ */ ++#define TBMU_ADDR_LO 0x0688 /* 32 bit Transmit Buffer Address Lower ++ * Register ++ */ ++#define TBMU_ADDR_HI 0x068C /* 32 bit Transmit Buffer Address Upper ++ * Register ++ */ ++#define TBMU_TFSW 0x0690 /* 32 bit Transmit Buffer Status Word ++ * Register ++ */ ++#define TBMU_VLAN 0x06A0 /* 32 bit VLAN Tag Register */ ++#define TBMU_DONE_IDX 0x06A4 /* 32 bit Done Index Register */ ++#define TBMU_REQ_ADDR_LO 0x06A8 /* 32 bit Request Address Lower Register */ ++#define TBMU_REQ_ADDR_HI 0x06AC /* 32 bit Request Address Upper Register */ ++#define TBMU_REQ_CNT 0x06B0 /* 32 bit Request Byte Count Register */ ++#define TBMU_CSR 0x06B4 /* 32 bit BMU Control/Status Register */ ++#define TBMU_TEST 0x06B8 /* 32 bit BMU Test Register */ ++#define TBMU_SM 0x06BC /* 32 bit BMU Statemachine Register */ ++#define TBMU_FIFO_WM 0x06C0 /* 16 bit FIFO Watermark Register */ ++#define TBMU_FIFO_AL 0x06C2 /* 16 bit FIFO Alignment Register */ ++#define TBMU_FIFO_WSPTR 0x06C4 /* 16 bit FIFO Write Shadow Pointer ++ * Register ++ */ ++#define TBMU_FIFO_WSLEV 0x06C6 /* 16 bit FIFO Write Shadow Level Register */ ++#define TBMU_FIFO_WPTR 0x06C8 /* 16 bit FIFO Write Pointer Register */ ++#define TBMU_FIFO_WLEV 0x06CA /* 16 bit FIFO Write Level Register */ ++#define TBMU_FIFO_RPTR 0x06CC /* 16 bit FIFO Read Pointer Register */ ++#define TBMU_RLEV 0x06CE /* 16 bit FIFO Read Level Register */ ++#define PFU_CTRL 0x06D0 /* 32 bit Prefetch Control Register */ ++#define PFU_LAST_IDX 0x06D4 /* 32 bit List Last Index Register */ ++#define PFU_LADR_LO 0x06D8 /* 32 bit List Start Address Low Register */ ++#define PFU_LADR_HI 0x06DC /* 32 bit List Start Address High Register */ ++#define PFU_GET_IDX 0x06E0 /* 32 bit Get Index Register */ ++#define PFU_PUT_IDX 0x06E4 /* 32 bit Put Index Register */ ++#define PFU_FIFO_WR 0x06F0 /* 32 bit FIFO RAM Write and Write Shadow ++ * Pointer Register ++ */ ++#define PFU_FIFO_RD 0x06F4 /* 32 bit FIFO RAM Read Pointer Register */ ++#define PFU_FIFO_REQ_NB 0x06F8 /* 32 bit Master Request nbytes Register */ ++#define PFU_FIFO_LEV 0x06FC /* 32 bit FIFO Shadow Level Register */ ++#define RA_SADDR 0x0900 /* 32 bit ASF Receive FIFO Start Address */ ++#define RA_EADDR 0x0904 /* 32 bit ASF Receive FIFO End Address */ ++#define RA_WPTR 0x0908 /* 32 bit ASF Receive FIFO Write Pointer */ ++#define RA_RPTR 0x090C /* 32 bit ASF Receive FIFO Read Pointer */ ++#define RA_BRST 0x0910 /* 32 bit ASF Receive FIFO Burst Control */ ++#define RA_PCNT 0x0920 /* 32 bit ASF Receive FIFO Packet Counter */ ++#define RA_LEV 0x0924 /* 32 bit ASF Receive FIFO Level */ ++#define RA_CTRL 0x0928 /* 32 bit ASF Receive FIFO Control/Test */ ++#define RA_FLSH_CTRL 0x092C /* 32 bit ASF Receive FIFO Flush Control */ ++#define TA_SADDR 0x0940 /* 32 bit ASF Transmit FIFO Start Address */ ++#define TA_EADDR 0x0944 /* 32 bit ASF Transmit FIFO End Address */ ++#define TA_WPTR 0x0948 /* 32 bit ASF Transmit FIFO Write Pointer */ ++#define TA_RPTR 0x094C /* 32 bit ASF Transmit FIFO Read Pointer */ ++#define TA_PCNT 0x0960 /* 32 bit ASF Transmit FIFO Packet Counter */ ++#define TA_LEV 0x0964 /* 32 bit ASF Transmit FIFO Level */ ++#define TA_CTRL 0x0968 /* 32 bit ASF Transmit FIFO Control/Test */ ++#define TA_SEND_CTRL 0x096C /* 32 bit ASF Transmit FIFO Send Control */ ++#define RXMF_EADDR 0x0C40 /* 32 bit Receive MAC FIFO End Address ++ * Register ++ */ ++#define RXMF_AFTH 0x0C44 /* 32 bit Receive MAC FIFO Almost Full ++ * Threshold Register ++ */ ++#define RXMF_TCTL 0x0C48 /* 32 bit Receive MAC FIFO Control/Test ++ * Register ++ */ ++#define RXMF_FLMSK 0x0C4C /* 32 bit Receive MAC FIFO Flush Mask ++ * Register ++ */ ++#define RXMF_FLTH 0x0C50 /* 32 bit Receive MAC FIFO Flush ++ * Threshold Register ++ */ ++#define RXMF_TRTH 0x0C54 /* 32 bit Receive Truncation Threshold ++ * Register ++ */ ++#define RXMF_ULTH 0x0C58 /* 32 bit Upper/Lower Threshold/Pause ++ * Packets Register ++ */ ++#define RXMF_VLTYP 0x0C5C /* 32 bit Receive VLAN Type Register */ ++#define RXMF_WPTR 0x0C60 /* 32 bit Receive MAC FIFO Write Pointer ++ * Register ++ */ ++#define RXMF_WLEV 0x0C68 /* 32 bit Receive MAC FIFO Write Level ++ * Register ++ */ ++#define RXMF_RPTR 0x0C70 /* 32 bit Receive MAC FIFO Read Pointer ++ * Register ++ */ ++#define RXMF_RLEV 0x0C78 /* 32 bit Receive MAC FIFO Read Level ++ * Register ++ */ ++#define TXMF_EADDR 0x0D40 /* 32 bit Transmit MAC FIFO End Address ++ * Register ++ */ ++#define TXMF_AETH 0x0D44 /* 32 bit Transmit MAC FIFO Almost Empty ++ * Threshold Register ++ */ ++#define TXMF_TCTL 0x0D48 /* 32 bit Transmit MAC FIFO Control/Test ++ * Register ++ */ ++#define TXMF_VLTYP 0x0D5C /* 32 bit Transmit VLAN Type Register */ ++#define TXMF_WPTR 0x0D60 /* 32 bit Transmit MAC FIFO Write Pointer ++ * Register ++ */ ++#define TXMF_WSPTR 0x0D64 /* 32 bit Transmit MAC FIFO Write Shadow ++ * Pointer Register ++ */ ++#define TXMF_WLEV 0x0D68 /* 32 bit Transmit MAC FIFO Write Level ++ * Register ++ */ ++#define TXMF_RPTR 0x0D70 /* 32 bit Transmit MAC FIFO Read Pointer ++ * Register ++ */ ++#define TXMF_RES_PTR 0x0D74 /* 32 bit Transmit MAC FIFO Restart ++ * Pointer Register ++ */ ++#define TXMF_RLEV 0x0D78 /* 32 bit Transmit MAC FIFO Read Level ++ * Register ++ */ ++#define DPOL_TIM_INIT 0x0E00 /* 32 bit Descriptor Poll Timer Init ++ * Value Register ++ */ ++#define DPOL_TIM_CNT 0x0E04 /* 32 bit Descriptor Poll Timer Register */ ++#define DPOL_TCTL 0x0E08 /* 32 bit Descriptor Poll Timer ++ * Control/Test Register ++ */ ++#define TSP_TIM_CNT 0x0E14 /* 32 bit Timestamp Timer Registers */ ++#define TSP_TIM_TCTL 0x0E18 /* 32 bit Timestamp Timer Control/Test ++ * Register ++ */ ++//#define POLL_CTRL 0x0E20 /* 32 bit Poll Control Register */ ++//#define POLL_LAST_IDX 0x0E24 /* 32 bit List Last Index Register */ ++#define POLL_LADR_LO 0x0E28 /* 32 bit List Start Address Low Register */ ++#define POLL_LADR_HI 0x0E2C /* 32 bit List Start Address High Register */ ++#define CPU_ISRC 0x0E30 /* 32 bit Interrupt Source Register */ ++#define CPU_IMSK 0x0E34 /* 32 bit Interrupt Mask Register */ ++#define SMB_CFG 0x0E40 /* 32 bit SMBus Config Register */ ++#define SMB_CSR 0x0E44 /* 32 bit SMBus Control/Status Register */ ++#define CPU_WDOG 0x0E48 /* 32 bit Watchdog Register */ ++#define CPU_CNTR 0x0E4C /* 32 bit Counter Register */ ++#define CPU_TIM 0x0E50 /* 32 bit Timer Compare Register */ ++#define CPU_AHB_ADDR 0x0E54 /* 32 bit CPU AHB Debug Register */ ++#define CPU_AHB_WDATA 0x0E58 /* 32 bit CPU AHB Debug Register */ ++#define CPU_AHB_RDATA 0x0E5C /* 32 bit CPU AHB Debug Register */ ++#define HCU_MAP_BASE 0x0E60 /* 32 bit Reset Mapping Base */ ++#define CPU_AHB_CTRL 0x0E64 /* 32 bit CPU AHB Debug Register */ ++#define HCU_CCSR 0x0E68 /* 32 bit CPU Control and Status Register */ ++#define HCU_HCSR 0x0E6C /* 32 bit Host Control and Status Register */ ++#define HCU_DATA1 0x0E70 /* 32 bit Data Register 1 */ ++#define HCU_DATA2 0x0E74 /* 32 bit Data Register 2 */ ++#define HCU_DATA3 0x0E78 /* 32 bit Data Register 3 */ ++#define HCU_DATA4 0x0E7C /* 32 bit Data Register 4 */ ++//#define STAT_CTRL 0x0E80 /* 32 bit Status BMU Control Register */ ++//#define STAT_LAST_IDX 0x0E84 /* 32 bit Last Index Register */ ++#define STAT_LADR_LO 0x0E88 /* 32 bit List Start Address Lower ++ * Register ++ */ ++#define STAT_LADR_HI 0x0E8C /* 32 bit List Start Address Upper ++ * Register ++ */ ++#define STAT_TXA_REP 0x0E90 /* 16 bit TXA Report Index Register */ ++#define STAT_TXTH 0x0E98 /* 16 bit TX Index Threshold Register */ ++#define STAT_PUT 0x0E9C /* 32 bit Put Index Register */ ++#define STAT_FIFO_WPTR 0x0EA0 /* 32 bit FIFO Write Pointer Register */ ++#define STAT_FIFO_RPTR 0x0EA4 /* 32 bit FIFO Read Pointer Register */ ++#define STAT_FIFO_LEV 0x0EA8 /* 32 bit FIFO Level Register */ ++//#define STAT_FIFO_WM 0x0EAC /* 8 bit FIFO Watermark Register */ ++#define STAT_FIFO_WM_ISR 0x0EAD /* 8 bit FIFO ISR Watermark Register */ ++#define LEV_TIM_INIT 0x0EB0 /* 32 bit Level Timer Init Value Register */ ++#define LEV_TIM_CNT 0x0EB4 /* 32 bit Level Timer Counter Register */ ++#define LEV_TIM_TCTL 0x0EB8 /* 32 bit Level Timer Control/Test ++ * Register ++ */ ++#define TX_TIM_INIT 0x0EC0 /* 32 bit TX TImer Init Value Register */ ++#define TX_TIM_CNT 0x0EC4 /* 32 bit TX Timer Counter Register */ ++#define TX_TIM_TCTL 0x0EC8 /* 32 bit TX Timer Control/Test Register */ ++#define ISR_TIM_INIT 0x0ED0 /* 32 bit ISR Timer Init Value Register */ ++#define ISR_TIM_CNT 0x0ED4 /* 32 bit ISR Timer Counter Register */ ++#define ISR_TIM_TCTL 0x0ED8 /* 32 bit ISR Timer Control/Test Register */ ++#define MAC_CTRL 0x0F00 /* 16 bit MAC Control Registers */ ++#define PHY_CFG 0x0F04 /* 32 bit PHY Config Register, loaded ++ * from external memory ++ */ ++#define MAC_ISRC 0x0F08 /* 32 bit MAC Interrupt Source Register */ ++#define MAC_IMSK 0x0F0C /* 32 bit MAC Interrupt Mask Register */ ++#define LINK_CTRL 0x0F10 /* 16 bit Link Control Register */ ++#define WOL_CSR 0x0F20 /* 16 bit WOL Control/Status Register */ ++#define WOL_MCTRL 0x0F22 /* 16 bit Match Control Register */ ++#define WOL_MADDR_LO 0x0F24 /* 32 bit MAC Address Register Low ++ * Register ++ */ ++#define WOL_MADDR_HI 0x0F28 /* 16 bit MAC Address Register High ++ * Register ++ */ ++#define WOL_PME_MEN 0x0F2A /* 16 bit PME Match Enable Register */ ++#define WOL_ASF_MEN 0x0F2C /* 16 bit ASF Match Enable Register */ ++#define WOL_MRSL 0x0F2E /* 16 bit Match Result Register */ ++#define WOL_PLEN0 0x0F30 /* 32 bit Pattern Length Register 0 (0-3) */ ++#define WOL_PLEN1 0x0F34 /* 32 bit Pattern Length Register 1 (4-7) */ ++#define WOL_PLEN2 0x0F38 /* 32 bit Pattern Length Register 2 (8) */ ++#define WOL_PCNT0 0x0F40 /* 32 bit Pattern Counter Register 0 (0-3) */ ++#define WOL_PCNT1 0x0F44 /* 32 bit Pattern Counter Register 1 (4-7) */ ++#define WOL_PCNT2 0x0F48 /* 32 bit Pattern Counter Register 2 (8) */ ++#define PAT_CSR 0x0F50 /* 32 bit Pattern RAM Control/Status ++ * Register ++ */ ++#define PAT_RAM 0x1000 /* 32 bit Pattern RAM Register */ ++#define THDR0_LO 0x1900 /* 32 bit TCP Segmentation Header ++ * Register 0 Lo ++ */ ++#define THDR0_HI 0x1904 /* 32 bit TCP Segmentation Header ++ * Register 0 Hi ++ */ ++#define THDR1_LO 0x1908 /* 32 bit TCP Segmentation Header ++ * Register 1 Lo ++ */ ++#define THDR1_HI 0x190C /* 32 bit TCP Segmentation Header ++ * Register 1 Hi ++ */ ++#define THDR2_LO 0x1910 /* 32 bit TCP Segmentation Header ++ * Register 2 Lo ++ */ ++#define THDR2_HI 0x1914 /* 32 bit TCP Segmentation Header ++ * Register 2 Hi ++ */ ++#define THDR3_LO 0x1918 /* 32 bit TCP Segmentation Header ++ * Register 3 Lo ++ */ ++#define THDR3_HI 0x191C /* 32 bit TCP Segmentation Header ++ * Register 3 Hi ++ */ ++#define THDR4_LO 0x1920 /* 32 bit TCP Segmentation Header ++ * Register 4 Lo ++ */ ++#define THDR4_HI 0x1924 /* 32 bit TCP Segmentation Header ++ * Register 4 Hi ++ */ ++#define THDR5_LO 0x1928 /* 32 bit TCP Segmentation Header ++ * Register 5 Lo ++ */ ++#define THDR5_HI 0x192C /* 32 bit TCP Segmentation Header ++ * Register 5 Hi ++ */ ++#define THDR6_LO 0x1930 /* 32 bit TCP Segmentation Header ++ * Register 6 Lo ++ */ ++#define THDR6_HI 0x1934 /* 32 bit TCP Segmentation Header ++ * Register 6 Hi ++ */ ++#define THDR7_LO 0x1938 /* 32 bit TCP Segmentation Header ++ * Register 7 Lo ++ */ ++#define THDR7_HI 0x193C /* 32 bit TCP Segmentation Header ++ * Register 7 Hi ++ */ ++#define THDR8_LO 0x1940 /* 32 bit TCP Segmentation Header ++ * Register 8 Lo ++ */ ++#define THDR8_HI 0x1944 /* 32 bit TCP Segmentation Header ++ * Register 8 Hi ++ */ ++#define THDR9_LO 0x1948 /* 32 bit TCP Segmentation Header ++ * Register 9 Lo ++ */ ++#define THDR9_HI 0x194C /* 32 bit TCP Segmentation Header ++ * Register 9 Hi ++ */ ++#define THDR10_LO 0x1950 /* 32 bit TCP Segmentation Header ++ * Register 10 Lo ++ */ ++#define THDR10_HI 0x1954 /* 32 bit TCP Segmentation Header ++ * Register 10 Hi ++ */ ++#define THDR11_LO 0x1958 /* 32 bit TCP Segmentation Header ++ * Register 11 Lo ++ */ ++#define THDR11_HI 0x195C /* 32 bit TCP Segmentation Header ++ * Register 11 Hi ++ */ ++#define THDR12_LO 0x1960 /* 32 bit TCP Segmentation Header ++ * Register 12 Lo ++ */ ++#define THDR12_HI 0x1964 /* 32 bit TCP Segmentation Header ++ * Register 12 Hi ++ */ ++#define THDR13_LO 0x1968 /* 32 bit TCP Segmentation Header ++ * Register 13 Lo ++ */ ++#define THDR13_HI 0x196C /* 32 bit TCP Segmentation Header ++ * Register 13 Hi ++ */ ++#define THDR14_LO 0x1970 /* 32 bit TCP Segmentation Header ++ * Register 14 Lo ++ */ ++#define THDR14_HI 0x1974 /* 32 bit TCP Segmentation Header ++ * Register 14 Hi ++ */ ++#define THDR15_LO 0x1978 /* 32 bit TCP Segmentation Header ++ * Register 15 Lo ++ */ ++#define THDR15_HI 0x197C /* 32 bit TCP Segmentation Header ++ * Register 15 Hi ++ */ ++#define THDR16_LO 0x1980 /* 32 bit TCP Segmentation Header ++ * Register 16 Lo ++ */ ++#define THDR16_HI 0x1984 /* 32 bit TCP Segmentation Header ++ * Register 16 Hi ++ */ ++#define THDR17_LO 0x1988 /* 32 bit TCP Segmentation Header ++ * Register 17 Lo ++ */ ++#define THDR17_HI 0x198C /* 32 bit TCP Segmentation Header ++ * Register 17 Hi ++ */ ++#define THDR18_LO 0x1990 /* 32 bit TCP Segmentation Header ++ * Register 18 Lo ++ */ ++#define THDR18_HI 0x1994 /* 32 bit TCP Segmentation Header ++ * Register 18 Hi ++ */ ++#define THDR19_LO 0x1998 /* 32 bit TCP Segmentation Header ++ * Register 19 Lo ++ */ ++#define THDR19_HI 0x199C /* 32 bit TCP Segmentation Header ++ * Register 19 Hi ++ */ ++#define THDR20_LO 0x19A0 /* 32 bit TCP Segmentation Header ++ * Register 20 Lo ++ */ ++#define THDR20_HI 0x19A4 /* 32 bit TCP Segmentation Header ++ * Register 20 Hi ++ */ ++#define THDR21_LO 0x19A8 /* 32 bit TCP Segmentation Header ++ * Register 21 Lo ++ */ ++#define THDR21_HI 0x19AC /* 32 bit TCP Segmentation Header ++ * Register 21 Hi ++ */ ++#define THDR22_LO 0x19B0 /* 32 bit TCP Segmentation Header ++ * Register 22 Lo ++ */ ++#define THDR22_HI 0x19B4 /* 32 bit TCP Segmentation Header ++ * Register 22 Hi ++ */ ++#define THDR23_LO 0x19B8 /* 32 bit TCP Segmentation Header ++ * Register 23 Lo ++ */ ++#define THDR23_HI 0x19BC /* 32 bit TCP Segmentation Header ++ * Register 23 Hi ++ */ ++#define THDR24_LO 0x19C0 /* 32 bit TCP Segmentation Header ++ * Register 24 Lo ++ */ ++#define THDR24_HI 0x19C4 /* 32 bit TCP Segmentation Header ++ * Register 24 Hi ++ */ ++#define THDR25_LO 0x19C8 /* 32 bit TCP Segmentation Header ++ * Register 25 Lo ++ */ ++#define THDR25_HI 0x19CC /* 32 bit TCP Segmentation Header ++ * Register 25 Hi ++ */ ++#define THDR26_LO 0x19D0 /* 32 bit TCP Segmentation Header ++ * Register 26 Lo ++ */ ++#define THDR26_HI 0x19D4 /* 32 bit TCP Segmentation Header ++ * Register 26 Hi ++ */ ++#define THDR27_LO 0x19D8 /* 32 bit TCP Segmentation Header ++ * Register 27 Lo ++ */ ++#define THDR27_HI 0x19DC /* 32 bit TCP Segmentation Header ++ * Register 27 Hi ++ */ ++#define THDR28_LO 0x19E0 /* 32 bit TCP Segmentation Header ++ * Register 28 Lo ++ */ ++#define THDR28_HI 0x19E4 /* 32 bit TCP Segmentation Header ++ * Register 28 Hi ++ */ ++#define THDR29_LO 0x19E8 /* 32 bit TCP Segmentation Header ++ * Register 29 Lo ++ */ ++#define THDR29_HI 0x19EC /* 32 bit TCP Segmentation Header ++ * Register 29 Hi ++ */ ++#define THDR30_LO 0x19F0 /* 32 bit TCP Segmentation Header ++ * Register 30 Lo ++ */ ++#define CFG_VLAN_ET1 0x2000 /* 32 bit VLAN Ethernet Type ++ * Configuration Register 1 ++ */ ++#define CFG_VLAN_ET0 0x2004 /* 32 bit VLAN Ethernet Type ++ * Configuration Register 0 ++ */ ++#define CFG_MACSEC_ET1 0x2008 /* 32 bit 802.1AE Ethernet Type ++ * Configuration Register 1 ++ */ ++#define CFG_MACSEC_ET0 0x200C /* 32 bit 802.1AE Ethernet Type ++ * Configuration Register 0 ++ */ ++#define CFG_TRAIL_SZ 0x2010 /* 32 bit Trail Size Configuration ++ * Register ++ */ ++#define CFG_DEFAULT_VLAN0 0x2014 /* 32 bit Default VLAN Register 0 */ ++#define CFG_DEFAULT_VLAN1 0x2018 /* 32 bit Default VLAN Register 1 */ ++#define CFG_MACSEC_SL_SZ 0x201C /* 32 bit MACSec Size Configuration ++ * Register ++ */ ++#define CFG_MIN_PKT_LEN 0x2020 /* 32 bit Minimum Packet Length ++ * Configuration Register ++ */ ++#define SEC_CLK_RST 0x2024 /* 32 bit MACSec Clock Reset Register */ ++#define EGR_KS_SELECT 0x2028 /* 32 bit Egress Key Store Select Register */ ++#define EGR_KS_WRDATA 0x202C /* 32 bit Egress Key Store Write Data ++ * Register ++ */ ++#define IGR_KS_SELECT 0x2030 /* 32 bit Ingress Key Store Select ++ * Register ++ */ ++#define IGR_KS_WRDATA 0x2034 /* 32 bit Ingress Key Store Write Data ++ * Register ++ */ ++#define CFG_ELU_MC_HIGH0 0x2038 /* 32 bit Multicast Match Register 0 */ ++#define CFG_ELU_MC_HIGH1 0x203C /* 32 bit Multicast Match Register 1 */ ++#define CFG_ELU_MC_HIGH2 0x2040 /* 32 bit Multicast Match Register 2 */ ++#define CFG_ELU_MC_HIGH3 0x2044 /* 32 bit Multicast Match Register 3 */ ++#define CFG_ELU_MC_HIGH4 0x2048 /* 32 bit Multicast Match Register 4 */ ++#define CFG_ELU_MC_HIGH5 0x204C /* 32 bit Multicast Match Register 5 */ ++#define CFG_ELU_MC_LOW_MSK0 0x2050 /* 32 bit Multicast Match Mask Register 0 */ ++#define CFG_ELU_MC_LOW_MSK1 0x2054 /* 32 bit Multicast Match Mask Register 1 */ ++#define CFG_DEFAULT_PORT0 0x2058 /* 32 bit Default Port Configuration ++ * Register 0 ++ */ ++#define CFG_DEFAULT_PORT1 0x205C /* 32 bit Default Port Configuration ++ * Register 1 ++ */ ++#define CFG_SCB_PORT0 0x2060 /* 32 bit SCB Port Configuration Register ++ * 0 ++ */ ++#define CFG_SCB_PORT1 0x2064 /* 32 bit SCB Port Configuration Register ++ * 1 ++ */ ++#define CFG_AUTH_ADJUST 0x2068 /* 32 bit Authentication Adjustment ++ * Register ++ */ ++#define CFG_ELU_GEN 0x206C /* 32 bit ELU Default Configuration ++ * Register ++ */ ++#define CFG_ELUC_ADDR 0x2070 /* 32 bit ELU Address Configuration ++ * Register ++ */ ++#define CFG_ELUC_DATA 0x2074 /* 32 bit ELU Context Data Configuration ++ * Register ++ */ ++#define CFG_ELUE_ADDR 0x2078 /* 32 bit ELU Entry Configuration Register */ ++#define CFG_ELUE_DATA 0x207C /* 32 bit ELU Lookup Entry Access ++ * Configuration Register ++ */ ++#define CFG_EPR_GEN 0x2080 /* 32 bit General Egress Parser ++ * Configuration Register ++ */ ++#define EGR_HR_SELECT 0x2084 /* 32 bit Egress Write Select for H-Store ++ * Register ++ */ ++#define EGR_HR_WRDATA 0x2088 /* 32 bit Egress Header Write Data ++ * Register ++ */ ++#define IGR_HR_SELECT 0x208C /* 32 bit Ingress Write Select for ++ * H-Store Register ++ */ ++#define IGR_HR_WRDATA 0x2090 /* 32 bit Ingress Header Write Data ++ * Register ++ */ ++#define CFG_ILU_GEN 0x2094 /* 8 bit cfg_ilu_gen */ ++#define CFG_IMPLICIT_SCI0 0x2098 /* 32 bit Implicit SCI Register 0 */ ++#define CFG_IMPLICIT_SCI1 0x209C /* 32 bit Implicit SCI Register 1 */ ++#define CFG_IMPLICIT_SCI2 0x20A0 /* 32 bit Implicit SCI Register 2 */ ++#define CFG_IMPLICIT_SCI3 0x20A4 /* 32 bit Implicit SCI Register 3 */ ++#define CFG_IMPLICIT_SCI4 0x20A8 /* 32 bit Implicit SCI Register 4 */ ++#define CFG_IMPLICIT_SCI5 0x20AC /* 32 bit Implicit SCI Register 5 */ ++#define CFG_IMPLICIT_SCI6 0x20B0 /* 32 bit Implicit SCI Register 6 */ ++#define CFG_IMPLICIT_SCI7 0x20B4 /* 32 bit Implicit SCI Register 7 */ ++#define CFG_REPLAY_WINDOW0 0x20B8 /* 32 bit Replay Window Register 0 */ ++#define CFG_REPLAY_WINDOW1 0x20BC /* 32 bit Replay Window Register 1 */ ++#define CFG_REPLAY_WINDOW2 0x20C0 /* 32 bit Replay Window Register 2 */ ++#define CFG_REPLAY_WINDOW3 0x20C4 /* 32 bit Replay Window Register 3 */ ++#define CFG_IPR_GEN 0x20C8 /* 32 bit Ingress Primary Parser Register */ ++#define CFG_ISC_GEN 0x20CC /* 32 bit Ingress Security Check Block ++ * Register ++ */ ++#define CFG_RPY_ADDR 0x20D0 /* 32 bit Replay Protect Table Access ++ * Register ++ */ ++#define CFG_RPY_DATA 0x20D4 /* 32 bit ELU Context Data Register */ ++#define CFG_ILUT_ADDR 0x20E0 /* 32 bit Ingress Lookup Table Access ++ * Address Configuration Register ++ */ ++#define CFG_ILUT_DATA 0x20E4 /* 32 bit ILU Table Data Register */ ++#define STAT_ADDR 0x20E8 /* 32 bit Statistic Register Address */ ++#define STAT_DATA0 0x20EC /* 32 bit Statistic Data Register 0 */ ++#define STAT_DATA1 0x20F0 /* 32 bit Statistic Data Register 1 */ ++#define STAT_DATA2 0x20F4 /* 32 bit Statistic Data Register 2 */ ++#define CFG_OVER_LEN1 0x20F8 /* 32 bit Over-Length Configuration ++ * Register 1 ++ */ ++#define CFG_IPAR_HYST 0x2104 /* 32 bit Ingress Parse FIFO Hystersis */ ++#define CFG_EPAR_HYST 0x2108 /* 32 bit Egress Parse FIFO Hystersis */ ++#define RE_TRF_TCTL 0x2200 /* 32 bit MACSec Retransmit FIFO Control */ ++#define RE_TRF_PCNT 0x2204 /* 32 bit Retransmit FIFO Packet Counter */ ++#define RE_TRF_TTH 0x2208 /* 32 bit Retransmit FIFO Transmit Start ++ * Threshold ++ */ ++#define RE_TRF_WPTR 0x2210 /* 32 bit Retransmit FIFO Write Pointer ++ * Register ++ */ ++#define RE_TRF_WLEV 0x2218 /* 32 bit Retransmit FIFO Write Level ++ * Register ++ */ ++#define RE_TRF_RPTR 0x2220 /* 32 bit Retransmit FIFO Read Pointer ++ * Register ++ */ ++#define RE_TRF_RES_PTR 0x2224 /* 32 bit Transmit FIFO Restart Pointer ++ * Register ++ */ ++#define RE_TRF_RLEV 0x2228 /* 32 bit Retransmit FIFO Read Level ++ * Register ++ */ ++#define RE_TRF_RSPTR 0x222c /* 32 bit Retransmit FIFO Read Shadow ++ * Level Register ++ */ ++ ++/* ++ * ++ * THE BIT DEFINES ++ * ++ */ ++/* GLB_RAP 0x0000 Register Address Port (RAP) Register */ ++/* Bit(s) GLB_RAP_RSRV_24_0 reserved */ ++#define GLB_RAP_MSK SHIFT0(0x7f) /* RAP */ ++#define GLB_RAP_BASE BIT_0 ++ ++/* GLB_CSR 0x0004 Control/Status Register */ ++/* Bit(s) GLB_CSR_RSRV_5_0 reserved */ ++#define GLB_CSR_VMAIN_AVL BIT_17S /* Vmain Available */ ++#define GLB_CSR_VAUX_AVL BIT_16S /* Vaux Available */ ++/* Bit(s) GLB_CSR_RSRV_1_0 reserved */ ++#define GLB_CSR_ASF_ENA_SET BIT_13S /* ASF Enable Set */ ++#define GLB_CSR_ASF_ENA_CLR BIT_12S /* ASF Enable Clear */ ++/* Bit(s) GLB_CSR_RSRV_ reserved */ ++/* Bit(s) GLB_CSR_RSRV_ reserved */ ++#define GLB_CSR_LED0_ON BIT_9S /* LED<0>On */ ++#define GLB_CSR_LED0_OFF BIT_8S /* LED<0>Off */ ++#define GLB_CSR_IRQ_SW_SET BIT_7S /* Set IRQ SW */ ++#define GLB_CSR_IRQ_SW_CLR BIT_6S /* Clear IRQ SW */ ++#define GLB_CSR_STOP_MST_DONE BIT_5S /* Stop Master Done */ ++#define GLB_CSR_STOP_MST BIT_4S /* Stop Master */ ++#define GLB_CSR_MST_RST_CLR BIT_3S /* Master Reset Clear */ ++#define GLB_CSR_MST_RST_SET BIT_2S /* Master Reset Set */ ++#define GLB_CSR_SW_RST_CLR BIT_1S /* SW Reset Clear */ ++#define GLB_CSR_SW_RST_SET BIT_0S /* SW Reset Set */ ++ ++/* GLB_PCTRL 0x0007 Power Control Register */ ++#define GLB_PCTRL_SW_VAUX_ENA BIT_7S /* Switch Vaux Enable */ ++#define GLB_PCTRL_SW_VAUX_DIS BIT_6S /* Switch Vaux Disable */ ++#define GLB_PCTRL_SW_VCC_ENA BIT_5S /* Switch VCC Enable */ ++#define GLB_PCTRL_SW_VCC_DIS BIT_4S /* Switch VCC Disable */ ++#define GLB_PCTRL_SW_VAUX_ON BIT_3S /* Switch Vaux On */ ++#define GLB_PCTRL_SW_VAUX_OFF BIT_2S /* Switch Vaux Off */ ++#define GLB_PCTRL_SW_VCC_ON BIT_1S /* Switch VCC On */ ++#define GLB_PCTRL_SW_VCC_OFF BIT_0S /* Switch VCC Off */ ++ ++/* GLB_ISRC 0x0008 Interrupt Source Register */ ++#define GLB_ISRC_HW_IRQ BIT_31 /* HW Interrupt */ ++#define GLB_ISRC_STAT_BMU BIT_30 /* Status BMU */ ++#define GLB_ISRC_CPU_HOST BIT_29 /* CPU to Host */ ++#define GLB_ISRC_CPU_TO BIT_28 /* CPU Timeout */ ++#define GLB_ISRC_POLL_CHK BIT_27 /* IRQ Polling CHK */ ++#define GLB_ISRC_TWSI_RDY BIT_26 /* IRQ TWSI Ready */ ++#define GLB_ISRC_SW BIT_25 /* IRQ SW */ ++#define GLB_ISRC_TIM BIT_24 /* IRQ Timer */ ++/* Bit(s) GLB_ISRC_RSRV_15_0 reserved */ ++/* Bit(s) GLB_ISRC_RSRV_2_0 reserved */ ++#define GLB_ISRC_PHY BIT_4 /* IRQ PHY */ ++#define GLB_ISRC_MAC BIT_3 /* IRQ MAC */ ++#define GLB_ISRC_CHK_RX BIT_2 /* IRQ CHCK Rx */ ++/* Bit(s) GLB_ISRC_RSRV_ reserved */ ++#define GLB_ISRC_CHK_TXA BIT_0 /* IRQ CHCK TxA */ ++ ++/* GLB_IMSK 0x000C Interrupt Mask Register */ ++#define GLB_IMSK_HW_IRQ BIT_31 /* En IRQ HW Interrupt */ ++#define GLB_IMSK_STAT_BMU BIT_30 /* En IRQ Status BMU */ ++#define GLB_IMSK_CPU_HOST BIT_29 /* En CPU to Host */ ++#define GLB_IMSK_CPU_TO BIT_28 /* En CPU Timeout */ ++#define GLB_IMSK_POLL_CHK BIT_27 /* En IRQ Polling CHK */ ++#define GLB_IMSK_TWSI_RDY BIT_26 /* En IRQ TWSI Ready */ ++#define GLB_IMSK_SW BIT_25 /* En IRQ SW */ ++#define GLB_IMSK_TIM BIT_24 /* En IRQ Timer */ ++/* Bit(s) GLB_IMSK_RSRV_15_0 reserved */ ++/* Bit(s) GLB_IMSK_RSRV_2_0 reserved */ ++#define GLB_IMSK_PHY BIT_4 /* En IRQ PHY */ ++#define GLB_IMSK_MAC BIT_3 /* En IRQ MAC */ ++#define GLB_IMSK_CHK_RX BIT_2 /* En IRQ CHCK Rx */ ++/* Bit(s) GLB_IMSK_RSRV_ reserved */ ++#define GLB_IMSK_CHK_TXA BIT_0 /* En IRQ CHCK TxA */ ++ ++/* GLB_ISRC_HW 0x0010 Interrupt HW Error Source Register */ ++/* Bit(s) GLB_ISRC_HW_RSRV_1_0 reserved */ ++/* IRQ Timestamp Timer Overflow */ ++#define GLB_ISRC_HW_TSP_TIM BIT_29 ++#define GLB_ISRC_HW_SEN BIT_28 /* IRQ Sensor */ ++#define GLB_ISRC_HW_MST_ERR BIT_27 /* IRQ Master Error */ ++#define GLB_ISRC_HW_PCI_STAT BIT_26 /* IRQ Status */ ++#define GLB_ISRC_HW_PCIE_SPE BIT_25 /* IRQ PE */ ++#define GLB_ISRC_HW_PCIE_NO_PE BIT_24 /* IRQ NO PE */ ++/* Bit(s) GLB_ISRC_HW_RSRV_15_0 reserved */ ++/* Bit(s) GLB_ISRC_HW_RSRV_3_0 reserved */ ++#define GLB_ISRC_HW_PAR_MAC BIT_3 /* IRQ Par MAC */ ++#define GLB_ISRC_HW_PAR_RX BIT_2 /* IRQ PAR Rx */ ++#define GLB_ISRC_HW_TCP_TXA BIT_0 /* IRQ TCP Length TxA1 */ ++ ++/* GLB_IMSK_HW 0x0014 Interrupt HW Error Mask Register */ ++/* Bit(s) GLB_IMSK_HW_RSRV_1_0 reserved */ ++/* En IRQ Timestamp Timer Overflow */ ++#define GLB_IMSK_HW_TSP_TIM BIT_29 ++#define GLB_IMSK_HW_SEN BIT_28 /* En IRQ Sensor */ ++#define GLB_IMSK_HW_MST_ERR BIT_27 /* En IRQ Master Error */ ++#define GLB_IMSK_HW_PCI_STAT BIT_26 /* En IRQ Status */ ++#define GLB_IMSK_HW_PCIE_SPE BIT_25 /* En IRQ PE */ ++#define GLB_IMSK_HW_PCIE_NO_PE BIT_24 /* En IRQ NO PE */ ++/* Bit(s) GLB_IMSK_HW_RSRV_15_0 reserved */ ++/* Bit(s) GLB_IMSK_HW_RSRV_3_0 reserved */ ++#define GLB_IMSK_HW_PAR_MAC BIT_3 /* En IRQ Par MAC */ ++#define GLB_IMSK_HW_PAR_RX BIT_2 /* En IRQ PAR Rx */ ++#define GLB_IMSK_HW_TCP_TXA BIT_0 /* En IRQ TCP Length TxA1 */ ++ ++/* GLB_ISRC_SP1 0x0018 Special Interrupt Source Register 1 */ ++#define GLB_ISRC_SP1__IRQ_XXX_MSK SHIFT0(0xffffffff) /* IRQ xxx */ ++#define GLB_ISRC_SP1__IRQ_XXX_BASE BIT_0 ++ ++/* GLB_ISRC_SP2 0x001C Special Interrupt Source Register 2 */ ++#define GLB_ISRC_SP2__IRQ_XXX_MSK SHIFT0(0xffffffff) /* IRQ xxx */ ++#define GLB_ISRC_SP2__IRQ_XXX_BASE BIT_0 ++ ++/* GLB_ISRC_SP3 0x0020 Special Interrupt Source Register 3 */ ++#define GLB_ISRC_SP3__IRQ_XXX_MSK SHIFT0(0xffffffff) /* IRQ xxx */ ++#define GLB_ISRC_SP3__IRQ_XXX_BASE BIT_0 ++ ++/* GLB_EISR 0x0024 Enter Interrupt Service Routine Register */ ++#define GLB_EISR__IRQ_XXX_MSK SHIFT0(0xffffffff) /* Enter ISR Reg */ ++#define GLB_EISR__IRQ_XXX_BASE BIT_0 ++ ++/* GLB_LISR 0x0028 Leave Interrupt Service Routine Register */ ++#define GLB_LISR__IRQ_XXX_MSK SHIFT0(0xffffffff) /* Leave ISR Reg */ ++#define GLB_LISR__IRQ_XXX_BASE BIT_0 ++ ++/* GLB_ICTRL 0x002C Interrupt Control Register */ ++/* Bit(s) GLB_ICTRL_RSRV_27_0 reserved */ ++#define GLB_ICTRL_ISR_MSK BIT_3 /* isr_mask */ ++#define GLB_ICTRL_ISR_STAT BIT_2 /* isr_status */ ++#define GLB_ICTRL_LEAVE_ISR BIT_1 /* Leave ISR */ ++#define GLB_ICTRL_ENTER_ISR BIT_0 /* Enter ISR */ ++ ++/* SPI_CTRL 0x0060 SPI Flash Memory Control Register */ ++#define SPI_CTRL_STRT_LDR BIT_31 /* Loader Start */ ++#define SPI_CTRL_BSY BIT_30 /* SPI Busy */ ++#define SPI_CTRL_RESV BIT_29 /* RESV */ ++#define SPI_CTRL_RD_ID_PROT BIT_28 /* RD ID Protocol */ ++/* Bit(s) SPI_CTRL_RSRV_7_0 reserved */ ++#define SPI_CTRL_STRT_SPI BIT_19 /* Start SPI */ ++#define SPI_CTRL_INST_MSK SHIFT16(0x7) /* Instruction */ ++#define SPI_CTRL_INST_BASE BIT_16 ++/* Bit(s) SPI_CTRL_RSRV_7_0 reserved */ ++#define SPI_CTRL_STAT_MSK SHIFT0(0xff) /* SPI device Status */ ++#define SPI_CTRL_STAT_BASE BIT_0 ++ ++/* SPI_ADDR 0x0064 SPI Flash Memory Address Register */ ++/* Bit(s) SPI_ADDR_RSRV_11_0 reserved */ ++#define SPI_ADDR_MSK SHIFT0(0xfffff) /* SPI Flash Memory address */ ++#define SPI_ADDR_BASE BIT_0 ++ ++/* SPI_DATA 0x0068 SPI Flash Memory Data Register */ ++#define SPI_DATA_MSK SHIFT0(0xffffffff) /* SPI Flash Memory data */ ++#define SPI_DATA_BASE BIT_0 ++ ++/* SPI_ID 0x006C SPI Flash Memory Vendor/Device ID Register */ ++/* Bit(s) SPI_ID_RSRV_15_0 reserved */ ++#define SPI_ID_VEN_ID_MSK SHIFT8(0xff) /* Vendor-ID */ ++#define SPI_ID_VEN_ID_BASE BIT_8 ++#define SPI_ID_DEV_ID_MSK SHIFT0(0xff) /* Device-ID */ ++#define SPI_ID_DEV_ID_BASE BIT_0 ++ ++/* SPI_LCFG 0x0070 SPI Flash Memory Loader Configuration Register */ ++/* Bit(s) SPI_LCFG_RSRV_3_0 reserved */ ++#define SPI_LCFG_NRML_ADDR_MSK SHIFT16(0xfff) /* Normal Loader start address */ ++#define SPI_LCFG_NRML_ADDR_BASE BIT_16 ++/* Bit(s) SPI_LCFG_RSRV_3_0 reserved */ ++#define SPI_LCFG_INIT_ADDR_MSK SHIFT0(0xfff) /* PIG Loader start address */ ++#define SPI_LCFG_INIT_ADDR_BASE BIT_0 ++ ++/* SPI_VCFG 0x0074 SPI Flash Memory VPD Configuration Register */ ++/* Bit(s) SPI_VCFG_RSRV_3_0 reserved */ ++#define SPI_VCFG_VPD_END_MSK SHIFT16(0xfff) /* VPD end address */ ++#define SPI_VCFG_VPD_END_BASE BIT_16 ++/* Bit(s) SPI_VCFG_RSRV_3_0 reserved */ ++#define SPI_VCFG_VPD_START_MSK SHIFT0(0xfff) /* VPD start address */ ++#define SPI_VCFG_VPD_START_BASE BIT_0 ++ ++/* SPI_OPC1 0x0078 SPI Flash Memory Opcode 1 Register */ ++#define SPI_OPC1_RDSR_MSK SHIFT24(0xff) /* Opcode Read Status */ ++#define SPI_OPC1_RDSR_BASE BIT_24 ++#define SPI_OPC1_RDID_MSK SHIFT16(0xff) /* Opcode Read ID */ ++#define SPI_OPC1_RDID_BASE BIT_16 ++#define SPI_OPC1_RD_MSK SHIFT8(0xff) /* Opcode Read */ ++#define SPI_OPC1_RD_BASE BIT_8 ++#define SPI_OPC1_NOP_MSK SHIFT0(0xff) /* Opcode No Operation */ ++#define SPI_OPC1_NOP_BASE BIT_0 ++ ++/* SPI_OPC2 0x007C SPI Flash Memory Opcode 2 Register */ ++#define SPI_OPC2_CE_MSK SHIFT24(0xff) /* Opcode Chip Erase */ ++#define SPI_OPC2_CE_BASE BIT_24 ++#define SPI_OPC2_SE_MSK SHIFT16(0xff) /* Opcode Sector Erase */ ++#define SPI_OPC2_SE_BASE BIT_16 ++#define SPI_OPC2_WR_MSK SHIFT8(0xff) /* Opcode Write */ ++#define SPI_OPC2_WR_BASE BIT_8 ++#define SPI_OPC2_WREN_MSK SHIFT0(0xff) /* Opcode Write Enable */ ++#define SPI_OPC2_WREN_BASE BIT_0 ++ ++/* GLB_BWIN 0x0080 Block Window Register */ ++#define GLB_BWIN_MSK SHIFT0(0xffffffff) /* Mapped register XY */ ++#define GLB_BWIN_BASE BIT_0 ++ ++/* L1_CFG_MADDR_Hi 0x0100 Link1_MAC Address Register High */ ++#define CFG_MADDR_HI_VAL_3_MSK SHIFT24(0xff) /* MAC Addr_x<3> */ ++#define CFG_MADDR_HI_VAL_3_BASE BIT_24 ++#define CFG_MADDR_HI_VAL_2_MSK SHIFT16(0xff) /* MAC Addr_x<2> */ ++#define CFG_MADDR_HI_VAL_2_BASE BIT_16 ++#define CFG_MADDR_HI_VAL_1_MSK SHIFT8(0xff) /* MAC Addr_x<1> */ ++#define CFG_MADDR_HI_VAL_1_BASE BIT_8 ++#define CFG_MADDR_HI_VAL_0_MSK SHIFT0(0xff) /* MAC Addr_x<0> */ ++#define CFG_MADDR_HI_VAL_0_BASE BIT_0 ++ ++/* L1_CFG_MADDR_LO 0x0104 Link1_MAC Address Register Low */ ++/* Bit(s) CFG_MADDR_LO_RSRV_15_0 reserved */ ++#define CFG_MADDR_LO_VAL_5_MSK SHIFT8(0xff) /* MAC Addr_x<5> */ ++#define CFG_MADDR_LO_VAL_5_BASE BIT_8 ++#define CFG_MADDR_LO_VAL_4_MSK SHIFT0(0xff) /* MAC Addr_x<4> */ ++#define CFG_MADDR_LO_VAL_4_BASE BIT_0 ++ ++/* CFG_IF 0x0118 Interface Type Register (PMD Type and ++ * Connector Type) ++ */ ++#define CFG_IF_PMD_MSK SHIFT8(0xffS) /* PMD */ ++#define CFG_IF_PMD_BASE BIT_8S ++#define CFG_IF_CONN_MSK SHIFT0(0xffS) /* Connector */ ++#define CFG_IF_CONN_BASE BIT_0S ++ ++/* CFG_CREV 0x011A Chip Revision Register */ ++#define CFG_CREV_MSK SHIFT4(0xfS) /* Chip Revision */ ++#define CFG_CREV_BASE BIT_4S ++#define CFG_CREV_HID_ID_MSK SHIFT0(0xfS) /* Hidden ID */ ++#define CFG_CREV_HID_ID_BASE BIT_0S ++ ++/* CFG_CID 0x011B Chip ID Register */ ++#define CFG_CID_MSK SHIFT0(0xffS) /* Chip ID */ ++#define CFG_CID_BASE BIT_0S ++ ++/* CFG_CGATE 0x011C Clock Gating Register */ ++/* Bit(s) CFG_CGATE_RSRV_ reserved */ ++/* Bit(s) CFG_CGATE_RSRV_2_0 reserved */ ++/* Bit(s) CFG_CGATE_RSRV_ reserved */ ++#define CFG_CGATE_DIS_MAC BIT_10S /* Disable PHY/MAC Link */ ++#define CFG_CGATE_CIS_CORE BIT_9S /* Disable core_clk Link */ ++#define CFG_CGATE_DIS_PCI BIT_8S /* Disable pci_clk Link */ ++/* Bit(s) CFG_CGATE_RSRV_7_0 reserved */ ++ ++/* CFG_AIR2 0x011E Application Information Register 2 */ ++/* Bit(s) CFG_AIR2_RSRV_7_0 reserved */ ++ ++/* CFG_AIR1 0x011F Application Information Register 1 */ ++/* Bit(s) CFG_AIR1_RSRV_7_0 reserved */ ++ ++/* CFG_CDIV 0x0120 Clock Divider Register */ ++/* Bit(s) CFG_CDIV_RSRV_7_0 reserved */ ++#define CFG_CDIV_MSK SHIFT16(0xff) /* Clock Div Value */ ++#define CFG_CDIV_BASE BIT_16 ++/* Bit(s) CFG_CDIV_RSRV_13_0 reserved */ ++#define CFG_CDIV_ENA BIT_1 /* Clock Div Enable */ ++#define CFG_CDIV_DIS BIT_0 /* Clock Div Disable */ ++ ++/* IRQ_TIM_INIT 0x0130 Timer Init Value Register */ ++#define IRQ_TIM_INIT_MSK SHIFT0(0xffffffff) /* Timer Init Value */ ++#define IRQ_TIM_INIT_BASE BIT_0 ++ ++/* IRQ_TIM_CNT 0x0134 Timer Register */ ++#define IRQ_TIM_CNT_MSK SHIFT0(0xffffffff) /* Timer */ ++#define IRQ_TIM_CNT_BASE BIT_0 ++ ++/* IRQ_TIM_TCTRL 0x0138 Timer Control/Test Register */ ++/* Bit(s) IRQ_TIM_TCTRL_RSRV_15_0 reserved */ ++/* Bit(s) IRQ_TIM_TCTRL_RSRV_4_0 reserved */ ++#define IRQ_TIM_TCTRL_ON BIT_10 /* Timer Test On */ ++#define IRQ_TIM_TCTRL_OFF BIT_9 /* Timer Test Off */ ++#define IRQ_TIM_TCTRL_STEP BIT_8 /* Timer Step */ ++/* Bit(s) IRQ_TIM_TCTRL_RSRV_4_0 reserved */ ++#define IRQ_TIM_TCTRL_STRT BIT_2 /* Timer Start */ ++#define IRQ_TIM_TCTRL_STOP BIT_1 /* Timer Stop */ ++#define IRQ_TIM_TCTRL_CLR_IRQ BIT_0 /* Timer Clear IRQ */ ++ ++/* MOD_TIM_INIT 0x0140 IRQ Moderation Timer Init Value Register */ ++/* IRQ Moderation Timer Init Value */ ++#define MOD_TIM_INIT_MSK SHIFT0(0xffffffff) ++#define MOD_TIM_INIT_BASE BIT_0 ++ ++/* MOD_TIM_CNT 0x0144 IRQ Moderation Timer Register */ ++#define MOD_TIM_CNT_MSK SHIFT0(0xffffffff) /* IRQ Moderation Timer */ ++#define MOD_TIM_CNT_BASE BIT_0 ++ ++/* MOD_TIM_TCTRL 0x0148 IRQ Moderation Timer Control/Test Register */ ++/* Bit(s) MOD_TIM_TCTRL_RSRV_15_0 reserved */ ++/* Bit(s) MOD_TIM_TCTRL_RSRV_4_0 reserved */ ++#define MOD_TIM_TCTRL_ON BIT_10 /* IM Timer Test On */ ++#define MOD_TIM_TCTRL_OFF BIT_9 /* IM Timer Test Off */ ++#define MOD_TIM_TCTRL_STEP BIT_8 /* IM Timer Step */ ++/* Bit(s) MOD_TIM_TCTRL_RSRV_4_0 reserved */ ++#define MOD_TIM_TCTRL_STRT BIT_2 /* IM Timer Start */ ++#define MOD_TIM_TCTRL_STOP BIT_1 /* IM Timer Stop */ ++/* Bit(s) MOD_TIM_TCTRL_RSRV_ reserved */ ++ ++/* MOD_TIM_MSK 0x014C Interrupt Moderation Mask Register */ ++/* En Mod IRQ xxx */ ++#define MOD_TIM_MSK_EN_MOD_IRQ_XXX_MSK SHIFT0(0xffffffff) ++#define MOD_TIM_BASE_EN_MOD_IRQ_XXX_BASE BIT_0 ++ ++/* MOD_TIM_MSK_HW 0x0150 Interrupt Hardware Error Moderation Mask ++ * Register ++ */ ++/* En Mod IRQ xxx */ ++#define MOD_TIM_MSK_HW_EN_MOD_IRQ_XXX_MSK SHIFT0(0xffffffff) ++#define MOD_TIM_BASE_HW_EN_MOD_IRQ_XXX_BASE BIT_0 ++ ++/* GLB_TCTRL 0x0158 Test Control Register 1 */ ++/* Bit(s) GLB_TCTRL_RSRV_2_0 reserved */ ++#define GLB_TCTRL_ASF_FIFO_RTC BIT_28 /* ASF FIFO RTC */ ++#define GLB_TCTRL_ASF_FIFO_WTC BIT_27 /* ASF FIFO WTC */ ++#define GLB_TCTRL_PCIE_MAC_TX_FIFO_RTC BIT_26 /* PCIE MAC Tx FIFO RTC */ ++#define GLB_TCTRL_PCIE_MAC_TX_FIFO_WTC BIT_25 /* PCIE MAC Tx FIFO WTC */ ++#define GLB_TCTRL_PCIE_MAC_RX_FIFO_RTC BIT_24 /* PCIE MAC Rx FIFO RTC */ ++#define GLB_TCTRL_PCIE_MAC_RX_FIFO_WTC BIT_23 /* PCIE MAC Rx FIFO WTC */ ++#define GLB_TCTRL_PEX_TL_RX_FIFO_RTC BIT_22 /* Pex Tl Rx FIFO RTC */ ++#define GLB_TCTRL_PEX_TL_RX_FIFO_WTC BIT_21 /* Pex Tl Rx FIFO WTC */ ++#define GLB_TCTRL_PEX_TL_TX_FIFO_RTC BIT_20 /* Pex Tl Tx FIFO RTC */ ++#define GLB_TCTRL_PEX_TL_TX_FIFO_WTC BIT_19 /* Pex Tl Tx FIFO WTC */ ++#define GLB_TCTRL_WOL_RAM_RTC BIT_18 /* WOL RAM RTC */ ++#define GLB_TCTRL_WOL_RAM_WTC BIT_17 /* WOL RAM WTC */ ++#define GLB_TCTRL_RMON_RAM_RTC BIT_16 /* RMON RAM RTC */ ++#define GLB_TCTRL_RMON_RAM_WTC BIT_15 /* RMON RAM WTC */ ++#define GLB_TCTRL_PFU_STAT_RTC BIT_14 /* PFU Status RTC */ ++#define GLB_TCTRL_PFU_STAT_WTC BIT_13 /* PFU Status WTC */ ++#define GLB_TCTRL_PFU_AQ_FIFO_RTC BIT_12 /* PFU Aq FIFO RTC */ ++#define GLB_TCTRL_PFU_AQ_FIFO_WTC BIT_11 /* PFU Aq FIFO WTC */ ++#define GLB_TCTRL_PFU_RQ_FIFO_RTC BIT_10 /* PFU Rq FIFO RTC */ ++#define GLB_TCTRL_PFU_RQ_FIFO_WTC BIT_9 /* PFU Rq FIFO WTC */ ++#define GLB_TCTRL_MAC_RX_FIFO_RTC_MSK SHIFT6(0x7) /* MAC Rx FIFO RTC */ ++#define GLB_TCTRL_MAC_RX_FIFO_RTC_BASE BIT_6 ++#define GLB_TCTRL_MAC_RX_FIFO_WTC_MSK SHIFT4(0x3) /* MAC Rx FIFO WTC */ ++#define GLB_TCTRL_MAC_RX_FIFO_WTC_BASE BIT_4 ++#define GLB_TCTRL_MAC_TX_FIFO_RTC BIT_3 /* MAC Tx FIFO RTC */ ++#define GLB_TCTRL_MAC_TX_FIFO_WTC BIT_2 /* MAC Tx FIFO WTC */ ++#define GLB_TCTRL_EN_CFG_WR_ON BIT_1 /* En Config Write On */ ++#define GLB_TCTRL_EN_CFG_WR_OFF BIT_0 /* En Config Write Off */ ++ ++/* GLB_GPIO 0x015C General Purpose I/O Register */ ++#define GLB_GPIO_CLK_DEB_ENA BIT_31 /* Clock Debug Enable */ ++/* Bit(s) GLB_GPIO_RSRV_ reserved */ ++#define GLB_GPIO_CLK_DBG_MSK SHIFT26(0xf) /* Clock Debug */ ++#define GLB_GPIO_CLK_DBG_BASE BIT_26 ++/* Bit(s) GLB_GPIO_RSRV_9_0 reserved */ ++/* Disable Internal Reset After D3 to D0 */ ++#define GLB_GPIO_INT_RST_D3_DIS BIT_15 ++#define GLB_GPIO_LED_PAD_SPEED_UP BIT_14 /* LED PAD Speed Up */ ++#define GLB_GPIO_STAT_RACE_DIS BIT_13 /* Status Race Disable */ ++#define GLB_GPIO_TEST_SEL_MSK SHIFT11(0x3) /* Testmode Select */ ++#define GLB_GPIO_TEST_SEL_BASE BIT_11 ++/* Bit(s) GLB_GPIO_RSRV_10_0 reserved */ ++ ++/* TWSI_CTRL 0x0160 TWSI (HW) Control Register */ ++#define TWSI_CTRL_FLAG BIT_31 /* Flag */ ++#define TWSI_CTRL_ADDR_MSK SHIFT16(0x7fff) /* TWSI Address */ ++#define TWSI_CTRL_ADDR_BASE BIT_16 ++#define TWSI_CTRL_DEVSEL_MSK SHIFT9(0x7f) /* TWSI Devsel */ ++#define TWSI_CTRL_DEVSEL_BASE BIT_9 ++/* Bit(s) TWSI_CTRL_RSRV_3_0 reserved */ ++#define TWSI_CTRL_BURST_ENA BIT_4 /* TWSI Burst */ ++#define TWSI_CTRL_DEVSIZE_MSK SHIFT1(0x7) /* TWSI Device Size */ ++#define TWSI_CTRL_DEVSIZE_BASE BIT_1 ++#define TWSI_CTRL_STOP BIT_0 /* TWSI Stop */ ++ ++/* TWSI_DATA 0x0164 TWSI (HW) Data Register */ ++#define TWSI_DATA_MSK SHIFT0(0xffffffff) /* TWSI Data */ ++#define TWSI_DATA_BASE BIT_0 ++ ++/* TWSI_IRQ 0x0168 TWSI (HW) IRQ Register */ ++/* Bit(s) TWSI_IRQ_RSRV_30_0 reserved */ ++#define TWSI_IRQ_CLR_IRQ BIT_0 /* Clear IRQ TWSI */ ++ ++/* TWSI_SW 0x016C TWSI (SW) Register */ ++/* Bit(s) TWSI_SW_RSRV_28_0 reserved */ ++#define TWSI_SW_DIR BIT_2 /* TWSI Data Dir */ ++#define TWSI_SW_DATA BIT_1 /* TWSI Data */ ++#define TWSI_SW_CLK BIT_0 /* TWSI Clock */ ++ ++/* PCIE_PHY 0x0170 PCI Express PHY Address Register */ ++#define PCIE_PHY_RW BIT_31 /* PEX PHY Access Mode */ ++#define PCIE_PHY_REGFILE BIT_30 /* PEX PHY regfile */ ++#define PCIE_PHY_ADDR_MSK SHIFT16(0x3fff) /* PEX PHY Address */ ++#define PCIE_PHY_ADDR_BASE BIT_16 ++#define PCIE_PHY_DATA_MSK SHIFT0(0xffff) /* PEX PHY Data */ ++#define PCIE_PHY_DATA_BASE BIT_0 ++ ++/* RAM_ADDR 0x0180 RAM Address Register */ ++#define RAM_ADDR_SEL_MSK SHIFT30(0x3) /* RAM Select */ ++#define RAM_ADDR_SEL_BASE BIT_30 ++#define RAM_ADDR_ADDR_MUX BIT_29 /* RAM Address Mux */ ++/* Bit(s) RAM_ADDR_RSRV_19_0 reserved */ ++#define RAM_ADDR_MSK SHIFT0(0x1ff) /* RAM Address */ ++#define RAM_ADDR_BASE BIT_0 ++ ++/* RAM_DATA_LO 0x0184 Data Port/Lower Dword Register */ ++#define RAM_DATA_LO_MSK SHIFT0(0xffffffff) /* Data Port/lower dword */ ++#define RAM_DATA_LO_BASE BIT_0 ++ ++/* RAM_DATA_HI 0x0188 Data Port/Upper Dword Register */ ++#define RAM_DATA_HI_MSK SHIFT0(0xffffffff) /* Data Port/upper dword */ ++#define RAM_DATA_HI_BASE BIT_0 ++ ++/* ASF_TO 0x0190 Timeout Register */ ++#define ASF_TO_ASF_TO3_MSK SHIFT24(0xff) /* Timeout Value 3 */ ++#define ASF_TO_ASF_TO3_BASE BIT_24 ++#define ASF_TO_ASF_TO2_MSK SHIFT16(0xff) /* Timeout Value 2 */ ++#define ASF_TO_ASF_TO2_BASE BIT_16 ++#define ASF_TO_ASF_TO1_MSK SHIFT8(0xff) /* Timeout Value 1 */ ++#define ASF_TO_ASF_TO1_BASE BIT_8 ++#define ASF_TO_ASF_TO0_MSK SHIFT0(0xff) /* Timeout Value 0 */ ++#define ASF_TO_ASF_TO0_BASE BIT_0 ++ ++/* ASF_CTRL 0x01A0 FIFO Interface Control */ ++/* Bit(s) ASF_CTRL_RSRV_29_0 reserved */ ++#define ASF_CTRL_ASF_ENA BIT_1 /* Reset Clear */ ++#define ASF_CTRL_ASF_RST BIT_0 /* Reset Set */ ++ ++/* RSS_KEY0 0x0220 RSS Key 0 Register */ ++#define RSS_KEY0_MSK SHIFT0(0xffffffff) /* RSS Key0 */ ++#define RSS_KEY0_BASE BIT_0 ++ ++/* RSS_KEY1 0x0224 RSS Key 1 Register */ ++#define RSS_KEY1_MSK SHIFT0(0xffffffff) /* RSS Key1 */ ++#define RSS_KEY1_BASE BIT_0 ++ ++/* RSS_KEY2 0x0228 RSS Key 2 Register */ ++#define RSS_KEY2_MSK SHIFT0(0xffffffff) /* RSS Key2 */ ++#define RSS_KEY2_BASE BIT_0 ++ ++/* RSS_KEY3 0x022C RSS Key 3 Register */ ++#define RSS_KEY3_MSK SHIFT0(0xffffffff) /* RSS Key3 */ ++#define RSS_KEY3_BASE BIT_0 ++ ++/* RSS_KEY4 0x0230 RSS Key 4 Register */ ++#define RSS_KEY4_MSK SHIFT0(0xffffffff) /* RSS Key4 */ ++#define RSS_KEY4_BASE BIT_0 ++ ++/* RSS_KEY5 0x0234 RSS Key 5 Register */ ++#define RSS_KEY5_MSK SHIFT0(0xffffffff) /* RSS Key5 */ ++#define RSS_KEY5_BASE BIT_0 ++ ++/* RSS_KEY6 0x0238 RSS Key 6 Register */ ++#define RSS_KEY6_MSK SHIFT0(0xffffffff) /* RSS Key6 */ ++#define RSS_KEY6_BASE BIT_0 ++ ++/* RSS_KEY7 0x023C RSS Key 7 Register */ ++#define RSS_KEY7_MSK SHIFT0(0xffffffff) /* RSS Key7 */ ++#define RSS_KEY7_BASE BIT_0 ++ ++/* RSS_KEY8 0x0240 RSS Key 8 Register */ ++#define RSS_KEY8_MSK SHIFT0(0xffffffff) /* RSS Key8 */ ++#define RSS_KEY8_BASE BIT_0 ++ ++/* RSS_KEY9 0x0244 RSS Key 9 Register */ ++#define RSS_KEY9_MSK SHIFT0(0xffffffff) /* RSS Key9 */ ++#define RSS_KEY9_BASE BIT_0 ++ ++/* RBMU_DESCR 0x0400 Current Receive Descriptor Register */ ++#define RBMU_DESCR_CTRL_MSK SHIFT16(0xffff) /* Receive Buffer Control */ ++#define RBMU_DESCR_CTRL_BASE BIT_16 ++/* Receive Buffer Byte Count */ ++#define RBMU_DESCR_BYTE_CNT_MSK SHIFT0(0xffff) ++#define RBMU_DESCR_BYTE_CNT_BASE BIT_0 ++ ++/* RBMU_HASH 0x0404 RSS Hash Checksum Register */ ++#define RBMU_HASH_MSK SHIFT0(0xffffffff) /* RSS Hash Checksum */ ++#define RBMU_HASH_BASE BIT_0 ++ ++/* RBMU_ADDR_HI 0x0408 Receive Buffer Address Lo Register */ ++#define RBMU_ADDR_HI_MSK SHIFT0(0xffffffff) /* Receive Buffer Address Lo */ ++#define RBMU_ADDR_HI_BASE BIT_0 ++ ++/* RBMU_ADDR_LO 0x040C Receive Buffer Address Hi Register */ ++#define RBMU_ADDR_LO_MSK SHIFT0(0xffffffff) /* Receive Buffer Address Hi */ ++#define RBMU_ADDR_LO_BASE BIT_0 ++ ++/* RBMU_RFSW 0x0410 Receive Buffer Status Word Register */ ++#define RBMU_RFSW_MSK SHIFT0(0xffffffff) /* RFSW */ ++#define RBMU_RFSW_BASE BIT_0 ++ ++/* RBMU_TSP 0x0414 Receive Timestamp Register */ ++#define RBMU_TSP_MSK SHIFT0(0xffffffff) /* Timestamp */ ++#define RBMU_TSP_BASE BIT_0 ++ ++/* RBMU_VLAN 0x0420 VLAN Tag Register */ ++/* Bit(s) RBMU_VLAN_RSRV_15_0 reserved */ ++#define RBMU_VLAN_MSK SHIFT0(0xffff) /* VLAN Tag */ ++#define RBMU_VLAN_BASE BIT_0 ++ ++/* RBMU_DONE_IDX 0x0424 Done Index Register */ ++/* Bit(s) RBMU_DONE_IDX_RSRV_19_0 reserved */ ++#define RBMU_DONE_IDX_MSK SHIFT0(0xfff) /* Done Index */ ++#define RBMU_DONE_IDX_BASE BIT_0 ++ ++/* RBMU_REQ_ADDR_LO 0x0428 Request Address, Lower Register */ ++#define RBMU_REQ_ADDR_LO_MSK SHIFT0(0xffffffff) /* Request Addr Lo */ ++#define RBMU_REQ_ADDR_LO_BASE BIT_0 ++ ++/* RBMU_REQ_ADDR_HI 0x042C Request Address, Upper Register */ ++#define RBMU_REQ_ADDR_HI_MSK SHIFT0(0xffffffff) /* Request Addr Hi */ ++#define RBMU_REQ_ADDR_HI_BASE BIT_0 ++ ++/* RBMU_REQ_CNT 0x0430 Request Byte Count Register */ ++/* Bit(s) RBMU_REQ_CNT_RSRV_20_0 reserved */ ++#define RBMU_REQ_CNT_MSK SHIFT0(0x7ff) /* Request Byte Count */ ++#define RBMU_REQ_CNT_BASE BIT_0 ++ ++/* RBMU_CSR 0x0434 BMU Control/Status Register */ ++#define RBMU_CSR_IDLE BIT_31 /* BMU Idle */ ++#define RBMU_CSR_TCPUDP_CSUMOK BIT_30 /* TCP/UDP Checksum OK */ ++#define RBMU_CSR_UDP_PKT BIT_29 /* UDP Pkt */ ++#define RBMU_CSR_FRAG_PKT BIT_28 /* Fragment Pkt */ ++#define RBMU_CSR_IPV4_CSUMOK BIT_27 /* IPv4 Checksum OK */ ++#define RBMU_CSR_IPV6_PKT BIT_26 /* IPv6 Pkt */ ++#define RBMU_CSR_TCP_PKT BIT_25 /* TCP Pkt */ ++#define RBMU_CSR_IPV4_PKT BIT_24 /* IPv4 Pkt */ ++/* Bit(s) RBMU_CSR_RSRV_3_0 reserved */ ++#define RBMU_CSR_GCORECLK_ENA BIT_19 /* RX Core CLock Gating Enable */ ++#define RBMU_CSR_GCORECLK_DIS BIT_18 /* RX Core Clock Gating Disable */ ++#define RBMU_CSR_MACSEC_LE_ENA BIT_17 /* MACSec LE Enable */ ++#define RBMU_CSR_MACSEC_LE_DIS BIT_16 /* MACSec LE Disable */ ++#define RBMU_CSR_RSS_ENA BIT_15 /* RSS Hash Enable */ ++#define RBMU_CSR_RSS_DIS BIT_14 /* RSS Hash Disable */ ++#define RBMU_CSR_CSUM_ENA BIT_13 /* RX Checksum Enable */ ++#define RBMU_CSR_CSUM_DIS BIT_12 /* RX Checksum Disable */ ++#define RBMU_CSR_CLR_IRQ_PAR BIT_11 /* Clear IRQ Parity */ ++#define RBMU_CSR_CLR_IRQ_CHK BIT_10 /* Clear IRQ Check */ ++#define RBMU_CSR_STOP_RBMU BIT_9 /* Stop Rx BMU */ ++#define RBMU_CSR_STRT_RBMU BIT_8 /* Start Rx BMU */ ++#define RBMU_CSR_FIFO_OP_ON BIT_7 /* FIFO Operational On */ ++#define RBMU_CSR_FIFO_OP_OFF BIT_6 /* FIFO Operational Off */ ++#define RBMU_CSR_FIFO_ENA BIT_5 /* FIFO Enable */ ++#define RBMU_CSR_FIFO_RST BIT_4 /* FIFO Reset */ ++#define RBMU_CSR_RBMU_OP_ON BIT_3 /* BMU Operational On */ ++#define RBMU_CSR_RBMU_OP_OFF BIT_2 /* BMU Operational Off */ ++#define RBMU_CSR_RBMU_ENA BIT_1 /* BMU Enable */ ++#define RBMU_CSR_RBMU_RST BIT_0 /* BMU Reset */ ++ ++/* RBMU_TEST 0x0438 BMU Test Register */ ++/* Bit(s) RBMU_TEST_RSRV_23_0 reserved */ ++/* Bit(s) RBMU_TEST_RSRV_ reserved */ ++/* Testmode Req Nbytes/Addr On */ ++#define RBMU_TEST_TEST_REQ_NB_ON BIT_6 ++/* Testmode Req Nbytes/Addr Off */ ++#define RBMU_TEST_TEST_REQ_NB_OFF BIT_5 ++/* Teststep Req Nbytes/Addr */ ++#define RBMU_TEST_TESTSTEP_REQ_NB BIT_4 ++/* Bit(s) RBMU_TEST_RSRV_ reserved */ ++/* Testmode Done Index On */ ++#define RBMU_TEST_TEST_DONE_IDX_ON BIT_2 ++/* Testmode Done Index Off */ ++#define RBMU_TEST_TEST_DONE_IDX_OFF BIT_1 ++/* Teststep Done Index */ ++#define RBMU_TEST_TESTSTEP_DONE_IDX BIT_0 ++ ++/* RBMU_SM 0x043C BMU Statemachine Register */ ++#define RBMU_SM_MSK SHIFT0(0xffffffff) /* BMU Statemachine */ ++#define RBMU_SM_BASE BIT_0 ++ ++/* RBMU_FIFO_WM 0x0440 FIFO Watermark Register */ ++/* Bit(s) RBMU_FIFO_WM_RSRV_4_0 reserved */ ++#define RBMU_FIFO_WM_MSK SHIFT0(0x7ffS) /* FIFO Watermark */ ++#define RBMU_FIFO_WM_BASE BIT_0S ++ ++/* RBMU_FIFO_AL 0x0442 FIFO Alignment Register */ ++/* Bit(s) RBMU_FIFO_AL_RSRV_8_0 reserved */ ++#define RBMU_FIFO_AL_MUX_MSK SHIFT4(0x7S) /* MUX */ ++#define RBMU_FIFO_AL_MUX_BASE BIT_4S ++/* Bit(s) RBMU_FIFO_AL_RSRV_ reserved */ ++#define RBMU_FIFO_AL_VRAM_MSK SHIFT0(0x7S) /* VRAM */ ++#define RBMU_FIFO_AL_VRAM_BASE BIT_0S ++ ++/* TBMU_DESC1 0x0680 Current Transmit Descriptor Register 1 */ ++#define TBMU_DESC1_MSK SHIFT16(0xffff) /* Transmit Buffer Control */ ++#define TBMU_DESC1_BASE BIT_16 ++ ++/* TBMU_DESC2 0x0684 Current Transmit Descriptor Register 2 */ ++#define TBMU_DESC2_MSK SHIFT0(0xffffS) /* Transmit Buffer Byte Count */ ++#define TBMU_DESC2_BASE BIT_0S ++ ++/* TBMU_ADDR_LO 0x0688 Transmit Buffer Address Lower Register */ ++#define TBMU_ADDR_LO_MSK SHIFT0(0xffffffff) /* Transmit Buffer Address Lo */ ++#define TBMU_ADDR_LO_BASE BIT_0 ++ ++/* TBMU_ADDR_HI 0x068C Transmit Buffer Address Upper Register */ ++#define TBMU_ADDR_HI_MSK SHIFT0(0xffffffff) /* Transmit Buffer Address Hi */ ++#define TBMU_ADDR_HI_BASE BIT_0 ++ ++/* TBMU_TFSW 0x0690 Transmit Buffer Status Word Register */ ++#define TBMU_TFSW_MSK SHIFT0(0xffffffff) /* TFSW */ ++#define TBMU_TFSW_BASE BIT_0 ++ ++/* TBMU_VLAN 0x06A0 VLAN Tag Register */ ++/* Bit(s) TBMU_VLAN_RSRV_15_0 reserved */ ++#define TBMU_VLAN_MSK SHIFT0(0xffff) /* VLAN Tag */ ++#define TBMU_VLAN_BASE BIT_0 ++ ++/* TBMU_DONE_IDX 0x06A4 Done Index Register */ ++/* Bit(s) TBMU_DONE_IDX_RSRV_19_0 reserved */ ++#define TBMU_DONE_IDX_MSK SHIFT0(0xfff) /* Done Index */ ++#define TBMU_DONE_IDX_BASE BIT_0 ++ ++/* TBMU_REQ_ADDR_LO 0x06A8 Request Address Lower Register */ ++#define TBMU_REQ_ADDR_LO_MSK SHIFT0(0xffffffff) /* Request Addr Lo */ ++#define TBMU_REQ_ADDR_LO_BASE BIT_0 ++ ++/* TBMU_REQ_ADDR_HI 0x06AC Request Address Upper Register */ ++#define TBMU_REQ_ADDR_HI_MSK SHIFT0(0xffffffff) /* Request Addr Hi */ ++#define TBMU_REQ_ADDR_HI_BASE BIT_0 ++ ++/* TBMU_REQ_CNT 0x06B0 Request Byte Count Register */ ++/* Bit(s) TBMU_REQ_CNT_RSRV_20_0 reserved */ ++#define TBMU_REQ_CNT_MSK SHIFT0(0x7ff) /* Request Byte Count */ ++#define TBMU_REQ_CNT_BASE BIT_0 ++ ++/* TBMU_CSR 0x06B4 BMU Control/Status Register */ ++#define TBMU_CSR_IDLE BIT_31 /* BMU Idle */ ++/* Bit(s) TBMU_CSR_RSRV_6_0 reserved */ ++/* Tx path automatic clock gating enable */ ++#define TBMU_CSR_TX_GATE_ON BIT_23 ++/* TX path automatic clock gating disable */ ++#define TBMU_CSR_TX_GATE_OFF BIT_22 ++/* TX path automatic clock gating timeout */ ++#define TBMU_CSR_TX_GATE_TIMEOUT_MSK SHIFT16(0x3f) ++#define TBMU_CSR_TX_GATE_TIMEOUT_BASE BIT_16 ++/* Bit(s) TBMU_CSR_RSRV_1_0 reserved */ ++/* IP ID Increment Enable */ ++#define TBMU_CSR_IP_ID_INCR_ENA BIT_13 ++/* IP ID Increment Disable */ ++#define TBMU_CSR_IP_ID_INCR_DIS BIT_12 ++#define TBMU_CSR_CLR_IRQ_TCP BIT_11 /* Clear IRQ TCP */ ++#define TBMU_CSR_CLR_IRQ_CHK BIT_10 /* Clear IRQ Check */ ++#define TBMU_CSR_STOP_TBMU BIT_9 /* Stop Tx BMU */ ++#define TBMU_CSR_STRT_TBMU BIT_8 /* Start Tx BMU */ ++#define TBMU_CSR_FIFO_OP_ON BIT_7 /* FIFO Operational On */ ++#define TBMU_CSR_FIFO_OP_OFF BIT_6 /* FIFO Operational Off */ ++#define TBMU_CSR_FIFO_ENA BIT_5 /* FIFO Enable */ ++#define TBMU_CSR_FIFO_RST BIT_4 /* FIFO Reset */ ++#define TBMU_CSR_TBMU_OP_ON BIT_3 /* BMU Operational On */ ++#define TBMU_CSR_TBMU_OP_OFF BIT_2 /* BMU Operational Off */ ++#define TBMU_CSR_TBMU_ENA BIT_1 /* BMU Enable */ ++#define TBMU_CSR_TBMU_RST BIT_0 /* BMU Reset */ ++ ++/* TBMU_TEST 0x06B8 BMU Test Register */ ++/* BMU tx checksum auto calculation disable */ ++#define TBMU_TEST_BMU_TX_CHK_AUTO_OFF BIT_31 ++/* BMU tx checksum auto calculation enable */ ++#define TBMU_TEST_BMU_TX_CHK_AUTO_ON BIT_30 ++/* Bit(s) TBMU_TEST_RSRV_6_0 reserved */ ++/* Testmode Shadow Read Ptr On */ ++#define TBMU_TEST_TEST_RSPTR_ON BIT_22 ++/* Testmode Shadow Read Ptr Off */ ++#define TBMU_TEST_TEST_RSPTR_OFF BIT_21 ++/* Teststep Shadow Read Ptr */ ++#define TBMU_TEST_TESTSTEP_RSPTR BIT_20 ++/* Bit(s) TBMU_TEST_RSRV_ reserved */ ++#define TBMU_TEST_TEST_RPTR_ON BIT_18 /* Testmode Read Ptr On */ ++/* Testmode Read Ptr Off */ ++#define TBMU_TEST_TEST_RPTR_OFF BIT_17 ++#define TBMU_TEST_TESTSTEP_RPTR BIT_16 /* Teststep Read Ptr */ ++/* Bit(s) TBMU_TEST_RSRV_ reserved */ ++/* Testmode Shadow Write Ptr On */ ++#define TBMU_TEST_TEST_WSPTR_ON BIT_14 ++/* Testmode Shadow Write Ptr Off */ ++#define TBMU_TEST_TEST_WSPTR_OFF BIT_13 ++/* Teststep Shadow Write Ptr */ ++#define TBMU_TEST_TESTSTEP_WSPTR BIT_12 ++/* Bit(s) TBMU_TEST_RSRV_ reserved */ ++/* Testmode Write Ptr On */ ++#define TBMU_TEST_TEST_WPTR_ON BIT_10 ++/* Testmode Write Ptr Off */ ++#define TBMU_TEST_TEST_WPTR_OFF BIT_9 ++#define TBMU_TEST_TESTSTEP_WPTR BIT_8 /* Teststep Write Ptr */ ++/* Bit(s) TBMU_TEST_RSRV_ reserved */ ++/* Testmode Req Nbytes/Addr On */ ++#define TBMU_TEST_TEST_REQ_NB_ON BIT_6 ++/* Testmode Req Nbytes/Addr Off */ ++#define TBMU_TEST_TEST_REQ_NB_OFF BIT_5 ++/* Teststep Req Nbytes/Addr */ ++#define TBMU_TEST_TESTSTEP_REQ_NB BIT_4 ++/* Bit(s) TBMU_TEST_RSRV_ reserved */ ++/* Testmode Done Index On */ ++#define TBMU_TEST_TEST_DONE_IDX_ON BIT_2 ++/* Testmode Done Index Off */ ++#define TBMU_TEST_TEST_DONE_IDX_OFF BIT_1 ++#define TBMU_TEST_TESTSTEP_DONE_IDX BIT_0 /* Teststep Done Index */ ++ ++/* TBMU_SM 0x06BC BMU Statemachine Register */ ++#define TBMU_SM_MSK SHIFT0(0xffffffff) /* BMU Statemachine */ ++#define TBMU_SM_BASE BIT_0 ++ ++/* TBMU_FIFO_WM 0x06C0 FIFO Watermark Register */ ++/* Bit(s) TBMU_FIFO_WM_RSRV_4_0 reserved */ ++#define TBMU_FIFO_WM_MSK SHIFT3(0xffS) /* FIFO Watermark */ ++#define TBMU_FIFO_WM_BASE BIT_3S ++/* Bit(s) TBMU_FIFO_WM_RSRV_2_0 reserved */ ++ ++/* TBMU_FIFO_AL 0x06C2 FIFO Alignment Register */ ++/* Bit(s) TBMU_FIFO_AL_RSRV_8_0 reserved */ ++#define TBMU_FIFO_AL_MUX_MSK SHIFT4(0x7S) /* MUX */ ++#define TBMU_FIFO_AL_MUX_BASE BIT_4S ++/* Bit(s) TBMU_FIFO_AL_RSRV_ reserved */ ++#define TBMU_FIFO_AL_VRAM_MSK SHIFT0(0x7S) /* VRAM */ ++#define TBMU_FIFO_AL_VRAM_BASE BIT_0S ++ ++/* TBMU_FIFO_WSPTR 0x06C4 FIFO Write Shadow Pointer Register */ ++/* Bit(s) TBMU_FIFO_WSPTR_RSRV_4_0 reserved */ ++/* FIFO Write Shadow Pointer */ ++#define TBMU_FIFO_WSPTR_MSK SHIFT0(0x7ffS) ++#define TBMU_FIFO_WSPTR_BASE BIT_0S ++ ++/* TBMU_FIFO_WSLEV 0x06C6 FIFO Write Shadow Level Register */ ++/* Bit(s) TBMU_FIFO_WSLEV_RSRV_7_0 reserved */ ++#define TBMU_FIFO_WSLEV_MSK SHIFT0(0xffS) /* FIFO Write Level */ ++#define TBMU_FIFO_WSLEV_BASE BIT_0S ++ ++/* TBMU_FIFO_WPTR 0x06C8 FIFO Write Pointer Register */ ++/* Bit(s) TBMU_FIFO_WPTR_RSRV_7_0 reserved */ ++#define TBMU_FIFO_WPTR_MSK SHIFT0(0xffS) /* FIFO Write Pointer */ ++#define TBMU_FIFO_WPTR_BASE BIT_0S ++ ++/* TBMU_FIFO_WLEV 0x06CA FIFO Write Level Register */ ++/* Bit(s) TBMU_FIFO_WLEV_RSRV_7_0 reserved */ ++#define TBMU_FIFO_WLEV_MSK SHIFT0(0xffS) /* FIFO Write Level */ ++#define TBMU_FIFO_WLEV_BASE BIT_0S ++ ++/* TBMU_FIFO_RPTR 0x06CC FIFO Read Pointer Register */ ++/* Bit(s) TBMU_FIFO_RPTR_RSRV_7_0 reserved */ ++#define TBMU_FIFO_RPTR_MSK SHIFT0(0xffS) /* FIFO Read Pointer */ ++#define TBMU_FIFO_RPTR_BASE BIT_0S ++ ++/* TBMU_RLEV 0x06CE FIFO Read Level Register */ ++/* Bit(s) TBMU_RLEV_RSRV_7_0 reserved */ ++#define TBMU_RLEV_MSK SHIFT0(0xffS) /* FIFO Read Level */ ++#define TBMU_RLEV_BASE BIT_0S ++ ++/* PFU_CTRL 0x06D0 Prefetch Control Register */ ++/* Bit(s) PFU_CTRL_RSRV_16_0 reserved */ ++/* Master Request Loopback Test On */ ++#define PFU_CTRL_MST_REQ_LPBK_ON BIT_14 ++/* Master Request Loopback Test Off */ ++#define PFU_CTRL_MST_REQ_LPBK_OFF BIT_13 ++/* Master Request Loopback Step */ ++#define PFU_CTRL_MST_REQ_LPBK_STEP BIT_12 ++/* Bit(s) PFU_CTRL_RSRV_ reserved */ ++/* FIFO Read Pointer Test On */ ++#define PFU_CTRL_FIFO_RPTR_TEST_ON BIT_10 ++/* FIFO Read Pointer Test Off */ ++#define PFU_CTRL_FIFO_RPTR_TEST_OFF BIT_9 ++/* FIFO Read Pointer Step */ ++#define PFU_CTRL_FIFO_RPTR_TEST_STEP BIT_8 ++/* Bit(s) PFU_CTRL_RSRV_ reserved */ ++/* FIFO Write Pointer Test On */ ++#define PFU_CTRL_FIFO_WPTR_TEST_ON BIT_6 ++/* FIFO Write Pointer Test Off */ ++#define PFU_CTRL_FIFO_WPTR_TEST_OFF BIT_5 ++/* FIFO Write Pointer Step */ ++#define PFU_CTRL_FIFO_WPTR_TEST_STEP BIT_4 ++#define PFU_CTRL_OP_ON BIT_3 /* Operational On */ ++#define PFU_CTRL_OP_OFF BIT_2 /* Operational Off */ ++#define PFU_CTRL_PFU_RST_CLR BIT_1 /* PFU Reset Clear */ ++#define PFU_CTRL_PFU_RST_SET BIT_0 /* PFU Reset Set */ ++ ++/* PFU_LAST_IDX 0x06D4 List Last Index Register */ ++/* Bit(s) PFU_LAST_IDX_RSRV_19_0 reserved */ ++#define PFU_LAST_IDX_MSK SHIFT2(0x3ff) /* List Last Index */ ++#define PFU_LAST_IDX_BASE BIT_2 ++#define PFU_LAST_IDX_VAL_FIX_MSK SHIFT0(0x3) /* List Last Index Fix */ ++#define PFU_LAST_IDX_VAL_FIX_BASE BIT_0 ++ ++/* PFU_LADR_LO 0x06D8 List Start Address Low Register */ ++/* List Start Address Low */ ++#define PFU_LADR_LO_MSK SHIFT5(0x7ffffff) ++#define PFU_LADR_LO_BASE BIT_5 ++/* List Start Address Low Fix */ ++#define PFU_LADR_LO_VAL_FIX_MSK SHIFT0(0x1f) ++#define PFU_LADR_LO_VAL_FIX_BASE BIT_0 ++ ++/* PFU_LADR_HI 0x06DC List Start Address High Register */ ++#define PFU_LADR_HI_MSK SHIFT0(0xffffffff) /* List Start Address High */ ++#define PFU_LADR_HI_BASE BIT_0 ++ ++/* PFU_GET_IDX 0x06E0 Get Index Register */ ++/* Bit(s) PFU_GET_IDX_RSRV_19_0 reserved */ ++#define PFU_GET_IDX_MSK SHIFT0(0xfff) /* Get Index */ ++#define PFU_GET_IDX_BASE BIT_0 ++ ++/* PFU_PUT_IDX 0x06E4 Put Index Register */ ++/* Bit(s) PFU_PUT_IDX_RSRV_19_0 reserved */ ++#define PFU_PUT_IDX_MSK SHIFT0(0xfff) /* Put Index */ ++#define PFU_PUT_IDX_BASE BIT_0 ++ ++/* PFU_FIFO_WR 0x06F0 FIFO RAM Write and Write Shadow Pointer ++ * Register ++ */ ++/* Bit(s) PFU_FIFO_WR_RSRV_7_0 reserved */ ++/* FIFO Write Shadow Pointer */ ++#define PFU_FIFO_WR_WSPTR_MSK SHIFT16(0xff) ++#define PFU_FIFO_WR_WSPTR_BASE BIT_16 ++/* Bit(s) PFU_FIFO_WR_RSRV_10_0 reserved */ ++#define PFU_FIFO_WR_WPTR_MSK SHIFT0(0x1f) /* FIFO Write Pointer */ ++#define PFU_FIFO_WR_WPTR_BASE BIT_0 ++ ++/* PFU_FIFO_RD 0x06F4 FIFO RAM Read Pointer Register */ ++/* Bit(s) PFU_FIFO_RD_RSRV_26_0 reserved */ ++#define PFU_FIFO_RD_RPTR_MSK SHIFT0(0x1f) /* FIFO Read Pointer */ ++#define PFU_FIFO_RD_RPTR_BASE BIT_0 ++ ++/* PFU_FIFO_REQ_NB 0x06F8 Master Request nbytes Register */ ++/* Bit(s) PFU_FIFO_REQ_NB_RSRV_4_0 reserved */ ++/* Master Request nBytes */ ++#define PFU_FIFO_REQ_NB_MR_MSK SHIFT16(0x7ff) ++#define PFU_FIFO_REQ_NB_MR_BASE BIT_16 ++/* Bit(s) PFU_FIFO_REQ_NB_RSRV_9_0 reserved */ ++#define PFU_FIFO_REQ_NB_WM_MSK SHIFT0(0x3f) /* FIFO Watermark */ ++#define PFU_FIFO_REQ_NB_WM_BASE BIT_0 ++ ++/* PFU_FIFO_LEV 0x06FC FIFO Shadow Level Register */ ++/* Bit(s) PFU_FIFO_LEV_RSRV_7_0 reserved */ ++#define PFU_FIFO_LEV_SLEV_MSK SHIFT16(0xff) /* FIFO Shadow level */ ++#define PFU_FIFO_LEV_SLEV_BASE BIT_16 ++/* Bit(s) PFU_FIFO_LEV_RSRV_10_0 reserved */ ++#define PFU_FIFO_LEV_MSK SHIFT0(0x1f) /* FIFO level */ ++#define PFU_FIFO_LEV_BASE BIT_0 ++ ++/* RA_SADDR 0x0900 ASF Receive FIFO Start Address */ ++/* Bit(s) RA_SADDR_RSRV_22_0 reserved */ ++#define RA_SADDR_RA_SADDR_MSK SHIFT0(0x1ff) /* Start Address */ ++#define RA_SADDR_RA_SADDR_BASE BIT_0 ++ ++/* RA_EADDR 0x0904 ASF Receive FIFO End Address */ ++/* Bit(s) RA_EADDR_RSRV_22_0 reserved */ ++#define RA_EADDR_RA_EADDR_MSK SHIFT0(0x1ff) /* End Address */ ++#define RA_EADDR_RA_EADDR_BASE BIT_0 ++ ++/* RA_WPTR 0x0908 ASF Receive FIFO Write Pointer */ ++/* Bit(s) RA_WPTR_RSRV_22_0 reserved */ ++#define RA_WPTR_RA_WPTR_MSK SHIFT0(0x1ff) /* Write Pointer */ ++#define RA_WPTR_RA_WPTR_BASE BIT_0 ++ ++/* RA_RPTR 0x090C ASF Receive FIFO Read Pointer */ ++/* Bit(s) RA_RPTR_RSRV_22_0 reserved */ ++#define RA_RPTR_RA_RPTR_MSK SHIFT0(0x1ff) /* Read Pointer */ ++#define RA_RPTR_RA_RPTR_BASE BIT_0 ++ ++/* RA_BRST 0x0910 ASF Receive FIFO Burst Control */ ++/* Bit(s) RA_BRST_RSRV_13_0 reserved */ ++#define RA_BRST_RA_BRST_EN BIT_17 /* Burst Enable */ ++#define RA_BRST_RA_BRST_RST BIT_16 /* Burst Disable */ ++/* Bit(s) RA_BRST_RSRV_6_0 reserved */ ++#define RA_BRST_RA_BRST_THRS_MSK SHIFT0(0x1ff) /* Burst Threshold */ ++#define RA_BRST_RA_BRST_THRS_BASE BIT_0 ++ ++/* RA_PCNT 0x0920 ASF Receive FIFO Packet Counter */ ++/* Bit(s) RA_PCNT_RSRV_22_0 reserved */ ++#define RA_PCNT_RA_PCNT_MSK SHIFT0(0x1ff) /* Packet Counter */ ++#define RA_PCNT_RA_PCNT_BASE BIT_0 ++ ++/* RA_LEV 0x0924 ASF Receive FIFO Level */ ++/* Bit(s) RA_LEV_RSRV_22_0 reserved */ ++#define RA_LEV_RA_LEV_MSK SHIFT0(0x1ff) /* Level */ ++#define RA_LEV_RA_LEV_BASE BIT_0 ++ ++/* RA_CTRL 0x0928 ASF Receive FIFO Control/Test */ ++/* Bit(s) RA_CTRL_RSRV_11_0 reserved */ ++#define RA_CTRL_RA_PCNT_DN BIT_19 /* Packet Counter Step Down */ ++#define RA_CTRL_RA_PCNT_ENA BIT_18 /* Packet Counter Test On */ ++#define RA_CTRL_RA_PCNT_RST BIT_17 /* Packet Counter Test Off */ ++#define RA_CTRL_RA_PCNT_UP BIT_16 /* Packet Counter Step Up */ ++/* Bit(s) RA_CTRL_RSRV_ reserved */ ++#define RA_CTRL_RA_WPTR_ENA BIT_14 /* Write Pointer Test On */ ++#define RA_CTRL_RA_WPTR_RST BIT_13 /* Write Pointer Test Off */ ++#define RA_CTRL_RA_WPTR_UP BIT_12 /* Write Pointer Step Up */ ++/* Bit(s) RA_CTRL_RSRV_4_0 reserved */ ++#define RA_CTRL_RA_IRQ_CLR BIT_6 /* Clear IRQ ASF Receive FIFO */ ++/* Bit(s) RA_CTRL_RSRV_1_0 reserved */ ++#define RA_CTRL_RA_OP_ON BIT_3 /* Operational On */ ++#define RA_CTRL_RA_OP_OFF BIT_2 /* Operational Off */ ++#define RA_CTRL_RA_RST_CLR BIT_1 /* Reset Clear */ ++#define RA_CTRL_RA_RST_SET BIT_0 /* Reset Set */ ++ ++/* RA_FLSH_CTRL 0x092C ASF Receive FIFO Flush Control */ ++#define RA_FLSH_CTRL_RA_FLSH BIT_31 /* Flush */ ++/* Bit(s) RA_FLSH_CTRL_RSRV_21_0 reserved */ ++#define RA_FLSH_CTRL_RA_FLSH_QWORD_MSK SHIFT0(0x1ff) /* Flush Qword */ ++#define RA_FLSH_CTRL_RA_FLSH_QWORD_BASE BIT_0 ++ ++/* TA_SADDR 0x0940 ASF Transmit FIFO Start Address */ ++/* Bit(s) TA_SADDR_RSRV_22_0 reserved */ ++#define TA_SADDR_TA_SADDR_MSK SHIFT0(0x1ff) /* Start Address */ ++#define TA_SADDR_TA_SADDR_BASE BIT_0 ++ ++/* TA_EADDR 0x0944 ASF Transmit FIFO End Address */ ++/* Bit(s) TA_EADDR_RSRV_22_0 reserved */ ++#define TA_EADDR_TA_EADDR_MSK SHIFT0(0x1ff) /* End Address */ ++#define TA_EADDR_TA_EADDR_BASE BIT_0 ++ ++/* TA_WPTR 0x0948 ASF Transmit FIFO Write Pointer */ ++/* Bit(s) TA_WPTR_RSRV_22_0 reserved */ ++#define TA_WPTR_TA_WPTR_MSK SHIFT0(0x1ff) /* Write Pointer */ ++#define TA_WPTR_TA_WPTR_BASE BIT_0 ++ ++/* TA_RPTR 0x094C ASF Transmit FIFO Read Pointer */ ++/* Bit(s) TA_RPTR_RSRV_22_0 reserved */ ++#define TA_RPTR_TA_RPTR_MSK SHIFT0(0x1ff) /* Read Pointer */ ++#define TA_RPTR_TA_RPTR_BASE BIT_0 ++ ++/* TA_PCNT 0x0960 ASF Transmit FIFO Packet Counter */ ++/* Bit(s) TA_PCNT_RSRV_22_0 reserved */ ++#define TA_PCNT_TA_PCNT_MSK SHIFT0(0x1ff) /* Packet Counter */ ++#define TA_PCNT_TA_PCNT_BASE BIT_0 ++ ++/* TA_LEV 0x0964 ASF Transmit FIFO Level */ ++/* Bit(s) TA_LEV_RSRV_22_0 reserved */ ++#define TA_LEV_TA_LEV_MSK SHIFT0(0x1ff) /* Level */ ++#define TA_LEV_TA_LEV_BASE BIT_0 ++ ++/* TA_CTRL 0x0968 ASF Transmit FIFO Control/Test */ ++/* Bit(s) TA_CTRL_RSRV_11_0 reserved */ ++#define TA_CTRL_TA_PCNT_DN BIT_19 /* Packet Counter Step Down */ ++#define TA_CTRL_TA_PCNT_ENA BIT_18 /* Packet Counter Test On */ ++#define TA_CTRL_TA_PCNT_RST BIT_17 /* Packet Counter Test Off */ ++#define TA_CTRL_TA_PCNT_UP BIT_16 /* Packet Counter Step Up */ ++/* Bit(s) TA_CTRL_RSRV_4_0 reserved */ ++#define TA_CTRL_TA_RPTR_ENA BIT_10 /* Read Pointer Test On */ ++#define TA_CTRL_TA_RPTR_RST BIT_9 /* Read Pointer Test Off */ ++#define TA_CTRL_TA_RPTR_UP BIT_8 /* Read Pointer Step Up */ ++/* Bit(s) TA_CTRL_RSRV_ reserved */ ++#define TA_CTRL_TA_IRQ_CLR BIT_6 /* Clear IRQ ASF Transmit FIFO */ ++/* Bit(s) TA_CTRL_RSRV_1_0 reserved */ ++#define TA_CTRL_TA_OP_ON BIT_3 /* Operational On */ ++#define TA_CTRL_TA_OP_OFF BIT_2 /* Operational Off */ ++#define TA_CTRL_TA_RST_CLR BIT_1 /* Reset Clear */ ++#define TA_CTRL_TA_RST_SET BIT_0 /* Reset Set */ ++ ++/* TA_SEND_CTRL 0x096C ASF Transmit FIFO Send Control */ ++#define TA_SEND_CTRL_TA_SEND BIT_31 /* Send */ ++/* Bit(s) TA_SEND_CTRL_RSRV_21_0 reserved */ ++#define TA_SEND_CTRL_TA_SEND_QWORD_MSK SHIFT0(0x1ff) /* Send Qword */ ++#define TA_SEND_CTRL_TA_SEND_QWORD_BASE BIT_0 ++ ++/* RXMF_EADDR 0x0C40 Receive MAC FIFO End Address Register */ ++/* Bit(s) RXMF_EADDR_RSRV_22_0 reserved */ ++#define RXMF_EADDR_MSK SHIFT0(0x1ff) /* End Address */ ++#define RXMF_EADDR_BASE BIT_0 ++ ++/* RXMF_AFTH 0x0C44 Receive MAC FIFO Almost Full Threshold Register */ ++/* Bit(s) RXMF_AFTH_RSRV_22_0 reserved */ ++/* Almost Full Threshold */ ++#define RXMF_AFTH_MSK SHIFT0(0x1ff) ++#define RXMF_AFTH_BASE BIT_0 ++ ++/* RXMF_TCTL 0x0C48 Receive MAC FIFO Control/Test Register */ ++#define RXMF_TCTL_GCLKMAC_ENA BIT_31 /* RX MAC Clock Gating Enable */ ++#define RXMF_TCTL_GCLKMAC_DIS BIT_30 /* RX MAC Clock Gating Disable */ ++#define RXMF_TCTL_STFWD_ENA BIT_29 /* RX Store and Forward Enable */ ++#define RXMF_TCTL_STFWD_DIS BIT_28 /* RX Store and Forward Disable */ ++#define RXMF_TCTL_TRUNC_ENA BIT_27 /* Truncation Enable */ ++#define RXMF_TCTL_TRUNC_DIS BIT_26 /* Truncation Disable */ ++#define RXMF_TCTL_VLAN_ENA BIT_25 /* VLAN Enable */ ++#define RXMF_TCTL_VLAN_DIS BIT_24 /* VLAN Disable */ ++#define RXMF_TCTL_MACSEC_FLSH_ENA BIT_23 /* RX MACSec Flush Enable */ ++#define RXMF_TCTL_MACSEC_FLSH_DIS BIT_22 /* RX MACSec Flush Disable */ ++#define RXMF_TCTL_RA_MACSEC_FLSH_ENA BIT_21 /* ASF RX MACSec Flush Enable */ ++#define RXMF_TCTL_RA_MACSEC_FLSH_DIS BIT_20 /* ASF RX MACSec Flush Disable */ ++#define RXMF_TCTL_OVRRN_FLSH_ENA BIT_19 /* RX Overrun Flush Enable */ ++#define RXMF_TCTL_OVRRN_FLSH_DIS BIT_18 /* RX Overrun Flush Disable */ ++#define RXMF_TCTL_RA_FLSH_ENA BIT_17 /* ASF RX Overrun Flush Enable */ ++#define RXMF_TCTL_RA_FLSH_DIS BIT_16 /* ASF RX Overrun Flush Disable */ ++/* Bit(s) RXMF_TCTL_RSRV_ reserved */ ++#define RXMF_TCTL_WPTR_TEST_ON BIT_14 /* Write Pointer Test On */ ++#define RXMF_TCTL_WPTR_TEST_OFF BIT_13 /* Write Pointer Test Off */ ++#define RXMF_TCTL_WPTR_TEST_STEP BIT_12 /* Write Pointer Step */ ++/* Bit(s) RXMF_TCTL_RSRV_ reserved */ ++#define RXMF_TCTL_RPTR_TEST_ON BIT_10 /* Read Pointer Test On */ ++#define RXMF_TCTL_RPTR_TEST_OFF BIT_9 /* Read Pointer Test Off */ ++#define RXMF_TCTL_RPTR_TEST_STEP BIT_8 /* Read Pointer Step */ ++#define RXMF_TCTL_FLUSH_ON BIT_7 /* FIFO Flush On */ ++#define RXMF_TCTL_FLUSH_OFF BIT_6 /* FIFO Flush Off */ ++/* Clear IRQ Receive FIFO Overrun */ ++#define RXMF_TCTL_CLR_IRQ_RX_OF BIT_5 ++/* Clear IRQ Frame Reception Complete */ ++#define RXMF_TCTL_CLR_IRQ_RX_OK BIT_4 ++#define RXMF_TCTL_OP_ON BIT_3 /* Operational On */ ++#define RXMF_TCTL_OP_OFF BIT_2 /* Operational Off */ ++#define RXMF_TCTL_RST_CLR BIT_1 /* MAC FIFO Reset Clear */ ++#define RXMF_TCTL_RST_SET BIT_0 /* MAC FIFO Reset Set */ ++ ++/* RXMF_FLMSK 0x0C4C Receive MAC FIFO Flush Mask Register */ ++/* Bit(s) RXMF_FLMSK_RSRV_16_0 reserved */ ++#define RXMF_FLMSK_LEN_ERR BIT_14 /* Length Error */ ++#define RXMF_FLMSK_VLAN BIT_13 /* VLAN packet */ ++#define RXMF_FLMSK_JBR BIT_12 /* Jabber */ ++#define RXMF_FLMSK_USIZE BIT_11 /* Undersize packet */ ++#define RXMF_FLMSK_MCST BIT_10 /* Multicast packet */ ++#define RXMF_FLMSK_BCST BIT_9 /* Broadcast packet */ ++#define RXMF_FLMSK_RX_OK BIT_8 /* Receive OK */ ++/* Good flow control packet */ ++#define RXMF_FLMSK_GD_FC BIT_7 ++#define RXMF_FLMSK_MII_ERR BIT_5 /* MII error */ ++#define RXMF_FLMSK_TLNG BIT_4 /* Too long packet */ ++#define RXMF_FLMSK_FRAG BIT_3 /* Fragment */ ++/* Bit(s) RXMF_FLMSK_RSRV_ reserved */ ++#define RXMF_FLMSK_CRC_ERR BIT_1 /* CRC error */ ++/* Receive FIFO overflow */ ++#define RXMF_FLMSK_RX_OF BIT_0 ++ ++/* RXMF_FLTH 0x0C50 Receive MAC FIFO Flush Threshold Register */ ++/* Bit(s) RXMF_FLTH_RSRV_11_0 reserved */ ++/* RX ASF Flag New Logic Enable */ ++#define RXMF_FLTH_ASF_NEWFLAG_ENA BIT_19 ++/* RX ASF Flag New Logic Disable */ ++#define RXMF_FLTH_ASF_NEWFLAG_DIS BIT_18 ++/* RX Flush Miss-Packet Enable */ ++#define RXMF_FLTH_FLSH_MISSPKT_ENA BIT_17 ++/* RX Flush Miss-Packet Disable */ ++#define RXMF_FLTH_FLSH_MISSPKT_DIS BIT_16 ++/* Bit(s) RXMF_FLTH_RSRV_6_0 reserved */ ++#define RXMF_FLTH_MSK SHIFT0(0x1ff) /* Flush Threshold */ ++#define RXMF_FLTH_BASE BIT_0 ++ ++/* RXMF_TRTH 0x0C54 Receive Truncation Threshold Register */ ++/* Bit(s) RXMF_TRTH_RSRV_22_0 reserved */ ++/* Truncation Threshold */ ++#define RXMF_TRTH_TRUNCATION_THRESHOLD_MSK SHIFT0(0x1ff) ++#define RXMF_TRTH_TRUNCATION_THRESHOLD_BASE BIT_0 ++ ++/* RXMF_ULTH 0x0C58 Upper/Lower Threshold/Pause Packets Register */ ++/* Bit(s) RXMF_ULTH_RSRV_6_0 reserved */ ++/* Pause Packet Watermark Low Threshold */ ++#define RXMF_ULTH_LO_TH_MSK SHIFT16(0x1ff) ++#define RXMF_ULTH_LO_TH_BASE BIT_16 ++/* Bit(s) RXMF_ULTH_RSRV_6_0 reserved */ ++/* Pause Packet Watermark High Threshold */ ++#define RXMF_ULTH_HI_TH_MSK SHIFT0(0x1ff) ++#define RXMF_ULTH_HI_TH_BASE BIT_0 ++ ++/* RXMF_VLTYP 0x0C5C Receive VLAN Type Register */ ++/* Bit(s) RXMF_VLTYP_RSRV_15_0 reserved */ ++#define RXMF_VLTYP_MSK SHIFT0(0xffff) /* Receive VLAN Type */ ++#define RXMF_VLTYP_BASE BIT_0 ++ ++/* RXMF_WPTR 0x0C60 Receive MAC FIFO Write Pointer Register */ ++/* Bit(s) RXMF_WPTR_RSRV_22_0 reserved */ ++#define RXMF_WPTR_MSK SHIFT0(0x1ff) /* Write Pointer */ ++#define RXMF_WPTR_BASE BIT_0 ++ ++/* RXMF_WLEV 0x0C68 Receive MAC FIFO Write Level Register */ ++/* Bit(s) RXMF_WLEV_RSRV_22_0 reserved */ ++#define RXMF_WLEV_MSK SHIFT0(0x1ff) /* Write Level */ ++#define RXMF_WLEV_BASE BIT_0 ++ ++/* RXMF_RPTR 0x0C70 Receive MAC FIFO Read Pointer Register */ ++/* Bit(s) RXMF_RPTR_RSRV_22_0 reserved */ ++#define RXMF_RPTR_MSK SHIFT0(0x1ff) /* Read Pointer */ ++#define RXMF_RPTR_BASE BIT_0 ++ ++/* RXMF_RLEV 0x0C78 Receive MAC FIFO Read Level Register */ ++/* Bit(s) RXMF_RLEV_RSRV_22_0 reserved */ ++#define RXMF_RLEV_MSK SHIFT0(0x1ff) /* Read Level */ ++#define RXMF_RLEV_BASE BIT_0 ++ ++/* TXMF_EADDR 0x0D40 Transmit MAC FIFO End Address Register */ ++/* Bit(s) TXMF_EADDR_RSRV_23_0 reserved */ ++#define TXMF_EADDR_MSK SHIFT0(0xff) /* End Address */ ++#define TXMF_EADDR_BASE BIT_0 ++ ++/* TXMF_AETH 0x0D44 Transmit MAC FIFO Almost Empty Threshold ++ * Register ++ */ ++/* Bit(s) TXMF_AETH_RSRV_4_0 reserved */ ++#define TXMF_AETH_JUMBO_WM_MSK SHIFT16(0x7ff) /* Jumbo Mode Watermark */ ++#define TXMF_AETH_JUMBO_WM_BASE BIT_16 ++/* Bit(s) TXMF_AETH_RSRV_7_0 reserved */ ++#define TXMF_AETH_MSK SHIFT0(0xff) /* Almost Empty Threshold */ ++#define TXMF_AETH_BASE BIT_0 ++ ++/* TXMF_TCTL 0x0D48 Transmit MAC FIFO Control/Test Register */ ++#define TXMF_TCTL_JUMBO_ENA BIT_31 /* Jumbo Mode Enable */ ++/* Tx Store and Forward Mode Enable */ ++#define TXMF_TCTL_STORE_FW_ENA BIT_30 ++#define TXMF_TCTL_FIX_440_OFF BIT_29 /* Perf Fix #4.40 Off */ ++#define TXMF_TCTL_FIX_440_ON BIT_28 /* Perf Fix #4.40 On */ ++#define TXMF_TCTL_TX_CSUM_DIS BIT_27 /* Tx Checksum Disable */ ++#define TXMF_TCTL_TX_CSUM_ENA BIT_26 /* Tx Checksum Enable */ ++#define TXMF_TCTL_VLAN_ENA BIT_25 /* VLAN Enable */ ++#define TXMF_TCTL_VLAN_DIS BIT_24 /* VLAN Disable */ ++#define TXMF_TCTL_PCI_JUMBO_ENA BIT_23 /* PCI Jumbo Mode Enable */ ++#define TXMF_TCTL_PCI_JUMBO_DIS BIT_22 /* PCI Jumbo Mode Disable */ ++/* Bit(s) TXMF_TCTL_RSRV_2_0 reserved */ ++/* Write Shadow Pointer Test On */ ++#define TXMF_TCTL_WSPTR_TEST_ON BIT_18 ++/* Write Shadow Pointer Test Off */ ++#define TXMF_TCTL_WSPTR_TEST_OFF BIT_17 ++/* Write Shadow Pointer Step */ ++#define TXMF_TCTL_WSPTR_TEST_STEP BIT_16 ++/* Bit(s) TXMF_TCTL_RSRV_ reserved */ ++#define TXMF_TCTL_WPTR_TEST_ON BIT_14 /* Write Pointer Test On */ ++#define TXMF_TCTL_WPTR_TEST_OFF BIT_13 /* Write Pointer Test Off */ ++#define TXMF_TCTL_WPTR_TEST_STEP BIT_12 /* Write Pointer Step */ ++/* Bit(s) TXMF_TCTL_RSRV_ reserved */ ++#define TXMF_TCTL_RPTR_TEST_ON BIT_10 /* Read Pointer Test On */ ++#define TXMF_TCTL_RPTR_TEST_OFF BIT_9 /* Read Pointer Test Off */ ++#define TXMF_TCTL_RPTR_TEST_STEP BIT_8 /* Read Pointer Step */ ++/* Bit(s) TXMF_TCTL_RSRV_ reserved */ ++/* Clear IRQ Transmit FIFO Underrun */ ++#define TXMF_TCTL_CLR_IRQ_TX_UR BIT_6 ++/* Clear IRQ Frame Transmission Complete */ ++#define TXMF_TCTL_CLR_IRQ_TX_OK BIT_5 ++#define TXMF_TCTL_CLR_IRQ_PAR BIT_4 /* Clear IRQ Parity Error */ ++#define TXMF_TCTL_OP_ON BIT_3 /* Operational On */ ++#define TXMF_TCTL_OP_OFF BIT_2 /* Operational Off */ ++#define TXMF_TCTL_RST_CLR BIT_1 /* MAC FIFO Reset Clear */ ++#define TXMF_TCTL_RST_SET BIT_0 /* MAC FIFO Reset Set */ ++ ++/* TXMF_VLTYP 0x0D5C Transmit VLAN Type Register */ ++/* Bit(s) TXMF_VLTYP_RSRV_15_0 reserved */ ++#define TXMF_VLTYP_MSK SHIFT0(0xffff) /* Transmit VLAN Type */ ++#define TXMF_VLTYP_BASE BIT_0 ++ ++/* TXMF_WPTR 0x0D60 Transmit MAC FIFO Write Pointer Register */ ++/* Bit(s) TXMF_WPTR_RSRV_23_0 reserved */ ++#define TXMF_WPTR_MSK SHIFT0(0xff) /* Write Pointer */ ++#define TXMF_WPTR_BASE BIT_0 ++ ++/* TXMF_WSPTR 0x0D64 Transmit MAC FIFO Write Shadow Pointer Register */ ++/* Bit(s) TXMF_WSPTR_RSRV_23_0 reserved */ ++#define TXMF_WSPTR_MSK SHIFT0(0xff) /* Write Shadow Pointer */ ++#define TXMF_WSPTR_BASE BIT_0 ++ ++/* TXMF_WLEV 0x0D68 Transmit MAC FIFO Write Level Register */ ++/* Bit(s) TXMF_WLEV_RSRV_23_0 reserved */ ++#define TXMF_WLEV_MSK SHIFT0(0xff) /* Write Level */ ++#define TXMF_WLEV_BASE BIT_0 ++ ++/* TXMF_RPTR 0x0D70 Transmit MAC FIFO Read Pointer Register */ ++/* Bit(s) TXMF_RPTR_RSRV_23_0 reserved */ ++#define TXMF_RPTR_MSK SHIFT0(0xff) /* Read Pointer */ ++#define TXMF_RPTR_BASE BIT_0 ++ ++/* TXMF_RES_PTR 0x0D74 Transmit MAC FIFO Restart Pointer Register */ ++/* Bit(s) TXMF_RES_PTR_RSRV_23_0 reserved */ ++#define TXMF_RES_PTR_MSK SHIFT0(0xff) /* Restart Pointer */ ++#define TXMF_RES_PTR_BASE BIT_0 ++ ++/* TXMF_RLEV 0x0D78 Transmit MAC FIFO Read Level Register */ ++/* Bit(s) TXMF_RLEV_RSRV_23_0 reserved */ ++#define TXMF_RLEV_MSK SHIFT0(0xff) /* Read Level */ ++#define TXMF_RLEV_BASE BIT_0 ++ ++/* DPOL_TIM_INIT 0x0E00 Descriptor Poll Timer Init Value Register */ ++#define DPOL_TIM_INIT_INIT_VALUE_MSK SHIFT0(0xffffffff) /* Init Value */ ++#define DPOL_TIM_INIT_INIT_VALUE_BASE BIT_0 ++ ++/* DPOL_TIM_CNT 0x0E04 Descriptor Poll Timer Register */ ++#define DPOL_TIM_CNT_MSK SHIFT0(0xffffffff) /* Descriptor Poll Timer */ ++#define DPOL_TIM_CNT_BASE BIT_0 ++ ++/* DPOL_TCTL 0x0E08 Descriptor Poll Timer Control/Test Register */ ++/* Bit(s) DPOL_TCTL_RSRV_20_0 reserved */ ++/* Descriptor Poll Timer Test On */ ++#define DPOL_TCTL_ON BIT_10 ++/* Descriptor Poll Timer Test Off */ ++#define DPOL_TCTL_OFF BIT_9 ++/* Descriptor Poll Timer Step */ ++#define DPOL_TCTL_STEP BIT_8 ++/* Bit(s) DPOL_TCTL_RSRV_4_0 reserved */ ++/* Descriptor Poll Timer Start */ ++#define DPOL_TCTL_STRT BIT_2 ++/* Descriptor Poll Timer Stop */ ++#define DPOL_TCTL_STOP BIT_1 ++/* Bit(s) DPOL_TCTL_RSRV_ reserved */ ++ ++/* TSP_TIM_CNT 0x0E14 Timestamp Timer Registers */ ++#define TSP_TIM_CNT_MSK SHIFT0(0xffffffff) /* Timestamp Timer */ ++#define TSP_TIM_CNT_BASE BIT_0 ++ ++/* TSP_TIM_TCTL 0x0E18 Timestamp Timer Control/Test Register */ ++/* Bit(s) TSP_TIM_TCTL_RSRV_20_0 reserved */ ++/* Timestamp Timer Test On */ ++#define TSP_TIM_TCTL_ON BIT_10 ++/* Timestamp Timer Test Off */ ++#define TSP_TIM_TCTL_OFF BIT_9 ++#define TSP_TIM_TCTL_STEP BIT_8 /* Timestamp Timer Step */ ++/* Bit(s) TSP_TIM_TCTL_RSRV_4_0 reserved */ ++/* Timestamp Timer Start */ ++#define TSP_TIM_TCTL_STRT BIT_2 ++#define TSP_TIM_TCTL_STOP BIT_1 /* Timestamp Timer Stop */ ++/* Timestamp Timer Clear IRQ */ ++#define TSP_TIM_TCTL_CLR_IRQ BIT_0 ++ ++/* POLL_CTRL 0x0E20 Poll Control Register */ ++/* Bit(s) POLL_CTRL_RSRV_25_0 reserved */ ++#define POLL_CTRL_CLR_IRQ BIT_5 /* Clear IRQ */ ++#define POLL_CTRL_POLL_REQ BIT_4 /* Poll Request */ ++#define POLL_CTRL_OP_ON BIT_3 /* Operational On */ ++#define POLL_CTRL_OP_OFF BIT_2 /* Operational Off */ ++#define POLL_CTRL_POLL_RST_CLR BIT_1 /* POLLU Reset Clear */ ++#define POLL_CTRL_POLL_RST_SET BIT_0 /* POLLU Reset Set */ ++ ++/* POLL_LAST_IDX 0x0E24 List Last Index Register */ ++/* Bit(s) POLL_LAST_IDX_RSRV_30_0 reserved */ ++//#define POLL_LAST_IDX BIT_0 /* List Last Index */ ++ ++/* POLL_LADR_LO 0x0E28 List Start Address Low Register */ ++/* List Start Address Low */ ++#define POLL_LADR_LO_MSK SHIFT3(0x1fffffff) ++#define POLL_LADR_LO_BASE BIT_3 ++/* List Start Address Low fixed */ ++#define POLL_LADR_LO_VAL_FIX_MSK SHIFT0(0x7) ++#define POLL_LADR_LO_VAL_FIX_BASE BIT_0 ++ ++/* POLL_LADR_HI 0x0E2C List Start Address High Register */ ++#define POLL_LADR_HI_MSK SHIFT0(0xffffffff) /* List Start Address High */ ++#define POLL_LADR_HI_BASE BIT_0 ++ ++/* CPU_ISRC 0x0E30 Interrupt Source Register */ ++/* Bit(s) CPU_ISRC_RSRV_25_0 reserved */ ++#define CPU_ISRC_CPU BIT_5 /* CPU Interrupt */ ++#define CPU_ISRC_TIM BIT_4 /* Timer Interrupt */ ++#define CPU_ISRC_SMB BIT_3 /* SMBus Interrupt */ ++#define CPU_ISRC_RX BIT_2 /* ASF Rx Queue Interrupt */ ++#define CPU_ISRC_TX BIT_1 /* ASF Tx Queue Interrupt */ ++/* Host Communication Unit Interrrupt */ ++#define CPU_ISRC_HCU BIT_0 ++ ++/* CPU_IMSK 0x0E34 Interrupt Mask Register */ ++/* Bit(s) CPU_IMSK_RSRV_9_0 reserved */ ++#define CPU_IMSK_FIQ_CPU BIT_21 /* CPU Interrupt mapped to FIQ */ ++#define CPU_IMSK_FIQ_TIM BIT_20 /* TIM Interrupt mapped to FIQ */ ++#define CPU_IMSK_FIQ_SMB BIT_19 /* SMB Interrupt mapped to FIQ */ ++#define CPU_IMSK_FIQ_RX BIT_18 /* RX Interrupt mapped to FIQ */ ++#define CPU_IMSK_FIQ_TX BIT_17 /* TX Interrupt mapped to FIQ */ ++#define CPU_IMSK_FIQ_HCU BIT_16 /* HCU Interrupt mapped to FIQ */ ++/* Bit(s) CPU_IMSK_RSRV_9_0 reserved */ ++#define CPU_IMSK_IRQ_CPU BIT_5 /* CPU Interrupt mapped to IRQ */ ++#define CPU_IMSK_IRQ_TIM BIT_4 /* TIM Interrupt mapped to IRQ */ ++#define CPU_IMSK_IRQ_SMB BIT_3 /* SMB Interrupt mapped to IRQ */ ++#define CPU_IMSK_IRQ_RX BIT_2 /* RX Interrupt mapped to IRQ */ ++#define CPU_IMSK_IRQ_TX BIT_1 /* TX Interrupt mapped to IRQ */ ++#define CPU_IMSK_IRQ_HCU BIT_0 /* HCU Interrupt mapped to IRQ */ ++ ++/* SMB_CFG 0x0E40 SMBus Config Register */ ++#define SMB_CFG_PS_MSK SHIFT30(0x3) /* SMBPS */ ++#define SMB_CFG_PS_BASE BIT_30 ++#define SMB_CFG_CSE BIT_29 /* SMBCSE */ ++#define SMB_CFG_BR_MSK SHIFT16(0x1fff) /* SMBBR */ ++#define SMB_CFG_BR_BASE BIT_16 ++#define SMB_CFG_SADDR_MSK SHIFT9(0x7f) /* SMBSlaveAddr */ ++#define SMB_CFG_SADDR_BASE BIT_9 ++#define SMB_CFG_SADDR_ENA BIT_8 /* SMBSAE */ ++#define SMB_CFG_DADDR_ENA BIT_7 /* SMBDAE */ ++#define SMB_CFG_GC_ENA BIT_6 /* SMBGCE */ ++#define SMB_CFG_ACK_ENA BIT_5 /* SMBEA */ ++#define SMB_CFG_IRQ_ENA BIT_4 /* SMBIE */ ++#define SMB_CFG_OP_ON BIT_3 /* Operational On */ ++#define SMB_CFG_OP_OFF BIT_2 /* Operational Off */ ++#define SMB_CFG_RST_CLR BIT_1 /* SMBus Reset Clear */ ++#define SMB_CFG_RST_SET BIT_0 /* SMBus Reset Set */ ++ ++/* SMB_CSR 0x0E44 SMBus Control/Status Register */ ++#define SMB_CSR_AL BIT_31 /* SMBAL */ ++#define SMB_CSR_RX_ACK BIT_30 /* SMBRxACK */ ++#define SMB_CSR_RX_FULL BIT_29 /* SMBRxFull */ ++#define SMB_CSR_TX_EMPTY BIT_28 /* SMBTxEmpty */ ++#define SMB_CSR_TX_DONE BIT_27 /* SMBTxDone */ ++#define SMB_CSR_STOP BIT_26 /* SMBSTOP */ ++#define SMB_CSR_IF BIT_25 /* SMBIF */ ++#define SMB_CSR_RX_STRT BIT_24 /* SMBRxSTA */ ++#define SMB_CSR_TIP BIT_23 /* SMBTIP */ ++#define SMB_CSR_BUSY BIT_22 /* SMBBusy */ ++#define SMB_CSR_SPEEDUP BIT_21 /* SMBUS Timer SpeedUp */ ++#define SMB_CSR_ALERT BIT_20 /* SMBALERT */ ++#define SMB_CSR_TX_CLR BIT_19 /* SMBTxCLR */ ++#define SMB_CSR_TX BIT_18 /* SMBTx */ ++#define SMB_CSR_TX_STOP BIT_17 /* SMBTxSTO */ ++#define SMB_CSR_TX_STRT BIT_16 /* SMBTxSTA */ ++#define SMB_CSR_RX_DATA_MSK SHIFT8(0xff) /* SMBRxData */ ++#define SMB_CSR_RX_DATA_BASE BIT_8 ++#define SMB_CSR_TX_DATA_MSK SHIFT0(0xff) /* SMBTxData */ ++#define SMB_CSR_TX_DATA_BASE BIT_0 ++ ++/* CPU_WDOG 0x0E48 Watchdog Register */ ++#define CPU_WDOG_MSK SHIFT0(0xffffffff) /* Watchdog */ ++#define CPU_WDOG_BASE BIT_0 ++ ++/* CPU_CNTR 0x0E4C Counter Register */ ++#define CPU_CNTR_MSK SHIFT0(0xffffffff) /* Counter */ ++#define CPU_CNTR_BASE BIT_0 ++ ++/* CPU_TIM 0x0E50 Timer Compare Register */ ++#define CPU_TIM_MSK SHIFT0(0xffffffff) /* Timer Compare */ ++#define CPU_TIM_BASE BIT_0 ++ ++/* CPU_AHB_ADDR 0x0E54 CPU AHB Debug Register */ ++#define CPU_AHB_ADDR_MSK SHIFT0(0xffffffff) /* Probe AHB address */ ++#define CPU_AHB_ADDR_BASE BIT_0 ++ ++/* CPU_AHB_WDATA 0x0E58 CPU AHB Debug Register */ ++#define CPU_AHB_WDATA_MSK SHIFT0(0xffffffff) /* Probe AHB wdata */ ++#define CPU_AHB_WDATA_BASE BIT_0 ++ ++/* CPU_AHB_RDATA 0x0E5C CPU AHB Debug Register */ ++#define CPU_AHB_RDATA_MSK SHIFT0(0xffffffff) /* Probe AHB rdata */ ++#define CPU_AHB_RDATA_BASE BIT_0 ++ ++/* HCU_MAP_BASE 0x0E60 Reset Mapping Base */ ++#define HCU_MAP_BASE_MSK SHIFT12(0xfffff) /* MAPBASE */ ++#define HCU_MAP_BASE_BASE BIT_12 ++/* Bit(s) HCU_MAP_BASE_RSRV_11_0 reserved */ ++ ++/* CPU_AHB_CTRL 0x0E64 CPU AHB Debug Register */ ++/* OspreyD SRAM Write setting */ ++#define CPU_AHB_CTRL_SRAM_WTC1 BIT_31 ++#define CPU_AHB_CTRL_TDO BIT_30 /* tdo */ ++#define CPU_AHB_CTRL_TMS BIT_29 /* tms */ ++#define CPU_AHB_CTRL_TDI BIT_28 /* tdi */ ++#define CPU_AHB_CTRL_TRST BIT_27 /* trst */ ++#define CPU_AHB_CTRL_TCLK BIT_26 /* tclk */ ++#define CPU_AHB_CTRL_SET_JTAG_TEST_MSK SHIFT24(0x3) /* CPU's JTAG testmode */ ++#define CPU_AHB_CTRL_SET_JTAG_TEST_BASE BIT_24 ++/* OspreyD SRAM Read setting */ ++#define CPU_AHB_CTRL_SRAM_RTC1 BIT_23 ++/* OspreyD SRAM Write setting */ ++#define CPU_AHB_CTRL_SRAM_WTC2_MSK SHIFT21(0x3) ++#define CPU_AHB_CTRL_SRAM_WTC2_BASE BIT_21 ++/* Bit(s) CPU_AHB_CTRL_RSRV_ reserved */ ++#define CPU_AHB_CTRL_FCE_HRESP_MSK SHIFT18(0x3) /* Force AHB HRESP */ ++#define CPU_AHB_CTRL_FCE_HRESP_BASE BIT_18 ++#define CPU_AHB_CTRL_FCE_HRDY BIT_17 /* Force AHB HREADY */ ++/* Enable force AHB response */ ++#define CPU_AHB_CTRL_FCE_RESP_EN BIT_16 ++/* OspreyD SRAM read setting */ ++#define CPU_AHB_CTRL_SRAM_RTC2_MSK SHIFT14(0x3) ++#define CPU_AHB_CTRL_SRAM_RTC2_BASE BIT_14 ++/* Bit(s) CPU_AHB_CTRL_RSRV_ reserved */ ++#define CPU_AHB_CTRL_PRB_HBURST_MSK SHIFT10(0x7) /* Probe AHB HBURST */ ++#define CPU_AHB_CTRL_PRB_HBURST_BASE BIT_10 ++#define CPU_AHB_CTRL_PRB_HSIZE_MSK SHIFT7(0x7) /* Probe AHB HSIZE */ ++#define CPU_AHB_CTRL_PRB_HSIZE_BASE BIT_7 ++#define CPU_AHB_CTRL_PRB_HTRANS_MSK SHIFT5(0x3) /* Probe AHB HTRANS */ ++#define CPU_AHB_CTRL_PRB_HTRANS_BASE BIT_5 ++#define CPU_AHB_CTRL_PRB_HBUSREQ BIT_4 /* Probe AHB HBUSREQ */ ++#define CPU_AHB_CTRL_PRB_HRESP_MSK SHIFT2(0x3) /* Probe AHB HRESP */ ++#define CPU_AHB_CTRL_PRB_HRESP_BASE BIT_2 ++#define CPU_AHB_CTRL_PRB_HRDY BIT_1 /* Probe AHB HREADY */ ++#define CPU_AHB_CTRL_PRB_HCLK BIT_0 /* Probe AHB HCLK */ ++ ++/* HCU_CCSR 0x0E68 CPU Control and Status Register */ ++/* Bit(s) HCU_CCSR_RSRV_3_0 reserved */ ++#define HCU_CCSR_SMBALERT_MONITOR BIT_27 /* SMBALERT pin monitor */ ++#define HCU_CCSR_CPU_SLEEP BIT_26 /* CPU sleep status */ ++/* Clock Stretching Timeout */ ++#define HCU_CCSR_CS_TO BIT_25 ++#define HCU_CCSR_WDOG BIT_24 /* Watchdog Reset */ ++/* Bit(s) HCU_CCSR_RSRV_5_0 reserved */ ++#define HCU_CCSR_CLR_IRQ_HOST BIT_17 /* Clear IRQ_HOST */ ++#define HCU_CCSR_SET_IRQ_HCU BIT_16 /* Set IRQ_HCU */ ++/* Bit(s) HCU_CCSR_RSRV_5_0 reserved */ ++#define HCU_CCSR_AHB_RST BIT_9 /* Reset AHB bridge */ ++#define HCU_CCSR_CPU_RST_MODE BIT_8 /* CPU Reset Mode */ ++/* Bit(s) HCU_CCSR_RSRV_1_0 reserved */ ++/* Enable Sync datapath inside AHB bridge */ ++#define HCU_CCSR_SET_SYNC_CPU BIT_5 ++#define HCU_CCSR_CPU_CLK_DIVIDE_MSK SHIFT3(0x3) /* CPU Clock Divide */ ++#define HCU_CCSR_CPU_CLK_DIVIDE_BASE BIT_3 ++#define HCU_CCSR_OS_PRSNT BIT_2 /* ASF OS Present */ ++/* Microcontroller State */ ++#define HCU_CCSR_UC_STATE_MSK SHIFT0(0x3) ++#define HCU_CCSR_UC_STATE_BASE BIT_0 ++#define HCU_CCSR_ASF_RESET 0 ++#define HCU_CCSR_ASF_RUNNING BIT_0 ++#define HCU_CCSR_ASF_HALTED BIT_1 ++ ++/* HCU_HCSR 0x0E6C Host Control and Status Register */ ++/* Bit(s) HCU_HCSR_RSRV_14_0 reserved */ ++#define HCU_HCSR_SET_IRQ_CPU BIT_16 /* Set IRQ_CPU */ ++/* Bit(s) HCU_HCSR_RSRV_13_0 reserved */ ++#define HCU_HCSR_CLR_IRQ_HCU BIT_1 /* Clear IRQ_HCU */ ++#define HCU_HCSR_SET_IRQ_HOST BIT_0 /* Set IRQ_HOST */ ++ ++/* HCU_DATA1 0x0E70 Data Register 1 */ ++#define HCU_DATA1_MSK SHIFT0(0xffffffff) /* DATA1 */ ++#define HCU_DATA1_BASE BIT_0 ++ ++/* HCU_DATA2 0x0E74 Data Register 2 */ ++#define HCU_DATA2_MSK SHIFT0(0xffffffff) /* DATA2 */ ++#define HCU_DATA2_BASE BIT_0 ++ ++/* HCU_DATA3 0x0E78 Data Register 3 */ ++#define HCU_DATA3_MSK SHIFT0(0xffffffff) /* DATA3 */ ++#define HCU_DATA3_BASE BIT_0 ++ ++/* HCU_DATA4 0x0E7C Data Register 4 */ ++#define HCU_DATA4_MSK SHIFT0(0xffffffff) /* DATA4 */ ++#define HCU_DATA4_BASE BIT_0 ++ ++/* STAT_CTRL 0x0E80 Status BMU Control Register */ ++/* Bit(s) STAT_CTRL_RSRV_12_0 reserved */ ++/* Master Request Loopback Test On */ ++#define STAT_CTRL_MST_REQ_LPBK_ON BIT_18 ++/* Master Request Loopback Test Off */ ++#define STAT_CTRL_MST_REQ_LPBK_OFF BIT_17 ++/* Master Request Loopback Step */ ++#define STAT_CTRL_MST_REQ_LPBK_STEP BIT_16 ++/* Bit(s) STAT_CTRL_RSRV_ reserved */ ++/* FIFO Read Pointer Test On */ ++#define STAT_CTRL_RPTR_TEST_ON BIT_14 ++/* FIFO Read Pointer Test Off */ ++#define STAT_CTRL_RPTR_TEST_OFF BIT_13 ++#define STAT_CTRL_RPTR_TEST_STEP BIT_12 /* FIFO Read Pointer Step */ ++/* Bit(s) STAT_CTRL_RSRV_ reserved */ ++/* FIFO Write Pointer Test On */ ++#define STAT_CTRL_WPTR_TEST_ON BIT_10 ++/* FIFO Write Pointer Test Off */ ++#define STAT_CTRL_WPTR_TEST_OFF BIT_9 ++#define STAT_CTRL_WPTR_TEST_STEP BIT_8 /* FIFO Write Pointer Step */ ++/* Bit(s) STAT_CTRL_RSRV_2_0 reserved */ ++#define STAT_CTRL_CLR_IRQ_STAT BIT_4 /* Clear IRQ Status BMU */ ++#define STAT_CTRL_OP_ON BIT_3 /* Operational On */ ++#define STAT_CTRL_OP_OFF BIT_2 /* Operational Off */ ++#define STAT_CTRL_ENA BIT_1 /* Enable */ ++#define STAT_CTRL_RST BIT_0 /* Reset */ ++ ++/* STAT_LAST_IDX 0x0E84 Last Index Register */ ++/* Bit(s) STAT_LAST_IDX_RSRV_19_0 reserved */ ++#define STAT_LAST_IDX_MSK SHIFT2(0x3ff) /* Last Index */ ++#define STAT_LAST_IDX_BASE BIT_2 ++#define STAT_LAST_IDX_VAL_FIX_MSK SHIFT0(0x3) /* Last Index Fix */ ++#define STAT_LAST_IDX_VAL_FIX_BASE BIT_0 ++ ++/* STAT_LADR_LO 0x0E88 List Start Address Lower Register */ ++/* List Start Address Lo */ ++#define STAT_LADR_LO_MSK SHIFT5(0x7ffffff) ++#define STAT_LADR_LO_BASE BIT_5 ++/* List Start Address Lo Fix */ ++#define STAT_LADR_LO_VAL_FIX_MSK SHIFT0(0x1f) ++#define STAT_LADR_LO_VAL_FIX_BASE BIT_0 ++ ++/* STAT_LADR_HI 0x0E8C List Start Address Upper Register */ ++#define STAT_LADR_HI_MSK SHIFT0(0xffffffff) /* List Start Address Hi */ ++#define STAT_LADR_HI_BASE BIT_0 ++ ++/* STAT_TXA_REP 0x0E90 TXA Report Index Register */ ++/* Bit(s) STAT_TXA_REP_RSRV_3_0 reserved */ ++#define STAT_TXA_REP_MSK SHIFT0(0xfffS) /* TXA Report Index */ ++#define STAT_TXA_REP_BASE BIT_0S ++ ++/* STAT_TXTH 0x0E98 TX Index Threshold Register */ ++/* Bit(s) STAT_TXTH_RSRV_3_0 reserved */ ++#define STAT_TXTH_MSK SHIFT0(0xfffS) /* TX Index Threshold */ ++#define STAT_TXTH_BASE BIT_0S ++ ++/* STAT_PUT 0x0E9C Put Index Register */ ++/* Bit(s) STAT_PUT_RSRV_19_0 reserved */ ++#define STAT_PUT_MSK SHIFT0(0xfff) /* Put Index */ ++#define STAT_PUT_BASE BIT_0 ++ ++/* STAT_FIFO_WPTR 0x0EA0 FIFO Write Pointer Register */ ++/* Bit(s) STAT_FIFO_WPTR_RSRV_26_0 reserved */ ++/* FIFO Write Pointer */ ++#define STAT_FIFO_WPTR_MSK SHIFT0(0x1f) ++#define STAT_FIFO_WPTR_BASE BIT_0 ++ ++/* STAT_FIFO_RPTR 0x0EA4 FIFO Read Pointer Register */ ++/* Bit(s) STAT_FIFO_RPTR_RSRV_10_0 reserved */ ++#define STAT_FIFO_RPTR_WSPTR_MSK SHIFT16(0x1f) /* FIFO Rd Shadow Ptr */ ++#define STAT_FIFO_RPTR_WSPTR_BASE BIT_16 ++/* Bit(s) STAT_FIFO_RPTR_RSRV_10_0 reserved */ ++#define STAT_FIFO_RPTR_MSK SHIFT0(0x1f) /* FIFO Read Pointer */ ++#define STAT_FIFO_RPTR_BASE BIT_0 ++ ++/* STAT_FIFO_LEV 0x0EA8 FIFO Level Register */ ++/* Bit(s) STAT_FIFO_LEV_RSRV_10_0 reserved */ ++#define STAT_FIFO_LEV_SLEV_MSK SHIFT16(0x1f) /* FIFO Shadow Level */ ++#define STAT_FIFO_LEV_SLEV_BASE BIT_16 ++/* Bit(s) STAT_FIFO_LEV_RSRV_10_0 reserved */ ++#define STAT_FIFO_LEV_MSK SHIFT0(0x1f) /* FIFO Level */ ++#define STAT_FIFO_LEV_BASE BIT_0 ++ ++/* STAT_FIFO_WM 0x0EAC FIFO Watermark Register */ ++/* Bit(s) STAT_FIFO_WM_RSRV_2_0 reserved */ ++#define STAT_FIFO_WM_MSK SHIFT0(0x1fS) /* FIFO Watermark */ ++#define STAT_FIFO_WM_BASE BIT_0S ++ ++/* STAT_FIFO_WM_ISR 0x0EAD FIFO ISR Watermark Register */ ++/* Bit(s) STAT_FIFO_WM_ISR_RSRV_2_0 reserved */ ++#define STAT_FIFO_WM_ISR_MSK SHIFT0(0x1fS) /* FIFO ISR Watermark */ ++#define STAT_FIFO_WM_ISR_BASE BIT_0S ++ ++/* LEV_TIM_INIT 0x0EB0 Level Timer Init Value Register */ ++#define LEV_TIM_INIT_MSK SHIFT0(0xffffffff) /* Level Timer Init Value */ ++#define LEV_TIM_INIT_BASE BIT_0 ++ ++/* LEV_TIM_CNT 0x0EB4 Level Timer Counter Register */ ++#define LEV_TIM_CNT_MSK SHIFT0(0xffffffff) /* Level Timer */ ++#define LEV_TIM_CNT_BASE BIT_0 ++ ++/* LEV_TIM_TCTL 0x0EB8 Level Timer Control/Test Register */ ++/* Bit(s) LEV_TIM_TCTL_RSRV_20_0 reserved */ ++#define LEV_TIM_TCTL_ON BIT_10 /* Level Timer Test On */ ++#define LEV_TIM_TCTL_OFF BIT_9 /* Level Timer Test Off */ ++#define LEV_TIM_TCTL_STEP BIT_8 /* Level Timer Step */ ++/* Bit(s) LEV_TIM_TCTL_RSRV_4_0 reserved */ ++#define LEV_TIM_TCTL_STRT BIT_2 /* Level Timer Start */ ++#define LEV_TIM_TCTL_STOP BIT_1 /* Level Timer Stop */ ++/* Bit(s) LEV_TIM_TCTL_RSRV_ reserved */ ++ ++/* TX_TIM_INIT 0x0EC0 TX TImer Init Value Register */ ++#define TX_TIM_INIT_MSK SHIFT0(0xffffffff) /* TX Timer Init Value */ ++#define TX_TIM_INIT_BASE BIT_0 ++ ++/* TX_TIM_CNT 0x0EC4 TX Timer Counter Register */ ++#define TX_TIM_CNT_MSK SHIFT0(0xffffffff) /* TX Timer */ ++#define TX_TIM_CNT_BASE BIT_0 ++ ++/* TX_TIM_TCTL 0x0EC8 TX Timer Control/Test Register */ ++/* Bit(s) TX_TIM_TCTL_RSRV_20_0 reserved */ ++#define TX_TIM_TCTL_ON BIT_10 /* TX Timer Test On */ ++#define TX_TIM_TCTL_OFF BIT_9 /* TX Timer Test Off */ ++#define TX_TIM_TCTL_STEP BIT_8 /* TX Timer Step */ ++/* Bit(s) TX_TIM_TCTL_RSRV_4_0 reserved */ ++#define TX_TIM_TCTL_STRT BIT_2 /* TX Timer Start */ ++#define TX_TIM_TCTL_STOP BIT_1 /* TX Timer Stop */ ++/* Bit(s) TX_TIM_TCTL_RSRV_ reserved */ ++ ++/* ISR_TIM_INIT 0x0ED0 ISR Timer Init Value Register */ ++#define ISR_TIM_INIT_MSK SHIFT0(0xffffffff) /* ISR Timer Init Value */ ++#define ISR_TIM_INIT_BASE BIT_0 ++ ++/* ISR_TIM_CNT 0x0ED4 ISR Timer Counter Register */ ++#define ISR_TIM_CNT_MSK SHIFT0(0xffffffff) /* ISR Timer */ ++#define ISR_TIM_CNT_BASE BIT_0 ++ ++/* ISR_TIM_TCTL 0x0ED8 ISR Timer Control/Test Register */ ++/* Bit(s) ISR_TIM_TCTL_RSRV_20_0 reserved */ ++#define ISR_TIM_TCTL_ON BIT_10 /* ISR Timer Test On */ ++#define ISR_TIM_TCTL_OFF BIT_9 /* ISR Timer Test Off */ ++#define ISR_TIM_TCTL_STEP BIT_8 /* ISR Timer Step */ ++/* Bit(s) ISR_TIM_TCTL_RSRV_4_0 reserved */ ++#define ISR_TIM_TCTL_STRT BIT_2 /* ISR Timer Start */ ++#define ISR_TIM_TCTL_STOP BIT_1 /* ISR Timer Stop */ ++/* Bit(s) ISR_TIM_TCTL_RSRV_ reserved */ ++ ++/* MAC_CTRL 0x0F00 MAC Control Registers */ ++/* Bit(s) MAC_CTRL_RSRV_1_0 reserved */ ++#define MAC_CTRL_BYP_MACSECRX_ON BIT_13S /* Bypass macsec RX */ ++#define MAC_CTRL_BYP_MACSECRX_OFF BIT_12S /* Bypass macsec RX off */ ++#define MAC_CTRL_BYP_MACSECTX_ON BIT_11S /* Bypass macsec TX */ ++#define MAC_CTRL_BYP_MACSECTX_OFF BIT_10S /* Bypass macsec TX off */ ++#define MAC_CTRL_BYP_RETR_ON BIT_9S /* Bypass retransmit fifo */ ++/* Bypass retransmit fifo off */ ++#define MAC_CTRL_BYP_RETR_OFF BIT_8S ++#define MAC_CTRL_BURST_ON BIT_7S /* En Burstmode On */ ++#define MAC_CTRL_BURST_OFF BIT_6S /* En Burstmode Off */ ++#define MAC_CTRL_LPBK_ON BIT_5S /* Loopback On */ ++#define MAC_CTRL_LPBK_OFF BIT_4S /* Loopback Off */ ++#define MAC_CTRL_PAUSE_ON BIT_3S /* En Pause On */ ++#define MAC_CTRL_PAUSE_OFF BIT_2S /* En Pause Off */ ++#define MAC_CTRL_RST_CLR BIT_1S /* GMAC Reset Clear */ ++#define MAC_CTRL_RST_SET BIT_0S /* GMAC Reset Set */ ++ ++/* PHY_CFG 0x0F04 PHY Config Register, loaded from external ++ * memory ++ */ ++#define PHY_CFG_STAT_MSK SHIFT24(0xff) /* PHY Status */ ++#define PHY_CFG_STAT_BASE BIT_24 ++/* Internal Regulator 2.5 Power Down Enable */ ++#define PHY_CFG_INT_REG_PD_ENA BIT_23 ++#define PHY_CFG_TEST BIT_22 /* Testmode */ ++#define PHY_CFG_REG18_PD BIT_21 /* Reg18 PowerDown */ ++#define PHY_CFG_REG12_SEL_MSK SHIFT19(0x3) /* Reg12 Sel */ ++#define PHY_CFG_REG12_SEL_BASE BIT_19 ++#define PHY_CFG_REG18_SEL_MSK SHIFT17(0x3) /* Reg18 Sel */ ++#define PHY_CFG_REG18_SEL_BASE BIT_17 ++#define PHY_CFG_SPI_LOCK BIT_16 /* SPI Lock */ ++#define PHY_CFG_CFG_LED_MUX_MSK SHIFT14(0x3) /* GPHY Config for LED Mux */ ++#define PHY_CFG_CFG_LED_MUX_BASE BIT_14 ++/* GPHY Config for Int Polarity */ ++#define PHY_CFG_CFG_POL BIT_13 ++/* GPHY Config for Energy Detect */ ++#define PHY_CFG_CFG_ERG_DET BIT_12 ++#define PHY_CFG_CFG_1000 BIT_11 /* GPHY Config for 1000M/HD */ ++/* GPHY Config for Master/Slave */ ++#define PHY_CFG_CFG_MST_SLV BIT_10 ++/* GPHY Config for Pause Enable */ ++#define PHY_CFG_CFG_PAUSE BIT_9 ++#define PHY_CFG_LED_CFG_MSK SHIFT6(0x7) /* GPHY LED Config */ ++#define PHY_CFG_LED_CFG_BASE BIT_6 ++/* Power Down GPHY's Clock 125MHz */ ++#define PHY_CFG_CLK_125_PD_MSK SHIFT4(0x3) ++#define PHY_CFG_CLK_125_PD_BASE BIT_4 ++#define PHY_CFG_DLL_RST_MSK SHIFT2(0x3) /* Reset GPHY's DPLL */ ++#define PHY_CFG_DLL_RST_BASE BIT_2 ++#define PHY_CFG_RST_CLR BIT_1 /* PHY Reset Clear */ ++#define PHY_CFG_RST_SET BIT_0 /* PHY Reset Set */ ++ ++/* MAC_ISRC 0x0F08 MAC Interrupt Source Register */ ++/* Bit(s) MAC_ISRC_RSRV_25_0 reserved */ ++/* Receive Counter Overflow Interrupt */ ++#define MAC_ISRC_RX_CNT_OF BIT_5 ++/* Transmit Counter Overflow Interrupt */ ++#define MAC_ISRC_TX_CNT_OF BIT_4 ++#define MAC_ISRC_TX_UR BIT_3 /* Transmit FIFO Underrun */ ++/* Frame Transmission Complete */ ++#define MAC_ISRC_TX_OK BIT_2 ++#define MAC_ISRC_RX_OF BIT_1 /* Receive FIFO Overrun */ ++#define MAC_ISRC_RX_OK BIT_0 /* Frame Reception Complete */ ++ ++/* MAC_IMSK 0x0F0C MAC Interrupt Mask Register */ ++/* Bit(s) MAC_IMSK_RSRV_25_0 reserved */ ++/* En IRQ Receive Counter Overflow Interrupt */ ++#define MAC_IMSK_RX_CNT_OF BIT_5 ++/* En IRQ Transmit Counter Overflow Interrupt */ ++#define MAC_IMSK_TX_CNT_OF BIT_4 ++/* En IRQ Transmit FIFO Underrun */ ++#define MAC_IMSK_TX_UR BIT_3 ++/* En IRQ Frame Transmission Complete */ ++#define MAC_IMSK_TX_OK BIT_2 ++/* En IRQ Receive FIFO Overrun */ ++#define MAC_IMSK_RX_OF BIT_1 ++/* En IRQ Frame Reception Complete */ ++#define MAC_IMSK_RX_OK BIT_0 ++ ++/* LINK_CTRL 0x0F10 Link Control Register */ ++/* Bit(s) LINK_CTRL_RSRV_13_0 reserved */ ++#define LINK_CTRL_RST_CLR BIT_1S /* Link Reset Clear */ ++#define LINK_CTRL_RST_SET BIT_0S /* Link Reset Set */ ++ ++/* WOL_CSR 0x0F20 WOL Control/Status Register */ ++#define WOL_CSR_LC_STAT BIT_15S /* Link Up Status */ ++#define WOL_CSR_MP_STAT BIT_14S /* Magic Pattern Status */ ++#define WOL_CSR_WF_STAT BIT_13S /* Wake up Frame Status */ ++#define WOL_CSR_CLR_RSLT BIT_12S /* Clear Match Result */ ++#define WOL_CSR_LC_PME_ENA BIT_11S /* Enable PME on Link Up */ ++#define WOL_CSR_LC_PME_DIS BIT_10S /* Disable PME on Link Up */ ++#define WOL_CSR_MP_PME_ENA BIT_9S /* Enable PME on Magic Pattern */ ++#define WOL_CSR_MP_PME_DIS BIT_8S /* Disable PME on Magic Pattern */ ++#define WOL_CSR_WF_PME_ENA BIT_7S /* Enable PME on Wake up Frame */ ++#define WOL_CSR_WF_PME_DIS BIT_6S /* Disable PME on Wake up Frame */ ++#define WOL_CSR_LC_ENA BIT_5S /* Enable Link Up Unit */ ++#define WOL_CSR_LC_DIS BIT_4S /* Disable Link Up Unit */ ++#define WOL_CSR_MP_ENA BIT_3S /* Enable Magic Pattern Unit */ ++#define WOL_CSR_MP_DIS BIT_2S /* Disable Magic Pattern Unit */ ++#define WOL_CSR_WF_ENA BIT_1S /* Enable Pattern Match Unit */ ++#define WOL_CSR_WF_DIS BIT_0S /* Disable Pattern Match Unit */ ++ ++/* WOL_MCTRL 0x0F22 Match Control Register */ ++/* Bit(s) WOL_MCTRL_RSRV_6_0 reserved */ ++#define WOL_MCTRL_P8_ENA BIT_8S /* Pattern 8 Enable */ ++#define WOL_MCTRL_P7_ENA BIT_7S /* Pattern 7 Enable */ ++#define WOL_MCTRL_P6_ENA BIT_6S /* Pattern 6 Enable */ ++#define WOL_MCTRL_P5_ENA BIT_5S /* Pattern 5 Enable */ ++#define WOL_MCTRL_P4_ENA BIT_4S /* Pattern 4 Enable */ ++#define WOL_MCTRL_P3_ENA BIT_3S /* Pattern 3 Enable */ ++#define WOL_MCTRL_P2_ENA BIT_2S /* Pattern 2 Enable */ ++#define WOL_MCTRL_P1_ENA BIT_1S /* Pattern 1 Enable */ ++#define WOL_MCTRL_P0_ENA BIT_0S /* Pattern 0 Enable */ ++ ++/* WOL_MADDR_LO 0x0F24 MAC Address Register Low Register */ ++#define WOL_MADDR_LO_MAC_3_MSK SHIFT24(0xff) /* MAC<3> */ ++#define WOL_MADDR_LO_MAC_3_BASE BIT_24 ++#define WOL_MADDR_LO_MAC_2_MSK SHIFT16(0xff) /* MAC<2> */ ++#define WOL_MADDR_LO_MAC_2_BASE BIT_16 ++#define WOL_MADDR_LO_MAC_1_MSK SHIFT8(0xff) /* MAC<1> */ ++#define WOL_MADDR_LO_MAC_1_BASE BIT_8 ++#define WOL_MADDR_LO_MAC_0_MSK SHIFT0(0xff) /* MAC<0> */ ++#define WOL_MADDR_LO_MAC_0_BASE BIT_0 ++ ++/* WOL_MADDR_HI 0x0F28 MAC Address Register High Register */ ++#define WOL_MADDR_HI_MAC_5_MSK SHIFT8(0xffS) /* MAC<5> */ ++#define WOL_MADDR_HI_MAC_5_BASE BIT_8S ++#define WOL_MADDR_HI_MAC_4_MSK SHIFT0(0xffS) /* MAC<4> */ ++#define WOL_MADDR_HI_MAC_4_BASE BIT_0S ++ ++/* WOL_PME_MEN 0x0F2A PME Match Enable Register */ ++#define WOL_PME_MEN_FRC_PME BIT_15S /* Force PME */ ++/* Bit(s) WOL_PME_MEN_RSRV_5_0 reserved */ ++#define WOL_PME_MEN_P8_PME_ENA BIT_8S /* PME 8 Enable */ ++#define WOL_PME_MEN_P7_PME_ENA BIT_7S /* PME 7 Enable */ ++#define WOL_PME_MEN_P6_PME_ENA BIT_6S /* PME 6 Enable */ ++#define WOL_PME_MEN_P5_PME_ENA BIT_5S /* PME 5 Enable */ ++#define WOL_PME_MEN_P4_PME_ENA BIT_4S /* PME 4 Enable */ ++#define WOL_PME_MEN_P3_PME_ENA BIT_3S /* PME 3 Enable */ ++#define WOL_PME_MEN_P2_PME_ENA BIT_2S /* PME 2 Enable */ ++#define WOL_PME_MEN_P1_PME_ENA BIT_1S /* PME 1 Enable */ ++#define WOL_PME_MEN_P0_PME_ENA BIT_0S /* PME 0 Enable */ ++ ++/* WOL_ASF_MEN 0x0F2C ASF Match Enable Register */ ++/* Bit(s) WOL_ASF_MEN_RSRV_6_0 reserved */ ++#define WOL_ASF_MEN_P8_ASF_ENA BIT_8S /* ASF 8 Enable */ ++#define WOL_ASF_MEN_P7_ASF_ENA BIT_7S /* ASF 7 Enable */ ++#define WOL_ASF_MEN_P6_ASF_ENA BIT_6S /* ASF 6 Enable */ ++#define WOL_ASF_MEN_P5_ASF_ENA BIT_5S /* ASF 5 Enable */ ++#define WOL_ASF_MEN_P4_ASF_ENA BIT_4S /* ASF 4 Enable */ ++#define WOL_ASF_MEN_P3_ASF_ENA BIT_3S /* ASF 3 Enable */ ++#define WOL_ASF_MEN_P2_ASF_ENA BIT_2S /* ASF 2 Enable */ ++#define WOL_ASF_MEN_P1_ASF_ENA BIT_1S /* ASF 1 Enable */ ++#define WOL_ASF_MEN_P0_ASF_ENA BIT_0S /* ASF 0 Enable */ ++ ++/* WOL_MRSL 0x0F2E Match Result Register */ ++/* Bit(s) WOL_MRSL_RSRV_6_0 reserved */ ++#define WOL_MRSL_P8_MATCH BIT_8S /* Pattern 8 Match */ ++#define WOL_MRSL_P7_MATCH BIT_7S /* Pattern 7 Match */ ++#define WOL_MRSL_P6_MATCH BIT_6S /* Pattern 6 Match */ ++#define WOL_MRSL_P5_MATCH BIT_5S /* Pattern 5 Match */ ++#define WOL_MRSL_P4_MATCH BIT_4S /* Pattern 4 Match */ ++#define WOL_MRSL_P3_MATCH BIT_3S /* Pattern 3 Match */ ++#define WOL_MRSL_P2_MATCH BIT_2S /* Pattern 2 Match */ ++#define WOL_MRSL_P1_MATCH BIT_1S /* Pattern 1 Match */ ++#define WOL_MRSL_P0_MATCH BIT_0S /* Pattern 0 Match */ ++ ++/* WOL_PLEN0 0x0F30 Pattern Length Register 0 (0-3) */ ++/* Bit(s) WOL_PLEN0_RSRV_ reserved */ ++#define WOL_PLEN0_P3_LEN_MSK SHIFT24(0x7f) /* Pattern 3 Length */ ++#define WOL_PLEN0_P3_LEN_BASE BIT_24 ++/* Bit(s) WOL_PLEN0_RSRV_ reserved */ ++#define WOL_PLEN0_P2_LEN_MSK SHIFT16(0x7f) /* Pattern 2 Length */ ++#define WOL_PLEN0_P2_LEN_BASE BIT_16 ++/* Bit(s) WOL_PLEN0_RSRV_ reserved */ ++#define WOL_PLEN0_P1_LEN_MSK SHIFT8(0x7f) /* Pattern 1 Length */ ++#define WOL_PLEN0_P1_LEN_BASE BIT_8 ++/* Bit(s) WOL_PLEN0_RSRV_ reserved */ ++#define WOL_PLEN0_P0_LEN_MSK SHIFT0(0x7f) /* Pattern 0 Length */ ++#define WOL_PLEN0_P0_LEN_BASE BIT_0 ++ ++/* WOL_PLEN1 0x0F34 Pattern Length Register 1 (4-7) */ ++/* Bit(s) WOL_PLEN1_RSRV_ reserved */ ++#define WOL_PLEN1_P7_LEN_MSK SHIFT24(0x7f) /* Pattern 7 Length */ ++#define WOL_PLEN1_P7_LEN_BASE BIT_24 ++/* Bit(s) WOL_PLEN1_RSRV_ reserved */ ++#define WOL_PLEN1_P6_LEN_MSK SHIFT16(0x7f) /* Pattern 6 Length */ ++#define WOL_PLEN1_P6_LEN_BASE BIT_16 ++/* Bit(s) WOL_PLEN1_RSRV_ reserved */ ++#define WOL_PLEN1_P5_LEN_MSK SHIFT8(0x7f) /* Pattern 5 Length */ ++#define WOL_PLEN1_P5_LEN_BASE BIT_8 ++/* Bit(s) WOL_PLEN1_RSRV_ reserved */ ++#define WOL_PLEN1_P4_LEN_MSK SHIFT0(0x7f) /* Pattern 4 Length */ ++#define WOL_PLEN1_P4_LEN_BASE BIT_0 ++ ++/* WOL_PLEN2 0x0F38 Pattern Length Register 2 (8) */ ++/* Bit(s) WOL_PLEN2_RSRV_24_0 reserved */ ++#define WOL_PLEN2_P8_LEN_MSK SHIFT0(0x7f) /* Pattern 8 Length */ ++#define WOL_PLEN2_P8_LEN_BASE BIT_0 ++ ++/* WOL_PCNT0 0x0F40 Pattern Counter Register 0 (0-3) */ ++/* Bit(s) WOL_PCNT0_RSRV_ reserved */ ++#define WOL_PCNT0_P3_CNTR_MSK SHIFT24(0x7f) /* Pattern 3 Counter */ ++#define WOL_PCNT0_P3_CNTR_BASE BIT_24 ++/* Bit(s) WOL_PCNT0_RSRV_ reserved */ ++#define WOL_PCNT0_P2_CNTR_MSK SHIFT16(0x7f) /* Pattern 2 Counter */ ++#define WOL_PCNT0_P2_CNTR_BASE BIT_16 ++/* Bit(s) WOL_PCNT0_RSRV_ reserved */ ++#define WOL_PCNT0_P1_CNTR_MSK SHIFT8(0x7f) /* Pattern 1 Counter */ ++#define WOL_PCNT0_P1_CNTR_BASE BIT_8 ++/* Bit(s) WOL_PCNT0_RSRV_ reserved */ ++#define WOL_PCNT0_P0_CNTR_MSK SHIFT0(0x7f) /* Pattern 0 Counter */ ++#define WOL_PCNT0_P0_CNTR_BASE BIT_0 ++ ++/* WOL_PCNT1 0x0F44 Pattern Counter Register 1 (4-7) */ ++/* Bit(s) WOL_PCNT1_RSRV_ reserved */ ++#define WOL_PCNT1_P7_CNTR_MSK SHIFT24(0x7f) /* Pattern 7 Counter */ ++#define WOL_PCNT1_P7_CNTR_BASE BIT_24 ++/* Bit(s) WOL_PCNT1_RSRV_ reserved */ ++#define WOL_PCNT1_P6_CNTR_MSK SHIFT16(0x7f) /* Pattern 6 Counter */ ++#define WOL_PCNT1_P6_CNTR_BASE BIT_16 ++/* Bit(s) WOL_PCNT1_RSRV_ reserved */ ++#define WOL_PCNT1_P5_CNTR_MSK SHIFT8(0x7f) /* Pattern 5 Counter */ ++#define WOL_PCNT1_P5_CNTR_BASE BIT_8 ++/* Bit(s) WOL_PCNT1_RSRV_ reserved */ ++#define WOL_PCNT1_P4_CNTR_MSK SHIFT0(0x7f) /* Pattern 4 Counter */ ++#define WOL_PCNT1_P4_CNTR_BASE BIT_0 ++ ++/* WOL_PCNT2 0x0F48 Pattern Counter Register 2 (8) */ ++/* Bit(s) WOL_PCNT2_RSRV_24_0 reserved */ ++#define WOL_PCNT2_P8_CNTR_MSK SHIFT0(0x7f) /* Pattern 8 Counter */ ++#define WOL_PCNT2_P8_CNTR_BASE BIT_0 ++ ++/* PAT_CSR 0x0F50 Pattern RAM Control/Status Register */ ++/* Bit(s) PAT_CSR_RSRV_8_0 reserved */ ++#define PAT_CSR_RPTR_MSK SHIFT16(0x7f) /* Pattern Read Pointer */ ++#define PAT_CSR_RPTR_BASE BIT_16 ++/* Bit(s) PAT_CSR_RSRV_14_0 reserved */ ++#define PAT_CSR_BSEL BIT_0 /* Pattern RAM Bank Select */ ++ ++/* PAT_RAM 0x1000 Pattern RAM Register */ ++#define PAT_RAM_MSK SHIFT0(0xffffffff) /* Lower Half qword No. 0 */ ++#define PAT_RAM_BASE BIT_0 ++ ++/* THDR0_LO 0x1900 TCP Segmentation Header Register 0 Lo */ ++#define THDR0_LO_MAC_HDR_0_MSK SHIFT0(0xffffffff) /* MAC_HDR_0 */ ++#define THDR0_LO_MAC_HDR_0_BASE BIT_0 ++ ++/* THDR0_HI 0x1904 TCP Segmentation Header Register 0 Hi */ ++#define THDR0_HI_MAC_HDR_1_MSK SHIFT0(0xffffffff) /* MAC_HDR_1 */ ++#define THDR0_HI_MAC_HDR_1_BASE BIT_0 ++ ++/* THDR1_LO 0x1908 TCP Segmentation Header Register 1 Lo */ ++#define THDR1_LO_MAC_HDR_2_MSK SHIFT0(0xffffffff) /* MAC_HDR_2 */ ++#define THDR1_LO_MAC_HDR_2_BASE BIT_0 ++ ++/* THDR1_HI 0x190C TCP Segmentation Header Register 1 Hi */ ++#define THDR1_HI_IP_HDR_0_MSK SHIFT16(0xffff) /* IP_HDR_0 */ ++#define THDR1_HI_IP_HDR_0_BASE BIT_16 ++#define THDR1_HI_MAC_HDR_3_MSK SHIFT0(0xffff) /* MAC_HDR_3 */ ++#define THDR1_HI_MAC_HDR_3_BASE BIT_0 ++ ++/* THDR2_LO 0x1910 TCP Segmentation Header Register 2 Lo */ ++#define THDR2_LO_IP_HDR_1_MSK SHIFT0(0xffffffff) /* IP_HDR_1 */ ++#define THDR2_LO_IP_HDR_1_BASE BIT_0 ++ ++/* THDR2_HI 0x1914 TCP Segmentation Header Register 2 Hi */ ++#define THDR2_HI_IP_HDR_2_MSK SHIFT0(0xffffffff) /* IP_HDR_2 */ ++#define THDR2_HI_IP_HDR_2_BASE BIT_0 ++ ++/* THDR3_LO 0x1918 TCP Segmentation Header Register 3 Lo */ ++#define THDR3_LO_IP_HDR_3_MSK SHIFT0(0xffffffff) /* IP_HDR_3 */ ++#define THDR3_LO_IP_HDR_3_BASE BIT_0 ++ ++/* THDR3_HI 0x191C TCP Segmentation Header Register 3 Hi */ ++#define THDR3_HI_IP_HDR_4_MSK SHIFT0(0xffffffff) /* IP_HDR_4 */ ++#define THDR3_HI_IP_HDR_4_BASE BIT_0 ++ ++/* THDR4_LO 0x1920 TCP Segmentation Header Register 4 Lo */ ++#define THDR4_LO_IP_HDR_5_MSK SHIFT0(0xffffffff) /* IP_HDR_5 */ ++#define THDR4_LO_IP_HDR_5_BASE BIT_0 ++ ++/* THDR4_HI 0x1924 TCP Segmentation Header Register 4 Hi */ ++#define THDR4_HI_IP_HDR_6_MSK SHIFT0(0xffffffff) /* IP_HDR_6 */ ++#define THDR4_HI_IP_HDR_6_BASE BIT_0 ++ ++/* THDR5_LO 0x1928 TCP Segmentation Header Register 5 Lo */ ++#define THDR5_LO_IP_HDR_7_MSK SHIFT0(0xffffffff) /* IP_HDR_7 */ ++#define THDR5_LO_IP_HDR_7_BASE BIT_0 ++ ++/* THDR5_HI 0x192C TCP Segmentation Header Register 5 Hi */ ++#define THDR5_HI_IP_HDR_8_MSK SHIFT0(0xffffffff) /* IP_HDR_8 */ ++#define THDR5_HI_IP_HDR_8_BASE BIT_0 ++ ++/* THDR6_LO 0x1930 TCP Segmentation Header Register 6 Lo */ ++#define THDR6_LO_IP_HDR_9_MSK SHIFT0(0xffffffff) /* IP_HDR_9 */ ++#define THDR6_LO_IP_HDR_9_BASE BIT_0 ++ ++/* THDR6_HI 0x1934 TCP Segmentation Header Register 6 Hi */ ++#define THDR6_HI_IP_HDR_10_MSK SHIFT0(0xffffffff) /* IP_HDR_10 */ ++#define THDR6_HI_IP_HDR_10_BASE BIT_0 ++ ++/* THDR7_LO 0x1938 TCP Segmentation Header Register 7 Lo */ ++#define THDR7_LO_IP_HDR_11_MSK SHIFT0(0xffffffff) /* IP_HDR_11 */ ++#define THDR7_LO_IP_HDR_11_BASE BIT_0 ++ ++/* THDR7_HI 0x193C TCP Segmentation Header Register 7 Hi */ ++#define THDR7_HI_IP_HDR_12_MSK SHIFT0(0xffffffff) /* IP_HDR_12 */ ++#define THDR7_HI_IP_HDR_12_BASE BIT_0 ++ ++/* THDR8_LO 0x1940 TCP Segmentation Header Register 8 Lo */ ++#define THDR8_LO_IP_HDR_13_MSK SHIFT0(0xffffffff) /* IP_HDR_13 */ ++#define THDR8_LO_IP_HDR_13_BASE BIT_0 ++ ++/* THDR8_HI 0x1944 TCP Segmentation Header Register 8 Hi */ ++#define THDR8_HI_IP_HDR_14_MSK SHIFT0(0xffffffff) /* IP_HDR_14 */ ++#define THDR8_HI_IP_HDR_14_BASE BIT_0 ++ ++/* THDR9_LO 0x1948 TCP Segmentation Header Register 9 Lo */ ++#define THDR9_LO_IP_HDR_15_MSK SHIFT0(0xffffffff) /* IP_HDR_15 */ ++#define THDR9_LO_IP_HDR_15_BASE BIT_0 ++ ++/* THDR9_HI 0x194C TCP Segmentation Header Register 9 Hi */ ++#define THDR9_HI_IP_HDR_16_MSK SHIFT0(0xffffffff) /* IP_HDR_16 */ ++#define THDR9_HI_IP_HDR_16_BASE BIT_0 ++ ++/* THDR10_LO 0x1950 TCP Segmentation Header Register 10 Lo */ ++#define THDR10_LO_IP_HDR_17_MSK SHIFT0(0xffffffff) /* IP_HDR_17 */ ++#define THDR10_LO_IP_HDR_17_BASE BIT_0 ++ ++/* THDR10_HI 0x1954 TCP Segmentation Header Register 10 Hi */ ++#define THDR10_HI_IP_HDR_18_MSK SHIFT0(0xffffffff) /* IP_HDR_18 */ ++#define THDR10_HI_IP_HDR_18_BASE BIT_0 ++ ++/* THDR11_LO 0x1958 TCP Segmentation Header Register 11 Lo */ ++#define THDR11_LO_IP_HDR_19_MSK SHIFT0(0xffffffff) /* IP_HDR_19 */ ++#define THDR11_LO_IP_HDR_19_BASE BIT_0 ++ ++/* THDR11_HI 0x195C TCP Segmentation Header Register 11 Hi */ ++#define THDR11_HI_IP_HDR_20_MSK SHIFT0(0xffffffff) /* IP_HDR_20 */ ++#define THDR11_HI_IP_HDR_20_BASE BIT_0 ++ ++/* THDR12_LO 0x1960 TCP Segmentation Header Register 12 Lo */ ++#define THDR12_LO_IP_HDR_21_MSK SHIFT0(0xffffffff) /* IP_HDR_21 */ ++#define THDR12_LO_IP_HDR_21_BASE BIT_0 ++ ++/* THDR12_HI 0x1964 TCP Segmentation Header Register 12 Hi */ ++#define THDR12_HI_IP_HDR_22_MSK SHIFT0(0xffffffff) /* IP_HDR_22 */ ++#define THDR12_HI_IP_HDR_22_BASE BIT_0 ++ ++/* THDR13_LO 0x1968 TCP Segmentation Header Register 13 Lo */ ++#define THDR13_LO_IP_HDR_23_MSK SHIFT0(0xffffffff) /* IP_HDR_23 */ ++#define THDR13_LO_IP_HDR_23_BASE BIT_0 ++ ++/* THDR13_HI 0x196C TCP Segmentation Header Register 13 Hi */ ++#define THDR13_HI_IP_HDR_24_MSK SHIFT0(0xffffffff) /* IP_HDR_24 */ ++#define THDR13_HI_IP_HDR_24_BASE BIT_0 ++ ++/* THDR14_LO 0x1970 TCP Segmentation Header Register 14 Lo */ ++#define THDR14_LO_IP_HDR_25_MSK SHIFT0(0xffffffff) /* IP_HDR_25 */ ++#define THDR14_LO_IP_HDR_25_BASE BIT_0 ++ ++/* THDR14_HI 0x1974 TCP Segmentation Header Register 14 Hi */ ++#define THDR14_HI_IP_HDR_26_MSK SHIFT0(0xffffffff) /* IP_HDR_26 */ ++#define THDR14_HI_IP_HDR_26_BASE BIT_0 ++ ++/* THDR15_LO 0x1978 TCP Segmentation Header Register 15 Lo */ ++#define THDR15_LO_IP_HDR_27_MSK SHIFT0(0xffffffff) /* IP_HDR_27 */ ++#define THDR15_LO_IP_HDR_27_BASE BIT_0 ++ ++/* THDR15_HI 0x197C TCP Segmentation Header Register 15 Hi */ ++#define THDR15_HI_IP_HDR_28_MSK SHIFT0(0xffffffff) /* IP_HDR_28 */ ++#define THDR15_HI_IP_HDR_28_BASE BIT_0 ++ ++/* THDR16_LO 0x1980 TCP Segmentation Header Register 16 Lo */ ++#define THDR16_LO_IP_HDR_29_MSK SHIFT0(0xffffffff) /* IP_HDR_29 */ ++#define THDR16_LO_IP_HDR_29_BASE BIT_0 ++ ++/* THDR16_HI 0x1984 TCP Segmentation Header Register 16 Hi */ ++#define THDR16_HI_IP_HDR_30_MSK SHIFT0(0xffffffff) /* IP_HDR_30 */ ++#define THDR16_HI_IP_HDR_30_BASE BIT_0 ++ ++/* THDR17_LO 0x1988 TCP Segmentation Header Register 17 Lo */ ++#define THDR17_LO_IP_HDR_31_MSK SHIFT0(0xffffffff) /* IP_HDR_31 */ ++#define THDR17_LO_IP_HDR_31_BASE BIT_0 ++ ++/* THDR17_HI 0x198C TCP Segmentation Header Register 17 Hi */ ++#define THDR17_HI_IP_HDR_32_MSK SHIFT0(0xffffffff) /* IP_HDR_32 */ ++#define THDR17_HI_IP_HDR_32_BASE BIT_0 ++ ++/* THDR18_LO 0x1990 TCP Segmentation Header Register 18 Lo */ ++#define THDR18_LO_IP_HDR_33_MSK SHIFT0(0xffffffff) /* IP_HDR_33 */ ++#define THDR18_LO_IP_HDR_33_BASE BIT_0 ++ ++/* THDR18_HI 0x1994 TCP Segmentation Header Register 18 Hi */ ++#define THDR18_HI_IP_HDR_34_MSK SHIFT0(0xffffffff) /* IP_HDR_34 */ ++#define THDR18_HI_IP_HDR_34_BASE BIT_0 ++ ++/* THDR19_LO 0x1998 TCP Segmentation Header Register 19 Lo */ ++#define THDR19_LO_IP_HDR_35_MSK SHIFT0(0xffffffff) /* IP_HDR_35 */ ++#define THDR19_LO_IP_HDR_35_BASE BIT_0 ++ ++/* THDR19_HI 0x199C TCP Segmentation Header Register 19 Hi */ ++#define THDR19_HI_IP_HDR_36_MSK SHIFT0(0xffffffff) /* IP_HDR_36 */ ++#define THDR19_HI_IP_HDR_36_BASE BIT_0 ++ ++/* THDR20_LO 0x19A0 TCP Segmentation Header Register 20 Lo */ ++#define THDR20_LO_IP_HDR_37_MSK SHIFT0(0xffffffff) /* IP_HDR_37 */ ++#define THDR20_LO_IP_HDR_37_BASE BIT_0 ++ ++/* THDR20_HI 0x19A4 TCP Segmentation Header Register 20 Hi */ ++#define THDR20_HI_IP_HDR_38_MSK SHIFT0(0xffffffff) /* IP_HDR_38 */ ++#define THDR20_HI_IP_HDR_38_BASE BIT_0 ++ ++/* THDR21_LO 0x19A8 TCP Segmentation Header Register 21 Lo */ ++#define THDR21_LO_IP_HDR_39_MSK SHIFT0(0xffffffff) /* IP_HDR_39 */ ++#define THDR21_LO_IP_HDR_39_BASE BIT_0 ++ ++/* THDR21_HI 0x19AC TCP Segmentation Header Register 21 Hi */ ++#define THDR21_HI_IP_HDR_40_MSK SHIFT0(0xffffffff) /* IP_HDR_40 */ ++#define THDR21_HI_IP_HDR_40_BASE BIT_0 ++ ++/* THDR22_LO 0x19B0 TCP Segmentation Header Register 22 Lo */ ++#define THDR22_LO_IP_HDR_41_MSK SHIFT0(0xffffffff) /* IP_HDR_41 */ ++#define THDR22_LO_IP_HDR_41_BASE BIT_0 ++ ++/* THDR22_HI 0x19B4 TCP Segmentation Header Register 22 Hi */ ++#define THDR22_HI_TCP_HDR_0_MSK SHIFT16(0xffff) /* TCP_HDR_0 */ ++#define THDR22_HI_TCP_HDR_0_BASE BIT_16 ++#define THDR22_HI_IP_HDR_42_MSK SHIFT0(0xffff) /* IP_HDR_42 */ ++#define THDR22_HI_IP_HDR_42_BASE BIT_0 ++ ++/* THDR23_LO 0x19B8 TCP Segmentation Header Register 23 Lo */ ++#define THDR23_LO_TCP_HDR_1_MSK SHIFT0(0xffffffff) /* TCP_HDR_1 */ ++#define THDR23_LO_TCP_HDR_1_BASE BIT_0 ++ ++/* THDR23_HI 0x19BC TCP Segmentation Header Register 23 Hi */ ++#define THDR23_HI_TCP_HDR_2_MSK SHIFT0(0xffffffff) /* TCP_HDR_2 */ ++#define THDR23_HI_TCP_HDR_2_BASE BIT_0 ++ ++/* THDR24_LO 0x19C0 TCP Segmentation Header Register 24 Lo */ ++#define THDR24_LO_TCP_HDR_3_MSK SHIFT0(0xffffffff) /* TCP_HDR_3 */ ++#define THDR24_LO_TCP_HDR_3_BASE BIT_0 ++ ++/* THDR24_HI 0x19C4 TCP Segmentation Header Register 24 Hi */ ++#define THDR24_HI_TCP_HDR_4_MSK SHIFT0(0xffffffff) /* TCP_HDR_4 */ ++#define THDR24_HI_TCP_HDR_4_BASE BIT_0 ++ ++/* THDR25_LO 0x19C8 TCP Segmentation Header Register 25 Lo */ ++#define THDR25_LO_TCP_HDR_5_MSK SHIFT0(0xffffffff) /* TCP_HDR_5 */ ++#define THDR25_LO_TCP_HDR_5_BASE BIT_0 ++ ++/* THDR25_HI 0x19CC TCP Segmentation Header Register 25 Hi */ ++#define THDR25_HI_TCP_HDR_6_MSK SHIFT0(0xffffffff) /* TCP_HDR_6 */ ++#define THDR25_HI_TCP_HDR_6_BASE BIT_0 ++ ++/* THDR26_LO 0x19D0 TCP Segmentation Header Register 26 Lo */ ++#define THDR26_LO_TCP_HDR_7_MSK SHIFT0(0xffffffff) /* TCP_HDR_7 */ ++#define THDR26_LO_TCP_HDR_7_BASE BIT_0 ++ ++/* THDR26_HI 0x19D4 TCP Segmentation Header Register 26 Hi */ ++#define THDR26_HI_TCP_HDR_8_MSK SHIFT0(0xffffffff) /* TCP_HDR_8 */ ++#define THDR26_HI_TCP_HDR_8_BASE BIT_0 ++ ++/* THDR27_LO 0x19D8 TCP Segmentation Header Register 27 Lo */ ++#define THDR27_LO_TCP_HDR_9_MSK SHIFT0(0xffffffff) /* TCP_HDR_9 */ ++#define THDR27_LO_TCP_HDR_9_BASE BIT_0 ++ ++/* THDR27_HI 0x19DC TCP Segmentation Header Register 27 Hi */ ++#define THDR27_HI_TCP_HDR_10_MSK SHIFT0(0xffffffff) /* TCP_HDR_10 */ ++#define THDR27_HI_TCP_HDR_10_BASE BIT_0 ++ ++/* THDR28_LO 0x19E0 TCP Segmentation Header Register 28 Lo */ ++#define THDR28_LO_TCP_HDR_11_MSK SHIFT0(0xffffffff) /* TCP_HDR_11 */ ++#define THDR28_LO_TCP_HDR_11_BASE BIT_0 ++ ++/* THDR28_HI 0x19E4 TCP Segmentation Header Register 28 Hi */ ++#define THDR28_HI_TCP_HDR_12_MSK SHIFT0(0xffffffff) /* TCP_HDR_12 */ ++#define THDR28_HI_TCP_HDR_12_BASE BIT_0 ++ ++/* THDR29_LO 0x19E8 TCP Segmentation Header Register 29 Lo */ ++#define THDR29_LO_TCP_HDR_13_MSK SHIFT0(0xffffffff) /* TCP_HDR_13 */ ++#define THDR29_LO_TCP_HDR_13_BASE BIT_0 ++ ++/* THDR29_HI 0x19EC TCP Segmentation Header Register 29 Hi */ ++#define THDR29_HI_TCP_HDR_14_MSK SHIFT0(0xffffffff) /* TCP_HDR_14 */ ++#define THDR29_HI_TCP_HDR_14_BASE BIT_0 ++ ++/* THDR30_LO 0x19F0 TCP Segmentation Header Register 30 Lo */ ++/* Bit(s) THDR30_LO_RSRV_15_0 reserved */ ++#define THDR30_LO_TCP_HDR_15_MSK SHIFT0(0xffff) /* TCP_HDR_15 */ ++#define THDR30_LO_TCP_HDR_15_BASE BIT_0 ++ ++/* CFG_VLAN_ET1 0x2000 VLAN Ethernet Type Configuration Register 1 */ ++/* Bit(s) CFG_VLAN_ET1_RSRV_23_0 reserved */ ++#define CFG_VLAN_ET1_MSK SHIFT0(0xff) /* Val */ ++#define CFG_VLAN_ET1_BASE BIT_0 ++ ++/* CFG_VLAN_ET0 0x2004 VLAN Ethernet Type Configuration Register 0 */ ++/* Bit(s) CFG_VLAN_ET0_RSRV_23_0 reserved */ ++#define CFG_VLAN_ET0_MSK SHIFT0(0xff) /* Val */ ++#define CFG_VLAN_ET0_BASE BIT_0 ++ ++/* CFG_MACSEC_ET1 0x2008 802.1AE Ethernet Type Configuration Register 1 */ ++/* Bit(s) CFG_MACSEC_ET1_RSRV_23_0 reserved */ ++#define CFG_MACSEC_ET1_MSK SHIFT0(0xff) /* Val */ ++#define CFG_MACSEC_ET1_BASE BIT_0 ++ ++/* CFG_MACSEC_ET0 0x200C 802.1AE Ethernet Type Configuration Register 0 */ ++/* Bit(s) CFG_MACSEC_ET0_RSRV_23_0 reserved */ ++#define CFG_MACSEC_ET0_MSK SHIFT0(0xff) /* Val */ ++#define CFG_MACSEC_ET0_BASE BIT_0 ++ ++/* CFG_TRAIL_SZ 0x2010 Trail Size Configuration Register */ ++/* Bit(s) CFG_TRAIL_SZ_RSRV_23_0 reserved */ ++#define CFG_TRAIL_SZ_MSK SHIFT0(0xff) /* Val */ ++#define CFG_TRAIL_SZ_BASE BIT_0 ++ ++/* CFG_DEFAULT_VLAN0 0x2014 Default VLAN Register 0 */ ++/* Bit(s) CFG_DEFAULT_VLAN0_RSRV_23_0 reserved */ ++#define CFG_DEFAULT_VLAN0_MSK SHIFT0(0xff) /* Val */ ++#define CFG_DEFAULT_VLAN0_BASE BIT_0 ++ ++/* CFG_DEFAULT_VLAN1 0x2018 Default VLAN Register 1 */ ++/* Bit(s) CFG_DEFAULT_VLAN1_RSRV_27_0 reserved */ ++#define CFG_DEFAULT_VLAN1_MSK SHIFT0(0xf) /* Val */ ++#define CFG_DEFAULT_VLAN1_BASE BIT_0 ++ ++/* CFG_MACSEC_SL_SZ 0x201C MACSec Size Configuration Register */ ++/* Bit(s) CFG_MACSEC_SL_SZ_RSRV_23_0 reserved */ ++#define CFG_MACSEC_SL_SZ_MSK SHIFT0(0xff) /* Val */ ++#define CFG_MACSEC_SL_SZ_BASE BIT_0 ++ ++/* CFG_MIN_PKT_LEN 0x2020 Minimum Packet Length Configuration Register */ ++/* Bit(s) CFG_MIN_PKT_LEN_RSRV_23_0 reserved */ ++#define CFG_MIN_PKT_LEN_MSK SHIFT0(0xff) /* Val */ ++#define CFG_MIN_PKT_LEN_BASE BIT_0 ++ ++/* SEC_CLK_RST 0x2024 MACSec Clock Reset Register */ ++/* Bit(s) SEC_CLK_RST_RSRV_27_0 reserved */ ++#define SEC_CLK_RST_GATE_DIS BIT_3 /* gate disable */ ++#define SEC_CLK_RST_INGRESS_RST BIT_2 /* ingress reset */ ++#define SEC_CLK_RST_EGRESS_RST BIT_1 /* egress reset */ ++#define SEC_CLK_RST_STAT_RST BIT_0 /* stat reset */ ++ ++/* EGR_KS_SELECT 0x2028 Egress Key Store Select Register */ ++/* Bit(s) EGR_KS_SELECT_RSRV_25_0 reserved */ ++#define EGR_KS_SELECT_CTXT_NUM_MSK SHIFT4(0x3) /* context number */ ++#define EGR_KS_SELECT_CTXT_NUM_BASE BIT_4 ++#define EGR_KS_SELECT_BYTE_NUM_MSK SHIFT0(0xf) /* byte number */ ++#define EGR_KS_SELECT_BYTE_NUM_BASE BIT_0 ++ ++/* EGR_KS_WRDATA 0x202C Egress Key Store Write Data Register */ ++/* Bit(s) EGR_KS_WRDATA_RSRV_23_0 reserved */ ++#define EGR_KS_WRDATA_MSK SHIFT0(0xff) /* Val */ ++#define EGR_KS_WRDATA_BASE BIT_0 ++ ++/* IGR_KS_SELECT 0x2030 Ingress Key Store Select Register */ ++/* Bit(s) IGR_KS_SELECT_RSRV_25_0 reserved */ ++#define IGR_KS_SELECT_CTXT_NUM_MSK SHIFT4(0x3) /* context number */ ++#define IGR_KS_SELECT_CTXT_NUM_BASE BIT_4 ++#define IGR_KS_SELECT_BYTE_NUM_MSK SHIFT0(0xf) /* byte number */ ++#define IGR_KS_SELECT_BYTE_NUM_BASE BIT_0 ++ ++/* IGR_KS_WRDATA 0x2034 Ingress Key Store Write Data Register */ ++/* Bit(s) IGR_KS_WRDATA_RSRV_23_0 reserved */ ++#define IGR_KS_WRDATA_MSK SHIFT0(0xff) /* Val */ ++#define IGR_KS_WRDATA_BASE BIT_0 ++ ++/* CFG_ELU_MC_HIGH0 0x2038 Multicast Match Register 0 */ ++/* Bit(s) CFG_ELU_MC_HIGH0_RSRV_27_0 reserved */ ++#define CFG_ELU_MC_HIGH0_MSK SHIFT0(0xf) /* Val */ ++#define CFG_ELU_MC_HIGH0_BASE BIT_0 ++ ++/* CFG_ELU_MC_HIGH1 0x203C Multicast Match Register 1 */ ++/* Bit(s) CFG_ELU_MC_HIGH1_RSRV_23_0 reserved */ ++#define CFG_ELU_MC_HIGH1_MSK SHIFT0(0xff) /* Val */ ++#define CFG_ELU_MC_HIGH1_BASE BIT_0 ++ ++/* CFG_ELU_MC_HIGH2 0x2040 Multicast Match Register 2 */ ++/* Bit(s) CFG_ELU_MC_HIGH2_RSRV_23_0 reserved */ ++#define CFG_ELU_MC_HIGH2_MSK SHIFT0(0xff) /* Val */ ++#define CFG_ELU_MC_HIGH2_BASE BIT_0 ++ ++/* CFG_ELU_MC_HIGH3 0x2044 Multicast Match Register 3 */ ++/* Bit(s) CFG_ELU_MC_HIGH3_RSRV_23_0 reserved */ ++#define CFG_ELU_MC_HIGH3_MSK SHIFT0(0xff) /* Val */ ++#define CFG_ELU_MC_HIGH3_BASE BIT_0 ++ ++/* CFG_ELU_MC_HIGH4 0x2048 Multicast Match Register 4 */ ++/* Bit(s) CFG_ELU_MC_HIGH4_RSRV_23_0 reserved */ ++#define CFG_ELU_MC_HIGH4_MSK SHIFT0(0xff) /* Val */ ++#define CFG_ELU_MC_HIGH4_BASE BIT_0 ++ ++/* CFG_ELU_MC_HIGH5 0x204C Multicast Match Register 5 */ ++/* Bit(s) CFG_ELU_MC_HIGH5_RSRV_23_0 reserved */ ++#define CFG_ELU_MC_HIGH5_MSK SHIFT0(0xff) /* Val */ ++#define CFG_ELU_MC_HIGH5_BASE BIT_0 ++ ++/* CFG_ELU_MC_LOW_MSK0 0x2050 Multicast Match Mask Register 0 */ ++/* Bit(s) CFG_ELU_MC_LOW_MSK0_RSRV_23_0 reserved */ ++#define CFG_ELU_MC_LOW_MSK0_MSK SHIFT0(0xff) /* Val */ ++#define CFG_ELU_MC_LOW_BASE0_BASE BIT_0 ++ ++/* CFG_ELU_MC_LOW_MSK1 0x2054 Multicast Match Mask Register 1 */ ++/* Bit(s) CFG_ELU_MC_LOW_MSK1_RSRV_23_0 reserved */ ++#define CFG_ELU_MC_LOW_MSK1_MSK SHIFT0(0xff) /* Val */ ++#define CFG_ELU_MC_LOW_BASE1_BASE BIT_0 ++ ++/* CFG_DEFAULT_PORT0 0x2058 Default Port Configuration Register 0 */ ++/* Bit(s) CFG_DEFAULT_PORT0_RSRV_23_0 reserved */ ++#define CFG_DEFAULT_PORT0_MSK SHIFT0(0xff) /* Val */ ++#define CFG_DEFAULT_PORT0_BASE BIT_0 ++ ++/* CFG_DEFAULT_PORT1 0x205C Default Port Configuration Register 1 */ ++/* Bit(s) CFG_DEFAULT_PORT1_RSRV_23_0 reserved */ ++#define CFG_DEFAULT_PORT1_MSK SHIFT0(0xff) /* Val */ ++#define CFG_DEFAULT_PORT1_BASE BIT_0 ++ ++/* CFG_SCB_PORT0 0x2060 SCB Port Configuration Register 0 */ ++/* Bit(s) CFG_SCB_PORT0_RSRV_23_0 reserved */ ++#define CFG_SCB_PORT0_MSK SHIFT0(0xff) /* Val */ ++#define CFG_SCB_PORT0_BASE BIT_0 ++ ++/* CFG_SCB_PORT1 0x2064 SCB Port Configuration Register 1 */ ++/* Bit(s) CFG_SCB_PORT1_RSRV_23_0 reserved */ ++#define CFG_SCB_PORT1_MSK SHIFT0(0xff) /* Val */ ++#define CFG_SCB_PORT1_BASE BIT_0 ++ ++/* CFG_AUTH_ADJUST 0x2068 Authentication Adjustment Register */ ++/* Bit(s) CFG_AUTH_ADJUST_RSRV_23_0 reserved */ ++#define CFG_AUTH_ADJUST_MSK SHIFT0(0xff) /* Val */ ++#define CFG_AUTH_ADJUST_BASE BIT_0 ++ ++/* CFG_ELU_GEN 0x206C ELU Default Configuration Register */ ++/* Bit(s) CFG_ELU_GEN_RSRV_27_0 reserved */ ++#define _MSK SHIFT2(0x3) /* min_bypass_len */ ++#define _BASE BIT_2 ++/* Bit(s) CFG_ELU_GEN_RSRV_1_0 reserved */ ++ ++/* CFG_ELUC_ADDR 0x2070 ELU Address Configuration Register */ ++/* Bit(s) CFG_ELUC_ADDR_RSRV_25_0 reserved */ ++#define CFG_ELUC_ADDR_CTXT_NUM_MSK SHIFT4(0x3) /* context number */ ++#define CFG_ELUC_ADDR_CTXT_NUM_BASE BIT_4 ++#define CFG_ELUC_ADDR_BYTE_NUM_MSK SHIFT0(0xf) /* byte number */ ++#define CFG_ELUC_ADDR_BYTE_NUM_BASE BIT_0 ++ ++/* CFG_ELUC_DATA 0x2074 ELU Context Data Configuration Register */ ++/* Bit(s) CFG_ELUC_DATA_RSRV_23_0 reserved */ ++#define CFG_ELUC_DATA_MSK SHIFT0(0xff) /* Val */ ++#define CFG_ELUC_DATA_BASE BIT_0 ++ ++/* CFG_ELUE_ADDR 0x2078 ELU Entry Configuration Register */ ++/* Bit(s) CFG_ELUE_ADDR_RSRV_23_0 reserved */ ++/* Lookup entry number */ ++#define CFG_ELUE_ADDR_LKUP_NUM_MSK SHIFT5(0x7) ++#define CFG_ELUE_ADDR_LKUP_NUM_BASE BIT_5 ++#define CFG_ELUE_ADDR_BYTE_NUM_MSK SHIFT0(0x1f) /* byte number */ ++#define CFG_ELUE_ADDR_BYTE_NUM_BASE BIT_0 ++ ++/* CFG_ELUE_DATA 0x207C ELU Lookup Entry Access Configuration Register */ ++/* Bit(s) CFG_ELUE_DATA_RSRV_23_0 reserved */ ++#define CFG_ELUE_DATA_MSK SHIFT0(0xff) /* Val */ ++#define CFG_ELUE_DATA_BASE BIT_0 ++ ++/* CFG_EPR_GEN 0x2080 General Egress Parser Configuration Register */ ++/* Bit(s) CFG_EPR_GEN_RSRV_28_0 reserved */ ++#define CFG_EPR_GEN_PARSE_VLAN BIT_2 /* Parse VLAN */ ++/* Bit(s) CFG_EPR_GEN_RSRV_ reserved */ ++#define CFG_EPR_GEN_PREAMBLE_PRESENT BIT_0 /* Preamble present */ ++ ++/* EGR_HR_SELECT 0x2084 Egress Write Select for H-Store Register */ ++/* Bit(s) EGR_HR_SELECT_RSRV_25_0 reserved */ ++#define EGR_HR_SELECT_KEY_NUM_MSK SHIFT4(0x3) /* Key number */ ++#define EGR_HR_SELECT_KEY_NUM_BASE BIT_4 ++#define EGR_HR_SELECT_BYTE_NUM_MSK SHIFT0(0xf) /* byte number */ ++#define EGR_HR_SELECT_BYTE_NUM_BASE BIT_0 ++ ++/* EGR_HR_WRDATA 0x2088 Egress Header Write Data Register */ ++/* Bit(s) EGR_HR_WRDATA_RSRV_23_0 reserved */ ++#define EGR_HR_WRDATA_MSK SHIFT0(0xff) /* Val */ ++#define EGR_HR_WRDATA_BASE BIT_0 ++ ++/* IGR_HR_SELECT 0x208C Ingress Write Select for H-Store Register */ ++/* Bit(s) IGR_HR_SELECT_RSRV_25_0 reserved */ ++#define IGR_HR_SELECT_KEY_NUM_MSK SHIFT4(0x3) /* Key number */ ++#define IGR_HR_SELECT_KEY_NUM_BASE BIT_4 ++#define IGR_HR_SELECT_BYTE_NUM_MSK SHIFT0(0xf) /* byte number */ ++#define IGR_HR_SELECT_BYTE_NUM_BASE BIT_0 ++ ++/* IGR_HR_WRDATA 0x2090 Ingress Header Write Data Register */ ++/* Bit(s) IGR_HR_WRDATA_RSRV_25_0 reserved */ ++#define IGR_HR_WRDATA_2_MSK SHIFT0(0xff) /* Val */ ++#define IGR_HR_WRDATA_2_BASE BIT_0 ++ ++/* CFG_IMPLICIT_SCI0 0x2098 Implicit SCI Register 0 */ ++/* Bit(s) CFG_IMPLICIT_SCI0_RSRV_23_0 reserved */ ++#define CFG_IMPLICIT_SCI0_MSK SHIFT0(0xff) /* Val */ ++#define CFG_IMPLICIT_SCI0_BASE BIT_0 ++ ++/* CFG_IMPLICIT_SCI1 0x209C Implicit SCI Register 1 */ ++/* Bit(s) CFG_IMPLICIT_SCI1_RSRV_23_0 reserved */ ++#define CFG_IMPLICIT_SCI1_MSK SHIFT0(0xff) /* Val */ ++#define CFG_IMPLICIT_SCI1_BASE BIT_0 ++ ++/* CFG_IMPLICIT_SCI2 0x20A0 Implicit SCI Register 2 */ ++/* Bit(s) CFG_IMPLICIT_SCI2_RSRV_23_0 reserved */ ++#define CFG_IMPLICIT_SCI2_MSK SHIFT0(0xff) /* Val */ ++#define CFG_IMPLICIT_SCI2_BASE BIT_0 ++ ++/* CFG_IMPLICIT_SCI3 0x20A4 Implicit SCI Register 3 */ ++/* Bit(s) CFG_IMPLICIT_SCI3_RSRV_23_0 reserved */ ++#define CFG_IMPLICIT_SCI3_MSK SHIFT0(0xff) /* Val */ ++#define CFG_IMPLICIT_SCI3_BASE BIT_0 ++ ++/* CFG_IMPLICIT_SCI4 0x20A8 Implicit SCI Register 4 */ ++/* Bit(s) CFG_IMPLICIT_SCI4_RSRV_23_0 reserved */ ++#define CFG_IMPLICIT_SCI4_MSK SHIFT0(0xff) /* Val */ ++#define CFG_IMPLICIT_SCI4_BASE BIT_0 ++ ++/* CFG_IMPLICIT_SCI5 0x20AC Implicit SCI Register 5 */ ++/* Bit(s) CFG_IMPLICIT_SCI5_RSRV_23_0 reserved */ ++#define CFG_IMPLICIT_SCI5_MSK SHIFT0(0xff) /* Val */ ++#define CFG_IMPLICIT_SCI5_BASE BIT_0 ++ ++/* CFG_IMPLICIT_SCI6 0x20B0 Implicit SCI Register 6 */ ++/* Bit(s) CFG_IMPLICIT_SCI6_RSRV_23_0 reserved */ ++#define CFG_IMPLICIT_SCI6_MSK SHIFT0(0xff) /* Val */ ++#define CFG_IMPLICIT_SCI6_BASE BIT_0 ++ ++/* CFG_IMPLICIT_SCI7 0x20B4 Implicit SCI Register 7 */ ++/* Bit(s) CFG_IMPLICIT_SCI7_RSRV_23_0 reserved */ ++#define CFG_IMPLICIT_SCI7_MSK SHIFT0(0xff) /* Val */ ++#define CFG_IMPLICIT_SCI7_BASE BIT_0 ++ ++/* CFG_REPLAY_WINDOW0 0x20B8 Replay Window Register 0 */ ++/* Bit(s) CFG_REPLAY_WINDOW0_RSRV_23_0 reserved */ ++#define CFG_REPLAY_WINDOW0_MSK SHIFT0(0xff) /* Val */ ++#define CFG_REPLAY_WINDOW0_BASE BIT_0 ++ ++/* CFG_REPLAY_WINDOW1 0x20BC Replay Window Register 1 */ ++/* Bit(s) CFG_REPLAY_WINDOW1_RSRV_23_0 reserved */ ++#define CFG_REPLAY_WINDOW1_MSK SHIFT0(0xff) /* Val */ ++#define CFG_REPLAY_WINDOW1_BASE BIT_0 ++ ++/* CFG_REPLAY_WINDOW2 0x20C0 Replay Window Register 2 */ ++/* Bit(s) CFG_REPLAY_WINDOW2_RSRV_23_0 reserved */ ++#define CFG_REPLAY_WINDOW2_MSK SHIFT0(0xff) /* Val */ ++#define CFG_REPLAY_WINDOW2_BASE BIT_0 ++ ++/* CFG_REPLAY_WINDOW3 0x20C4 Replay Window Register 3 */ ++/* Bit(s) CFG_REPLAY_WINDOW3_RSRV_23_0 reserved */ ++#define CFG_REPLAY_WINDOW3_MSK SHIFT0(0xff) /* Val */ ++#define CFG_REPLAY_WINDOW3_BASE BIT_0 ++ ++/* CFG_IPR_GEN 0x20C8 Ingress Primary Parser Register */ ++/* Bit(s) CFG_IPR_GEN_RSRV_28_0 reserved */ ++#define CFG_IPR_GEN_PREAMBLE_PRESENT BIT_2 /* Preamble present */ ++#define CFG_IPR_GEN_PARSE_VLAN BIT_1 /* Parse VLAN */ ++/* extract header field */ ++#define CFG_IPR_GEN_EXTRACT_HDR_FIELD BIT_0 ++ ++/* CFG_ISC_GEN 0x20CC Ingress Security Check Block Register */ ++/* Bit(s) CFG_ISC_GEN_RSRV_23_0 reserved */ ++/* Bit(s) CFG_ISC_GEN_RSRV_ reserved */ ++/* Bit(s) CFG_ISC_GEN_RSRV_ reserved */ ++/* Bit(s) CFG_ISC_GEN_RSRV_1_0 reserved */ ++/* replay_protect */ ++#define CFG_ISC_GEN_RPY_PROTECT BIT_2 ++/* validate_frames */ ++#define CFG_ISC_GEN_VALIDATE_FRAMES_MSK SHIFT0(0x3) ++#define CFG_ISC_GEN_VALIDATE_FRAMES_BASE BIT_0 ++ ++/* CFG_RPY_ADDR 0x20D0 Replay Protect Table Access Register */ ++/* Bit(s) CFG_RPY_ADDR_RSRV_27_0 reserved */ ++/* Replay table entry */ ++#define CFG_RPY_ADDR_RPY_TAB_NUM_MSK SHIFT2(0x3) ++#define CFG_RPY_ADDR_RPY_TAB_NUM_BASE BIT_2 ++#define CFG_RPY_ADDR_BYTE_NUM_MSK SHIFT0(0x3) /* byte number */ ++#define CFG_RPY_ADDR_BYTE_NUM_BASE BIT_0 ++ ++/* CFG_RPY_DATA 0x20D4 ELU Context Data Register */ ++/* Bit(s) CFG_RPY_DATA_RSRV_23_0 reserved */ ++#define CFG_RPY_DATA_MSK SHIFT0(0xff) /* val */ ++#define CFG_RPY_DATA_BASE BIT_0 ++ ++/* CFG_ILUT_ADDR 0x20E0 Ingress Lookup Table Access Address ++ * Configuration Register ++ */ ++/* Bit(s) CFG_ILUT_ADDR_RSRV_23_0 reserved */ ++/* Lookup table entry */ ++#define CFG_ILUT_ADDR_LOOKUP_NUM_MSK SHIFT5(0x7) ++#define CFG_ILUT_ADDR_LOOKUP_NUM_BASE BIT_5 ++#define CFG_ILUT_ADDR_BYTE_NUM_MSK SHIFT0(0x1f) /* byte number */ ++#define CFG_ILUT_ADDR_BYTE_NUM_BASE BIT_0 ++ ++/* CFG_ILUT_DATA 0x20E4 ILU Table Data Register */ ++/* Bit(s) CFG_ILUT_DATA_RSRV_23_0 reserved */ ++#define CFG_ILUT_DATA_MSK SHIFT0(0xff) /* val */ ++#define CFG_ILUT_DATA_BASE BIT_0 ++ ++/* STAT_ADDR 0x20E8 Statistic Register Address */ ++/* Bit(s) STAT_ADDR_RSRV_25_0 reserved */ ++#define STAT_ADDR_MSK SHIFT0(0x3f) /* val */ ++#define STAT_ADDR_BASE BIT_0 ++ ++/* STAT_DATA0 0x20EC Statistic Data Register 0 */ ++/* Bit(s) STAT_DATA0_RSRV_23_0 reserved */ ++#define STAT_DATA0_MSK SHIFT0(0xff) /* val */ ++#define STAT_DATA0_BASE BIT_0 ++ ++/* STAT_DATA1 0x20F0 Statistic Data Register 1 */ ++/* Bit(s) STAT_DATA1_RSRV_23_0 reserved */ ++#define STAT_DATA1_MSK SHIFT0(0xff) /* val */ ++#define STAT_DATA1_BASE BIT_0 ++ ++/* STAT_DATA2 0x20F4 Statistic Data Register 2 */ ++/* Bit(s) STAT_DATA2_RSRV_23_0 reserved */ ++#define STAT_DATA2_MSK SHIFT0(0xff) /* val */ ++#define STAT_DATA2_BASE BIT_0 ++ ++/* CFG_OVER_LEN1 0x20F8 Over-Length Configuration Register 1 */ ++/* Bit(s) CFG_OVER_LEN1_RSRV_23_0 reserved */ ++#define CFG_OVER_LEN1_MSK SHIFT0(0xff) /* val */ ++#define CFG_OVER_LEN1_BASE BIT_0 ++ ++/* */ ++/* Bit(s) CNT_TX_ERR_RSRV_23_0 reserved */ ++#define CNT_TX_ERR_MSK SHIFT0(0xff) /* err_cnt */ ++#define CNT_TX_ERR_BASE BIT_0 ++ ++/* CFG_IPAR_HYST 0x2104 Ingress Parse FIFO Hystersis */ ++/* Bit(s) CFG_IPAR_HYST_RSRV_27_0 reserved */ ++#define CFG_IPAR_HYST_MSK SHIFT0(0xf) /* ipar_hyst */ ++#define CFG_IPAR_HYST_BASE BIT_0 ++ ++/* CFG_EPAR_HYST 0x2108 Egress Parse FIFO Hystersis */ ++/* Bit(s) CFG_EPAR_HYST_RSRV_27_0 reserved */ ++#define CFG_EPAR_HYST_MSK SHIFT0(0xf) /* epar_hyst */ ++#define CFG_EPAR_HYST_BASE BIT_0 ++ ++/* RE_TRF_TCTL 0x2200 MACSec Retransmit FIFO Control */ ++/* Bit(s) RE_TRF_TCTL_RSRV_27_0 reserved */ ++#define RE_TRF_TCTL_RETRAN_OP_ON BIT_3 /* Operational On */ ++#define RE_TRF_TCTL_RETRAN_OP_OFF BIT_2 /* Operational Off */ ++#define RE_TRF_TCTL_RETRAN_RST_CLR BIT_1 /* Reset Clear */ ++#define RE_TRF_TCTL_RETRAN_RST_SET BIT_0 /* Reset Set */ ++ ++/* RE_TRF_PCNT 0x2204 Retransmit FIFO Packet Counter */ ++/* Bit(s) RE_TRF_PCNT_RSRV_22_0 reserved */ ++#define RE_TRF_PCNT_MSK SHIFT0(0xff) /* Packet Counter */ ++#define RE_TRF_PCNT_BASE BIT_0 ++ ++/* RE_TRF_TTH 0x2208 Retransmit FIFO Transmit Start Threshold */ ++/* Bit(s) RE_TRF_TTH_RSRV_26_0 reserved */ ++/* Transmit Start Threshold */ ++#define RE_TRF_TTH_MSK SHIFT0(0x1f) ++#define RE_TRF_TTH_BASE BIT_0 ++ ++/* RE_TRF_WPTR 0x2210 Retransmit FIFO Write Pointer Register */ ++/* Bit(s) RE_TRF_WPTR_RSRV_26_0 reserved */ ++#define RE_TRF_WPTR_MSK SHIFT0(0x1f) /* Write Pointer */ ++#define RE_TRF_WPTR_BASE BIT_0 ++ ++/* RE_TRF_WLEV 0x2218 Retransmit FIFO Write Level Register */ ++/* Bit(s) RE_TRF_WLEV_RSRV_26_0 reserved */ ++#define RE_TRF_WLEV_MSK SHIFT0(0x1f) /* Write Level */ ++#define RE_TRF_WLEV_BASE BIT_0 ++ ++/* RE_TRF_RPTR 0x2220 Retransmit FIFO Read Pointer Register */ ++/* Bit(s) RE_TRF_RPTR_RSRV_26_0 reserved */ ++#define RE_TRF_RPTR_MSK SHIFT0(0x1f) /* Read Pointer */ ++#define RE_TRF_RPTR_BASE BIT_0 ++ ++/* RE_TRF_RES_PTR 0x2224 Transmit FIFO Restart Pointer Register */ ++/* Bit(s) RE_TRF_RES_PTR_RSRV_26_0 reserved */ ++#define RE_TRF_RES_PTR_MSK SHIFT0(0x1f) /* Restart Pointer */ ++#define RE_TRF_RES_PTR_BASE BIT_0 ++ ++/* RE_TRF_RLEV 0x2228 Retransmit FIFO Read Level Register */ ++/* Bit(s) RE_TRF_RLEV_RSRV_26_0 reserved */ ++#define RE_TRF_RLEV_MSK SHIFT0(0x1f) /* Read Level */ ++#define RE_TRF_RLEV_BASE BIT_0 ++ ++/* RE_TRF_RSPTR 0x222c Retransmit FIFO Read Shadow Level Register */ ++/* Bit(s) RE_TRF_RSPTR_RSRV_26_0 reserved */ ++#define RE_TRF_RSPTR_MSK SHIFT0(0x1f) /* Read Shadow Level */ ++#define RE_TRF_RSPTR_BASE BIT_0 ++ ++ ++ ++/* -------------------- */ ++ ++ ++ ++/* ++ * ++ * THE BASE ADDRESSES ++ * ++ */ ++ ++/* ++ * ++ * THE REGISTER DEFINES ++ * ++ */ ++#define GPSR 0x2800 /* 16 bit General Purpose Status Register */ ++#define GPCR 0x2804 /* 16 bit General Purpose Control Register */ ++#define TCR 0x2808 /* 16 bit Transmit Control Register */ ++#define RCR 0x280C /* 16 bit Receive Control Register */ ++#define TFCR 0x2810 /* 16 bit Transmit Flow Control Register */ ++#define TPR 0x2814 /* 16 bit Transmit Parameter Register */ ++#define SMR 0x2818 /* 16 bit Serial Mode Register */ ++#define SAL1 0x281C /* 16 bit Source Address Low */ ++#define SAM1 0x2820 /* 16 bit Source Address Middle */ ++#define SA1H 0x2824 /* 16 bit Source Address High */ ++#define SAL2 0x2828 /* 16 bit Source Address Low */ ++#define SAM2 0x282C /* 16 bit Source Address Middle */ ++#define SAH2 0x2830 /* 16 bit Source Address High */ ++#define MCAH1 0x2834 /* 16 bit Multicast Address Hash Register 1 */ ++#define MCAH2 0x2838 /* 16 bit Multicast Address Hash Register 2 */ ++#define MCAH3 0x283C /* 16 bit Multicast Address Hash Register 3 */ ++#define MCAH4 0x2840 /* 16 bit Multicast Address Hash Register 4 */ ++#define TIR 0x2844 /* 16 bit Transmit Interrupt Register */ ++#define RIR 0x2848 /* 16 bit Receive Interrupt Register */ ++#define TIR_RIR 0x284C /* 16 bit Transmit and Receive Interrupt Register */ ++#define TIMR 0x2850 /* 16 bit Transmit Interrupt Mask Register */ ++#define RIMR 0x2854 /* 16 bit Receive Interrupt Mask Register */ ++#define TIMR_RIMR 0x2858 /* 16 bit Transmit and Receive Interrupt Mask ++ * Register ++ */ ++#define SMICR 0x2880 /* 16 bit SMI Control Register */ ++#define SMIDR 0x2884 /* 16 bit SMI Data Register */ ++ ++/* ++ * ++ * THE BIT DEFINES ++ * ++ */ ++/* GPSR 0x2800 General Purpose Status Register */ ++#define GPSR_SPEED BIT_15S /* Speed */ ++#define GPSR_DUPLEX BIT_14S /* Duplex */ ++#define GPSR_FCTLTX BIT_13S /* FctlTx */ ++#define GPSR_LINK BIT_12S /* Link */ ++#define GPSR_PAUSE BIT_11S /* Pause */ ++#define GPSR_TXINPROG BIT_10S /* TxinProg */ ++#define GPSR_EXCESSCOL BIT_9S /* ExcessCol */ ++#define GPSR_LATECOL BIT_8S /* LateCol */ ++#define GPSR_TX_EN_STATUS BIT_7S /* TxEnStatus */ ++#define GPSR_RX_EN_STATUS BIT_6S /* RxEnStatus */ ++#define GPSR_MIIPHYSTC BIT_5S /* MIIPhySTC */ ++#define GPSR_GIGSPEED BIT_4S /* GigSpeed */ ++#define GPSR_PARTITION BIT_3S /* Partition */ ++#define GPSR_FCTLRX BIT_2S /* FctlRx */ ++#define GPSR_PROMISC_MODE BIT_1S /* Promiscuous Mode */ ++/* Bit(s) GPSR_RSRV_ reserved */ ++ ++/* GPCR 0x2804 General Purpose Control Register */ ++/* Bit(s) GPCR_RSRV_1_0 reserved */ ++#define GPCR_FCTLTX BIT_13S /* FCTLTX */ ++#define GPCR_TXEN BIT_12S /* TxEn */ ++#define GPCR_RXEN BIT_11S /* RxEn */ ++/* Bit(s) GPCR_RSRV_ reserved */ ++#define GPCR_LPBK BIT_9S /* LPBK */ ++#define GPCR_PAR BIT_8S /* PAR */ ++#define GPCR_GIGSPEED BIT_7S /* GigSpeed */ ++#define GPCR_FLP BIT_6S /* FLP */ ++#define GPCR_HD BIT_5S /* HD */ ++#define GPCR_FCTLRX BIT_4S /* FCTLRX */ ++#define GPCR_SPEED BIT_3S /* Speed */ ++#define GPCR_DPLYXEN BIT_2S /* DPLYXen */ ++#define GPCR_FCTLEN BIT_1S /* FCTLen */ ++#define GPCR_SPEEDEN BIT_0S /* SpeedEn */ ++ ++/* TCR 0x2808 Transmit Control Register */ ++#define TCR_FJ BIT_15S /* FJ */ ++#define TCR_CRCD BIT_14S /* CRCD */ ++#define TCR_PADD BIT_13S /* PADD */ ++#define TCR_COLTH_MSK SHIFT10(0x7S) /* ColTh */ ++#define TCR_COLTH_BASE BIT_10S ++#define TCR_HD_LPBK_DIS BIT_9S /* HALF DUPLEX LPBK DISABLE */ ++#define TCR_JAM_FIX_EN BIT_8S /* JAM UNH FIX_EN */ ++#define TCR_PADD_PAT_MSK SHIFT0(0xffS) /* Padding Pattern */ ++#define TCR_PADD_PAT_BASE BIT_0S ++ ++/* RCR 0x280C Receive Control Register */ ++#define RCR_UNFIEN BIT_15S /* UnFiEn */ ++#define RCR_MUFIEN BIT_14S /* MuFiEn */ ++#define RCR_CRCR BIT_13S /* CRCR */ ++/* Bit(s) RCR_RSRV_ reserved */ ++/* Bit(s) RCR_RSRV_11_0 reserved */ ++ ++/* TFCR 0x2810 Transmit Flow Control Register */ ++#define TFCR_PAUSETIME_MSK SHIFT0(0xffffS) /* PauseTime */ ++#define TFCR_PAUSETIME_BASE BIT_0S ++ ++/* TPR 0x2814 Transmit Parameter Register */ ++#define TPR_JAM_LEN_MSK SHIFT14(0x3S) /* JAM_Len */ ++#define TPR_JAM_LEN_BASE BIT_14S ++#define TPR_JAM_IPG_MSK SHIFT9(0x1fS) /* JAM_IPG */ ++#define TPR_JAM_IPG_BASE BIT_9S ++#define TPR_IPGJAM2DATA_MSK SHIFT4(0x1fS) /* IPGJAM2Data */ ++#define TPR_IPGJAM2DATA_BASE BIT_4S ++#define TPR_BACK_OFF_LIMIT_MSK SHIFT0(0xfS) /* Back-off Limit */ ++#define TPR_BACK_OFF_LIMIT_BASE BIT_0S ++ ++/* SMR 0x2818 Serial Mode Register */ ++#define SMR_DATA_BLINDER_MSK SHIFT11(0x1fS) /* Data Blinder */ ++#define SMR_DATA_BLINDER_BASE BIT_11S ++#define SMR_LIMIT4 BIT_10S /* Limit4 */ ++#define SMR_VLAN_EN_MFL_MSK SHIFT8(0x3S) /* Vlan_en, MFL */ ++#define SMR_VLAN_EN_MFL_BASE BIT_8S ++/* Bit(s) SMR_RSRV_2_0 reserved */ ++#define SMR_IPGDATA_MSK SHIFT0(0x1fS) /* IPGData */ ++#define SMR_IPGDATA_BASE BIT_0S ++ ++/* SAL1 0x281C Source Address Low */ ++#define SAL1_SA1_MSK SHIFT0(0xffffS) /* SA1 [15:0] */ ++#define SAL1_SA1_BASE BIT_0S ++ ++/* SAM1 0x2820 Source Address Middle */ ++#define SAM1_SA1_MSK SHIFT0(0xffffS) /* SA1 [31:16] */ ++#define SAM1_SA1_BASE BIT_0S ++ ++/* SA1H 0x2824 Source Address High */ ++#define SA1H_SA1_MSK SHIFT0(0xffffS) /* SA1 [47:32] */ ++#define SA1H_SA1_BASE BIT_0S ++ ++/* SAL2 0x2828 Source Address Low */ ++#define SAL2_SA2_MSK SHIFT0(0xffffS) /* SA2 [15:0] */ ++#define SAL2_SA2_BASE BIT_0S ++ ++/* SAM2 0x282C Source Address Middle */ ++#define SAM2_SA2_MSK SHIFT0(0xffffS) /* SA2 [31:16] */ ++#define SAM2_SA2_BASE BIT_0S ++ ++/* SAH2 0x2830 Source Address High */ ++#define SAH2_SA2_MSK SHIFT0(0xffffS) /* SA 2[47:32] */ ++#define SAH2_SA2_BASE BIT_0S ++ ++/* MCAH1 0x2834 Multicast Address Hash Register 1 */ ++#define MCAH1_MCAH1_MSK SHIFT0(0xffffS) /* MCAH1[15:0] */ ++#define MCAH1_MCAH1_BASE BIT_0S ++ ++/* MCAH2 0x2838 Multicast Address Hash Register 2 */ ++#define MCAH2_MCAH2_MSK SHIFT0(0xffffS) /* MCAH2[15:0] */ ++#define MCAH2_MCAH2_BASE BIT_0S ++ ++/* MCAH3 0x283C Multicast Address Hash Register 3 */ ++#define MCAH3__MCAH3_MSK SHIFT0(0xffffS) /* MCAH3[15:0] */ ++#define MCAH3__MCAH3_BASE BIT_0S ++ ++/* MCAH4 0x2840 Multicast Address Hash Register 4 */ ++#define MCAH4_MCAH4_MSK SHIFT0(0xffffS) /* MCAH4[15:0] */ ++#define MCAH4_MCAH4_BASE BIT_0S ++ ++/* TIR 0x2844 Transmit Interrupt Register */ ++#define TIR_TIR_MSK SHIFT0(0xffffS) /* TIR[15:0] */ ++#define TIR_TIR_BASE BIT_0S ++ ++/* RIR 0x2848 Receive Interrupt Register */ ++#define RIR_RIR_MSK SHIFT0(0xffffS) /* RIR[15:0] */ ++#define RIR_RIR_BASE BIT_0S ++ ++/* TIR_RIR 0x284C Transmit and Receive Interrupt Register */ ++#define TIR_RIR_TIR_RIR_MSK SHIFT0(0xffffS) /* TIR_RIR[15:0] */ ++#define TIR_RIR_TIR_RIR_BASE BIT_0S ++ ++/* TIMR 0x2850 Transmit Interrupt Mask Register */ ++#define TIMR_TIMR_MSK SHIFT0(0xffffS) /* TIMR[15:0] */ ++#define TIMR_TIMR_BASE BIT_0S ++ ++/* RIMR 0x2854 Receive Interrupt Mask Register */ ++#define RIMR_RIMR_MSK SHIFT0(0xffffS) /* RIMR[15:0] */ ++#define RIMR_RIMR_BASE BIT_0S ++ ++/* TIMR_RIMR 0x2858 Transmit and Receive Interrupt Mask Register */ ++#define TIMR_RIMR_TIMR_RIMR_MSK SHIFT0(0xffffS) /* TIMR_RIMR[15:0] */ ++#define TIMR_RIMR_TIMR_RIMR_BASE BIT_0S ++ ++/* SMICR 0x2880 SMI Control Register */ ++#define SMICR_PHYAD_MSK SHIFT11(0x1fS) /* PhyAd */ ++#define SMICR_PHYAD_BASE BIT_11S ++#define SMICR_REGAD_MSK SHIFT6(0x1fS) /* RegAd */ ++#define SMICR_REGAD_BASE BIT_6S ++#define SMICR_OPCODE BIT_5S /* OpCode */ ++#define SMICR_READVALID BIT_4S /* ReadValid */ ++#define SMICR_BUSY BIT_3S /* Busy */ ++/* Bit(s) SMICR_RSRV_2_0 reserved */ ++ ++/* SMIDR 0x2884 SMI Data Register */ ++#define SMIDR_DATA_MSK SHIFT0(0xffffS) /* Data */ ++#define SMIDR_DATA_BASE BIT_0S ++ ++ ++ ++/* -------------------- */ ++ ++ ++#endif /* __INC_SKY3HW_H */ +diff -ruN linux/drivers/net/sk98lin/h/skaddr.h linux-new/drivers/net/sk98lin/h/skaddr.h +--- linux/drivers/net/sk98lin/h/skaddr.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skaddr.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,14 +2,15 @@ + * + * Name: skaddr.h + * Project: Gigabit Ethernet Adapters, ADDR-Modul +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Header file for Address Management (MC, UC, Prom). + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. + * +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -236,6 +238,18 @@ + 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, +@@ -243,11 +257,41 @@ + 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 SK_U32 SkXmacMcHash( ++ unsigned char *pMc); ++ ++extern int SkAddrGmacMcAdd( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ SK_U32 PortNumber, ++ SK_MAC_ADDR *pMc, ++ int Flags); ++ ++extern SK_U32 SkGmacMcHash( ++ unsigned char *pMc); ++ + 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, +@@ -261,6 +305,18 @@ + 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, +diff -ruN linux/drivers/net/sk98lin/h/skcsum.h linux-new/drivers/net/sk98lin/h/skcsum.h +--- linux/drivers/net/sk98lin/h/skcsum.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skcsum.h 2007-01-24 13:58:33.000000000 +0100 +@@ -2,14 +2,15 @@ + * + * Name: skcsum.h + * Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx) +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Store/verify Internet checksum in send/receive packets. + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2001 SysKonnect GmbH. + * + * This program is free software; you can redistribute it and/or modify +@@ -18,6 +19,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -157,9 +159,7 @@ + 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]; +@@ -203,6 +203,12 @@ + 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, +diff -ruN linux/drivers/net/sk98lin/h/skdebug.h linux-new/drivers/net/sk98lin/h/skdebug.h +--- linux/drivers/net/sk98lin/h/skdebug.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skdebug.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,23 +2,24 @@ + * + * Name: skdebug.h + * Project: Gigabit Ethernet Adapters, Common Modules +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: SK specific DEBUG support + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2005 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. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -28,9 +29,9 @@ + #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 ; \ ++ if ( ((comp) & SK_DBG_CHKMOD(pAC)) && \ ++ ((cat) & SK_DBG_CHKCAT(pAC)) ) { \ ++ SK_DBG_PRINTF arg; \ + } + #endif + #else +@@ -58,6 +59,14 @@ + #define SK_DBGMOD_ADDR 0x00000080L /* ADDR module */ + #define SK_DBGMOD_PECP 0x00000100L /* PECP module */ + #define SK_DBGMOD_POWM 0x00000200L /* Power Management module */ ++#ifdef SK_ASF ++#define SK_DBGMOD_ASF 0x00000400L /* ASF module */ ++#endif ++#ifdef SK_LBFO ++#define SK_DBGMOD_LACP 0x00000800L /* link aggregation control protocol */ ++#define SK_DBGMOD_FD 0x00001000L /* frame distributor (link aggregation) */ ++#endif /* SK_LBFO */ ++#define SK_DBGMOD_MACS 0x00002000L /* MACSec module */ + + /* Debug events */ + +diff -ruN linux/drivers/net/sk98lin/h/skdrv1st.h linux-new/drivers/net/sk98lin/h/skdrv1st.h +--- linux/drivers/net/sk98lin/h/skdrv1st.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skdrv1st.h 2007-01-24 13:58:37.000000000 +0100 +@@ -2,8 +2,8 @@ + * + * Name: skdrv1st.h + * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: First header file for driver and all other modules + * + ******************************************************************************/ +@@ -11,7 +11,7 @@ + /****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2005 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 +@@ -22,23 +22,12 @@ + * + ******************************************************************************/ + +-/****************************************************************************** +- * +- * 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 ++ + typedef struct s_AC SK_AC; + + /* Set card versions */ +@@ -55,6 +44,9 @@ + + #define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6)) + ++#define SK_STRNCMP(s1,s2,len) strncmp(s1,s2,len) ++#define SK_STRCPY(dest,src) strcpy(dest,src) ++ + #include + #include + #include +@@ -63,10 +55,9 @@ + #include + #include + #include +-#include + #include ++#include + #include +-#include + #include + #include + #include +@@ -76,11 +67,7 @@ + #include + + #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 ++#define SkCsCalculateChecksum(p,l) (~csum_fold(csum_partial(p, l, 0))) + + #include "h/sktypes.h" + #include "h/skerror.h" +@@ -88,10 +75,15 @@ + #include "h/lm80.h" + #include "h/xmac_ii.h" + ++#ifndef SK_BMU_RX_WM_PEX ++#define SK_BMU_RX_WM_PEX 0x80 ++#endif ++ + #ifdef __LITTLE_ENDIAN + #define SK_LITTLE_ENDIAN + #else + #define SK_BIG_ENDIAN ++#define SK_USE_REV_DESC + #endif + + #define SK_NET_DEVICE net_device +@@ -107,7 +99,7 @@ + #define SK_MAX_MACS 2 + #define SK_MAX_NETS 2 + +-#define SK_IOC char __iomem * ++#define SK_IOC char* + + typedef struct s_DrvRlmtMbuf SK_MBUF; + +@@ -186,3 +178,8 @@ + + #endif + ++/******************************************************************************* ++ * ++ * End of file ++ * ++ ******************************************************************************/ +diff -ruN linux/drivers/net/sk98lin/h/skdrv2nd.h linux-new/drivers/net/sk98lin/h/skdrv2nd.h +--- linux/drivers/net/sk98lin/h/skdrv2nd.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skdrv2nd.h 2007-01-24 14:03:43.000000000 +0100 +@@ -1,17 +1,17 @@ + /****************************************************************************** + * +- * Name: skdrv2nd.h +- * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ +- * Purpose: Second header file for driver and all other modules ++ * Name: skdrv2nd.h ++ * Project: GEnesis, PCI Gigabit Ethernet Adapter ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Second header file for driver and all other modules + * + ******************************************************************************/ + + /****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2005 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 +@@ -42,114 +42,209 @@ + #include "h/skqueue.h" + #include "h/skgehwt.h" + #include "h/sktimer.h" +-#include "h/ski2c.h" ++#include "h/sktwsi.h" + #include "h/skgepnmi.h" + #include "h/skvpd.h" + #include "h/skgehw.h" ++#include "h/sky2le.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" ++#include "h/mvyexhw.h" + ++/* Defines for the poll cotroller */ ++#if !defined(SK_NETDUMP_POLL) ++#define SK_NETDUMP_POLL ++#endif + +-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 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); ++#if defined(SK_NETDUMP_POLL) ++#if defined(HAVE_POLL_CONTROLLER) ++#define SK_POLL_CONTROLLER ++#define CONFIG_SK98LIN_NAPI ++#elif defined(CONFIG_NET_POLL_CONTROLLER) ++#define SK_POLL_CONTROLLER ++#define CONFIG_SK98LIN_NAPI ++#endif + #endif + ++ ++/****************************************************************************** ++ * ++ * Generic driver defines ++ * ++ ******************************************************************************/ ++ ++#define USE_TIST_FOR_RESET /* Use timestamp for reset */ ++#define Y2_RECOVERY /* use specific recovery yukon2 functions */ ++#define Y2_LE_CHECK /* activate check for LE order */ ++#define Y2_SYNC_CHECK /* activate check for receiver in sync */ ++#define SK_YUKON2 /* Enable Yukon2 dual net support */ ++#define USE_SK_TX_CHECKSUM /* use the tx hw checksum driver functionality */ ++#define USE_SK_RX_CHECKSUM /* use the rx hw checksum driver functionality */ ++#define USE_SK_TSO_FEATURE /* use TCP segmentation offload if possible */ ++#define SK_COPY_THRESHOLD 50 /* threshold for copying small RX frames; ++ * 0 avoids copying, 9001 copies all */ ++#define SK_MAX_CARD_PARAM 16 /* number of adapters that can be configured via ++ * command line params */ ++//#define USE_TX_COMPLETE /* use of a transmit complete interrupt */ ++#define Y2_RX_CHECK /* RX Check timestamp */ ++ ++#define SK_REL_SPIN_LOCK(IoC) ++#define SK_ACQ_SPIN_LOCK(IoC) ++ ++/* ++ * 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",} ++ ++#ifdef Y2_RECOVERY ++#define CHECK_TRANSMIT_TIMEOUT ++#define Y2_RESYNC_WATERMARK 1000000L ++#endif ++ ++ ++/****************************************************************************** ++ * ++ * Generic ISR defines ++ * ++ ******************************************************************************/ ++ ++#define SkIsrRetVar irqreturn_t ++#define SkIsrRetNone IRQ_NONE ++#define SkIsrRetHandled IRQ_HANDLED ++ ++#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) ++ ++/****************************************************************************** ++ * ++ * Global function prototypes ++ * ++ ******************************************************************************/ ++ ++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); ++extern int SkDrvEnterDiagMode(SK_AC *pAc); ++extern int SkDrvLeaveDiagMode(SK_AC *pAc); ++ ++/****************************************************************************** ++ * ++ * Linux specific RLMT buffer structure (SK_MBUF typedef in skdrv1st)! ++ * ++ ******************************************************************************/ ++ + 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. */ ++ 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 */ ++ SK_RLMT_MBUF Rlmt; /* Private part for RLMT. */ ++#endif ++ struct sk_buff *pOs; /* Pointer to message block */ + }; + ++/****************************************************************************** ++ * ++ * Linux specific TIME defines ++ * ++ ******************************************************************************/ + +-/* +- * 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)) ++#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t)*100)/(SK_TICKS_PER_SEC)) + #endif + +-/* +- * New SkOsGetTime +- */ + #define SkOsGetTimeCurrent(pAC, pUsec) {\ ++ static struct timeval prev_t; \ + struct timeval t;\ + do_gettimeofday(&t);\ +- *pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\ ++ if (prev_t.tv_sec == t.tv_sec) { \ ++ if (prev_t.tv_usec > t.tv_usec) { \ ++ t.tv_usec = prev_t.tv_usec; \ ++ } else { \ ++ prev_t.tv_usec = t.tv_usec; \ ++ } \ ++ } else { \ ++ prev_t = t; \ ++ } \ ++ *pUsec = ((t.tv_sec*100L)+(t.tv_usec/10000));\ + } + ++/****************************************************************************** ++ * ++ * Linux specific IOCTL defines and typedefs ++ * ++ ******************************************************************************/ + +-/* +- * 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; ++#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; + }; + ++/****************************************************************************** ++ * ++ * Generic sizes and length definitions ++ * ++ ******************************************************************************/ + +-/* +- * 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 ++#define TX_RING_SIZE (24*1024) /* GEnesis/Yukon */ ++#define RX_RING_SIZE (24*1024) /* GEnesis/Yukon */ ++#define RX_MAX_NBR_BUFFERS 128 /* Yukon-EC/-II */ ++#define TX_MAX_NBR_BUFFERS 128 /* Yukon-EC/-II */ ++#define MAXIMUM_LOW_ADDRESS 0xFFFFFFFF /* Max. low address */ ++ ++#define ETH_BUF_SIZE 1560 /* multiples of 8 bytes */ ++#define ETH_MAX_MTU 1514 ++#define ETH_MIN_MTU 60 ++#define ETH_MULTICAST_BIT 0x01 ++#define SK_JUMBO_MTU 9000 ++ ++#define TX_PRIO_LOW 0 /* asynchronous queue */ ++#define TX_PRIO_HIGH 1 /* synchronous queue */ ++#define DESCR_ALIGN 64 /* alignment of Rx/Tx descriptors */ + +-/* +- * alignment of rx/tx descriptors +- */ +-#define DESCR_ALIGN 64 ++/****************************************************************************** ++ * ++ * PNMI related definitions ++ * ++ ******************************************************************************/ + +-/* +- * 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 +@@ -158,20 +253,16 @@ + #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 been finalized +-*/ +-#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. +-*/ ++/****************************************************************************** ++ * ++ * Various offsets and sizes ++ * ++ ******************************************************************************/ ++ ++#define SK_DRV_MODERATION_TIMER 1 /* id */ ++#define SK_DRV_MODERATION_TIMER_LENGTH 1 /* 1 second */ ++ + #define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6 + #define C_LEN_ETHERMAC_HEADER_SRC_ADDR 6 + #define C_LEN_ETHERMAC_HEADER_LENTYPE 2 +@@ -197,112 +288,454 @@ + #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 *****************************************************/ ++/****************************************************************************** ++ * ++ * Tx and Rx descriptor definitions ++ * ++ ******************************************************************************/ + + 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 */ ++ 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 */ ++ 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 *********************/ ++/****************************************************************************** ++ * ++ * Generic Yukon-II defines ++ * ++ ******************************************************************************/ ++ ++ ++/* Number of Status LE which will be allocated at init time. */ ++#define NUMBER_OF_ST_LE 4096L + +-#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)) ++/* Number of revceive LE which will be allocated at init time. */ ++#define NUMBER_OF_RX_LE 512 + +-#define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */ ++/* Number of transmit LE which will be allocated at init time. */ ++#define NUMBER_OF_TX_LE 1024L ++ ++#define LE_SIZE sizeof(SK_HWLE) ++#define MAX_NUM_FRAGS (MAX_SKB_FRAGS + 1) ++#define MIN_LEN_OF_LE_TAB 128 ++#define MAX_UNUSED_RX_LE_WORKING 8 ++#ifdef MAX_FRAG_OVERHEAD ++#undef MAX_FRAG_OVERHEAD ++#define MAX_FRAG_OVERHEAD 4 ++#endif ++// as we have a maximum of 16 physical fragments, ++// maximum 1 ADDR64 per physical fragment ++// maximum 4 LEs for VLAN, Csum, LargeSend, Packet ++#define MIN_LE_FREE_REQUIRED ((16*2) + 4) ++#define IS_GMAC(pAc) (!pAc->GIni.GIGenesis) ++#ifdef USE_SYNC_TX_QUEUE ++#define TXS_MAX_LE 256 ++#else /* !USE_SYNC_TX_QUEUE */ ++#define TXS_MAX_LE 0 ++#endif ++ ++#define ETHER_MAC_HDR_LEN (6+6+2) // MAC SRC ADDR, MAC DST ADDR, TYPE ++#define IP_HDR_LEN 20 ++#define TCP_CSUM_OFFS 0x10 ++#define UDP_CSUM_OFFS 0x06 ++ ++#if (defined (Y2_RECOVERY) || defined (Y2_LE_CHECK)) ++/* event for recovery from rx out of sync */ ++#define SK_DRV_RECOVER SK_DRV_PRIVATE_BASE + 1 ++#endif ++/****************************************************************************** ++ * ++ * Structures specific for Yukon-II ++ * ++ ******************************************************************************/ ++ ++typedef struct s_frag SK_FRAG; ++struct s_frag { ++ SK_FRAG *pNext; ++ char *pVirt; ++ SK_U64 pPhys; ++ unsigned int FragLen; ++}; ++ ++typedef struct s_packet SK_PACKET; ++struct s_packet { ++ /* Common infos: */ ++ SK_PACKET *pNext; /* pointer for packet queues */ ++ unsigned int PacketLen; /* length of packet */ ++ unsigned int NumFrags; /* nbr of fragments (for Rx always 1) */ ++ SK_FRAG *pFrag; /* fragment list */ ++ SK_FRAG FragArray[MAX_NUM_FRAGS]; /* TX fragment array */ ++ unsigned int NextLE; /* next LE to use for the next packet */ ++ ++ /* Private infos: */ ++ struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */ ++}; ++ ++typedef struct s_queue SK_PKT_QUEUE; ++struct s_queue { ++ SK_PACKET *pHead; ++ SK_PACKET *pTail; ++ spinlock_t QueueLock; /* serialize packet accesses */ ++}; ++ ++/******************************************************************************* ++ * ++ * Macros specific for Yukon-II queues ++ * ++ ******************************************************************************/ ++ ++#define IS_Q_EMPTY(pQueue) ((pQueue)->pHead != NULL) ? SK_FALSE : SK_TRUE ++#define IS_Q_LOCKED(pQueue) spin_is_locked(&((pQueue)->QueueLock)) ++ ++#define PLAIN_POP_FIRST_PKT_FROM_QUEUE(pQueue, pPacket) { \ ++ if ((pQueue)->pHead != NULL) { \ ++ (pPacket) = (pQueue)->pHead; \ ++ (pQueue)->pHead = (pPacket)->pNext; \ ++ if ((pQueue)->pHead == NULL) { \ ++ (pQueue)->pTail = NULL; \ ++ } \ ++ (pPacket)->pNext = NULL; \ ++ } else { \ ++ (pPacket) = NULL; \ ++ } \ ++} ++ ++#define PLAIN_PUSH_PKT_AS_FIRST_IN_QUEUE(pQueue, pPacket) { \ ++ if ((pQueue)->pHead != NULL) { \ ++ (pPacket)->pNext = (pQueue)->pHead; \ ++ } else { \ ++ (pPacket)->pNext = NULL; \ ++ (pQueue)->pTail = (pPacket); \ ++ } \ ++ (pQueue)->pHead = (pPacket); \ ++} ++ ++#define PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(pQueue, pPacket) { \ ++ (pPacket)->pNext = NULL; \ ++ if ((pQueue)->pTail != NULL) { \ ++ (pQueue)->pTail->pNext = (pPacket); \ ++ } else { \ ++ (pQueue)->pHead = (pPacket); \ ++ } \ ++ (pQueue)->pTail = (pPacket); \ ++} ++ ++#define PLAIN_PUSH_MULTIPLE_PKT_AS_LAST_IN_QUEUE(pQueue,pPktGrpStart,pPktGrpEnd) { \ ++ if ((pPktGrpStart) != NULL) { \ ++ if ((pQueue)->pTail != NULL) { \ ++ (pQueue)->pTail->pNext = (pPktGrpStart); \ ++ } else { \ ++ (pQueue)->pHead = (pPktGrpStart); \ ++ } \ ++ (pQueue)->pTail = (pPktGrpEnd); \ ++ } \ ++} ++ ++/* Required: 'Flags' */ ++#define POP_FIRST_PKT_FROM_QUEUE(pQueue, pPacket) { \ ++ spin_lock_irqsave(&((pQueue)->QueueLock), Flags); \ ++ if ((pQueue)->pHead != NULL) { \ ++ (pPacket) = (pQueue)->pHead; \ ++ (pQueue)->pHead = (pPacket)->pNext; \ ++ if ((pQueue)->pHead == NULL) { \ ++ (pQueue)->pTail = NULL; \ ++ } \ ++ (pPacket)->pNext = NULL; \ ++ } else { \ ++ (pPacket) = NULL; \ ++ } \ ++ spin_unlock_irqrestore(&((pQueue)->QueueLock), Flags); \ ++} ++ ++/* Required: 'Flags' */ ++#define PUSH_PKT_AS_FIRST_IN_QUEUE(pQueue, pPacket) { \ ++ spin_lock_irqsave(&(pQueue)->QueueLock, Flags); \ ++ if ((pQueue)->pHead != NULL) { \ ++ (pPacket)->pNext = (pQueue)->pHead; \ ++ } else { \ ++ (pPacket)->pNext = NULL; \ ++ (pQueue)->pTail = (pPacket); \ ++ } \ ++ (pQueue)->pHead = (pPacket); \ ++ spin_unlock_irqrestore(&(pQueue)->QueueLock, Flags); \ ++} ++ ++/* Required: 'Flags' */ ++#define PUSH_PKT_AS_LAST_IN_QUEUE(pQueue, pPacket) { \ ++ (pPacket)->pNext = NULL; \ ++ spin_lock_irqsave(&(pQueue)->QueueLock, Flags); \ ++ if ((pQueue)->pTail != NULL) { \ ++ (pQueue)->pTail->pNext = (pPacket); \ ++ } else { \ ++ (pQueue)->pHead = (pPacket); \ ++ } \ ++ (pQueue)->pTail = (pPacket); \ ++ spin_unlock_irqrestore(&(pQueue)->QueueLock, Flags); \ ++} ++ ++/* Required: 'Flags' */ ++#define PUSH_MULTIPLE_PKT_AS_LAST_IN_QUEUE(pQueue,pPktGrpStart,pPktGrpEnd) { \ ++ if ((pPktGrpStart) != NULL) { \ ++ spin_lock_irqsave(&(pQueue)->QueueLock, Flags); \ ++ if ((pQueue)->pTail != NULL) { \ ++ (pQueue)->pTail->pNext = (pPktGrpStart); \ ++ } else { \ ++ (pQueue)->pHead = (pPktGrpStart); \ ++ } \ ++ (pQueue)->pTail = (pPktGrpEnd); \ ++ spin_unlock_irqrestore(&(pQueue)->QueueLock, Flags); \ ++ } \ ++} ++ ++/* ++ *Check if the low address (32 bit) is near the 4G limit or over it. ++ * Set the high address to a wrong value. ++ * Doing so we force to write the ADDR64 LE. ++ */ ++#define CHECK_LOW_ADDRESS( _HighAddress, _LowAddress , _Length) { \ ++ if ((~0-_LowAddress) <_Length) { \ ++ _HighAddress= MAXIMUM_LOW_ADDRESS; \ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, \ ++ ("High Address must be set for HW. LowAddr = %d Length = %d\n", \ ++ _LowAddress, _Length)); \ ++ } \ ++} ++ ++/******************************************************************************* ++ * ++ * Macros specific for Yukon-II queues (tist) ++ * ++ ******************************************************************************/ ++ ++#ifdef USE_TIST_FOR_RESET ++/* port is fully operational */ ++#define SK_PSTATE_NOT_WAITING_FOR_TIST 0 ++/* port in reset until any tist LE */ ++#define SK_PSTATE_WAITING_FOR_ANY_TIST BIT_0 ++/* port in reset until timer reaches pAC->MinTistLo */ ++#define SK_PSTATE_WAITING_FOR_SPECIFIC_TIST BIT_1 ++#define SK_PSTATE_PORT_SHIFT 4 ++#define SK_PSTATE_PORT_MASK ((1 << SK_PSTATE_PORT_SHIFT) - 1) ++ ++/* use this + Port to build OP_MOD_TXINDEX_NO_PORT_A|B */ ++#define OP_MOD_TXINDEX 0x71 ++/* opcode for a TX_INDEX LE in which Port A has to be ignored */ ++#define OP_MOD_TXINDEX_NO_PORT_A 0x71 ++/* opcode for a TX_INDEX LE in which Port B has to be ignored */ ++#define OP_MOD_TXINDEX_NO_PORT_B 0x72 ++/* opcode for LE to be ignored because port is still in reset */ ++#define OP_MOD_LE 0x7F ++ ++/* set tist wait mode Bit for port */ ++#define SK_SET_WAIT_BIT_FOR_PORT(pAC, Bit, Port) \ ++ { \ ++ (pAC)->AdapterResetState |= ((Bit) << (SK_PSTATE_PORT_SHIFT * Port)); \ ++ } ++ ++/* reset tist waiting for specified port */ ++#define SK_CLR_STATE_FOR_PORT(pAC, Port) \ ++ { \ ++ (pAC)->AdapterResetState &= \ ++ ~(SK_PSTATE_PORT_MASK << (SK_PSTATE_PORT_SHIFT * Port)); \ ++ } ++ ++/* return SK_TRUE when port is in reset waiting for tist */ ++#define SK_PORT_WAITING_FOR_TIST(pAC, Port) \ ++ ((((pAC)->AdapterResetState >> (SK_PSTATE_PORT_SHIFT * Port)) & \ ++ SK_PSTATE_PORT_MASK) != SK_PSTATE_NOT_WAITING_FOR_TIST) ++ ++/* return SK_TRUE when port is in reset waiting for any tist */ ++#define SK_PORT_WAITING_FOR_ANY_TIST(pAC, Port) \ ++ ((((pAC)->AdapterResetState >> (SK_PSTATE_PORT_SHIFT * Port)) & \ ++ SK_PSTATE_WAITING_FOR_ANY_TIST) == SK_PSTATE_WAITING_FOR_ANY_TIST) ++ ++/* return SK_TRUE when port is in reset waiting for a specific tist */ ++#define SK_PORT_WAITING_FOR_SPECIFIC_TIST(pAC, Port) \ ++ ((((pAC)->AdapterResetState >> (SK_PSTATE_PORT_SHIFT * Port)) & \ ++ SK_PSTATE_WAITING_FOR_SPECIFIC_TIST) == \ ++ SK_PSTATE_WAITING_FOR_SPECIFIC_TIST) ++ ++/* return whether adapter is expecting a tist LE */ ++#define SK_ADAPTER_WAITING_FOR_TIST(pAC) ((pAC)->AdapterResetState != 0) ++ ++/* enable timestamp timer and force creation of tist LEs */ ++#define Y2_ENABLE_TIST(IoC) \ ++ SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8) GMT_ST_START) ++ ++/* disable timestamp timer and stop creation of tist LEs */ ++#define Y2_DISABLE_TIST(IoC) \ ++ SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8) GMT_ST_STOP) ++ ++/* get current value of timestamp timer */ ++#define Y2_GET_TIST_LOW_VAL(IoC, pVal) \ ++ SK_IN32(IoC, GMAC_TI_ST_VAL, pVal) ++ ++#endif ++ ++ ++/******************************************************************************* ++ * ++ * 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 TX_COMPL_IRQS ((IS_XS1_B) | (IS_XS1_F) | \ ++ (IS_XA1_B) | (IS_XA1_F) | \ ++ (IS_XS2_B) | (IS_XS2_F) | \ ++ (IS_XA2_B) | (IS_XA2_F)) ++ ++#define NAPI_DRV_IRQS ((IS_R1_F) | (IS_R2_F) | \ ++ (IS_XS1_F) | (IS_XA1_F)| \ ++ (IS_XS2_F) | (IS_XA2_F)) ++ ++#define Y2_DRIVER_IRQS ((Y2_IS_STAT_BMU) | (Y2_IS_IRQ_SW) | (Y2_IS_POLL_CHK)) ++ ++#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 Y2_SPECIAL_IRQS ((Y2_IS_HW_ERR) |(Y2_IS_ASF) | \ ++ (Y2_IS_TWSI_RDY) |(Y2_IS_TIMINT) | \ ++ (Y2_IS_IRQ_PHY2) |(Y2_IS_IRQ_MAC2) | \ ++ (Y2_IS_CHK_RX2) |(Y2_IS_CHK_TXS2) | \ ++ (Y2_IS_CHK_TXA2) |(Y2_IS_IRQ_PHY1) | \ ++ (Y2_IS_IRQ_MAC1) |(Y2_IS_CHK_RX1) | \ ++ (Y2_IS_CHK_TXS1) |(Y2_IS_CHK_TXA1)) ++ ++#define IRQ_MASK ((IS_IRQ_SW) | \ ++ (IS_R1_F) |(IS_R2_F) | \ ++ (IS_XS1_F) |(IS_XA1_F) | \ ++ (IS_XS2_F) |(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 Y2_IRQ_MASK ((Y2_DRIVER_IRQS) | (Y2_SPECIAL_IRQS)) ++ ++#define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */ ++#define Y2_IRQ_HWE_MASK (Y2_HWE_ALL_MSK) /* enable all HW irqs */ + + typedef struct s_DevNet DEV_NET; + + struct s_DevNet { +- int PortNr; +- int NetNr; +- SK_AC *pAC; ++ struct proc_dir_entry *proc; ++ int PortNr; ++ int NetNr; ++ char InitialDevName[20]; ++ char CurrentName[20]; ++ SK_BOOL NetConsoleMode; ++#ifdef Y2_RECOVERY ++ struct timer_list KernelTimer; /* Kernel timer struct */ ++ int TransmitTimeoutTimer; /* Transmit timer */ ++ SK_BOOL TimerExpired; /* Transmit timer */ ++ SK_BOOL InRecover; /* Recover flag */ ++#ifdef Y2_RX_CHECK ++ SK_U32 PreviousMACFifoRP; /* Backup of the FRP */ ++ SK_U32 PreviousMACFifoRLev; /* Backup of the FRL */ ++ SK_U32 PreviousRXFifoRP; /* Backup of the RX FRP */ ++ SK_U8 PreviousRXFifoRLev; /* Backup of the RX FRL */ ++ SK_U32 LastJiffies; /* Backup of the jiffies*/ ++#endif ++#endif ++ SK_AC *pAC; ++ struct timer_list ProcfsTimer; /* Procfs timer struct */ ++ + }; + +-typedef struct s_TxPort TX_PORT; ++/******************************************************************************* ++ * ++ * Rx/Tx Port structures ++ * ++ ******************************************************************************/ + +-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_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 TxdRingPrevFree;/* previously # of free entrys */ ++ int TxdRingFree; /* # of free entrys */ ++ spinlock_t TxDesRingLock; /* serialize descriptor accesses */ ++ caddr_t HwAddr; /* bmu registers address */ ++ int PortIndex; /* index number of port (0 or 1) */ ++ SK_PACKET *TransmitPacketTable; ++ SK_LE_TABLE TxALET; /* tx (async) list element table */ ++ SK_LE_TABLE TxSLET; /* tx (sync) list element table */ ++ SK_PKT_QUEUE TxQ_free; ++ SK_PKT_QUEUE TxAQ_waiting; ++ SK_PKT_QUEUE TxSQ_waiting; ++ SK_PKT_QUEUE TxAQ_working; ++ SK_PKT_QUEUE TxSQ_working; ++ unsigned LastDone; + }; + +-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 */ +- int RxCsum; /* use receive checksum hardware */ +- 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) */ ++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; /* descr given to BMU previously */ ++ int RxdRingFree; /* # of free entrys */ ++ spinlock_t RxDesRingLock; /* serialize descriptor accesses */ ++ int RxFillLimit; /* limit for buffers in ring */ ++ caddr_t HwAddr; /* bmu registers address */ ++ int PortIndex; /* index number of port (0 or 1) */ ++ SK_BOOL UseRxCsum; /* use Rx checksumming (yes/no) */ ++ SK_PACKET *ReceivePacketTable; ++ SK_LE_TABLE RxLET; /* rx list element table */ ++ SK_PKT_QUEUE RxQ_working; ++ SK_PKT_QUEUE RxQ_waiting; ++ int RxBufSize; + }; + +-/* Definitions needed for interrupt moderation *******************************/ ++/******************************************************************************* ++ * ++ * Interrupt masks used in combination with interrupt moderation ++ * ++ ******************************************************************************/ + + #define IRQ_EOF_AS_TX ((IS_XA1_F) | (IS_XA2_F)) + #define IRQ_EOF_SY_TX ((IS_XS1_F) | (IS_XS2_F)) +@@ -314,134 +747,157 @@ + #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') */ ++#define IRQ_MASK_Y2_TX_ONLY (Y2_IS_STAT_BMU) ++#define IRQ_MASK_Y2_RX_ONLY (Y2_IS_STAT_BMU) ++#define IRQ_MASK_Y2_SP_ONLY (SPECIAL_IRQS) ++#define IRQ_MASK_Y2_TX_RX ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY)) ++#define IRQ_MASK_Y2_SP_RX ((SPECIAL_IRQS) | (IRQ_MASK_RX_ONLY)) ++#define IRQ_MASK_Y2_SP_TX ((SPECIAL_IRQS) | (IRQ_MASK_TX_ONLY)) ++#define IRQ_MASK_Y2_RX_TX_SP ((SPECIAL_IRQS) | (IRQ_MASK_TX_RX)) + +- SK_TIMER ModTimer; /* just some timer */ +-}; ++/******************************************************************************* ++ * ++ * Defines and typedefs regarding interrupt moderation ++ * ++ ******************************************************************************/ + +-typedef struct s_PerStrm PER_STRM; ++#define C_INT_MOD_NONE 1 ++#define C_INT_MOD_STATIC 2 ++#define C_INT_MOD_DYNAMIC 4 ++ ++#define C_CLK_FREQ_GENESIS 53215000 /* or: 53.125 MHz */ ++#define C_CLK_FREQ_YUKON 78215000 /* or: 78.125 MHz */ ++#define C_CLK_FREQ_YUKON_EC 125000000 /* or: 125.000 MHz */ ++ ++#define C_Y2_INTS_PER_SEC_DEFAULT 5000 ++#define C_INTS_PER_SEC_DEFAULT 2000 ++#define C_INT_MOD_IPS_LOWER_RANGE 30 /* in IRQs/second */ ++#define C_INT_MOD_IPS_UPPER_RANGE 40000 /* in IRQs/second */ ++ ++typedef struct s_DynIrqModInfo { ++ SK_U64 PrevPort0RxIntrCts; ++ SK_U64 PrevPort1RxIntrCts; ++ SK_U64 PrevPort0TxIntrCts; ++ SK_U64 PrevPort1TxIntrCts; ++ SK_U64 PrevPort0StatusLeIntrCts; ++ SK_U64 PrevPort1StatusLeIntrCts; ++ int MaxModIntsPerSec; /* Moderation Threshold */ ++ int MaxModIntsPerSecUpperLimit; /* Upper limit for DIM */ ++ int MaxModIntsPerSecLowerLimit; /* Lower limit for DIM */ ++ long MaskIrqModeration; /* IRQ Mask (eg. 'TxRx') */ ++ int IntModTypeSelect; /* Type (eg. 'dynamic') */ ++ int DynIrqModSampleInterval; /* expressed in seconds! */ ++ SK_TIMER ModTimer; /* Timer for dynamic mod. */ ++} DIM_INFO; + +-#define SK_ALLOC_IRQ 0x00000001 ++/******************************************************************************* ++ * ++ * Defines and typedefs regarding wake-on-lan ++ * ++ ******************************************************************************/ ++ ++typedef struct s_WakeOnLanInfo { ++ SK_U32 SupportedWolOptions; /* e.g. WAKE_PHY... */ ++ SK_U32 ConfiguredWolOptions; /* e.g. WAKE_PHY... */ ++} WOL_INFO; + +-#ifdef SK_DIAG_SUPPORT ++#define SK_ALLOC_IRQ 0x00000001 + #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.: +- */ ++ * 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) */ +- +- SK_U32 AllocFlag; /* flag allocation of resources */ +- struct pci_dev *PciDev; /* for access to pci config space */ +- struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */ +- +- 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]; +- +- 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 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 +- */ ++ 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 ctrl struct */ ++ SK_TIMCTRL Tim; /* Software Timer ctrl 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 */ ++#ifdef SK_ASF ++ SK_ASF_DATA AsfData; ++ unsigned char IpAddr[4]; ++#endif ++ spinlock_t SlowPathLock; /* Normal IRQ lock */ ++ spinlock_t InitLock; /* Init lock */ ++ spinlock_t TxQueueLock; /* TX Queue lock */ ++ SK_PNMI_STRUCT_DATA PnmiStruct; /* struct for 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 hw init (0-2) */ ++ char DeviceStr[80]; /* adapter string from vpd */ ++ SK_U32 AllocFlag; /* alloc flag of resources */ ++ struct pci_dev *PciDev; /* for access to pci cfg space*/ ++ SK_U32 PciDevId; /* pci device id */ ++ struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */ ++ char Name[30]; /* driver name */ ++ struct SK_NET_DEVICE *Next; /* link all devs for cleanup */ ++ struct net_device_stats stats; /* linux 'netstat -i' stats */ ++ int Index; /* internal board idx number */ ++ int RxQueueSize; /* memory used for RX queue */ ++ int TxSQueueSize; /* memory used for TXS queue */ ++ int TxAQueueSize; /* memory used for TXA queue */ ++ int PromiscCount; /* promiscuous mode counter */ ++ int AllMultiCount; /* allmulticast mode counter */ ++ int MulticCount; /* number of MC addresses used*/ ++ int HWRevision; /* Hardware revision */ ++ int ActivePort; /* the active XMAC port */ ++ int MaxPorts; /* number of activated ports */ ++ int TxDescrPerRing;/* # of descriptors TX ring */ ++ int RxDescrPerRing;/* # of descriptors RX ring */ ++ caddr_t pDescrMem; /* Ptr to the descriptor area */ ++ dma_addr_t pDescrMemDMA; /* PCI DMA address of area */ ++ SK_U32 PciState[16]; /* PCI state */ ++ TX_PORT TxPort[SK_MAX_MACS][2]; ++ RX_PORT RxPort[SK_MAX_MACS]; ++ SK_LE_TABLE StatusLETable; ++ unsigned SizeOfAlignedLETables; ++ spinlock_t SetPutIndexLock; ++ int MaxUnusedRxLeWorking; ++ int InterfaceUp[2]; ++ 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 */ ++ DIM_INFO DynIrqModInfo; /* all data related to IntMod */ ++ WOL_INFO WolInfo; /* all info regarding WOL */ ++ int ChipsetType; /* 0=GENESIS; 1=Yukon */ ++ SK_BOOL LowLatency; /* LowLatency optimization on?*/ ++ SK_U32 DiagModeActive;/* is diag active? */ ++ SK_BOOL DiagFlowCtrl; /* for control purposes */ ++ SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for PNMI */ ++ SK_BOOL WasIfUp[SK_MAX_MACS]; ++#ifdef USE_TIST_FOR_RESET ++ int AdapterResetState; ++ SK_U32 MinTistLo; ++ SK_U32 MinTistHi; ++#endif ++#ifdef Y2_RECOVERY ++ int LastPort; /* port for curr. handled rx */ ++ int LastOpc; /* last rx LEs opcode */ ++#endif ++#ifdef Y2_SYNC_CHECK ++ unsigned long FramesWithoutSyncCheck; /* since last check */ + #endif +- + }; + + +-#endif /* __INC_SKDRV2ND_H */ ++ ++#endif ++ ++/******************************************************************************* ++ * ++ * End of file ++ * ++ ******************************************************************************/ + +diff -ruN linux/drivers/net/sk98lin/h/skerror.h linux-new/drivers/net/sk98lin/h/skerror.h +--- linux/drivers/net/sk98lin/h/skerror.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skerror.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,23 +2,24 @@ + * + * Name: skerror.h + * Project: Gigabit Ethernet Adapters, Common Modules +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: SK specific Error log support + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2006 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. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -28,28 +29,31 @@ + /* + * 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 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 SK_ERRCL_INFO (1L<<6) /* Information */ + + /* + * 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 */ ++#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 */ ++#define SK_ERRBASE_ASF 1200 /* Base Error number for ASF */ ++#define SK_ERRBASE_MACSEC 1300 /* Base Error number for MACSec module */ + + #endif /* _INC_SKERROR_H_ */ ++ +diff -ruN linux/drivers/net/sk98lin/h/skfops.h linux-new/drivers/net/sk98lin/h/skfops.h +--- linux/drivers/net/sk98lin/h/skfops.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/h/skfops.h 2007-01-24 14:03:40.000000000 +0100 +@@ -0,0 +1,39 @@ ++ ++/****************************************************************************** ++ * ++ * Name: skfops.c ++ * Project: Gigabit Ethernet Adapters, Common Modules ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Kernel mode file read functions. ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * (C)Copyright 1998-2002 SysKonnect ++ * (C)Copyright 2002-2003 Marvell ++ * ++ * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT ++ * The copyright notice above does not evidence any ++ * actual or intended publication of such source code. ++ * ++ * This Module contains Proprietary Information of SysKonnect ++ * and should be treated as Confidential. ++ * ++ * The information in this file is provided for the exclusive use of ++ * the licensees of SysKonnect. ++ * Such users have the right to use, modify, and incorporate this code ++ * into products for purposes authorized by the license agreement ++ * provided they include this notice and the associated copyright notice ++ * with any such product. ++ * The information in this file is provided "AS IS" without warranty. ++ * ++ ******************************************************************************/ ++ ++ ++SK_BOOL fw_read( SK_AC *pAC, /* Pointer to adapter context */ ++ char *name, SK_U8 **addr, SK_U32 *len ); ++SK_BOOL fw_file_exists( SK_AC *pAC, /* Pointer to adapter context */ ++ char *name ); ++ +diff -ruN linux/drivers/net/sk98lin/h/skgeasfconv.h linux-new/drivers/net/sk98lin/h/skgeasfconv.h +--- linux/drivers/net/sk98lin/h/skgeasfconv.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/h/skgeasfconv.h 2007-01-24 14:03:40.000000000 +0100 +@@ -0,0 +1,94 @@ ++ ++/****************************************************************************** ++ * ++ * Name: skgeasfconv.h ++ * Project: asf/ipmi ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: asf/ipmi interface in windows 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 _ASFWMI_H ++#define _ASFWMI_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++// lengths for string conversion ++#define ASF_IPADDRGRPSIZE (4) // 4 groups in ip address string (111.222.333.444) ++#define ASF_MACADDRGRPSIZE (6) // 6 groups in mac address string (11-22-33-44-55-66) ++#define ASF_GUIDGRPSIZE (16) // 16 groups in a GUID string ++#define ASF_COMMUNITYSTRLEN (64) // length of community string ++#define ASF_IPADDRSTRLEN (3*ASF_IPADDRGRPSIZE+3) // length of xxx.xxx.xxx.xxx ++#define ASF_MACADDRSTRLEN (2*ASF_MACADDRGRPSIZE+5) // length of xx-xx-xx-xx-xx-xx ++#define ASF_GUIDSTRLEN (2*ASF_GUIDGRPSIZE) // length of GUID string ++ ++// module sizes ++#define ASF_MAX_STRINGLEN (ASF_COMMUNITYSTRLEN+1) // length of a ascii string (with string end marker 0x00) ++#define ASF_MAX_UNICODESTRINGLEN (ASF_COMMUNITYSTRLEN) // length of a unicode string (without length information) ++ ++ ++// tags in strings ++#define ASF_IPSEPARATOR ('.') // separator in ip string ++#define ASF_MACSEPARATOR ('-') // separator in mac address ++ ++ ++// modes for AsfWmiInternal2External() and AsfWmiExternal2Internal() ++#define ASF_MODE_IPADDR (10) // input is a IP address (IPv4 format) ++#define ASF_MODE_MACADDR (11) // input is a MAC address ++#define ASF_MODE_COMMUNITY (12) // input is a community string ++#define ASF_MODE_GUID (13) // input is a number ++#define ASF_MODE_SYSID (14) // input is a number ++#define ASF_MODE_MANUID (15) // input is a number ++ ++// modes for AsfWmiHexVal2Str() ++#define ASF_MODE_IPSTRDECIMAL (15) // get string with ip in decimal ++#define ASF_MODE_MACADDRHEX (16) // get string in hex ++ ++// returncodes ++#define ASF_RETVAL_FAIL (-1) ++#define ASF_RETVAL_UNDEFINED (0) ++#define ASF_RETVAL_SUCCESS (1) ++ ++// Unicode String structure ++typedef struct _STR_ASF_UNISTRING ++{ ++ SK_U16 len; ++ SK_U16 buf[ASF_MAX_UNICODESTRINGLEN]; ++ ++} STR_ASF_UNISTRING; ++ ++ ++// function prototypes ++SK_I8 AsfMac2Asci( SK_U8 *buf, SK_U32 *len, SK_U8 *mac ); ++SK_I8 AsfIp2Asci( SK_U8 *buf, SK_U32 *len, SK_U8 *ip ); ++SK_I8 AsfAsci2Mac( SK_U8 *buf, SK_U32 len, SK_U8 *mac ); ++SK_I8 AsfAsci2Ip( SK_U8 *buf, SK_U32 len, SK_U8 *ip ); ++SK_I8 AsfHex2Array( SK_U8 *buf, SK_U32 len, SK_U8 *array ); ++SK_I8 AsfArray2Hex( SK_U8 *buf, SK_U32 len, SK_U8 *array ); ++SK_I8 AsfHex2U8( SK_U8 *buf, SK_U8 *val ); ++SK_I8 AsfInt2Hex( SK_U8 *buf, SK_U8 size, SK_U32 val ); ++SK_I8 AsfDec2Int( SK_U8 *buf, SK_U8 size, SK_U32 *val ); ++ ++#ifdef __cplusplus ++} ++#endif // cpp ++ ++#endif // asfwmi.h ++ +diff -ruN linux/drivers/net/sk98lin/h/skgeasf.h linux-new/drivers/net/sk98lin/h/skgeasf.h +--- linux/drivers/net/sk98lin/h/skgeasf.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/h/skgeasf.h 2007-01-24 13:58:33.000000000 +0100 +@@ -0,0 +1,547 @@ ++/****************************************************************************** ++ * ++ * Name: skgeasf.h ++ * Project: asf/ipmi ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: asf/ipmi interface in windows 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_SKGEASF_H_ ++#define _INC_SKGEASF_H_ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++ ++/* DEFINES */ ++#define ASF_FW_ARP_RESOLVE // FW is resolving the destination IP addr ++#define ASF_FW_WD // Driver is watching the FW ++#define ASF_CHECK_HIDDEN_ID // ASF init checks hidden id ++ ++// modes for the asf driver ++#define SK_GEASF_MODE_UNKNOWN 0 // unknown operation mode (initial) ++#define SK_GEASF_MODE_ASF 1 // asfec.bin binary found -> ASF operation ++#define SK_GEASF_MODE_IPMI 2 // ipmiy2.bin binary found -> IPMI operation ++ ++// chip modes for asf driver ++#define SK_GEASF_CHIP_UNKNOWN 0 // bad chip id / hidden id ++#define SK_GEASF_CHIP_EC 1 // EC: ASF ++#define SK_GEASF_CHIP_Y2 2 // Yukon2 ++ ++// dual link mode ++#define SK_GEASF_Y2_SINGLEPORT 1 // Yukon2 sigle link adapter ++#define SK_GEASF_Y2_DUALPORT 2 // Yukon2 dual link adapter ++ ++#define ASF_GUI_TSF 10 /* Time Scale Factor: 1s(GUI) <-> 10*100ms(FW) */ ++ ++#define ASF_MAX_STRLEN 64 ++ ++// lengths used in get oid ++#define ASF_ACPI_MAXBUFFLENGTH 256 // max bytes for holding ACPI table ++#define ASF_SMBUS_MAXBUFFLENGTH 128 // max bytes for holding SMBus info ++#define ASF_FWVER_MAXBUFFLENGTH 40 // max stringlen for firmware version ++ ++#define SK_ASF_EVT_TIMER_EXPIRED 1 /* Counter overflow */ ++#define SK_ASF_EVT_TIMER_SPI_EXPIRED 2 /* Counter overflow */ ++#define SK_ASF_EVT_TIMER_HCI_EXPIRED 3 /* Counter overflow */ ++ ++/* Return codes to the PNMI module */ ++#define SK_ASF_PNMI_ERR_OK 0 ++#define SK_ASF_PNMI_ERR_GENERAL 1 ++#define SK_ASF_PNMI_ERR_TOO_SHORT 2 ++#define SK_ASF_PNMI_ERR_BAD_VALUE 3 ++#define SK_ASF_PNMI_ERR_READ_ONLY 4 ++#define SK_ASF_PNMI_ERR_UNKNOWN_OID 5 ++#define SK_ASF_PNMI_ERR_UNKNOWN_INST 6 ++#define SK_ASF_PNMI_ERR_UNKNOWN_NET 7 ++#define SK_ASF_PNMI_ERR_NOT_SUPPORTED 10 ++ ++#define REG_ASF_MAC_ADDR 0x0f24 ++#define REG_ASF_MY_IP 0x0f50 ++#define REG_ASF_STATUS_CMD 0x0e68 ++#define REG_ASF_SMBUS_CFG 0x0e40 ++ ++#define ASF_CPU_STATE_UNKNOWN 0 ++#define ASF_CPU_STATE_RESET 1 ++#define ASF_CPU_STATE_RUNNING 2 ++ ++ ++/* ASF MIB default values */ ++#define ASF_DEF_RETRANS_COUNT_MIN 0 // x1 ++#define ASF_DEF_RETRANS_COUNT_MAX 255 // x1 ++#define ASF_DEF_WATCHDOG_ENA 0 // ++#define ASF_DEF_WATCHDOG_TIME 1200 // *100ms ++#define ASF_DEF_WATCHDOG_TIME_MAX 36000 // *100ms ++#define ASF_DEF_WATCHDOG_TIME_MIN 600 // *100ms ++#define ASF_DEF_RETRANS_INT_MIN 0 // *100ms ++#define ASF_DEF_RETRANS_INT_MAX 2550 // *100ms ++#define ASF_DEF_HB_INT_MIN 10 // *100ms ++#define ASF_DEF_HB_INT_MAX 2550 // *100ms ++#define ASF_DEF_ASF_ENA 0 ++#define ASF_DEF_RETRANS 2 ++#define ASF_DEF_RETRANS_INT 10 // *100ms ++#define ASF_DEF_HB_ENA 0 ++#define ASF_DEF_HB_INT 600 // *100ms ++ ++/* ASF HCI Commands */ ++#define YASF_HOSTCMD_ASF_INFO 1 ++#define YASF_HOSTCMD_LEG_CONF 2 ++#define YASF_HOSTCMD_ASF_CONF 3 ++#define YASF_HOSTCMD_RCTRL_CONF 4 ++#define YASF_HOSTCMD_KEEP_ALIVE 5 ++#define YASF_HOSTCMD_NEW_SEPROM_CONFIG 6 ++#define YASF_HOSTCMD_ENTER_RAM_IDLE 7 ++#define YASF_HOSTCMD_LEAVE_RAM_IDLE 8 ++#define YASF_HOSTCMD_RUN_DIAG 9 ++#define YASF_HOSTCMD_RESET_STATE 10 ++#define YASF_HOSTCMD_RESET 11 ++#define YASF_HOSTCMD_CHECK_ALIVE 12 ++#define YASF_HOSTCMD_DRV_HELLO 13 ++#define YASF_HOSTCMD_DRV_GOODBYE 14 ++#define YASF_HOSTCMD_DRV_STANDBY 15 ++#define YASF_HOSTCMD_UPDATE_OWN_MACADDR 16 ++#define YASF_HOSTCMD_ARP_RESOLVE 17 ++#define YASF_HOSTCMD_RESET_COLD 18 ++#define YASF_HOSTCMD_ACPI_RMCP_DATA 19 ++#define YASF_HOSTCMD_ACPI_ERROR 20 ++ ++#define YASF_HOSTCMD_CFG_SET_ASF_ENABLE 100 ++#define YASF_HOSTCMD_CFG_SET_RSP_ENABLE 101 ++#define YASF_HOSTCMD_CFG_SET_RETRANS 102 ++#define YASF_HOSTCMD_CFG_SET_RETRANS_INT 103 ++#define YASF_HOSTCMD_CFG_SET_HB_ENABLE 104 ++#define YASF_HOSTCMD_CFG_SET_HB_INT 105 ++#define YASF_HOSTCMD_CFG_SET_IP_DESTINATION 106 ++#define YASF_HOSTCMD_CFG_SET_IP_SOURCE 107 ++#define YASF_HOSTCMD_CFG_SET_MAC_DESTINATION 108 ++#define YASF_HOSTCMD_CFG_SET_COMMUNITY_NAME 109 ++#define YASF_HOSTCMD_CFG_SET_RSP_KEY_1 110 ++#define YASF_HOSTCMD_CFG_SET_RSP_KEY_2 111 ++#define YASF_HOSTCMD_CFG_SET_RSP_KEY_3 112 ++#define YASF_HOSTCMD_CFG_SET_DRWD_ENABLE 113 ++#define YASF_HOSTCMD_CFG_SET_DRWD_INT 114 ++#define YASF_HOSTCMD_CFG_SET_WD_ENABLE 115 ++#define YASF_HOSTCMD_CFG_SET_WD_INT 116 ++#define YASF_HOSTCMD_CFG_SET_ASF_RAMSIZE 117 ++#define YASF_HOSTCMD_CFG_SET_ACTIVE_PORT 118 ++ ++#define YASF_HOSTCMD_CFG_STORE_CONFIG 130 ++ ++#define YASF_HOSTCMD_CFG_GET_ASF_ENABLE 150 ++#define YASF_HOSTCMD_CFG_GET_RSP_ENABLE 151 ++#define YASF_HOSTCMD_CFG_GET_RETRANS 152 ++#define YASF_HOSTCMD_CFG_GET_RETRANS_INT 153 ++#define YASF_HOSTCMD_CFG_GET_HB_ENABLE 154 ++#define YASF_HOSTCMD_CFG_GET_HB_INT 155 ++#define YASF_HOSTCMD_CFG_GET_IP_DESTINATION 156 ++#define YASF_HOSTCMD_CFG_GET_IP_SOURCE 157 ++#define YASF_HOSTCMD_CFG_GET_MAC_DESTINATION 158 ++#define YASF_HOSTCMD_CFG_GET_COMMUNITY_NAME 159 ++#define YASF_HOSTCMD_CFG_GET_RSP_KEY_1 160 ++#define YASF_HOSTCMD_CFG_GET_RSP_KEY_2 161 ++#define YASF_HOSTCMD_CFG_GET_RSP_KEY_3 162 ++#define YASF_HOSTCMD_CFG_GET_DRWD_ENABLE 163 ++#define YASF_HOSTCMD_CFG_GET_DRWD_INT 164 ++#define YASF_HOSTCMD_CFG_GET_WD_ENABLE 165 ++#define YASF_HOSTCMD_CFG_GET_WD_INT 166 ++#define YASF_HOSTCMD_CFG_GET_ASF_RAMSIZE 167 ++#define YASF_HOSTCMD_CFG_GET_FW_VERSION_STRING 168 ++#define YASF_HOSTCMD_CFG_GET_SMBUS_INFOS 169 ++#define YASF_HOSTCMD_CFG_GET_ACTIVE_PORT 170 ++#define YASF_HOSTCMD_CFG_READ_CONFIG 180 ++ ++ ++/* ASF HCI Master */ ++#define ASF_HCI_READ 0x08000000 ++#define ASF_HCI_WRITE 0x04000000 ++#define ASF_HCI_CMD_RD_READY 0x02000000 ++#define ASF_HCI_CMD_WR_READY 0x01000000 ++#define ASF_HCI_UNSUCCESS 0x00800000 ++#define ASF_HCI_OFFSET 0x000000ff ++ ++#define ASF_HCI_CMDREG 0x0e70 ++#define ASF_HCI_DATAREG 0x0e78 ++ ++#define ASF_HCI_WAIT 1 ++#define ASF_HCI_NOWAIT 0 ++ ++#define ASF_HCI_TO 100 /* 1s */ ++ ++#define HCI_EN_CMD_IDLE 0 ++#define HCI_EN_CMD_WRITING 1 ++#define HCI_EN_CMD_READING 2 ++#define HCI_EN_CMD_WAIT 3 ++#define HCI_EN_CMD_READY 4 ++#define HCI_EN_CMD_ERROR 5 ++ ++#define ASF_HCI_REC_BUF_SIZE 128 ++#define ASF_HCI_TRA_BUF_SIZE 128 ++ ++ ++/* SEPROM (VPD) */ ++#define ASF_VPD_CONFIG_BASE 0x340 ++#define ASF_VPD_CONFIG_SIZE 0x80 ++#define ASF_VPD_DATA_BASE 0x3c0 ++#define ASF_VPD_DATA_SIZE 0x40 ++ ++/* Flash (SPI)*/ ++#define ASF_FLASH_SIZE (1024*64) ++#define ASF_FLASH_OFFS 0x20000 ++#define ASF_FLASH_OFFS_VER 0x1fc00 ++#define ASF_FLASH_OFFS_REV 0x1fc0b ++#define ASF_FLASH_OFFS_CS 0x1fffc ++#define ASF_FLASH_OFFS_GUID 0x1f000 ++#define ASF_FLASH_OFFS_ACPI 0x1f010 ++ ++#define ASF_RESET_HOT 0 ++#define ASF_RESET_COLD 1 ++ ++#define ASF_INIT_UNDEFINED 0 ++#define ASF_INIT_OK 1 ++#define ASF_INIT_ERROR 2 ++#define ASF_INIT_ERROR_CHIP_ID 3 ++#define ASF_INIT_ERROR_OPMODE 4 ++ ++#define RSP_KEYLENGTH 20 ++ ++// ACPI module defines ++#define ASF_ACPI_STATE_OK 1 ++#define ASF_ACPI_STATE_UNDEFINED 0 ++#define ASF_ACPI_STATE_ERROR -1 ++#define ASF_ACPI_STATE_ERROR_NO_RSDPTR -2 ++#define ASF_ACPI_STATE_ERROR_RSDT -3 ++#define ASF_ACPI_STATE_ERROR_XSDT -4 ++#define ASF_ACPI_STATE_ERROR_RSDT_NO_TABLE -5 ++#define ASF_ACPI_STATE_ERROR_RSDT_HEADER -6 ++#define ASF_ACPI_STATE_ERROR_ASF -7 ++#define ASF_ACPI_STATE_ERROR_ASF_HEADER -8 ++#define ASF_ACPI_STATE_ERROR_RSDT_NO_ASF_TABLE -9 ++#define ASF_ACPI_STATE_ERROR_FILE_OPEN -10 ++#define ASF_ACPI_STATE_ERROR_FILE_MAP -11 ++#define ASF_ACPI_STATE_ERROR_FILE_SIZE -12 ++#define ASF_ACPI_STATE_ERROR_FILE_CS -13 ++ ++#define ASF_RECORD_INFO 0x00 ++#define ASF_RECORD_ALRT 0x01 ++#define ASF_RECORD_RCTL 0x02 ++#define ASF_RECORD_RMCP 0x03 ++#define ASF_RECORD_ADDR 0x04 ++ ++#define TABLE_HEADER_LENGTH 36 ++#define SEC_COMMIT 0x08000000 ++ ++ ++// endianess depended macros ++ ++#define REVERSE_16(x) ((((x)<<8)&0xff00) + (((x)>>8)&0x00ff)) ++ ++#define REVERSE_32(x) ( ((((SK_U32)(x))<<24UL)&0xff000000UL) + \ ++ ((((SK_U32)(x))<< 8UL)&0x00ff0000UL) + \ ++ ((((SK_U32)(x))>> 8UL)&0x0000ff00UL) + \ ++ ((((SK_U32)(x))>>24UL)&0x000000ffUL) ) ++ ++#ifdef SK_LITTLE_ENDIAN ++#define NTOHS(x) REVERSE_16(x) ++#define HTONS(x) REVERSE_16(x) ++#define NTOHL(x) REVERSE_32(x) ++#define HTONL(x) REVERSE_32(x) ++#else ++#define NTOHS(x) (x) ++#define HTONS(x) (x) ++#define NTOHL(x) (x) ++#define HTONL(x) (x) ++#endif ++ ++/* ++ * ASF MIB structure ++ */ ++struct _STR_PET_DAT ++{ ++ SK_U8 EventSensorType; ++ SK_U8 EventType; ++ SK_U8 EventOffset; ++ SK_U8 TrapSourceType; ++ SK_U8 EventSourceType; ++ SK_U8 EventSeverity; ++ SK_U8 SensorDevice; ++ SK_U8 SensorNumber; ++ SK_U8 Entity; ++ SK_U8 EntityInstance; ++ SK_U8 EventData [8]; ++ SK_U8 LanguageCode; ++ SK_U8 OemCustomField [64]; ++ // 83 Bytes so far ++}; ++typedef struct _STR_PET_DAT STR_PET_DAT; ++ ++// structure for ACPI data for reporting to GUI ++struct _STR_ASF_ACPI ++{ ++ SK_U8 buffer [ASF_ACPI_MAXBUFFLENGTH]; ++ SK_U32 length; ++}; ++typedef struct _STR_ASF_ACPI STR_ASF_ACPI; ++ ++// structure for SMBus data for reporting to GUI ++struct _STR_ASF_SMBUSINFO ++{ ++ SK_U8 UpdateReq; ++ SK_U8 buffer [ASF_SMBUS_MAXBUFFLENGTH]; ++ SK_U32 length; ++}; ++typedef struct _STR_ASF_SMBUSINFO STR_ASF_SMBUSINFO; ++ ++struct _STR_ASF_MIB ++{ ++ SK_U8 WriteToFlash; ++ SK_U8 ConfigChange; ++ // Configuration parameter related to registers ++ SK_U8 NewParam; ++ SK_U8 Ena; ++ SK_U16 Retrans; ++ SK_U32 RetransInt; ++ SK_U8 HbEna; ++ SK_U32 HbInt; ++ SK_U8 WdEna; ++ SK_U32 WdTime; ++ SK_U8 IpSource [4]; ++ SK_U8 MacSource [6]; ++ SK_U8 IpDest [4]; ++ SK_U8 MacDest [6]; ++ SK_U8 CommunityName [64]; ++ SK_U8 Guid [16]; ++ SK_U8 RspEnable; ++ SK_U32 RetransCountMin; ++ SK_U32 RetransCountMax; ++ SK_U32 RetransIntMin; ++ SK_U32 RetransIntMax; ++ SK_U32 HbIntMin; ++ SK_U32 HbIntMax; ++ SK_U32 WdTimeMax; ++ SK_U32 WdTimeMin; ++ SK_U8 KeyOperator [RSP_KEYLENGTH]; ++ SK_U8 KeyAdministrator [RSP_KEYLENGTH]; ++ SK_U8 KeyGenerator [RSP_KEYLENGTH]; ++ STR_ASF_ACPI Acpi; ++ STR_ASF_SMBUSINFO SMBus; ++ SK_U8 RlmtMode; ++ SK_U8 Reserved [6]; // reserved bytes in vpd ++ SK_U8 PattUpReq; ++}; ++typedef struct _STR_ASF_MIB STR_ASF_MIB; ++ ++typedef struct s_Hci ++{ ++ SK_U32 To; ++ SK_U8 Status; ++ SK_U8 OldStatus; ++ SK_U32 OldCmdReg; ++ SK_U8 SendIndex; ++ SK_U8 ReceiveIndex; ++ SK_U8 SendLength; ++ SK_U8 ReceiveLength; ++ SK_U8 ExpectResponse; ++ SK_U8 Cycles; ++ SK_U64 Time; ++ SK_U8 ReceiveBuf [ASF_HCI_REC_BUF_SIZE]; ++ SK_U8 TransmitBuf [ASF_HCI_TRA_BUF_SIZE]; ++ SK_TIMER AsfTimerHci; ++} STR_HCI; ++ ++/* ++ * ASF specific adapter context structure ++ */ ++typedef struct s_AsfData ++{ ++ SK_U8 CurrentMacAddr[6]; ++ SK_U8 IpAddress[4]; ++ SK_TIMER AsfTimer; ++ SK_TIMER AsfTimerWrSpi; ++ SK_U8 StateHci; ++ SK_U8 StateWrSpi; ++ SK_U8 DriverVersion [5]; ++ SK_U8 FlashFwVersion [5]; ++ SK_U8 FlashFwRev; ++ SK_U8 FileFwVersion [5]; ++ SK_U8 FileFwRev; ++//VSz ++ SK_U8 FlashBuffer [ASF_FLASH_SIZE]; ++ SK_U8 VpdConfigBuf [ASF_VPD_CONFIG_SIZE]; ++ STR_ASF_MIB Mib; ++ STR_HCI Hci; ++ SK_U8 GlHciState; ++ SK_U8 LastGlHciState; ++ SK_U8 InitState; ++ SK_U8 VpdInitOk; ++ SK_U32 FwError; ++ SK_U8 CpuAlive; ++ SK_U16 FwWdIntervall; ++ SK_U16 FwRamSize; ++ SK_U8 ActivePort; ++ SK_U8 PrefPort; ++ SK_U8 FwVersionString [80]; ++ SK_U8 NewGuid; ++ SK_U8 OpMode; // ASF or IPMI operation mode - see SkAsfInit ++ SK_U8 ChipMode; // relevant for ASF or IPMI operation mode ++ SK_U8 DualMode; ++}SK_ASF_DATA; ++ ++#define MAX_EVENT_DATA 8 ++ ++struct _STR_EVENT_DATA { ++ struct _STR_EVENT_DATA *next; ++ SK_U8 SensorType; // SNMP (Specific Trap) ++ SK_U8 Type; // SNMP (Specific Trap) ++ SK_U8 Offset; // SNMP (Specific Trap) ++ SK_U8 SourceType; // PET ++ SK_U8 Severity; // PET ++ SK_U8 SensorDevice; // PET ++ SK_U8 SensorNumber; // PET ++ SK_U8 Entity; // PET ++ SK_U8 EntityInstance; // PET ++ SK_U8 DataLen; ++ SK_U8 Data [MAX_EVENT_DATA]; // PET ++}; ++typedef struct _STR_EVENT_DATA STR_EVENT_DATA; ++ ++ ++/* Functions provided by SkGeAsf */ ++ ++/* ANSI/C++ compliant function prototypes */ ++ ++/* ++ * Public Function prototypes ++ */ ++extern int SkAsfDeInit(SK_AC *pAC, SK_IOC IoC ); ++extern int SkAsfInit (SK_AC *pAC , SK_IOC IoC , int level); ++extern int SkAsfDeInitStandBy( SK_AC *pAC, SK_IOC IoC ); ++extern int SkAsfInitStandBy( SK_AC *pAC, SK_IOC IoC, int Level ); ++extern int SkAsfGet (SK_AC *pAC , SK_IOC IoC , SK_U8 *pBuf, unsigned int *pLen); ++extern int SkAsfPreSet (SK_AC *pAC , SK_IOC IoC , SK_U8 *pBuf, unsigned int *pLen); ++extern int SkAsfSet (SK_AC *pAC , SK_IOC IoC , SK_U8 *pBuf, unsigned int *pLen); ++extern int SkAsfEvent (SK_AC *pAC , SK_IOC IoC , SK_U32 Event , SK_EVPARA Param); ++extern int SkAsfSetOid(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, SK_U32 Inst, SK_U8 *pBuf, unsigned int *pLen); ++extern int SkAsfPreSetOid(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, SK_U32 Inst, SK_U8 *pBuf, unsigned int *pLen); ++extern int SkAsfGetOid(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, SK_U32 Inst, SK_U8 *pBuf, unsigned int *pLen); ++extern int SkAsfRestorePattern(SK_AC *pAC , SK_IOC IoC); ++ ++ ++SK_I8 SkAsfReadSpiConfigData( SK_AC *pAC ); ++SK_I8 SkAsfWriteSpiConfigData( SK_AC *pAC ); ++SK_I8 SkAsfUpdateSpiConfigData(SK_AC *pAC, SK_U8 *data , SK_U32 off , SK_U32 len, SK_U32 ClrCnt ); ++SK_I8 SkAsfUpdateConfDat( SK_AC *pAC, SK_U8 Pig, SK_U16 RegOffs, SK_U8 ByteEnable, SK_U32 Val, SK_U8 ForceNewEntry ); ++SK_I8 SkAsfReadConfDat( SK_AC *pAC, SK_U8 Pig, SK_U16 RegOffs, SK_U8 ByteEnable, SK_U32 *Val ); ++SK_I8 SkAsfWriteDeferredFlash( SK_AC *pAC, SK_IOC IoC ); ++SK_I8 SkAsfStartWriteDeferredFlash( SK_AC *pAC, SK_IOC IoC ); ++void SkAsfTimer( SK_AC *pAC, SK_IOC IoC ); ++void SkAsfShowMib( SK_AC *pAC ); ++void AsfResetCpu( SK_IOC IoC ); ++void AsfRunCpu( SK_IOC IoC ); ++SK_U8 AsfCheckAliveCpu( SK_AC *pAC, SK_IOC IoC ); ++SK_I8 SkAsfSeprom2Mib( SK_AC *pAC, SK_IOC IoC ); ++SK_I8 SkAsfMib2Seprom( SK_AC *pAC, SK_IOC IoC ); ++SK_U8 AsfSmartResetCpu( SK_AC *pAC, SK_IOC IoC, SK_U8 Cold ); ++SK_U8 AsfSmartResetStateCpu( SK_AC *pAC, SK_IOC IoC ); ++SK_U8 AsfCpuState( SK_IOC Ioc ); ++ ++SK_U8 AsfHciGetData( SK_AC *pAC, SK_U8 **pHciRecBuf ); ++SK_U8 AsfHciGetState( SK_AC *pAC ); ++SK_U8 AsfHciSendCommand( SK_AC *pAC, SK_IOC IoC, SK_U8 Command, SK_U8 Par1, SK_U8 Par2, SK_U8 ExpectResponse, SK_U8 Wait, SK_U8 Retry ); ++SK_U8 AsfHciSendData( SK_AC *pAC, SK_IOC IoC, SK_U8 *Buffer, SK_U8 ExpectResponse, SK_U8 Wait, SK_U8 Retry ); ++SK_U8 AsfHciSendMessage( SK_AC *pAC, SK_IOC IoC, SK_U8 *message, SK_U8 length, SK_U8 ExpectResponse, SK_U8 Wait ); ++ ++void SkAsfHci( SK_AC *pAC, SK_IOC IoC, SK_U8 ToEna ); ++void AsfWatchCpu( SK_AC *pAC, SK_IOC IoC, SK_U32 par ); ++void AsfEnable(SK_AC *pAC, SK_IOC IoC ); ++void AsfDisable(SK_AC *pAC, SK_IOC IoC ); ++ ++void AsfSetUpPattern(SK_AC *pAC, SK_IOC IoC, SK_U8 port ); ++SK_I8 AsfWritePatternRam( SK_AC *pAC, ++ SK_IOC IoC, ++ SK_U8 Port, ++ SK_U8 PatternId1, ++ SK_U8 PatternId2, ++ SK_U8 Length1, ++ SK_U8 Length2, ++ SK_U8 *pMask1, ++ SK_U8 *pPattern1, ++ SK_U8 *pMask2, ++ SK_U8 *pPattern2 ); ++SK_I8 YlciEnablePattern (SK_AC *pAC, SK_IOC IoC, SK_U8 port, SK_U8 pattno ); ++SK_I8 YlciDisablePattern (SK_AC *pAC, SK_IOC IoC, SK_U8 port, SK_U8 pattno ); ++ ++// ACPI and "ASF!" stuff ++SK_I8 SkAsfAcpi( SK_AC *pAC, SK_IOC IoC, SK_U8 *pImage ); ++//SK_I8 SkAsfAcpiRsdt( SK_AC *pAC, SK_IOC IoC, SK_U8 *pImage, HANDLE SectionHandle, SK_U32 PhysAddr ); ++//SK_I8 SkAsfAcpiXsdt( SK_AC *pAC, SK_IOC IoC, SK_U8 *pImage, HANDLE SectionHandle, SK_U64 PhysAddr ); ++//SK_I8 SkAsfAcpiAsf( SK_AC *pAC, SK_IOC IoC, SK_U8 *pImage, HANDLE SectionHandle, SK_U32 PhysAddr ); ++SK_I8 SkAsfPatchAsfTable( SK_AC *pAC, SK_IOC IoC, SK_U8 *pImage, SK_U8 *pAsfTable, SK_U32 TableLength ); ++SK_I8 SkAsfPatchGuid( SK_AC *pAC, SK_IOC IoC, SK_U8 *pImage, SK_U8 *pGuid ); ++void SkAsfExamineAsfTable( SK_AC *pAC, SK_IOC IoC, SK_U8 *pAsf, SK_U32 TableLength ); ++SK_I8 SkAsfSendRmcpData(SK_AC *pAC, SK_IOC IoC,SK_U8 *pData, SK_U8 Length ); ++ ++// ipmi ++SK_I8 AsfWriteIpmiPattern(SK_AC *pAC, SK_IOC IoC, SK_U8 port); ++ ++/* in file skspilole.c */ ++void spi_init_pac( SK_AC *pAC ); ++ ++// for cleaning up smbus register ++void AsfSetSMBusRegister(SK_IOC IoC); ++ ++#define SKERR_ASF_E001 (SK_ERRBASE_ASF) ++#define SKERR_ASF_E001MSG "SkAsfInit() error: wrong HCI version" ++#define SKERR_ASF_E002 (SKERR_ASF_E001+1) ++#define SKERR_ASF_E002MSG "SkAsfInit() error: flash read" ++#define SKERR_ASF_E003 (SKERR_ASF_E001+2) ++#define SKERR_ASF_E003MSG "SkAsfInit() error: flash erase" ++#define SKERR_ASF_E004 (SKERR_ASF_E001+3) ++#define SKERR_ASF_E004MSG "SkAsfInit() error: flash write" ++#define SKERR_ASF_E005 (SKERR_ASF_E001+4) ++#define SKERR_ASF_E005MSG "SkAsfInit() error: map FW image" ++#define SKERR_ASF_E006 (SKERR_ASF_E001+5) ++#define SKERR_ASF_E006MSG "SkAsfInit() error: flash reread" ++#define SKERR_ASF_E007 (SKERR_ASF_E001+6) ++#define SKERR_ASF_E007MSG "SkAsfInit() error: flash compare" ++#define SKERR_ASF_E008 (SKERR_ASF_E001+7) ++#define SKERR_ASF_E008MSG "SkAsfInit() flash successfully updated" ++#define SKERR_ASF_E009 (SKERR_ASF_E001+8) ++#define SKERR_ASF_E009MSG "SkAsfInit() updating flash" ++ ++ ++#define ASF_YEC_YTB_BASE_WOL_CTRL1 ((SK_U32)0x0f20) // YTB WOL CTRL register link 1 ++#define ASF_YEC_PATTRAM_CLUSTER_BYTES ((SK_U8)4) // 4 bytes is a word ++#define ASF_YEC_PATTRAM_CLUSTER_WORDS ((SK_U8)4) // 4 words in a cluster ++#define ASF_YEC_PATTRAM_CLUSTER_SIZE ((SK_U8)64) // pattern ram has 64 cluster ++ ++#define ASF_YEC_PATTERN_ENA1 (ASF_YEC_YTB_BASE_WOL_CTRL1 + 0x02) // enable pattern register, width:8 ++#define ASF_YEC_PATTERN_LENGTH_R1_L (ASF_YEC_YTB_BASE_WOL_CTRL1 + 0x10) // pattern length register, pattern 0-3, width: 4x8 ++#define ASF_YEC_PATTERN_LENGTH_R1_H (ASF_YEC_YTB_BASE_WOL_CTRL1 + 0x14) // pattern length register, pattern 4-6, width: 3x8 ++#define ASF_YEC_PATTERN_MATCHENA1 (ASF_YEC_YTB_BASE_WOL_CTRL1 + 0x0b) // ASF/PME match enable register, width: 8 ++#define ASF_YEC_PATTERN_CTRL1 (ASF_YEC_YTB_BASE_WOL_CTRL1 + 0x00) // match result, match control, wol ctrl and status ++ ++#define ASF_YEC_YTB_BASE_MACRXFIFO1 ((SK_U32)0x0c40) // base of receive MAC fifo registers, port 1 ++#define ASF_YEC_MAC_FIFO_CTRL1 (ASF_YEC_YTB_BASE_MACRXFIFO1 + 0x08) // control/test Rx MAC, link1, 32 bit ++#define ASF_YEC_MAC_FIFO_FLUSHMASK1 (ASF_YEC_YTB_BASE_MACRXFIFO1 + 0x0c) // flush mask register Rx MAC, link1, 32 bit ++#define ASF_YEC_MAC_FIFO_FLUSHTHRES1 (ASF_YEC_YTB_BASE_MACRXFIFO1 + 0x10) // Rx MAC FIFO Flush Threshold, link1, 32 bit ++ ++#define ASF_YLCI_MACRXFIFOTHRES 8 // mac rx threshold in qwords ++ ++ ++#endif /* _INC_SKGEASF_H_ */ +diff -ruN linux/drivers/net/sk98lin/h/skgedrv.h linux-new/drivers/net/sk98lin/h/skgedrv.h +--- linux/drivers/net/sk98lin/h/skgedrv.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skgedrv.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,23 +2,24 @@ + * + * Name: skgedrv.h + * Project: Gigabit Ethernet Adapters, Common Modules +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Interface with the driver + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2007 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. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -33,7 +34,7 @@ + * 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_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 */ +@@ -44,8 +45,13 @@ + #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_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) */ ++#define SK_DRV_RX_OVERFLOW 15 /* Receive Overflow */ ++#define SK_DRV_LIPA_NOT_AN_ABLE 16 /* Link Partner not Auto-Negotiation able */ ++#define SK_DRV_PEX_LINK_WIDTH 17 /* PEX negotiated Link width not maximum */ ++ ++#define SK_DRV_PRIVATE_BASE 100 /* Base for driver private events */ + #endif /* __INC_SKGEDRV_H_ */ +diff -ruN linux/drivers/net/sk98lin/h/skgehw.h linux-new/drivers/net/sk98lin/h/skgehw.h +--- linux/drivers/net/sk98lin/h/skgehw.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skgehw.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,23 +2,24 @@ + * + * Name: skgehw.h + * Project: Gigabit Ethernet Adapters, Common Modules +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2007 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. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -114,6 +115,16 @@ + #define SHIFT1(x) ((x) << 1) + #define SHIFT0(x) ((x) << 0) + ++/* Macro for arbitrary alignment of a given pointer */ ++#define ALIGN_ADDR( ADDRESS, GRANULARITY ) { \ ++ SK_UPTR addr = (SK_UPTR)(ADDRESS); \ ++ if (addr & ((GRANULARITY)-1)) { \ ++ addr += (GRANULARITY); \ ++ addr &= ~(SK_UPTR)((GRANULARITY)-1); \ ++ ADDRESS = (void *)addr; \ ++ }\ ++} ++ + /* + * Configuration Space header + * Since this module is used for different OS', those may be +@@ -132,34 +143,84 @@ + #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 */ ++ /* Bytes 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_CAP_PTR 0x34 /* 8 bit Capabilities Pointer */ ++ /* Bytes 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 */ ++#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 */ ++#define PCI_PM_CAP_ID 0x48 /* 8 bit Power Management Cap. ID */ ++#define PCI_PM_NITEM 0x49 /* 8 bit PM Next Item Pointer */ ++#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 */ ++#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 */ ++#define PCI_VPD_CAP_ID 0x50 /* 8 bit VPD Cap. ID */ ++#define PCI_VPD_NITEM 0x51 /* 8 bit VPD Next Item Pointer */ ++#define PCI_VPD_ADR_REG 0x52 /* 16 bit VPD Address Register */ ++#define PCI_VPD_DAT_REG 0x54 /* 32 bit VPD Data Register */ ++ /* Bytes 0x58..0x59: reserved */ ++#define PCI_SER_LD_CTRL 0x5a /* 16 bit SEEPROM Loader Ctrl (YUKON only) */ ++ /* Bytes 0x5c..0xfc: used by Yukon-2 */ ++#define PCI_MSI_CAP_ID 0x5c /* 8 bit MSI Capability ID Register */ ++#define PCI_MSI_NITEM 0x5d /* 8 bit MSI Next Item Pointer */ ++#define PCI_MSI_CTRL 0x5e /* 16 bit MSI Message Control */ ++#define PCI_MSI_ADR_LO 0x60 /* 32 bit MSI Message Address (Lower) */ ++#define PCI_MSI_ADR_HI 0x64 /* 32 bit MSI Message Address (Upper) */ ++#define PCI_MSI_DATA 0x68 /* 16 bit MSI Message Data */ ++ /* Bytes 0x6a..0x6b: reserved */ ++#define PCI_X_CAP_ID 0x6c /* 8 bit PCI-X Capability ID Register */ ++#define PCI_X_NITEM 0x6d /* 8 bit PCI-X Next Item Pointer */ ++#define PCI_X_COMMAND 0x6e /* 16 bit PCI-X Command */ ++#define PCI_X_PE_STAT 0x70 /* 32 bit PCI-X / PE Status */ ++#define PCI_CAL_CTRL 0x74 /* 16 bit PCI Calibration Control Register */ ++#define PCI_CAL_STAT 0x76 /* 16 bit PCI Calibration Status Register */ ++#define PCI_DISC_CNT 0x78 /* 16 bit PCI Discard Counter */ ++#define PCI_RETRY_CNT 0x7a /* 8 bit PCI Retry Counter */ ++ /* Byte 0x7b: reserved */ ++#define PCI_OUR_STATUS 0x7c /* 32 bit Adapter Status Register */ ++#define PCI_OUR_REG_3 0x80 /* 32 bit Our Register 3 (Yukon-ECU only) */ ++#define PCI_OUR_REG_4 0x84 /* 32 bit Our Register 4 (Yukon-ECU only) */ ++#define PCI_OUR_REG_5 0x88 /* 32 bit Our Register 5 (Yukon-ECU only) */ ++ /* Bytes 0x8c..0xdf: reserved */ ++ ++/* PCI Express Capability */ ++#define PEX_CAP_ID 0xe0 /* 8 bit PEX Capability ID */ ++#define PEX_NITEM 0xe1 /* 8 bit PEX Next Item Pointer */ ++#define PEX_CAP_REG 0xe2 /* 16 bit PEX Capability Register */ ++#define PEX_DEV_CAP 0xe4 /* 32 bit PEX Device Capabilities */ ++#define PEX_DEV_CTRL 0xe8 /* 16 bit PEX Device Control */ ++#define PEX_DEV_STAT 0xea /* 16 bit PEX Device Status */ ++#define PEX_LNK_CAP 0xec /* 32 bit PEX Link Capabilities */ ++#define PEX_LNK_CTRL 0xf0 /* 16 bit PEX Link Control */ ++#define PEX_LNK_STAT 0xf2 /* 16 bit PEX Link Status */ ++ /* Bytes 0xf4..0xff: reserved */ ++ ++/* PCI Express Extended Capabilities */ ++#define PEX_ADV_ERR_REP 0x100 /* 32 bit PEX Advanced Error Reporting */ ++#define PEX_UNC_ERR_STAT 0x104 /* 32 bit PEX Uncorr. Errors Status */ ++#define PEX_UNC_ERR_MASK 0x108 /* 32 bit PEX Uncorr. Errors Mask */ ++#define PEX_UNC_ERR_SEV 0x10c /* 32 bit PEX Uncorr. Errors Severity */ ++#define PEX_COR_ERR_STAT 0x110 /* 32 bit PEX Correc. Errors Status */ ++#define PEX_COR_ERR_MASK 0x114 /* 32 bit PEX Correc. Errors Mask */ ++#define PEX_ADV_ERR_CAP_C 0x118 /* 32 bit PEX Advanced Error Cap./Ctrl */ ++#define PEX_HEADER_LOG 0x11c /* 4x32 bit PEX Header Log Register */ ++ ++#define PEX_COMPL_TIMEOUT 0x220 /* 32 bit PEX Completion Timeout */ ++#define PEX_FLOW_CONTROL 0x224 /* 32 bit PEX Flow Control */ ++ ++/* PCI Express Ack Timer for 1x Link */ ++#define PEX_ACK_LAT_TOX1 0x228 /* 16 bit PEX Ack Latency Timeout x1 */ ++#define PEX_ACK_RPLY_TOX1 0x22a /* 16 bit PEX Ack Reply Timeout val x1 */ + + /* + * I2C Address (PCI Config) +@@ -180,13 +241,13 @@ + #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_MWIEN BIT_4S /* Memory write an inv cycl enable */ + #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 |\ ++#define PCI_COMMAND_VAL (PCI_INT_DIS | PCI_SERREN | PCI_PERREN | \ + PCI_BMEN | PCI_MEMEN | PCI_IOEN) + + /* PCI_STATUS 16 bit Status */ +@@ -208,7 +269,7 @@ + /* Bit 2.. 0: reserved */ + + #define PCI_ERRBITS (PCI_PERR | PCI_SERR | PCI_RMABORT | PCI_RTABORT |\ +- PCI_DATAPERR) ++ PCI_DATAPERR) + + /* PCI_CLASS_CODE 24 bit Class Code */ + /* Byte 2: Base Class (02) */ +@@ -216,11 +277,11 @@ + /* Byte 0: Programming Interface (00) */ + + /* PCI_CACHE_LSZ 8 bit Cache Line Size */ +-/* Possible values: 0,2,4,8,16,32,64,128 */ ++/* 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 */ ++#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) */ +@@ -229,46 +290,56 @@ + #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_PREFEN BIT_3 /* Prefetch enable */ ++#define PCI_MEM_TYP_MSK (3L<<1) /* Bit 2.. 1: Memory Type Mask */ ++#define PCI_MEMSPACE BIT_0 /* Memory Space Indicator */ ++ + #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 */ ++ /* 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 */ ++ /* 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 */ ++ /* 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 */ ++/* Yukon-2 */ ++#define PCI_Y2_PIG_ENA BIT_31 /* Enable Plug-in-Go (YUKON-2) */ ++#define PCI_Y2_DLL_DIS BIT_30 /* Disable PCI DLL (YUKON-2) */ ++#define PCI_Y2_PHY2_COMA BIT_29 /* Set PHY 2 to Coma Mode (YUKON-2) */ ++#define PCI_Y2_PHY1_COMA BIT_28 /* Set PHY 1 to Coma Mode (YUKON-2) */ ++#define PCI_Y2_PHY2_POWD BIT_27 /* Set PHY 2 to Power Down (YUKON-2) */ ++#define PCI_Y2_PHY1_POWD BIT_26 /* Set PHY 1 to Power Down (YUKON-2) */ ++ /* Bit 25: reserved */ + #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_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_PEX_LEGNAT BIT_15 /* PEX PM legacy/native mode (YUKON-2) */ + #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 */ +@@ -277,14 +348,22 @@ + #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 */ ++#define PCI_SKEW_BASE 0xfL /* Bit 3.. 0: Skew Ctrl, Base */ ++#define PCI_CLS_OPT BIT_3 /* Cache Line Size opt. PCI-X (YUKON-2) */ + ++/* Yukon-EC Ultra only */ ++ /* Bit 14..10: reserved */ ++#define PCI_PHY_LNK_TIM_MSK (3L<<8) /* Bit 9.. 8: GPHY Link Trigger Timer */ ++#define PCI_ENA_L1_EVENT BIT_7 /* Enable PEX L1 Event */ ++#define PCI_ENA_GPHY_LNK BIT_6 /* Enable PEX L1 on GPHY Link down */ ++#define PCI_FORCE_PEX_L1 BIT_5 /* Force to PEX L1 */ ++ /* Bit 4.. 0: reserved */ + + /* 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_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 +@@ -296,22 +375,21 @@ + #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_REV_DESC BIT_2 /* Reverse Descriptor Bytes */ ++ /* Bit 1: reserved */ + #define PCI_USEDATA64 BIT_0 /* Use 64Bit Data bus ext */ + +- +-/* Power Management Region */ ++/* Power Management (PM) 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_SUP_MSK (0x1f<<11) /* Bit 15..11: PM Event (PME) Supp. 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 */ ++ /* 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 */ +@@ -322,7 +400,7 @@ + #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 */ ++ /* 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) */ +@@ -333,7 +411,156 @@ + /* 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 */ ++#define PCI_VPD_ADR_MSK 0x7fffL /* Bit 14.. 0: VPD Address Mask */ ++ ++/* PCI_OUR_STATUS 32 bit Adapter Status Register (Yukon-2) */ ++#define PCI_OS_PCI64B BIT_31 /* Conventional PCI 64 bits Bus */ ++#define PCI_OS_PCIX BIT_30 /* PCI-X Bus */ ++#define PCI_OS_MODE_MSK (3L<<28) /* Bit 29..28: PCI-X Bus Mode Mask */ ++#define PCI_OS_PCI66M BIT_27 /* PCI 66 MHz Bus */ ++#define PCI_OS_PCI_X BIT_26 /* PCI/PCI-X Bus (0 = PEX) */ ++#define PCI_OS_DLLE_MSK (3L<<24) /* Bit 25..24: DLL Status Indication */ ++#define PCI_OS_DLLR_MSK (0xfL<<20) /* Bit 23..20: DLL Row Counters Values */ ++#define PCI_OS_DLLC_MSK (0xfL<<16) /* Bit 19..16: DLL Col. Counters Values */ ++ /* Bit 15.. 8: reserved */ ++ ++#define PCI_OS_SPEED(val) ((val & PCI_OS_MODE_MSK) >> 28) /* PCI-X Speed */ ++/* possible values for the speed field of the register */ ++#define PCI_OS_SPD_PCI 0 /* PCI Conventional Bus */ ++#define PCI_OS_SPD_X66 1 /* PCI-X 66MHz Bus */ ++#define PCI_OS_SPD_X100 2 /* PCI-X 100MHz Bus */ ++#define PCI_OS_SPD_X133 3 /* PCI-X 133MHz Bus */ ++ ++/* PCI_OUR_REG_3 32 bit Our Register 3 (Yukon-ECU only) */ ++ /* Bit 31..18: reserved */ ++#define P_CLK_COR_REGS_D0_DIS BIT_17 /* Disable Clock Core Regs in D0 */ ++#define P_CLK_PCI_REGS_D0_DIS BIT_16 /* Disable Clock PCI Regs in D0 */ ++#define P_CLK_COR_YTB_ARB_DIS BIT_15 /* Disable Clock YTB Arbiter */ ++#define P_CLK_MAC_LNK1_D3_DIS BIT_14 /* Disable Clock MAC Link1 in D3 */ ++#define P_CLK_COR_LNK1_D0_DIS BIT_13 /* Disable Clock Core Link1 in D0 */ ++#define P_CLK_MAC_LNK1_D0_DIS BIT_12 /* Disable Clock MAC Link1 in D0 */ ++#define P_CLK_COR_LNK1_D3_DIS BIT_11 /* Disable Clock Core Link1 in D3 */ ++#define P_CLK_PCI_MST_ARB_DIS BIT_10 /* Disable Clock PCI Master Arb. */ ++#define P_CLK_COR_REGS_D3_DIS BIT_9 /* Disable Clock Core Regs in D3 */ ++#define P_CLK_PCI_REGS_D3_DIS BIT_8 /* Disable Clock PCI Regs in D3 */ ++#define P_CLK_REF_LNK1_GM_DIS BIT_7 /* Disable Clock Ref. Link1 GMAC */ ++#define P_CLK_COR_LNK1_GM_DIS BIT_6 /* Disable Clock Core Link1 GMAC */ ++#define P_CLK_PCI_COMMON_DIS BIT_5 /* Disable Clock PCI Common */ ++#define P_CLK_COR_COMMON_DIS BIT_4 /* Disable Clock Core Common */ ++#define P_CLK_PCI_LNK1_BMU_DIS BIT_3 /* Disable Clock PCI Link1 BMU */ ++#define P_CLK_COR_LNK1_BMU_DIS BIT_2 /* Disable Clock Core Link1 BMU */ ++#define P_CLK_PCI_LNK1_BIU_DIS BIT_1 /* Disable Clock PCI Link1 BIU */ ++#define P_CLK_COR_LNK1_BIU_DIS BIT_0 /* Disable Clock Core Link1 BIU */ ++ ++/* PCI_OUR_REG_4 32 bit Our Register 4 (Yukon-ECU only) */ ++#define P_PEX_LTSSM_STAT_MSK (0x7fL<<25) /* Bit 31..25: PEX LTSSM Mask */ ++ /* (Link Training & Status State Machine) */ ++ /* Bit 24: reserved */ ++#define P_TIMER_VALUE_MSK (0xffL<<16) /* Bit 23..16: Timer Value Mask */ ++#define P_FORCE_ASPM_REQUEST BIT_15 /* Force ASPM Request (A1 only) */ ++ /* (Active State Power Management) */ ++ /* Bit 14..12: Force ASPM on Event */ ++#define P_ASPM_GPHY_LINK_DOWN BIT_14 /* GPHY Link Down (A1 only) */ ++#define P_ASPM_INT_FIFO_EMPTY BIT_13 /* Internal FIFO Empty (A1 only) */ ++#define P_ASPM_CLKRUN_REQUEST BIT_12 /* CLKRUN Request (A1 only) */ ++ /* Bit 11.. 7: reserved */ ++#define P_PIN63_LINK_LED_ENA BIT_8 /* Enable Pin #63 as Link LED (A3) */ ++#define P_ASPM_FORCE_ASPM_L1 BIT_7 /* Force ASPM L1 Enable (A1b only) */ ++#define P_ASPM_FORCE_ASPM_L0S BIT_6 /* Force ASPM L0s Enable (A1b only) */ ++#define P_ASPM_FORCE_CLKREQ_PIN BIT_5 /* Force CLKREQn pin low (A1b only) */ ++#define P_ASPM_FORCE_CLKREQ_ENA BIT_4 /* Force CLKREQ Enable (A1b only) */ ++#define P_ASPM_CLKREQ_PAD_CTL BIT_3 /* CLKREQ PAD Control (A1 only) */ ++#define P_ASPM_A1_MODE_SELECT BIT_2 /* A1 Mode Select (A1 only) */ ++#define P_CLK_GATE_PEX_UNIT_ENA BIT_1 /* Enable Gate PEX Unit Clock */ ++#define P_CLK_GATE_ROOT_COR_ENA BIT_0 /* Enable Gate Root Core Clock */ ++ ++#define P_PEX_LTSSM_STAT(x) (SHIFT25(x) & P_PEX_LTSSM_STAT_MSK) ++#define P_PEX_LTSSM_L1_STAT 0x34 ++#define P_PEX_LTSSM_DET_STAT 0x01 ++ ++#define P_ASPM_CONTROL_MSK (P_FORCE_ASPM_REQUEST | P_ASPM_GPHY_LINK_DOWN | \ ++ P_ASPM_CLKRUN_REQUEST | P_ASPM_INT_FIFO_EMPTY | \ ++ P_PIN63_LINK_LED_ENA) ++ ++/* PCI_OUR_REG_5 32 bit Our Register 5 (Yukon-ECU only) */ ++ /* Bit 31..27: reserved */ ++ /* Bit 26..16: Release Clock on Event */ ++#define P_REL_PCIE_RST_DE_ASS BIT_26 /* PCIe Reset De-Asserted */ ++#define P_REL_GPHY_REC_PACKET BIT_25 /* GPHY Received Packet */ ++#define P_REL_INT_FIFO_N_EMPTY BIT_24 /* Internal FIFO Not Empty */ ++#define P_REL_MAIN_PWR_AVAIL BIT_23 /* Main Power Available */ ++#define P_REL_CLKRUN_REQ_REL BIT_22 /* CLKRUN Request Release */ ++#define P_REL_PCIE_RESET_ASS BIT_21 /* PCIe Reset Asserted */ ++#define P_REL_PME_ASSERTED BIT_20 /* PME Asserted */ ++#define P_REL_PCIE_EXIT_L1_ST BIT_19 /* PCIe Exit L1 State */ ++#define P_REL_LOADER_NOT_FIN BIT_18 /* EPROM Loader Not Finished */ ++#define P_REL_PCIE_RX_EX_IDLE BIT_17 /* PCIe Rx Exit Electrical Idle State */ ++#define P_REL_GPHY_LINK_UP BIT_16 /* GPHY Link Up */ ++ /* Bit 15..11: reserved */ ++ /* Bit 10.. 0: Mask for Gate Clock */ ++#define P_GAT_PCIE_RST_ASSERTED BIT_10 /* PCIe Reset Asserted */ ++#define P_GAT_GPHY_N_REC_PACKET BIT_9 /* GPHY Not Received Packet */ ++#define P_GAT_INT_FIFO_EMPTY BIT_8 /* Internal FIFO Empty */ ++#define P_GAT_MAIN_PWR_N_AVAIL BIT_7 /* Main Power Not Available */ ++#define P_GAT_CLKRUN_REQ_REL BIT_6 /* CLKRUN Not Requested */ ++#define P_GAT_PCIE_RESET_ASS BIT_5 /* PCIe Reset Asserted */ ++#define P_GAT_PME_DE_ASSERTED BIT_4 /* PME De-Asserted */ ++#define P_GAT_PCIE_ENTER_L1_ST BIT_3 /* PCIe Enter L1 State */ ++#define P_GAT_LOADER_FINISHED BIT_2 /* EPROM Loader Finished */ ++#define P_GAT_PCIE_RX_EL_IDLE BIT_1 /* PCIe Rx Electrical Idle State */ ++#define P_GAT_GPHY_LINK_DOWN BIT_0 /* GPHY Link Down */ ++ ++/* PEX_DEV_CTRL 16 bit PEX Device Control (Yukon-2) */ ++ /* Bit 15 reserved */ ++#define PEX_DC_MAX_RRS_MSK (7<<12) /* Bit 14..12: Max. Read Request Size */ ++#define PEX_DC_EN_NO_SNOOP BIT_11S /* Enable No Snoop */ ++#define PEX_DC_EN_AUX_POW BIT_10S /* Enable AUX Power */ ++#define PEX_DC_EN_PHANTOM BIT_9S /* Enable Phantom Functions */ ++#define PEX_DC_EN_EXT_TAG BIT_8S /* Enable Extended Tag Field */ ++#define PEX_DC_MAX_PLS_MSK (7<<5) /* Bit 7.. 5: Max. Payload Size Mask */ ++#define PEX_DC_EN_REL_ORD BIT_4S /* Enable Relaxed Ordering */ ++#define PEX_DC_EN_UNS_RQ_RP BIT_3S /* Enable Unsupported Request Reporting */ ++#define PEX_DC_EN_FAT_ER_RP BIT_2S /* Enable Fatal Error Reporting */ ++#define PEX_DC_EN_NFA_ER_RP BIT_1S /* Enable Non-Fatal Error Reporting */ ++#define PEX_DC_EN_COR_ER_RP BIT_0S /* Enable Correctable Error Reporting */ ++ ++#define PEX_DC_MAX_RD_RQ_SIZE(x) (SHIFT12(x) & PEX_DC_MAX_RRS_MSK) ++ ++/* PEX_LNK_CAP 32 bit PEX Link Capabilities */ ++#define PEX_CAP_MAX_WI_MSK (0x3f<<4) /* Bit 9.. 4: Max. Link Width Mask */ ++#define PEX_CAP_MAX_SP_MSK 0x0f /* Bit 3.. 0: Max. Link Speed Mask */ ++ ++/* PEX_LNK_CTRL 16 bit PEX Link Control (Yukon-2) */ ++#define PEX_LC_CLK_PM_ENA BIT_8S /* Enable Clock Power Management (CLKREQ) */ ++#define PEX_LC_ASPM_LC_L1 BIT_1S /* Enable ASPM Entry L1 */ ++#define PEX_LC_ASPM_LC_L0S BIT_0S /* Enable ASPM Entry L0s */ ++#define PEX_LC_ASPM_LC_MSK 0x03 /* Bit 1.. 0: ASPM Link Control Mask */ ++ ++/* PEX_LNK_STAT 16 bit PEX Link Status (Yukon-2) */ ++ /* Bit 15..13 reserved */ ++#define PEX_LS_SLOT_CLK_CFG BIT_12S /* Slot Clock Config */ ++#define PEX_LS_LINK_TRAIN BIT_11S /* Link Training */ ++#define PEX_LS_TRAIN_ERROR BIT_10S /* Training Error */ ++#define PEX_LS_LINK_WI_MSK (0x3f<<4) /* Bit 9.. 4: Neg. Link Width Mask */ ++#define PEX_LS_LINK_SP_MSK 0x0f /* Bit 3.. 0: Link Speed Mask */ ++ ++/* PEX_UNC_ERR_STAT 16 bit PEX Uncorrectable Errors Status (Yukon-2) */ ++ /* Bit 31..21 reserved */ ++#define PEX_UNSUP_REQ BIT_20 /* Unsupported Request Error */ ++ /* ECRC Error (not supported) */ ++#define PEX_MALFOR_TLP BIT_18 /* Malformed TLP */ ++#define PEX_RX_OV BIT_17 /* Receiver Overflow (not supported) */ ++#define PEX_UNEXP_COMP BIT_16 /* Unexpected Completion */ ++ /* Completer Abort (not supported) */ ++#define PEX_COMP_TO BIT_14 /* Completion Timeout */ ++#define PEX_FLOW_CTRL_P BIT_13 /* Flow Control Protocol Error */ ++#define PEX_POIS_TLP BIT_12 /* Poisoned TLP */ ++ /* Bit 11.. 5: reserved */ ++#define PEX_DATA_LINK_P BIT_4 /* Data Link Protocol Error */ ++ /* Bit 3.. 1: reserved */ ++ /* Training Error (not supported) */ ++ ++#define PEX_FATAL_ERRORS (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P) + + /* Control Register File (Address Map) */ + +@@ -342,15 +569,21 @@ + */ + #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_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 */ ++#define B0_SP_ISRC 0x0018 /* 32 bit Special Interrupt Source Reg 1 */ ++ ++/* Special ISR registers (Yukon-2 only) */ ++#define B0_Y2_SP_ISRC2 0x001c /* 32 bit Special Interrupt Source Reg 2 */ ++#define B0_Y2_SP_ISRC3 0x0020 /* 32 bit Special Interrupt Source Reg 3 */ ++#define B0_Y2_SP_EISR 0x0024 /* 32 bit Enter ISR Register */ ++#define B0_Y2_SP_LISR 0x0028 /* 32 bit Leave ISR Register */ ++#define B0_Y2_SP_ICR 0x002c /* 32 bit Interrupt Control Register */ + + /* B0 XMAC 1 registers (GENESIS only) */ + #define B0_XM1_IMSK 0x0020 /* 16 bit r/w XMAC 1 Interrupt Mask Register*/ +@@ -372,7 +605,7 @@ + #define B0_XM2_PHY_DATA 0x0054 /* 16 bit r/w XMAC 2 PHY Data Register */ + /* 0x0056 - 0x005f: reserved */ + +-/* BMU Control Status Registers */ ++/* BMU Control Status Registers (Yukon and Genesis) */ + #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 */ +@@ -390,7 +623,7 @@ + /* + * Bank 2 + */ +-/* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */ ++/* NA reg = 48 bit Network Address Register, 3x16 or 6x8 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 */ +@@ -400,14 +633,23 @@ + #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_CHIP_ID 0x011b /* 8 bit Chip Identification Number */ ++ /* Eprom registers */ + #define B2_E_0 0x011c /* 8 bit EPROM Byte 0 (ext. SRAM size */ ++/* Yukon and Genesis */ + #define B2_E_1 0x011d /* 8 bit EPROM Byte 1 (PHY type) */ + #define B2_E_2 0x011e /* 8 bit EPROM Byte 2 */ ++/* Yukon-2 */ ++#define B2_Y2_CLK_GATE 0x011d /* 8 bit Clock Gating (Yukon-2) */ ++#define B2_Y2_HW_RES 0x011e /* 8 bit HW Resources (Yukon-2) */ ++ + #define B2_E_3 0x011f /* 8 bit EPROM Byte 3 */ ++ ++/* Yukon and Genesis */ + #define B2_FAR 0x0120 /* 32 bit Flash-Prom Addr Reg/Cnt */ + #define B2_FDP 0x0124 /* 8 bit Flash-Prom Data Port */ ++/* Yukon-2 */ ++#define B2_Y2_CLK_CTRL 0x0120 /* 32 bit Core Clock Frequency Control */ + /* 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 */ +@@ -439,6 +681,10 @@ + #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 */ ++ ++/* Yukon-2 */ ++#define Y2_PEX_PHY_DATA 0x0170 /* 16 bit PEX PHY Data Register */ ++#define Y2_PEX_PHY_ADDR 0x0172 /* 16 bit PEX PHY Address Register */ + /* 0x017c - 0x017f: reserved */ + + /* +@@ -448,9 +694,14 @@ + #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) */ ++#define B3_RAM_PARITY 0x018c /* 8 bit RAM Parity (Yukon-ECU A1) */ ++ ++#define SELECT_RAM_BUFFER(rb, addr) (addr | (rb << 6)) /* Yukon-2 only */ ++ + /* 0x018c - 0x018f: reserved */ + + /* RAM Interface Registers */ ++/* Yukon-2: use SELECT_RAM_BUFFER() to access the RAM buffer */ + /* + * 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 +@@ -466,8 +717,8 @@ + #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_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 */ +@@ -517,8 +768,8 @@ + /* 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 */ ++#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 */ + + /* +@@ -532,7 +783,16 @@ + #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 */ ++ /* 0x0213 - 0x021f: reserved */ ++ ++ /* RSS key registers for Yukon-2 Family */ ++#define B4_RSS_KEY 0x0220 /* 4x32 bit RSS Key register (Yukon-2) */ ++ /* RSS key register offsets */ ++#define KEY_IDX_0 0 /* offset for location of KEY 0 */ ++#define KEY_IDX_1 4 /* offset for location of KEY 1 */ ++#define KEY_IDX_2 8 /* offset for location of KEY 2 */ ++#define KEY_IDX_3 12 /* offset for location of KEY 3 */ ++ + /* 0x0280 - 0x0292: MAC 2 */ + /* 0x0213 - 0x027f: reserved */ + +@@ -556,10 +816,10 @@ + + /* 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_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 */ +@@ -568,10 +828,58 @@ + #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 */ ++#define Q_T2 0x40 /* 32 bit Test Register 2 */ ++#define Q_T3 0x44 /* 32 bit Test Register 3 */ ++ ++/* Yukon-2 */ ++#define Q_DONE 0x24 /* 16 bit Done Index */ ++ ++#define Q_WM 0x40 /* 16 bit FIFO Watermark */ ++#define Q_AL 0x42 /* 8 bit FIFO Alignment */ ++ /* 0x43: reserved */ ++/* RX Queue */ ++#define Q_RX_RSP 0x44 /* 16 bit FIFO Read Shadow Pointer */ ++#define Q_RX_RSL 0x46 /* 8 bit FIFO Read Shadow Level */ ++ /* 0x47: reserved */ ++#define Q_RX_RP 0x48 /* 8 bit FIFO Read Pointer */ ++ /* 0x49: reserved */ ++#define Q_RX_RL 0x4a /* 8 bit FIFO Read Level */ ++ /* 0x4b: reserved */ ++#define Q_RX_WP 0x4c /* 8 bit FIFO Write Pointer */ ++#define Q_RX_WSP 0x4d /* 8 bit FIFO Write Shadow Pointer */ ++#define Q_RX_WL 0x4e /* 8 bit FIFO Write Level */ ++#define Q_RX_WSL 0x4f /* 8 bit FIFO Write Shadow Level */ ++/* TX Queue */ ++#define Q_TX_WSP 0x44 /* 16 bit FIFO Write Shadow Pointer */ ++#define Q_TX_WSL 0x46 /* 8 bit FIFO Write Shadow Level */ ++ /* 0x47: reserved */ ++#define Q_TX_WP 0x48 /* 8 bit FIFO Write Pointer */ ++ /* 0x49: reserved */ ++#define Q_TX_WL 0x4a /* 8 bit FIFO Write Level */ ++ /* 0x4b: reserved */ ++#define Q_TX_RP 0x4c /* 8 bit FIFO Read Pointer */ ++ /* 0x4d: reserved */ ++#define Q_TX_RL 0x4e /* 8 bit FIFO Read Level */ ++ /* 0x4f: reserved */ ++ + /* 0x48 - 0x7f: reserved */ + ++/* Queue Prefetch Unit Offs, use Y2_PREF_Q_ADDR() to address (Yukon-2 only) */ ++#define Y2_B8_PREF_REGS 0x0450 ++ ++#define PREF_UNIT_CTRL_REG 0x00 /* 32 bit Prefetch Control register */ ++#define PREF_UNIT_LAST_IDX_REG 0x04 /* 16 bit Last Index */ ++#define PREF_UNIT_ADDR_LOW_REG 0x08 /* 32 bit List start addr, low part */ ++#define PREF_UNIT_ADDR_HI_REG 0x0c /* 32 bit List start addr, high part*/ ++#define PREF_UNIT_GET_IDX_REG 0x10 /* 16 bit Get Index */ ++#define PREF_UNIT_PUT_IDX_REG 0x14 /* 16 bit Put Index */ ++#define PREF_UNIT_FIFO_WP_REG 0x20 /* 8 bit FIFO write pointer */ ++#define PREF_UNIT_FIFO_RP_REG 0x24 /* 8 bit FIFO read pointer */ ++#define PREF_UNIT_FIFO_WM_REG 0x28 /* 8 bit FIFO watermark */ ++#define PREF_UNIT_FIFO_LEV_REG 0x2c /* 8 bit FIFO level */ ++ ++#define PREF_UNIT_MASK_IDX 0x0fff ++ + /* + * Bank 16 - 23 + */ +@@ -583,17 +891,17 @@ + #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_UTPP 0x10 /* 32 bit Rx Upper Threshold, Pause Packet */ ++#define RB_RX_LTPP 0x14 /* 32 bit Rx Lower Threshold, Pause Packet */ + #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_CTRL 0x28 /* 32 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 */ ++#define RB_TST2 0x2a /* 8 bit RAM Buffer Test Register 2 */ ++ /* 0x2b - 0x7f: reserved */ + + /* + * Bank 24 +@@ -603,7 +911,7 @@ + * 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 */ ++#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 */ +@@ -628,20 +936,23 @@ + #define LNK_LED_REG 0x0c3c /* 8 bit Link LED Register */ + /* 0x0c3d - 0x0c3f: reserved */ + +-/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */ ++/* Receive GMAC FIFO (YUKON and Yukon-2), 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 */ ++#define RX_GMF_TR_THR 0x0c54 /* 32 bit Rx Truncation Threshold (Yukon-2) */ ++#define RX_GMF_UP_THR 0x0c58 /* 16 bit Rx Upper Pause Thr (Yukon-EC_U) */ ++#define RX_GMF_LP_THR 0x0c5a /* 16 bit Rx Lower Pause Thr (Yukon-EC_U) */ ++#define RX_GMF_VLAN 0x0c5c /* 32 bit Rx VLAN Type Register (Yukon-2) */ ++#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 */ ++#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 */ ++#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 */ ++#define RX_GMF_RLEV 0x0c78 /* 32 bit Rx GMAC FIFO Read Level */ + /* 0x0c7c - 0x0c7f: reserved */ + + /* +@@ -658,7 +969,7 @@ + * 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_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 */ +@@ -676,18 +987,19 @@ + #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 */ ++/* Transmit GMAC FIFO (YUKON and Yukon-2), 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_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 */ ++ /* 0x0d4c - 0x0d5b: reserved */ ++#define TX_GMF_VLAN 0x0d5c /* 32 bit Tx VLAN Type Register (Yukon-2) */ ++#define TX_GMF_WP 0x0d60 /* 32 bit Tx GMAC FIFO Write Pointer */ ++#define TX_GMF_WSP 0x0d64 /* 32 bit Tx GMAC FIFO Write Shadow Pointer */ ++#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 */ ++#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 */ + + /* +@@ -713,12 +1025,84 @@ + #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 */ ++ /* 0x0e1b - 0x0e1f: reserved */ ++ ++/* Polling Unit Registers (Yukon-2 only) */ ++#define POLL_CTRL 0x0e20 /* 32 bit Polling Unit Control Reg */ ++#define POLL_LAST_IDX 0x0e24 /* 16 bit Polling Unit List Last Index */ ++ /* 0x0e26 - 0x0e27: reserved */ ++#define POLL_LIST_ADDR_LO 0x0e28 /* 32 bit Poll. List Start Addr (low) */ ++#define POLL_LIST_ADDR_HI 0x0e2c /* 32 bit Poll. List Start Addr (high) */ ++ /* 0x0e30 - 0x0e3f: reserved */ ++ ++/* ASF Subsystem Registers (Yukon-2 only) */ ++#define B28_Y2_SMB_CONFIG 0x0e40 /* 32 bit ASF SMBus Config Register */ ++#define B28_Y2_SMB_CSD_REG 0x0e44 /* 32 bit ASF SMB Control/Status/Data */ ++ /* 0x0e48 - 0x0e5f: reserved */ ++#define B28_Y2_ASF_IRQ_V_BASE 0x0e60 /* 32 bit ASF IRQ Vector Base */ ++ /* 0x0e64 - 0x0e67: reserved */ ++#define B28_Y2_ASF_STAT_CMD 0x0e68 /* 32 bit ASF Status and Command Reg */ ++#define B28_Y2_ASF_HOST_COM 0x0e6c /* 32 bit ASF Host Communication Reg */ ++#define B28_Y2_DATA_REG_1 0x0e70 /* 32 bit ASF/Host Data Register 1 */ ++#define B28_Y2_DATA_REG_2 0x0e74 /* 32 bit ASF/Host Data Register 2 */ ++#define B28_Y2_DATA_REG_3 0x0e78 /* 32 bit ASF/Host Data Register 3 */ ++#define B28_Y2_DATA_REG_4 0x0e7c /* 32 bit ASF/Host Data Register 4 */ + + /* + * Bank 29 + */ +- /* 0x0e80 - 0x0efc: reserved */ ++ ++/* Status BMU Registers (Yukon-2 only) */ ++#define STAT_CTRL 0x0e80 /* 32 bit Status BMU Control Reg */ ++#define STAT_LAST_IDX 0x0e84 /* 16 bit Status BMU Last Index */ ++ /* 0x0e85 - 0x0e86: reserved */ ++#define STAT_LIST_ADDR_LO 0x0e88 /* 32 bit Status List Start Addr (low) */ ++#define STAT_LIST_ADDR_HI 0x0e8c /* 32 bit Status List Start Addr (high) */ ++#define STAT_TXA1_RIDX 0x0e90 /* 16 bit Status TxA1 Report Index Reg */ ++#define STAT_TXS1_RIDX 0x0e92 /* 16 bit Status TxS1 Report Index Reg */ ++#define STAT_TXA2_RIDX 0x0e94 /* 16 bit Status TxA2 Report Index Reg */ ++#define STAT_TXS2_RIDX 0x0e96 /* 16 bit Status TxS2 Report Index Reg */ ++#define STAT_TX_IDX_TH 0x0e98 /* 16 bit Status Tx Index Threshold Reg */ ++ /* 0x0e9a - 0x0e9b: reserved */ ++#define STAT_PUT_IDX 0x0e9c /* 16 bit Status Put Index Reg */ ++ /* 0x0e9e - 0x0e9f: reserved */ ++ ++/* FIFO Control/Status Registers (Yukon-2 only) */ ++#define STAT_FIFO_WP 0x0ea0 /* 8 bit Status FIFO Write Pointer Reg */ ++ /* 0x0ea1 - 0x0ea3: reserved */ ++#define STAT_FIFO_RP 0x0ea4 /* 8 bit Status FIFO Read Pointer Reg */ ++ /* 0x0ea5: reserved */ ++#define STAT_FIFO_RSP 0x0ea6 /* 8 bit Status FIFO Read Shadow Ptr */ ++ /* 0x0ea7: reserved */ ++#define STAT_FIFO_LEVEL 0x0ea8 /* 8 bit Status FIFO Level Reg */ ++ /* 0x0ea9: reserved */ ++#define STAT_FIFO_SHLVL 0x0eaa /* 8 bit Status FIFO Shadow Level Reg */ ++ /* 0x0eab: reserved */ ++#define STAT_FIFO_WM 0x0eac /* 8 bit Status FIFO Watermark Reg */ ++#define STAT_FIFO_ISR_WM 0x0ead /* 8 bit Status FIFO ISR Watermark Reg */ ++ /* 0x0eae - 0x0eaf: reserved */ ++ ++/* Level and ISR Timer Registers (Yukon-2 only) */ ++#define STAT_LEV_TIMER_INI 0x0eb0 /* 32 bit Level Timer Init. Value Reg */ ++#define STAT_LEV_TIMER_CNT 0x0eb4 /* 32 bit Level Timer Counter Reg */ ++#define STAT_LEV_TIMER_CTRL 0x0eb8 /* 8 bit Level Timer Control Reg */ ++#define STAT_LEV_TIMER_TEST 0x0eb9 /* 8 bit Level Timer Test Reg */ ++ /* 0x0eba - 0x0ebf: reserved */ ++#define STAT_TX_TIMER_INI 0x0ec0 /* 32 bit Tx Timer Init. Value Reg */ ++#define STAT_TX_TIMER_CNT 0x0ec4 /* 32 bit Tx Timer Counter Reg */ ++#define STAT_TX_TIMER_CTRL 0x0ec8 /* 8 bit Tx Timer Control Reg */ ++#define STAT_TX_TIMER_TEST 0x0ec9 /* 8 bit Tx Timer Test Reg */ ++ /* 0x0eca - 0x0ecf: reserved */ ++#define STAT_ISR_TIMER_INI 0x0ed0 /* 32 bit ISR Timer Init. Value Reg */ ++#define STAT_ISR_TIMER_CNT 0x0ed4 /* 32 bit ISR Timer Counter Reg */ ++#define STAT_ISR_TIMER_CTRL 0x0ed8 /* 8 bit ISR Timer Control Reg */ ++#define STAT_ISR_TIMER_TEST 0x0ed9 /* 8 bit ISR Timer Test Reg */ ++ /* 0x0eda - 0x0eff: reserved */ ++ ++#define ST_LAST_IDX_MASK 0x007f /* Last Index Mask */ ++#define ST_TXRP_IDX_MASK 0x0fff /* Tx Report Index Mask */ ++#define ST_TXTH_IDX_MASK 0x0fff /* Tx Threshold Index Mask */ ++#define ST_WM_IDX_MASK 0x3f /* FIFO Watermark Index Mask */ + + /* + * Bank 30 +@@ -742,11 +1126,9 @@ + #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)) +- ++#define WOL_PATT_PME 0x0f2a /* 8 bit WOL PME Match Enable (Yukon-2) */ ++#define WOL_PATT_ASFM 0x0f2b /* 8 bit WOL ASF Match Enable (Yukon-2) */ ++#define WOL_PATT_RPTR 0x0f2c /* 8 bit WOL Pattern Read Pointer */ + + /* WOL Pattern Length Registers (YUKON only) */ + +@@ -764,11 +1146,22 @@ + */ + /* 0x0f80 - 0x0fff: reserved */ + ++/* WOL registers link 2 */ ++ ++/* use this macro to access WOL registers */ ++#define WOL_REG(Port, Reg) ((Reg) + ((Port)*0x80) + (pAC->GIni.GIWolOffs)) ++ + /* + * Bank 32 - 33 + */ + #define WOL_PATT_RAM_1 0x1000 /* WOL Pattern RAM Link 1 */ ++#define WOL_PATT_RAM_2 0x1400 /* WOL Pattern RAM Link 2 */ + ++/* use this macro to retrieve the pattern ram base address */ ++#define WOL_PATT_RAM_BASE(Port) (WOL_PATT_RAM_1 + (Port)*0x400) ++ ++/* offset to configuration space on Yukon-2 */ ++#define Y2_CFG_SPC 0x1c00 + /* + * Bank 0x22 - 0x3f + */ +@@ -800,13 +1193,27 @@ + */ + /* B0_RAP 8 bit Register Address Port */ + /* Bit 7: reserved */ +-#define RAP_RAP 0x3f /* Bit 6..0: 0 = block 0,..,6f = block 6f */ ++#define RAP_MSK 0x7f /* Bit 6..0: 0 = block 0,..,6f = block 6f */ ++ ++/* B0_CTST 24 bit Control/Status register */ ++ /* Bit 23..18: reserved */ ++#define Y2_VMAIN_AVAIL BIT_17 /* VMAIN available (YUKON-2 only) */ ++#define Y2_VAUX_AVAIL BIT_16 /* VAUX available (YUKON-2 only) */ ++#define Y2_HW_WOL_ON BIT_15S /* HW WOL On (Yukon-EC Ultra A1 only) */ ++#define Y2_HW_WOL_OFF BIT_14S /* HW WOL Off (Yukon-EC Ultra A1 only) */ ++#define Y2_ASF_ENABLE BIT_13S /* ASF Unit Enable (YUKON-2 only) */ ++#define Y2_ASF_DISABLE BIT_12S /* ASF Unit Disable (YUKON-2 only) */ ++#define Y2_CLK_RUN_ENA BIT_11S /* CLK_RUN Enable (YUKON-2 only) */ ++#define Y2_CLK_RUN_DIS BIT_10S /* CLK_RUN Disable (YUKON-2 only) */ ++#define Y2_LED_STAT_ON BIT_9S /* Status LED On (YUKON-2 only) */ ++#define Y2_LED_STAT_OFF BIT_8S /* Status LED Off (YUKON-2 only) */ ++ /* Bit 7.. 0: same as below */ + + /* 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_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 */ +@@ -814,26 +1221,27 @@ + #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 */ ++#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 */ ++/* B0_LED 8 Bit LED register (GENESIS only) */ + /* Bit 7.. 2: reserved */ +-#define LED_STAT_ON BIT_1S /* Status LED on */ +-#define LED_STAT_OFF BIT_0S /* Status LED off */ ++#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 */ ++#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 */ + ++/* Yukon and Genesis */ + /* B0_ISRC 32 bit Interrupt Source Register */ + /* B0_IMSK 32 bit Interrupt Mask Register */ + /* B0_SP_ISRC 32 bit Special Interrupt Source Reg */ +@@ -846,13 +1254,13 @@ + #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_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_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_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 */ +@@ -879,12 +1287,65 @@ + #define IS_XA2_F BIT_1 /* Q_XA2 End of Frame */ + #define IS_XA2_C BIT_0 /* Q_XA2 Encoding Error */ + ++/* Yukon-2 */ ++/* 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 */ ++/* B0_Y2_SP_ISRC2 32 bit Special Interrupt Source Reg 2 */ ++/* B0_Y2_SP_ISRC3 32 bit Special Interrupt Source Reg 3 */ ++/* B0_Y2_SP_EISR 32 bit Enter ISR Reg */ ++/* B0_Y2_SP_LISR 32 bit Leave ISR Reg */ ++#define Y2_IS_PORT_MASK(Port, Mask) ((Mask) << (Port*8)) ++#define Y2_IS_HW_ERR BIT_31 /* Interrupt HW Error */ ++#define Y2_IS_STAT_BMU BIT_30 /* Status BMU Interrupt */ ++#define Y2_IS_ASF BIT_29 /* ASF subsystem Interrupt */ ++ /* Bit 28: reserved */ ++#define Y2_IS_POLL_CHK BIT_27 /* Check IRQ from polling unit */ ++#define Y2_IS_TWSI_RDY BIT_26 /* IRQ on end of TWSI Tx */ ++#define Y2_IS_IRQ_SW BIT_25 /* SW forced IRQ */ ++#define Y2_IS_TIMINT BIT_24 /* IRQ from Timer */ ++ /* Bit 23..16 reserved */ ++ /* Link 2 Interrupts */ ++#define Y2_IS_IRQ_PHY2 BIT_12 /* Interrupt from PHY 2 */ ++#define Y2_IS_IRQ_MAC2 BIT_11 /* Interrupt from MAC 2 */ ++#define Y2_IS_CHK_RX2 BIT_10 /* Descriptor error Rx 2 */ ++#define Y2_IS_CHK_TXS2 BIT_9 /* Descriptor error TXS 2 */ ++#define Y2_IS_CHK_TXA2 BIT_8 /* Descriptor error TXA 2 */ ++ /* Bit 7.. 5 reserved */ ++ /* Link 1 interrupts */ ++#define Y2_IS_IRQ_PHY1 BIT_4 /* Interrupt from PHY 1 */ ++#define Y2_IS_IRQ_MAC1 BIT_3 /* Interrupt from MAC 1 */ ++#define Y2_IS_CHK_RX1 BIT_2 /* Descriptor error Rx 1 */ ++#define Y2_IS_CHK_TXS1 BIT_1 /* Descriptor error TXS 1 */ ++#define Y2_IS_CHK_TXA1 BIT_0 /* Descriptor error TXA 1 */ ++ ++ /* IRQ Mask for port 1 */ ++#define Y2_IS_L1_MASK (Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1 | Y2_IS_CHK_RX1 |\ ++ Y2_IS_CHK_TXS1 | Y2_IS_CHK_TXA1) ++ ++ /* IRQ Mask for port 2 */ ++#define Y2_IS_L2_MASK (Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2 | Y2_IS_CHK_RX2 |\ ++ Y2_IS_CHK_TXS2 | Y2_IS_CHK_TXA2) ++ ++ /* All Interrupt bits */ ++#define Y2_IS_ALL_MSK (Y2_IS_HW_ERR | Y2_IS_STAT_BMU | Y2_IS_ASF |\ ++ Y2_IS_POLL_CHK | Y2_IS_TWSI_RDY | Y2_IS_IRQ_SW |\ ++ Y2_IS_TIMINT | Y2_IS_L1_MASK | Y2_IS_L2_MASK) ++ ++/* B0_Y2_SP_ICR 32 bit Interrupt Control Register */ ++ /* Bit 31.. 4: reserved */ ++#define Y2_IC_ISR_MASK BIT_3 /* ISR mask flag */ ++#define Y2_IC_ISR_STAT BIT_2 /* ISR status flag */ ++#define Y2_IC_LEAVE_ISR BIT_1 /* Leave ISR */ ++#define Y2_IC_ENTER_ISR BIT_0 /* Enter ISR */ + ++/* Yukon and Genesis */ + /* 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 */ ++ /* 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 */ +@@ -900,6 +1361,43 @@ + #define IS_R1_PAR_ERR BIT_1 /* Queue R1 Parity Error */ + #define IS_R2_PAR_ERR BIT_0 /* Queue R2 Parity Error */ + ++/* Yukon-2 */ ++/* 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 */ ++ /* Bit: 31..30 reserved */ ++#define Y2_IS_TIST_OV BIT_29 /* Time Stamp Timer overflow interrupt */ ++#define Y2_IS_SENSOR BIT_28 /* Sensor interrupt */ ++#define Y2_IS_MST_ERR BIT_27 /* Master error interrupt */ ++#define Y2_IS_IRQ_STAT BIT_26 /* Status exception interrupt */ ++#define Y2_IS_PCI_EXP BIT_25 /* PCI-Express interrupt */ ++#define Y2_IS_PCI_NEXP BIT_24 /* Bus Abort detected */ ++ /* Bit: 23..14 reserved */ ++ /* Link 2 */ ++#define Y2_IS_PAR_RD2 BIT_13 /* Read RAM parity error interrupt */ ++#define Y2_IS_PAR_WR2 BIT_12 /* Write RAM parity error interrupt */ ++#define Y2_IS_PAR_MAC2 BIT_11 /* MAC hardware fault interrupt */ ++#define Y2_IS_PAR_RX2 BIT_10 /* Parity Error Rx Queue 2 */ ++#define Y2_IS_TCP_TXS2 BIT_9 /* TCP length mismatch sync Tx queue IRQ */ ++#define Y2_IS_TCP_TXA2 BIT_8 /* TCP length mismatch async Tx queue IRQ */ ++ /* Bit: 9.. 6 reserved */ ++ /* Link 1 */ ++#define Y2_IS_PAR_RD1 BIT_5 /* Read RAM parity error interrupt */ ++#define Y2_IS_PAR_WR1 BIT_4 /* Write RAM parity error interrupt */ ++#define Y2_IS_PAR_MAC1 BIT_3 /* MAC hardware fault interrupt */ ++#define Y2_IS_PAR_RX1 BIT_2 /* Parity Error Rx Queue 1 */ ++#define Y2_IS_TCP_TXS1 BIT_1 /* TCP length mismatch sync Tx queue IRQ */ ++#define Y2_IS_TCP_TXA1 BIT_0 /* TCP length mismatch async Tx queue IRQ */ ++ ++#define Y2_HWE_L1_MASK (Y2_IS_PAR_RD1 | Y2_IS_PAR_WR1 | Y2_IS_PAR_MAC1 |\ ++ Y2_IS_PAR_RX1 | Y2_IS_TCP_TXS1| Y2_IS_TCP_TXA1) ++#define Y2_HWE_L2_MASK (Y2_IS_PAR_RD2 | Y2_IS_PAR_WR2 | Y2_IS_PAR_MAC2 |\ ++ Y2_IS_PAR_RX2 | Y2_IS_TCP_TXS2| Y2_IS_TCP_TXA2) ++ ++#define Y2_HWE_ALL_MSK (Y2_IS_TIST_OV | /* Y2_IS_SENSOR | */ Y2_IS_MST_ERR |\ ++ Y2_IS_IRQ_STAT | Y2_IS_PCI_EXP |\ ++ Y2_HWE_L1_MASK | Y2_HWE_L2_MASK) ++ + /* 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 */ +@@ -908,19 +1406,82 @@ + #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*/ ++#define CFG_SNG_MAC BIT_0S /* MAC Config: 0 = 2 MACs; 1 = 1 MAC */ + +-/* B2_CHIP_ID 8 bit Chip Identification Number */ ++/* 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_ID_YUKON_XL 0xb3 /* Chip ID for YUKON-2 XL */ ++#define CHIP_ID_YUKON_EC_U 0xb4 /* Chip ID for YUKON-2 EC Ultra */ ++#define CHIP_ID_YUKON_EX 0xb5 /* Chip ID for YUKON-2 Extreme */ ++#define CHIP_ID_YUKON_EC 0xb6 /* Chip ID for YUKON-2 EC */ ++#define CHIP_ID_YUKON_FE 0xb7 /* Chip ID for YUKON-2 FE */ + + #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 */ + ++#define CHIP_REV_YU_XL_A0 0 /* Chip Rev. for Yukon-2 A0 */ ++#define CHIP_REV_YU_XL_A1 1 /* Chip Rev. for Yukon-2 A1 */ ++#define CHIP_REV_YU_XL_A2 2 /* Chip Rev. for Yukon-2 A2 */ ++#define CHIP_REV_YU_XL_A3 3 /* Chip Rev. for Yukon-2 A3 */ ++ ++#define CHIP_REV_YU_EC_A1 0 /* Chip Rev. for Yukon-EC A0,A1 */ ++#define CHIP_REV_YU_EC_A2 1 /* Chip Rev. for Yukon-EC A2 */ ++#define CHIP_REV_YU_EC_A3 2 /* Chip Rev. for Yukon-EC A3 */ ++ ++#define CHIP_REV_YU_EC_U_A0 1 /* Chip Rev. for Yukon-EC Ultra A0 */ ++#define CHIP_REV_YU_EC_U_A1 2 /* Chip Rev. for Yukon-EC Ultra A1 */ ++#define CHIP_REV_YU_EC_U_B0 3 /* Chip Rev. for Yukon-EC Ultra B0 */ ++ ++#define CHIP_REV_YU_FE_A1 1 /* Chip Rev. for Yukon-FE A1 */ ++#define CHIP_REV_YU_FE_A2 3 /* Chip Rev. for Yukon-FE A2 */ ++ ++#define CHIP_REV_YU_EX_A0 1 /* Chip Rev. for Yukon-Exteme A0 */ ++ ++/* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */ ++#define Y2_STATUS_LNK2_INAC BIT_7S /* Status Link 2 inactiv (0 = activ) */ ++#define Y2_CLK_GAT_LNK2_DIS BIT_6S /* Disable PHY clock for Link 2 */ ++#define Y2_COR_CLK_LNK2_DIS BIT_5S /* Disable Core clock Link 2 */ ++#define Y2_PCI_CLK_LNK2_DIS BIT_4S /* Disable PCI clock Link 2 */ ++#define Y2_STATUS_LNK1_INAC BIT_3S /* Status Link 1 inactiv (0 = activ) */ ++#define Y2_CLK_GAT_LNK1_DIS BIT_2S /* Disable PHY clock for Link 1 */ ++#define Y2_COR_CLK_LNK1_DIS BIT_1S /* Disable Core clock Link 1 */ ++#define Y2_PCI_CLK_LNK1_DIS BIT_0S /* Disable PCI clock Link 1 */ ++ ++/* B2_Y2_HW_RES 8 bit HW Resources (Yukon-2 only) */ ++ /* Bit 7.. 6: reserved */ ++#define CFG_PEX_PME_NATIVE BIT_5S /* PCI-E PME native mode select */ ++#define CFG_LED_MODE_MSK (7<<2) /* Bit 4.. 2: LED Mode Mask */ ++#define CFG_LINK_2_AVAIL BIT_1S /* Link 2 available */ ++#define CFG_LINK_1_AVAIL BIT_0S /* Link 1 available */ ++ ++#define CFG_LED_MODE(x) (((x) & CFG_LED_MODE_MSK) >> 2) ++#define CFG_DUAL_MAC_MSK (CFG_LINK_2_AVAIL | CFG_LINK_1_AVAIL) ++ ++#define CFG_LED_DUAL_ACT_LNK 1 /* Dual LED ACT/LNK mode */ ++#define CFG_LED_LINK_MUX_P60 2 /* Link LED on pin 60 (Yukon-EC Ultra) */ ++ ++/* B2_E_3 8 bit lower 4 bits used for HW self test result */ ++#define B2_E3_RES_MASK 0x0f ++ + /* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */ +-#define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address mask */ ++#define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address Mask */ ++ ++/* B2_Y2_CLK_CTRL 32 bit Core Clock Frequency Control Register (Yukon-2/EC) */ ++ /* Bit 31..24: reserved */ ++/* Yukon-EC/FE */ ++#define Y2_CLK_DIV_VAL_MSK (0xffL<<16) /* Bit 23..16: Clock Divisor Value */ ++#define Y2_CLK_DIV_VAL(x) (SHIFT16(x) & Y2_CLK_DIV_VAL_MSK) ++/* Yukon-2 */ ++#define Y2_CLK_DIV_VAL2_MSK (7L<<21) /* Bit 23..21: Clock Divisor Value */ ++#define Y2_CLK_SELECT2_MSK (0x1fL<<16) /* Bit 20..16: Clock Select */ ++#define Y2_CLK_DIV_VAL_2(x) (SHIFT21(x) & Y2_CLK_DIV_VAL2_MSK) ++#define Y2_CLK_SEL_VAL_2(x) (SHIFT16(x) & Y2_CLK_SELECT2_MSK) ++ /* Bit 15.. 2: reserved */ ++#define Y2_CLK_DIV_ENA BIT_1S /* Enable Core Clock Division */ ++#define Y2_CLK_DIV_DIS BIT_0S /* Disable Core Clock Division */ + + /* B2_LD_CTRL 8 bit EPROM loader control register */ + /* Bits are currently reserved */ +@@ -960,9 +1521,6 @@ + #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 */ +@@ -975,14 +1533,14 @@ + + /* 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 */ ++ /* force the following error on the next master read/write */ ++#define TST_FRC_DPERR_MR64 BIT_3S /* Data PERR RD 64 */ ++#define TST_FRC_DPERR_MW64 BIT_2S /* Data PERR WR 64 */ ++#define TST_FRC_APERR_1M64 BIT_1S /* Addr PERR on 1. phase */ ++#define TST_FRC_APERR_2M64 BIT_0S /* Addr PERR on 2. phase */ + + /* B2_GP_IO 32 bit General Purpose I/O Register */ +- /* Bit 31..26: reserved */ ++ /* 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 */ +@@ -1009,33 +1567,31 @@ + #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 */ ++ /* 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_DEV_SIZE (7<<1) /* Bit 3.. 1: I2C Device Size */ ++#define I2C_025K_DEV (0<<1) /* 0: 256 Bytes or smaller */ ++#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 */ ++/* B2_I2C_SW 32 bit (8 bit access) I2C 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 */ ++#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)*/ ++/* I2C Address */ ++#define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address (Volt and Temp) */ + + + /* B2_BSC_CTRL 8 bit Blink Source Counter Control */ +@@ -1052,16 +1608,20 @@ + #define BSC_T_OFF BIT_1S /* Test mode off */ + #define BSC_T_STEP BIT_0S /* Test step */ + ++/* Y2_PEX_PHY_ADDR/DATA PEX PHY address and data reg (Yukon-2 only) */ ++#define PEX_RD_ACCESS BIT_31 /* Access Mode Read = 1, Write = 0 */ ++#define PEX_DB_ACCESS BIT_30 /* Access to debug register */ ++ + + /* 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 */ ++/* B3_RI_CTRL 16 bit RAM Interface 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*/ ++#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 */ +@@ -1111,7 +1671,7 @@ + #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) ++ 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 */ +@@ -1171,7 +1731,7 @@ + /* Bit 31..16: reserved */ + #define BC_MAX 0xffff /* Bit 15.. 0: Byte counter */ + +-/* BMU Control Status Registers */ ++/* BMU Control / Status Registers (Yukon and Genesis) */ + /* 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 */ +@@ -1206,11 +1766,46 @@ + #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) ++ 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) ++ CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\ ++ CSR_TRANS_RUN) ++ ++/* Rx BMU Control / Status Registers (Yukon-2) */ ++#define BMU_IDLE BIT_31 /* BMU Idle State */ ++#define BMU_RX_TCP_PKT BIT_30 /* Rx TCP Packet (when RSS Hash enabled) */ ++#define BMU_RX_IP_PKT BIT_29 /* Rx IP Packet (when RSS Hash enabled) */ ++ /* Bit 28..16: reserved */ ++#define BMU_ENA_RX_RSS_HASH BIT_15 /* Enable Rx RSS Hash */ ++#define BMU_DIS_RX_RSS_HASH BIT_14 /* Disable Rx RSS Hash */ ++#define BMU_ENA_RX_CHKSUM BIT_13 /* Enable Rx TCP/IP Checksum Check */ ++#define BMU_DIS_RX_CHKSUM BIT_12 /* Disable Rx TCP/IP Checksum Check */ ++#define BMU_CLR_IRQ_PAR BIT_11 /* Clear IRQ on Parity errors (Rx) */ ++#define BMU_CLR_IRQ_TCP BIT_11 /* Clear IRQ on TCP segmen. error (Tx) */ ++#define BMU_CLR_IRQ_CHK BIT_10 /* Clear IRQ Check */ ++#define BMU_STOP BIT_9 /* Stop Rx/Tx Queue */ ++#define BMU_START BIT_8 /* Start Rx/Tx Queue */ ++#define BMU_FIFO_OP_ON BIT_7 /* FIFO Operational On */ ++#define BMU_FIFO_OP_OFF BIT_6 /* FIFO Operational Off */ ++#define BMU_FIFO_ENA BIT_5 /* Enable FIFO */ ++#define BMU_FIFO_RST BIT_4 /* Reset FIFO */ ++#define BMU_OP_ON BIT_3 /* BMU Operational On */ ++#define BMU_OP_OFF BIT_2 /* BMU Operational Off */ ++#define BMU_RST_CLR BIT_1 /* Clear BMU Reset (Enable) */ ++#define BMU_RST_SET BIT_0 /* Set BMU Reset */ ++ ++#define BMU_CLR_RESET (BMU_FIFO_RST | BMU_OP_OFF | BMU_RST_CLR) ++#define BMU_OPER_INIT (BMU_CLR_IRQ_PAR | BMU_CLR_IRQ_CHK | BMU_START | \ ++ BMU_FIFO_ENA | BMU_OP_ON) ++ ++/* Tx BMU Control / Status Registers (Yukon-2) */ ++ /* Bit 31: same as for Rx */ ++ /* Bit 30..14: reserved */ ++#define BMU_TX_IPIDINCR_ON BIT_13 /* Enable IP ID Increment */ ++#define BMU_TX_IPIDINCR_OFF BIT_12 /* Disable IP ID Increment */ ++#define BMU_TX_CLR_IRQ_TCP BIT_11 /* Clear IRQ on TCP segm. length mism. */ ++ /* Bit 10..0: same as for Rx */ + + /* Q_F 32 bit Flag Register */ + /* Bit 31..28: reserved */ +@@ -1218,7 +1813,7 @@ + #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_M_RX_RAM_DIS BIT_24 /* MAC Rx RAM Read Port disable */ + #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 */ +@@ -1243,7 +1838,7 @@ + #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 */ ++/* 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 */ +@@ -1254,12 +1849,18 @@ + #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 */ ++/* 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 */ + ++/* PREF_UNIT_CTRL_REG 32 bit Prefetch Control register */ ++#define PREF_UNIT_OP_ON BIT_3 /* prefetch unit operational */ ++#define PREF_UNIT_OP_OFF BIT_2 /* prefetch unit not operational */ ++#define PREF_UNIT_RST_CLR BIT_1 /* Clear Prefetch Unit Reset */ ++#define PREF_UNIT_RST_SET BIT_0 /* Set Prefetch Unit Reset */ ++ + /* 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 */ +@@ -1275,24 +1876,24 @@ + #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 */ ++ /* Bit 7.. 4: reserved */ ++#define RB_PC_DEC BIT_3S /* Packet Counter Decrement */ + #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 */ ++#define RB_PC_T_OFF BIT_1S /* Packet Counter Test Off */ ++#define RB_PC_INC BIT_0S /* Packet Counter Increment */ + + /* 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 */ ++#define RB_WP_INC BIT_4S /* Write Pointer Increment */ + /* 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 */ ++#define RB_RP_INC BIT_0S /* Read Pointer Increment */ + + /* RB_CTRL 8 bit RAM Buffer Control Register */ +- /* Bit 7.. 6: reserved */ ++ /* 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 */ +@@ -1300,16 +1901,31 @@ + #define RB_RST_CLR BIT_1S /* Clear RAM Buf STM Reset */ + #define RB_RST_SET BIT_0S /* Set RAM Buf STM Reset */ + ++/* Yukon-2 */ ++ /* Bit 31..20: reserved */ ++#define RB_CNT_DOWN BIT_19 /* Packet Counter Decrement */ ++#define RB_CNT_TST_ON BIT_18 /* Packet Counter Test On */ ++#define RB_CNT_TST_OFF BIT_17 /* Packet Counter Test Off */ ++#define RB_CNT_UP BIT_16 /* Packet Counter Increment */ ++ /* Bit 15: reserved */ ++#define RB_WP_TST_ON BIT_14 /* Write Pointer Test On */ ++#define RB_WP_TST_OFF BIT_13 /* Write Pointer Test Off */ ++#define RB_WP_UP BIT_12 /* Write Pointer Increment */ ++ /* Bit 11: reserved */ ++#define RB_RP_TST_ON BIT_10 /* Read Pointer Test On */ ++#define RB_RP_TST_OFF BIT_9 /* Read Pointer Test Off */ ++#define RB_RP_UP BIT_8 /* Read Pointer Increment */ ++ + + /* 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_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_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 */ +@@ -1359,9 +1975,9 @@ + /* 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_WSP_T_ON BIT_6S /* Tx: Write Shadow Pointer Test On */ ++#define MFF_WSP_T_OFF BIT_5S /* Tx: Write Shadow Pointer Test Off */ ++#define MFF_WSP_INC BIT_4S /* Tx: Write Shadow Pointer 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 */ +@@ -1372,7 +1988,7 @@ + /* 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 */ ++#define MFF_WP_INC BIT_4S /* Write Pointer Increment */ + /* 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 */ +@@ -1391,12 +2007,16 @@ + + /* RX_LED_CTRL 8 bit Receive LED Cnt Control Reg */ + /* TX_LED_CTRL 8 bit Transmit LED Cnt Control Reg */ ++ /* Bit 7.. 3: reserved */ ++#define LED_START BIT_2S /* Start Counter */ ++#define LED_STOP BIT_1S /* Stop Counter */ ++#define LED_STATE BIT_0S /* Rx/Tx: LED State, 1=LED On */ ++ + /* 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 */ ++#define LNK_START BIT_2S /* Start Counter */ ++#define LNK_STOP BIT_1S /* Stop Counter */ ++#define LNK_CLR_IRQ BIT_0S /* Clear Link IRQ */ + + /* RX_LED_TST 8 bit Receive LED Cnt Test Register */ + /* TX_LED_TST 8 bit Transmit LED Cnt Test Register */ +@@ -1407,86 +2027,142 @@ + #define LED_T_STEP BIT_0S /* LED Counter Step */ + + /* LNK_LED_REG 8 bit Link LED Register */ +- /* Bit 7.. 6: reserved */ ++ /* 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 */ ++#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 */ ++/* 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 */ ++/* TX_GMF_WP 32 bit Tx GMAC FIFO Write Pointer */ ++/* TX_GMF_WSP 32 bit Tx GMAC FIFO Write Shadow Pointer */ ++/* 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 31..28 reserved */ ++#define RX_TRUNC_ON BIT_27 /* Enable Packet Truncation */ ++#define RX_TRUNC_OFF BIT_26 /* Disable Packet Truncation */ ++#define RX_VLAN_STRIP_ON BIT_25 /* Enable VLAN Stripping */ ++#define RX_VLAN_STRIP_OFF BIT_24 /* Disable VLAN Stripping */ ++ /* Bit 23..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 */ ++#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 (YUKON and Yukon-2) */ ++#define TX_STFW_DIS BIT_31 /* Disable Store & Forward (Yukon-EC Ultra) */ ++#define TX_STFW_ENA BIT_30 /* Enable Store & Forward (Yukon-EC Ultra) */ ++ /* Bits 29..26: reserved */ ++#define TX_VLAN_TAG_ON BIT_25 /* Enable VLAN tagging */ ++#define TX_VLAN_TAG_OFF BIT_24 /* Disable VLAN tagging */ ++#define TX_PCI_JUM_ENA BIT_23 /* Enable PCI Jumbo Mode (Yukon-EC Ultra) */ ++#define TX_PCI_JUM_DIS BIT_22 /* Disable PCI Jumbo Mode (Yukon-EC Ultra) */ ++ /* Bits 21..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..8: same as for RX_GMF_CTRL_T */ ++ /* Bit 7: reserved */ ++#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_AF_THR_MIN 0x0c /* Rx GMAC FIFO Almost Full Thresh. min. */ + #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 */ +- ++ /* 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 */ ++ ++/* POLL_CTRL 32 bit Polling Unit control register (Yukon-2 only) */ ++ /* Bit 31.. 6: reserved */ ++#define PC_CLR_IRQ_CHK BIT_5 /* Clear IRQ Check */ ++#define PC_POLL_RQ BIT_4 /* Poll Request Start */ ++#define PC_POLL_OP_ON BIT_3 /* Operational Mode On */ ++#define PC_POLL_OP_OFF BIT_2 /* Operational Mode Off */ ++#define PC_POLL_RST_CLR BIT_1 /* Clear Polling Unit Reset (Enable) */ ++#define PC_POLL_RST_SET BIT_0 /* Set Polling Unit Reset */ ++ ++ ++/* The bit definition of the following registers is still missing! */ ++/* B28_Y2_SMB_CONFIG 32 bit ASF SMBus Config Register */ ++/* B28_Y2_SMB_CSD_REG 32 bit ASF SMB Control/Status/Data */ ++/* B28_Y2_ASF_IRQ_V_BASE 32 bit ASF IRQ Vector Base */ ++ ++/* B28_Y2_ASF_STAT_CMD 32 bit ASF Status and Command Reg */ ++/* This register is used by the host driver software */ ++ /* Bit 31.. 5 reserved */ ++#define Y2_ASF_OS_PRES BIT_4S /* ASF operation system present */ ++#define Y2_ASF_RESET BIT_3S /* ASF system in reset state */ ++#define Y2_ASF_RUNNING BIT_2S /* ASF system operational */ ++#define Y2_ASF_CLR_HSTI BIT_1S /* Clear ASF IRQ */ ++#define Y2_ASF_IRQ BIT_0S /* Issue an IRQ to ASF system */ ++ ++#define Y2_ASF_UC_STATE (3<<2) /* ASF uC State */ ++#define Y2_ASF_CLK_HALT 0 /* ASF system clock stopped */ ++ ++/* B28_Y2_ASF_HOST_COM 32 bit ASF Host Communication Reg */ ++/* This register is used by the ASF firmware */ ++ /* Bit 31.. 2 reserved */ ++#define Y2_ASF_CLR_ASFI BIT_1 /* Clear host IRQ */ ++#define Y2_ASF_HOST_IRQ BIT_0 /* Issue an IRQ to HOST system */ ++ ++ ++/* STAT_CTRL 32 bit Status BMU control register (Yukon-2 only) */ ++ /* Bit 7.. 5: reserved */ ++#define SC_STAT_CLR_IRQ BIT_4 /* Status Burst IRQ clear */ ++#define SC_STAT_OP_ON BIT_3 /* Operational Mode On */ ++#define SC_STAT_OP_OFF BIT_2 /* Operational Mode Off */ ++#define SC_STAT_RST_CLR BIT_1 /* Clear Status Unit Reset (Enable) */ ++#define SC_STAT_RST_SET BIT_0 /* Set Status Unit Reset */ ++ + /* 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 */ ++#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_INT_POL BIT_27 /* IRQ Polarity is Active Low */ + #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 */ +@@ -1501,15 +2177,24 @@ + #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 */ ++#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 */ + ++/* Yukon-EC Ultra only */ ++#define GPC_LED_CONF_MSK (7<<6) /* Bit 8.. 6: GPHY LED Config */ ++#define GPC_PD_125M_CLK_OFF BIT_5 /* Disable Power Down Clock 125 MHz */ ++#define GPC_PD_125M_CLK_ON BIT_4 /* Enable Power Down Clock 125 MHz */ ++#define GPC_DPLL_RST_SET BIT_3 /* Set GPHY's DPLL Reset */ ++#define GPC_DPLL_RST_CLR BIT_2 /* Clear GPHY's DPLL Reset */ ++ /* (DPLL = Digital Phase Lock Loop) */ ++#define GPC_LED_CONF_VAL(x) (SHIFT6(x) & GPC_LED_CONF_MSK) ++ + #define GPC_HWCFG_GMII_COP (GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | \ + GPC_HWCFG_M_1 | GPC_HWCFG_M_0) + +@@ -1540,20 +2225,20 @@ + + /* 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 GM_IS_RX_CO_OV BIT_5S /* Receive Counter Overflow IRQ */ ++#define GM_IS_TX_CO_OV BIT_4S /* Transmit Counter Overflow IRQ */ ++#define GM_IS_TX_FF_UR BIT_3S /* Transmit FIFO Underrun */ ++#define GM_IS_TX_COMPL BIT_2S /* Frame Transmission Complete */ ++#define GM_IS_RX_FF_OR BIT_1S /* Receive FIFO Overrun */ ++#define GM_IS_RX_COMPL BIT_0S /* Frame Reception Complete */ + +-#define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \ ++#define GMAC_DEF_MSK (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV | \ + GM_IS_TX_FF_UR) + +-/* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ ++/* GMAC_LINK_CTRL 16 bit 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 */ ++#define GMLC_RST_CLR BIT_1S /* Clear Link Reset */ ++#define GMLC_RST_SET BIT_0S /* Set Link Reset */ + + + /* WOL_CTRL_STAT 16 bit WOL Control/Status Reg */ +@@ -1579,16 +2264,21 @@ + + #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_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)) + ++/* WOL_PATT_PME 8 bit WOL PME Match Enable (Yukon-2) */ ++#define WOL_PATT_FORCE_PME BIT_7 /* Generates a PME */ ++#define WOL_PATT_MATCH_PME_ALL 0x7f ++ + #define SK_NUM_WOL_PATTERN 7 ++#define SK_NUM_WOL_PATTERN_EX 9 + #define SK_PATTERN_PER_WORD 4 + #define SK_BITMASK_PATTERN 7 + #define SK_POW_PATTERN_LENGTH 128 +@@ -1597,26 +2287,28 @@ + #define WOL_LENGTH_SHIFT 8 + + ++/* typedefs ******************************************************************/ ++ + /* 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 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 ++#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 */ ++#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 */ ++#endif /* SK_USE_REV_DESC */ + SK_U32 TxRes2; /* 32 bit reserved field */ + } SK_HWTXD; + +@@ -1624,33 +2316,311 @@ + 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 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 */ ++#ifndef SK_USE_REV_DESC ++ SK_U16 RxTcpSum1; /* Rx TCP Checksum 1 */ ++ SK_U16 RxTcpSum2; /* Rx 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 */ ++#else /* SK_USE_REV_DESC */ ++ SK_U16 RxTcpSum2; /* Rx TCP Checksum 2 */ ++ SK_U16 RxTcpSum1; /* Rx 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 */ ++#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. ++ * Structures are 'normally' 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 7.th DWord. + * The bit positions inside a DWord are of course endianess dependent and +- * swaps if the DWord is swapped by the hardware. ++ * swap if the DWord is swapped by the hardware. + */ + ++/* YUKON-2 descriptors ******************************************************/ ++ ++typedef struct _TxMss { /* Yukon-Extreme only */ ++#ifndef SK_USE_REV_DESC ++ SK_U16 TxMssVal; /* MSS value */ ++ SK_U16 reserved; /* reserved */ ++#else /* SK_USE_REV_DESC */ ++ SK_U16 reserved; /* TCP Checksum Calculation Start Position */ ++ SK_U16 TxMssVal; /* MSS value */ ++#endif /* SK_USE_REV_DESC */ ++} SK_HWTXMSS; ++ ++typedef struct _TxChksum { ++#ifndef SK_USE_REV_DESC ++ SK_U16 TxTcpWp; /* TCP Checksum Write Position */ ++ SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */ ++#else /* SK_USE_REV_DESC */ ++ SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */ ++ SK_U16 TxTcpWp; /* TCP Checksum Write Position */ ++#endif /* SK_USE_REV_DESC */ ++} SK_HWTXCS; ++ ++typedef struct _LargeSend { ++#ifndef SK_USE_REV_DESC ++ SK_U16 Length; /* Large Send Segment Length */ ++ SK_U16 Reserved; /* reserved */ ++#else /* SK_USE_REV_DESC */ ++ SK_U16 Reserved; /* reserved */ ++ SK_U16 Length; /* Large Send Segment Length */ ++#endif /* SK_USE_REV_DESC */ ++} SK_HWTXLS; ++ ++typedef union u_HwTxBuf { ++ SK_U16 BufLen; /* Tx Buffer Length */ ++ SK_U16 VlanTag; /* VLAN Tag */ ++ SK_U16 InitCsum; /* Init. Checksum */ ++} SK_HWTXBUF; ++ ++/* Tx List Element structure */ ++typedef struct s_HwLeTx { ++ union { ++ SK_U32 BufAddr; /* Tx LE Buffer Address high/low */ ++ SK_U32 LsoV2Len; /* Total lenght of LSOv2 packet */ ++ SK_HWTXCS ChkSum; /* Tx LE TCP Checksum parameters */ ++ SK_HWTXLS LargeSend;/* Large Send length */ ++ SK_HWTXMSS Mss; /* MSS value; Yukon Extreme only */ ++ } TxUn; ++#ifndef SK_USE_REV_DESC ++ SK_HWTXBUF Send; ++ SK_U8 ControlFlags; /* Tx LE Control field or Lock Number */ ++ SK_U8 Opcode; /* Tx LE Opcode field */ ++#else /* SK_USE_REV_DESC */ ++ SK_U8 Opcode; /* Tx LE Opcode field */ ++ SK_U8 ControlFlags; /* Tx LE Control field or Lock Number */ ++ SK_HWTXBUF Send; ++#endif /* SK_USE_REV_DESC */ ++} SK_HWLETX; ++ ++typedef struct _RxChkSum{ ++#ifndef SK_USE_REV_DESC ++ 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 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */ ++ SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */ ++#endif /* SK_USE_REV_DESC */ ++} SK_HWRXCS; ++ ++/* Rx List Element structure */ ++typedef struct s_HwLeRx { ++ union { ++ SK_U32 BufAddr; /* Rx LE Buffer Address high/low */ ++ SK_HWRXCS ChkSum; /* Rx LE TCP Checksum parameters */ ++ } RxUn; ++#ifndef SK_USE_REV_DESC ++ SK_U16 BufferLength; /* Rx LE Buffer Length field */ ++ SK_U8 ControlFlags; /* Rx LE Control field */ ++ SK_U8 Opcode; /* Rx LE Opcode field */ ++#else /* SK_USE_REV_DESC */ ++ SK_U8 Opcode; /* Rx LE Opcode field */ ++ SK_U8 ControlFlags; /* Rx LE Control field */ ++ SK_U16 BufferLength; /* Rx LE Buffer Length field */ ++#endif /* SK_USE_REV_DESC */ ++} SK_HWLERX; ++ ++typedef struct s_StRxTCPChkSum { ++#ifndef SK_USE_REV_DESC ++ SK_U16 RxTCPSum1; /* Rx TCP Checksum 1 */ ++ SK_U16 RxTCPSum2; /* Rx TCP Checksum 2 */ ++#else /* SK_USE_REV_DESC */ ++ SK_U16 RxTCPSum2; /* Rx TCP Checksum 2 */ ++ SK_U16 RxTCPSum1; /* Rx TCP Checksum 1 */ ++#endif /* SK_USE_REV_DESC */ ++} SK_HWSTCS; ++ ++typedef struct s_StRxRssFlags { ++#ifndef SK_USE_REV_DESC ++ SK_U8 FlagField; /* contains TCP and IP flags */ ++ SK_U8 reserved; /* reserved */ ++#else /* SK_USE_REV_DESC */ ++ SK_U8 reserved; /* reserved */ ++ SK_U8 FlagField; /* contains TCP and IP flags */ ++#endif /* SK_USE_REV_DESC */ ++} SK_HWSTRSS; ++ ++/* bit definition of MAC Sec Rx Status (SK_HWLEST.StMacSecWord) */ ++/* (Yukon-Ext only) */ ++ /* bit 31..10 reserved */ ++#define MS_AUTH_RES_MSK (0xf<<6) /* MAC Sec, encoded auth. result info */ ++ /* see figure 10-5 in 802.1AE spec */ ++#define MS_ENCRYPT_ENA BIT_5 /* MAC Sec, encryption enabled */ ++#define MS_AUTHENT_ENA BIT_4 /* MAC Sec, authentication enabled */ ++#define MS_LKUP_NUM_MSK (3<<1) /* MAC Sec, lookup entry number mask */ ++ /* Info needed 0 = Bypass etc... TBD XXX */ ++#define MS_LKUP_TAB_HIT BIT_0 /* MAC Sec, lookup table hit */ ++ ++/* bit definition of RSS LE bit 32/33 (SK_HWSTRSS.FlagField) */ ++ /* bit 7..3 reserved */ ++#define RSS_IPV6_FLAG BIT_2S /* RSS value related to IP V6 (Yukon-Ext only)*/ ++#define RSS_TCP_FLAG BIT_1S /* RSS value related to TCP area */ ++#define RSS_IP_FLAG BIT_0S /* RSS value related to IP area */ ++/* StRxRssValue is valid if at least RSS_IP_FLAG is set */ ++/* For protocol errors or other protocols an empty RSS LE is generated */ ++ ++typedef union u_HwStBuf { ++ SK_U16 BufLen; /* Rx Buffer Length */ ++ SK_U16 VlanTag; /* VLAN Tag */ ++ SK_U16 StTxStatHi; /* Tx Queue Status (high) */ ++ SK_HWSTRSS Rss; /* Flag Field for TCP and IP protocol */ ++} SK_HWSTBUF; ++ ++/* Status List Element structure */ ++typedef struct s_HwLeSt { ++ union { ++ SK_U32 StRxStatWord; /* Rx Status Dword */ ++ SK_U32 StRxTimeStamp; /* Rx Timestamp */ ++ SK_HWSTCS StRxTCPCSum; /* Rx TCP Checksum */ ++ SK_U32 StTxStatLow; /* Tx Queue Status (low) */ ++ SK_U32 StRxRssValue; /* Rx RSS value */ ++ SK_U32 StMacSecWord; /* Rx MAC Sec Satus Word (Yukon-Ext only) */ ++ } StUn; ++#ifndef SK_USE_REV_DESC ++ SK_HWSTBUF Stat; ++ SK_U8 Link; /* Status LE Link field (& Csum Stat for Yukon-Ext)*/ ++ SK_U8 Opcode; /* Status LE Opcode field */ ++#else /* SK_USE_REV_DESC */ ++ SK_U8 Opcode; /* Status LE Opcode field */ ++ SK_U8 Link; /* Status LE Link field (& Csum Stat for Yukon-Ext)*/ ++ SK_HWSTBUF Stat; ++#endif /* SK_USE_REV_DESC */ ++} SK_HWLEST; ++ ++/* Special Action List Element */ ++typedef struct s_HwLeSa { ++#ifndef SK_USE_REV_DESC ++ SK_U16 TxAIdxVld; /* Special Action LE TxA Put Index field */ ++ SK_U16 TxSIdxVld; /* Special Action LE TxS Put Index field */ ++ SK_U16 RxIdxVld; /* Special Action LE Rx Put Index field */ ++ SK_U8 Link; /* Special Action LE Link field */ ++ SK_U8 Opcode; /* Special Action LE Opcode field */ ++#else /* SK_USE_REV_DESC */ ++ SK_U16 TxSIdxVld; /* Special Action LE TxS Put Index field */ ++ SK_U16 TxAIdxVld; /* Special Action LE TxA Put Index field */ ++ SK_U8 Opcode; /* Special Action LE Opcode field */ ++ SK_U8 Link; /* Special Action LE Link field */ ++ SK_U16 RxIdxVld; /* Special Action LE Rx Put Index field */ ++#endif /* SK_USE_REV_DESC */ ++} SK_HWLESA; ++ ++/* Common List Element union */ ++typedef union u_HwLeTxRxSt { ++ /* Transmit List Element Structure */ ++ SK_HWLETX Tx; ++ /* Receive List Element Structure */ ++ SK_HWLERX Rx; ++ /* Status List Element Structure */ ++ SK_HWLEST St; ++ /* Special Action List Element Structure */ ++ SK_HWLESA Sa; ++ /* Full List Element */ ++ SK_U64 Full; ++} SK_HWLE; ++ ++#define MAX_LARGE_SEND_LEN 0xffff ++ ++/* mask and shift value to get Tx async queue status for port 1 */ ++#define STLE_TXA1_MSKL 0x00000fff ++#define STLE_TXA1_SHIFTL 0 ++ ++/* mask and shift value to get Tx sync queue status for port 1 */ ++#define STLE_TXS1_MSKL 0x00fff000 ++#define STLE_TXS1_SHIFTL 12 ++ ++/* mask and shift value to get Tx async queue status for port 2 */ ++#define STLE_TXA2_MSKL 0xff000000 ++#define STLE_TXA2_SHIFTL 24 ++#define STLE_TXA2_MSKH 0x000f ++/* this one shifts up */ ++#define STLE_TXA2_SHIFTH 8 ++ ++/* mask and shift value to get Tx sync queue status for port 2 */ ++#define STLE_TXS2_MSKL 0x00000000 ++#define STLE_TXS2_SHIFTL 0 ++#define STLE_TXS2_MSKH 0xfff0 ++#define STLE_TXS2_SHIFTH 4 ++ ++/* YUKON-2 bit values */ ++#define HW_OWNER BIT_7 ++#define SW_OWNER 0 ++ ++#define PU_PUTIDX_VALID BIT_12 ++ ++/* YUKON-2 Control flags */ ++#define UDPTCP BIT_0S ++#define CALSUM BIT_1S ++#define WR_SUM BIT_2S ++#define INIT_SUM BIT_3S ++#define LOCK_SUM BIT_4S ++#define INS_VLAN BIT_5S ++#define FRC_STAT BIT_6S ++#define MACSEC BIT_6S /* Yukon-Ext only */ ++#define EOP BIT_7S ++ ++#define TX_LOCK BIT_8S ++#define BUF_SEND BIT_9S ++#define PACKET_SEND BIT_10S ++ ++#define NO_WARNING BIT_14S ++#define NO_UPDATE BIT_15S ++ ++/* Yukon-Ext CSum Status defines (Rx Status, Link field) */ ++#define CSS_TCPUDPCSOK BIT_7S /* TCP / UDP checksum is ok */ ++#define CSS_ISUDP BIT_6S /* packet is a UDP packet */ ++#define CSS_ISTCP BIT_5S /* packet is a TCP packet */ ++#define CSS_ISIPFRAG BIT_4S /* packet is a TCP/UDP frag, CS calc not done */ ++#define CSS_ISIPV6 BIT_3S /* packet is a IPv6 packet */ ++#define CSS_IPV4CSUMOK BIT_2S /* IP v4: TCP header checksum is ok */ ++#define CSS_ISIPV4 BIT_1S /* packet is a IPv4 packet */ ++#define CSS_LINK_BIT BIT_0S /* port number (legacy) */ ++ ++ ++/* YUKON-2 Rx/Tx opcodes defines */ ++#define OP_TCPWRITE 0x11 ++#define OP_TCPSTART 0x12 ++#define OP_TCPINIT 0x14 ++#define OP_TCPLCK 0x18 ++#define OP_TCPCHKSUM OP_TCPSTART ++#define OP_TCPIS (OP_TCPINIT | OP_TCPSTART) ++#define OP_TCPLW (OP_TCPLCK | OP_TCPWRITE) ++#define OP_TCPLSW (OP_TCPLCK | OP_TCPSTART | OP_TCPWRITE) ++#define OP_TCPLISW (OP_TCPLCK | OP_TCPINIT | OP_TCPSTART | OP_TCPWRITE) ++#define OP_ADDR64 0x21 ++#define OP_VLAN 0x22 ++#define OP_ADDR64VLAN (OP_ADDR64 | OP_VLAN) ++#define OP_LRGLEN 0x24 /* not Yukon-Ext */ ++#define OP_LRGLENVLAN (OP_LRGLEN | OP_VLAN) /* not Yukon-Ext */ ++#define OP_MSS 0x28 /* Yukon-Ext only */ ++#define OP_MSSVLAN (OP_MSS | OP_VLAN) /* Yukon-Ext only */ ++#define OP_BUFFER 0x40 ++#define OP_PACKET 0x41 ++#define OP_LARGESEND 0x43 ++#define OP_LSOV2 0x45 /* Yukon Ext only */ ++ ++ ++/* YUKON-2 STATUS opcodes defines */ ++#define OP_RXSTAT 0x60 ++#define OP_RXTIMESTAMP 0x61 ++#define OP_RXVLAN 0x62 ++#define OP_RXCHKS 0x64 ++#define OP_RXCHKSVLAN (OP_RXCHKS | OP_RXVLAN) ++#define OP_RXTIMEVLAN (OP_RXTIMESTAMP | OP_RXVLAN) ++#define OP_RSS_HASH 0x65 ++#define OP_TXINDEXLE 0x68 ++#define OP_MACSEC 0x6c /* Yukon-Ext only */ ++#define OP_MACSECVLAN (OP_MACSEC | OP_RXVLAN) /* Yukon-Ext only */ ++ ++/* YUKON-2 SPECIAL opcodes defines */ ++#define OP_PUTIDX 0x70 + + /* Descriptor Bit Definition */ + /* TxCtrl Transmit Buffer Control Field */ +@@ -1685,6 +2655,10 @@ + + /* macros ********************************************************************/ + ++/* Macro for accessing the key registers */ ++#define RSS_KEY_ADDR(Port, KeyIndex) \ ++ ((B4_RSS_KEY | ( ((Port) == 0) ? 0 : 0x80)) + (KeyIndex)) ++ + /* Receive and Transmit Queues */ + #define Q_R1 0x0000 /* Receive Queue 1 */ + #define Q_R2 0x0080 /* Receive Queue 2 */ +@@ -1693,6 +2667,10 @@ + #define Q_XS2 0x0300 /* Synchronous Transmit Queue 2 */ + #define Q_XA2 0x0380 /* Asynchronous Transmit Queue 2 */ + ++#define Q_ASF_R1 0x100 /* ASF Rx Queue 1 */ ++#define Q_ASF_R2 0x180 /* ASF Rx Queue 2 */ ++#define Q_ASF_T1 0x140 /* ASF Tx Queue 1 */ ++#define Q_ASF_T2 0x1c0 /* ASF Tx Queue 2 */ + /* + * Macro Q_ADDR() + * +@@ -1704,11 +2682,27 @@ + * 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) ++ * usage SK_IN32(IoC, Q_ADDR(Q_R2, Q_BC), pVal) + */ + #define Q_ADDR(Queue, Offs) (B8_Q_REGS + (Queue) + (Offs)) + + /* ++ * Macro Y2_PREF_Q_ADDR() ++ * ++ * Use this macro to access the Prefetch Units of the receive and ++ * transmit queues of Yukon-2. ++ * ++ * para: ++ * Queue Queue to access. ++ * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, Q_XA2, ++ * Offs Queue register offset. ++ * Values: PREF_UNIT_CTRL_REG ... PREF_UNIT_FIFO_LEV_REG ++ * ++ * usage SK_IN16(IoC, Y2_Q_ADDR(Q_R2, PREF_UNIT_GET_IDX_REG), pVal) ++ */ ++#define Y2_PREF_Q_ADDR(Queue, Offs) (Y2_B8_PREF_REGS + (Queue) + (Offs)) ++ ++/* + * Macro RB_ADDR() + * + * Use this macro to access the RAM Buffer Registers. +@@ -1719,14 +2713,14 @@ + * Offs Queue register offset. + * Values: RB_START, RB_END ... RB_LEV, RB_CTRL + * +- * usage SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal) ++ * usage SK_IN32(IoC, 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 */ ++#define MAC_1 0 /* 1st port */ ++#define MAC_2 1 /* 2nd port */ + + /* + * Macro MR_ADDR() +@@ -1740,19 +2734,10 @@ + * 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) ++ * usage SK_IN32(IoC, 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) + * +@@ -1777,22 +2762,31 @@ + #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_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_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]); \ ++#ifdef SK_LITTLE_ENDIAN ++ ++#define XM_IN32(IoC, Mac, Reg, pVal) { \ ++ SK_IN16(IoC, XMA(Mac, Reg), (SK_U16 SK_FAR *)(pVal)); \ ++ SK_IN16(IoC, XMA(Mac, (Reg) + 2), (SK_U16 SK_FAR *)(pVal) + 1); \ + } + ++#else /* !SK_LITTLE_ENDIAN */ ++ ++#define XM_IN32(IoC, Mac, Reg, pVal) { \ ++ SK_IN16(IoC, XMA(Mac, Reg), (SK_U16 SK_FAR *)(pVal) + 1); \ ++ SK_IN16(IoC, XMA(Mac, (Reg) + 2), (SK_U16 SK_FAR *)(pVal)); \ ++} ++ ++#endif /* !SK_LITTLE_ENDIAN */ ++ + #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));\ ++ 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 */ +@@ -1802,13 +2796,13 @@ + SK_U8 *pByte; \ + pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ + SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \ +- pByte[0] = (SK_U8)(Word & 0x00ff); \ ++ 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); \ ++ 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); \ ++ SK_IN16((IoC), XMA((Mac), (Reg) + 4), &Word); \ ++ pByte[4] = (SK_U8)(Word & 0x00ff); \ + pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \ + } + +@@ -1818,10 +2812,10 @@ + 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_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_OUT16((IoC), XMA((Mac), (Reg) + 4), (SK_U16) \ + (((SK_U16)(pByte[4]) & 0x00ff) | \ + (((SK_U16)(pByte[5]) << 8) & 0xff00))); \ + } +@@ -1831,16 +2825,16 @@ + 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[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); \ ++ 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); \ ++ 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); \ ++ SK_IN16((IoC), XMA((Mac), (Reg) + 6), &Word); \ ++ pByte[6] = (SK_U8)(Word & 0x00ff); \ + pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \ + } + +@@ -1850,13 +2844,13 @@ + 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_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_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_OUT16((IoC), XMA((Mac), (Reg) + 6), (SK_U16) \ + (((SK_U16)(pByte[6]) & 0x00ff)| \ + (((SK_U16)(pByte[7]) << 8) & 0xff00))); \ + } +@@ -1866,12 +2860,12 @@ + * + * 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_IN32(), to read a 32 bit register (e.g. GM_RXF_UC_OK) ++ * GM_OUT32(), to write a 32 bit register + * 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 ++ * GM_INHASH(), to read the hash registers (e.g. GM_MC_ADDR_H1..4) ++ * GM_OUTHASH() to write the hash registers (e.g. GM_MC_ADDR_H1..4) + * + * para: + * Mac GMAC to access values: MAC_1 or MAC_2 +@@ -1885,37 +2879,63 @@ + #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_IN16(IoC, Mac, Reg, pVal) { \ ++ SK_U8 Dummy; \ ++ SK_ACQ_SPIN_LOCK(IoC); \ ++ SK_IN16(IoC, GMA(Mac, Reg), pVal); \ ++ SK_IN8(IoC, B0_RAP, &Dummy); \ ++ SK_REL_SPIN_LOCK(IoC); \ ++} ++ ++#define GM_OUT16(IoC, Mac, Reg, Val) \ ++ SK_OUT16(IoC, GMA(Mac, Reg), Val) ++ ++#ifdef SK_LITTLE_ENDIAN ++ ++#define GM_IN32(IoC, Mac, Reg, pVal) { \ ++ SK_U8 Dummy; \ ++ SK_ACQ_SPIN_LOCK(IoC); \ ++ SK_IN16(IoC, GMA(Mac, Reg), (SK_U16 SK_FAR *)(pVal)); \ ++ SK_IN16((IoC), GMA(Mac, (Reg) + 4), (SK_U16 SK_FAR *)(pVal) + 1); \ ++ SK_IN8(IoC, B0_RAP, &Dummy); \ ++ SK_REL_SPIN_LOCK(IoC); \ ++} + +-#define GM_OUT16(IoC, Mac, Reg, Val) \ +- SK_OUT16((IoC), GMA((Mac), (Reg)), (Val)) ++#else /* !SK_LITTLE_ENDIAN */ + +-#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_IN32(IoC, Mac, Reg, pVal) { \ ++ SK_U8 Dummy; \ ++ SK_ACQ_SPIN_LOCK(IoC); \ ++ SK_IN16(IoC, GMA(Mac, Reg), (SK_U16 SK_FAR *)(pVal) + 1); \ ++ SK_IN16(IoC, GMA(Mac, (Reg) + 4), (SK_U16 SK_FAR *)(pVal)); \ ++ SK_IN8(IoC, B0_RAP, &Dummy); \ ++ SK_REL_SPIN_LOCK(IoC); \ + } + ++#endif /* !SK_LITTLE_ENDIAN */ ++ + #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));\ ++ 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_INADDR(IoC, Mac, Reg, pVal) { \ ++ SK_U16 Word; \ ++ SK_U8 Dummy; \ ++ SK_U8 *pByte; \ ++ pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ ++ SK_ACQ_SPIN_LOCK(IoC); \ ++ 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_IN8(IoC, B0_RAP, &Dummy); \ ++ SK_REL_SPIN_LOCK(IoC); \ + } + + #define GM_OUTADDR(IoC, Mac, Reg, pVal) { \ +@@ -1924,30 +2944,34 @@ + 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_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_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 Dummy; \ + SK_U8 *pByte; \ + pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ ++ SK_ACQ_SPIN_LOCK(IoC); \ + SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \ +- pByte[0] = (SK_U8)(Word & 0x00ff); \ ++ 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); \ ++ 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); \ ++ 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); \ ++ SK_IN16((IoC), GMA((Mac), (Reg) + 12), &Word); \ ++ pByte[6] = (SK_U8)(Word & 0x00ff); \ + pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \ ++ SK_IN8(IoC, B0_RAP, &Dummy); \ ++ SK_REL_SPIN_LOCK(IoC); \ + } + + #define GM_OUTHASH(IoC, Mac, Reg, pVal) { \ +@@ -1956,13 +2980,13 @@ + 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_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_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_OUT16((IoC), GMA((Mac), (Reg) + 12), (SK_U16) \ + (((SK_U16)(pByte[6]) & 0x00ff)| \ + (((SK_U16)(pByte[7]) << 8) & 0xff00))); \ + } +@@ -1980,8 +3004,8 @@ + #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 */ ++#define SK_PHY_MARV_COPPER 4 /* Marvell 88E1040S */ ++#define SK_PHY_MARV_FIBER 5 /* Marvell 88E1040S working on fiber */ + + /* + * PHY addresses (bits 12..8 of PHY address reg) +@@ -2010,30 +3034,30 @@ + * + * 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. ++ * comes back. This is checked in DEBUG mode. + */ + #ifndef DEBUG + #define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \ +- SK_U16 Mmu; \ ++ 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 { \ ++ 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; \ ++ 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 { \ ++ do { \ + XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \ + __i++; \ + if (__i > 100000) { \ +@@ -2044,7 +3068,7 @@ + } \ + } while ((Mmu & XM_MMU_PHY_RDY) == 0); \ + XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \ +- } \ ++ } \ + } + #endif /* DEBUG */ + +@@ -2052,17 +3076,17 @@ + SK_U16 Mmu; \ + \ + if ((pPort)->PhyType != SK_PHY_XMAC) { \ +- do { \ ++ 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 { \ ++ do { \ + XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \ + } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \ +- } \ ++ } \ + } + + /* +@@ -2071,12 +3095,14 @@ + * Use this macro to access PCI config register from the I/O space. + * + * para: ++ * pAC Pointer to adapter context + * Addr PCI configuration register to access. + * Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG, + * +- * usage SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal); ++ * usage SK_IN16(IoC, PCI_C(pAC, PCI_VENDOR_ID), pVal); + */ +-#define PCI_C(Addr) (B7_CFG_SPC + (Addr)) /* PCI Config Space */ ++#define PCI_C(p, Addr) \ ++ (((CHIP_ID_YUKON_2(p)) ? Y2_CFG_SPC : B7_CFG_SPC) + (Addr)) + + /* + * Macro SK_HW_ADDR(Base, Addr) +@@ -2088,7 +3114,7 @@ + * Addr Address offset + * + * usage: May be used in SK_INxx and SK_OUTxx macros +- * #define SK_IN8(pAC, Addr, pVal) ...\ ++ * #define SK_IN8(IoC, Addr, pVal) ...\ + * *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr))) + */ + #ifdef SK_MEM_MAPPED_IO +@@ -2107,20 +3133,31 @@ + * para: + * pAC Pointer to adapter context struct + * IoC I/O context needed for SK I/O macros +- * Port Port number ++ * 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); + ++#define SK_SET_GP_IO(IoC, Bit) { \ ++ SK_U32 DWord; \ ++ SK_IN32(IoC, B2_GP_IO, &DWord); \ ++ DWord |= ((GP_DIR_0 | GP_IO_0) << (Bit));\ ++ SK_OUT32(IoC, B2_GP_IO, DWord); \ ++} + +-/* typedefs *******************************************************************/ +- ++#define SK_CLR_GP_IO(IoC, Bit) { \ ++ SK_U32 DWord; \ ++ SK_IN32(IoC, B2_GP_IO, &DWord); \ ++ DWord &= ~((GP_DIR_0 | GP_IO_0) << (Bit));\ ++ SK_OUT32(IoC, B2_GP_IO, DWord); \ ++} + +-/* function prototypes ********************************************************/ ++#define SK_GE_PCI_FIFO_SIZE 1600 /* PCI FIFO Size */ + + #ifdef __cplusplus + } + #endif /* __cplusplus */ + + #endif /* __INC_SKGEHW_H */ ++ +diff -ruN linux/drivers/net/sk98lin/h/skgehwt.h linux-new/drivers/net/sk98lin/h/skgehwt.h +--- linux/drivers/net/sk98lin/h/skgehwt.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skgehwt.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,14 +2,15 @@ + * + * Name: skhwt.h + * Project: Gigabit Ethernet Adapters, Event Scheduler Module +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Defines for the hardware timer functions + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. + * +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +diff -ruN linux/drivers/net/sk98lin/h/skgei2c.h linux-new/drivers/net/sk98lin/h/skgei2c.h +--- linux/drivers/net/sk98lin/h/skgei2c.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skgei2c.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,210 +0,0 @@ +-/****************************************************************************** +- * +- * Name: skgei2c.h +- * Project: Gigabit Ethernet Adapters, TWSI-Module +- * Version: $Revision$ +- * Date: $Date$ +- * 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 -ruN linux/drivers/net/sk98lin/h/skgeinit.h linux-new/drivers/net/sk98lin/h/skgeinit.h +--- linux/drivers/net/sk98lin/h/skgeinit.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skgeinit.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,23 +2,24 @@ + * + * Name: skgeinit.h + * Project: Gigabit Ethernet Adapters, Common Modules +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Structures and prototypes for the GE Init Module + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2006 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. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -60,14 +61,17 @@ + #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_DEF 0x00ee6b28UL /* 250 ms at 62.5 MHz (Genesis) */ ++#define SK_DPOLL_DEF_Y2 0x0000124fUL /* 75 us (Yukon-2) */ + + #define SK_DPOLL_MAX 0x00ffffffUL /* 268 ms at 62.5 MHz */ +- /* 215 ms at 78.12 MHz */ ++ /* 215 ms at 78.12 MHz (Yukon) */ + + #define SK_FACT_62 100 /* is given in percent */ +-#define SK_FACT_53 85 /* on GENESIS: 53.12 MHz */ ++#define SK_FACT_53 85 /* on GENESIS: 53.12 MHz */ + #define SK_FACT_78 125 /* on YUKON: 78.12 MHz */ ++#define SK_FACT_100 161 /* on YUKON-FE: 100 MHz */ ++#define SK_FACT_125 202 /* on YUKON-EC: 125 MHz */ + + /* Timeout values */ + #define SK_MAC_TO_53 72 /* MAC arbiter timeout */ +@@ -82,11 +86,24 @@ + #define SK_RB_LLPP_S (10 * 1024) /* Lower Level for small Queues */ + #define SK_RB_LLPP_B (16 * 1024) /* Lower Level for big Queues */ + ++/* Threshold values for Yukon-EC Ultra and Extreme*/ ++#define SK_ECU_ULPP 0x0080 /* Upper Pause Threshold (multiples of 8) */ ++#define SK_ECU_LLPP 0x0060 /* Lower Pause Threshold (multiples of 8) */ ++#define SK_ECU_AE_THR 0x0070 /* Almost Empty Threshold */ ++#define SK_ECU_TXFF_LEV 0x01a0 /* Tx BMU FIFO Level */ ++#define SK_ECU_JUMBO_WM 0x0400 /* Jumbo Mode Watermark */ ++ + #ifndef SK_BMU_RX_WM +-#define SK_BMU_RX_WM 0x600 /* BMU Rx Watermark */ ++#define SK_BMU_RX_WM 0x600 /* BMU Rx Watermark */ + #endif ++ + #ifndef SK_BMU_TX_WM +-#define SK_BMU_TX_WM 0x600 /* BMU Tx Watermark */ ++#define SK_BMU_TX_WM 0x600 /* BMU Tx Watermark */ ++#endif ++ ++/* performance sensitive drivers should set this define to 0x80 */ ++#ifndef SK_BMU_RX_WM_PEX ++#define SK_BMU_RX_WM_PEX 0x80 /* BMU Rx Watermark for PEX */ + #endif + + /* XMAC II Rx High Watermark */ +@@ -98,37 +115,31 @@ + #define SK_XM_THR_MULL 0x01fb /* .. for multiple link usage */ + #define SK_XM_THR_JUMBO 0x03fc /* .. for jumbo frame usage */ + +-/* values for GIPortUsage */ ++/* values for PortUsage */ + #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 */ ++#define SK_MIN_RXQ_SIZE (((pAC)->GIni.GIYukon2) ? 10 : 16) /* 10/16 kB */ + + /* Minimum RAM Buffer Tx Queue Size */ +-#define SK_MIN_TXQ_SIZE 16 /* 16 kB */ ++#define SK_MIN_TXQ_SIZE (((pAC)->GIni.GIYukon2) ? 10 : 16) /* 10/16 kB */ + +-/* Queue Size units */ +-#define QZ_UNITS 0x7 ++/* Queue Size units (Genesis/Yukon) */ ++#define QZ_UNITS 7 + #define QZ_STEP 8 + ++/* Queue Size units (Yukon-2) */ ++#define QZ_STEP_Y2 1 ++ + /* Percentage of queue size from whole memory */ + /* 80 % for receive */ +-#define RAM_QUOTA_RX 80L +-/* 0% for sync transfer */ +-#define RAM_QUOTA_SYNC 0L ++#define RAM_QUOTA_RX 80 ++/* 0 % for sync transfer */ ++#define RAM_QUOTA_SYNC 0 + /* 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 */ +@@ -167,11 +178,11 @@ + + + /* 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 */ ++#define SK_LSPEED_CAP_AUTO BIT_0S /* Automatic resolution */ ++#define SK_LSPEED_CAP_10MBPS BIT_1S /* 10 Mbps */ ++#define SK_LSPEED_CAP_100MBPS BIT_2S /* 100 Mbps */ ++#define SK_LSPEED_CAP_1000MBPS BIT_3S /* 1000 Mbps */ ++#define SK_LSPEED_CAP_INDETERMINATED BIT_4S /* indeterminated */ + + /* Link Speed Parameter */ + #define SK_LSPEED_AUTO 1 /* Automatic resolution */ +@@ -189,11 +200,11 @@ + + + /* 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 */ ++#define SK_LMODE_CAP_HALF BIT_0S /* Half Duplex Mode */ ++#define SK_LMODE_CAP_FULL BIT_1S /* Full Duplex Mode */ ++#define SK_LMODE_CAP_AUTOHALF BIT_2S /* AutoHalf Duplex Mode */ ++#define SK_LMODE_CAP_AUTOFULL BIT_3S /* AutoFull Duplex Mode */ ++#define SK_LMODE_CAP_INDETERMINATED BIT_4S /* indeterminated */ + + /* Link Mode Current State */ + #define SK_LMODE_STAT_UNKNOWN 1 /* Unknown Duplex Mode */ +@@ -204,7 +215,7 @@ + #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_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 +@@ -220,10 +231,10 @@ + #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 */ ++#define SK_MS_CAP_AUTO BIT_0S /* Automatic resolution */ ++#define SK_MS_CAP_MASTER BIT_1S /* This station is master */ ++#define SK_MS_CAP_SLAVE BIT_2S /* This station is slave */ ++#define SK_MS_CAP_INDETERMINATED BIT_3S /* indeterminated */ + + /* Set Master/Slave Mode Parameter (and capabilities) */ + #define SK_MS_MODE_AUTO 1 /* Automatic resolution */ +@@ -238,25 +249,25 @@ + #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 'Mode' when calling SkMacSetRxCmd() */ ++#define SK_STRIP_FCS_ON BIT_0S /* Enable FCS stripping of Rx frames */ ++#define SK_STRIP_FCS_OFF BIT_1S /* Disable FCS stripping of Rx frames */ ++#define SK_STRIP_PAD_ON BIT_2S /* Enable pad byte stripping of Rx fr */ ++#define SK_STRIP_PAD_OFF BIT_3S /* Disable pad byte stripping of Rx fr */ ++#define SK_LENERR_OK_ON BIT_4S /* Don't chk fr for in range len error */ ++#define SK_LENERR_OK_OFF BIT_5S /* Check frames for in range len error */ ++#define SK_BIG_PK_OK_ON BIT_6S /* Don't set Rx Error bit for big frames */ ++#define SK_BIG_PK_OK_OFF BIT_7S /* Set Rx Error bit for big frames */ ++#define SK_SELF_RX_ON BIT_8S /* Enable Rx of own packets */ ++#define SK_SELF_RX_OFF BIT_9S /* 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 */ ++#define SK_MAC_LOOPB_ON BIT_0S /* Enable MAC Loopback Mode */ ++#define SK_MAC_LOOPB_OFF BIT_1S /* Disable MAC Loopback Mode */ ++#define SK_PHY_LOOPB_ON BIT_2S /* Enable PHY Loopback Mode */ ++#define SK_PHY_LOOPB_OFF BIT_3S /* Disable PHY Loopback Mode */ ++#define SK_PHY_FULLD_ON BIT_4S /* Enable GMII Full Duplex */ ++#define SK_PHY_FULLD_OFF BIT_5S /* Disable GMII Full Duplex */ + + /* States of PState */ + #define SK_PRT_RESET 0 /* the port is reset */ +@@ -266,18 +277,25 @@ + + /* 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_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 */ ++#define PHY_PM_ENERGY_DETECT 3 /* Energy detect */ ++#define PHY_PM_ENERGY_DETECT_PLUS 4 /* Energy detect plus */ ++ ++/* PCI Bus Types */ ++#define SK_PCI_BUS BIT_0S /* normal PCI bus */ ++#define SK_PCIX_BUS BIT_1S /* PCI-X bus */ ++#define SK_PEX_BUS BIT_2S /* PCI-Express bus */ + + /* 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 */ ++#define SK_ACT_LED_BLINK BIT_0S /* Active LED blinking */ ++#define SK_DUP_LED_NORMAL BIT_1S /* Duplex LED normal */ ++#define SK_LED_LINK100_ON BIT_2S /* Link 100M LED on */ ++#define SK_DUAL_LED_ACT_LNK BIT_3S /* Dual LED ACT/LNK configuration */ ++#define SK_LED_LINK_MUX_P60 BIT_4S /* Link LED muxed to pin 60 */ + + /* Link Partner Status */ + #define SK_LIPA_UNKNOWN 0 /* Link partner is in unknown state */ +@@ -290,18 +308,204 @@ + /* 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 */ + ++ ++/****************************************************************************** ++ * ++ * HW_FEATURE() macro ++ */ ++ ++/* DWORD 0: Features */ ++#define HWF_ENA_POW_SAV_W_WOL 0x08000000UL /* Power saving with WOL ena. */ ++#define HWF_FORCE_AUTO_NEG 0x04000000UL /* Force Auto-Negotiation */ ++#define HWF_CLK_GATING_ENABLE 0x02000000UL /* Enable Clock Gating */ ++#define HWF_RED_CORE_CLK_SUP 0x01000000UL /* Reduced Core Clock supp. */ ++#define HWF_RESTORE_LOST_BARS 0x00800000UL /* Save and restore PCI BARs */ ++#define HWF_ASPM_SWITCHING 0x00400000UL /* Activate ASPM feature */ ++#define HWF_TX_IP_ID_INCR_ON 0x00200000UL /* Enable Tx IP ID Increment */ ++ ++/*-RMV- DWORD 1: Deviations */ ++#define HWF_WA_DEV_53 0x11000000UL /*-RMV- 5.3 (Tx Done LSOv2 rep)*/ ++#define HWF_WA_DEV_LIM_IPV6_RSS 0x10800000UL /*-RMV- IPV6 RSS limitted */ ++#define HWF_WA_DEV_4217 0x10400000UL /*-RMV- 4.217 (PCI-E blockage) */ ++#define HWF_WA_DEV_4200 0x10200000UL /*-RMV- 4.200 (D3 Blue Screen)*/ ++#define HWF_WA_DEV_4185CS 0x10100000UL /*-RMV- 4.185 (ECU 100 CS cal)*/ ++#define HWF_WA_DEV_4185 0x10080000UL /*-RMV- 4.185 (ECU Tx h check)*/ ++#define HWF_WA_DEV_4167 0x10040000UL /*-RMV- 4.167 (Rx OvSize Hang)*/ ++#define HWF_WA_DEV_4152 0x10020000UL /*-RMV- 4.152 (RSS issue) */ ++#define HWF_WA_DEV_4115 0x10010000UL /*-RMV- 4.115 (Rx MAC FIFO) */ ++#define HWF_WA_DEV_4109 0x10008000UL /*-RMV- 4.109 (BIU hang) */ ++#define HWF_WA_DEV_483 0x10004000UL /*-RMV- 4.83 (Rx TCP wrong) */ ++#define HWF_WA_DEV_479 0x10002000UL /*-RMV- 4.79 (Rx BMU hang II) */ ++#define HWF_WA_DEV_472 0x10001000UL /*-RMV- 4.72 (GPHY2 MDC clk) */ ++#define HWF_WA_DEV_463 0x10000800UL /*-RMV- 4.63 (Rx BMU hang I) */ ++#define HWF_WA_DEV_427 0x10000400UL /*-RMV- 4.27 (Tx Done Rep) */ ++#define HWF_WA_DEV_42 0x10000200UL /*-RMV- 4.2 (pref unit burst) */ ++#define HWF_WA_DEV_46 0x10000100UL /*-RMV- 4.6 (CPU crash II) */ ++#define HWF_WA_DEV_43_418 0x10000080UL /*-RMV- 4.3 & 4.18 (PCI unexp */ ++ /*-RMV- compl&Stat BMU deadl) */ ++#define HWF_WA_DEV_420 0x10000040UL /*-RMV- 4.20 (Status BMU ov) */ ++#define HWF_WA_DEV_423 0x10000020UL /*-RMV- 4.23 (TCP Segm Hang) */ ++#define HWF_WA_DEV_424 0x10000010UL /*-RMV- 4.24 (MAC reg overwr) */ ++#define HWF_WA_DEV_425 0x10000008UL /*-RMV- 4.25 (Magic packet */ ++ /*-RMV- with odd offset) */ ++#define HWF_WA_DEV_428 0x10000004UL /*-RMV- 4.28 (Poll-U &BigEndi)*/ ++#define HWF_WA_FIFO_FLUSH_YLA0 0x10000002UL /*-RMV- dis Rx GMAC FIFO Flush*/ ++ /*-RMV- for Yu-L Rev. A0 only */ ++#define HWF_WA_COMA_MODE 0x10000001UL /*-RMV- Coma Mode WA req */ ++ ++/* DWORD 2: Real HW features not settable from outside */ ++/* not yet used */ ++#if 0 ++#define HWF_SYNC_TX_SUP 0x20800000UL /* Synch. Tx Queue available */ ++#define HWF_SINGLE_PORT_DEVICE 0x20400000UL /* Device has only one LAN IF */ ++#define HWF_JUMBO_FRAMES_SUP 0x20200000UL /* Jumbo Frames supported */ ++#define HWF_TX_TCP_CSUM_SUP 0x20100000UL /* TCP Tx checksum supported */ ++#define HWF_TX_UDP_CSUM_SUP 0x20080000UL /* UDP Tx checksum supported */ ++#define HWF_RX_CSUM_SUP 0x20040000UL /* RX checksum supported */ ++#define HWF_TCP_SEGM_SUP 0x20020000UL /* TCP segmentation supported */ ++#define HWF_RSS_HASH_SUP 0x20010000UL /* RSS Hash supported */ ++#define HWF_PORT_VLAN_SUP 0x20008000UL /* VLAN can be config per port*/ ++#define HWF_ROLE_PARAM_SUP 0x20004000UL /* Role parameter supported */ ++#define HWF_LOW_PMODE_SUP 0x20002000UL /* Low Power Mode supported */ ++#define HWF_ENERGIE_DEMO_SUP 0x20001000UL /* Energy Detect mode supp. */ ++#define HWF_SPEED1000_SUP 0x20000800UL /* Line Speed 1000 supported */ ++#define HWF_SPEED100_SUP 0x20000400UL /* Line Speed 100 supported */ ++#define HWF_SPEED10_SUP 0x20000200UL /* Line Speed 10 supported */ ++#define HWF_AUTONEGSENSE_SUP 0x20000100UL /* Autoneg Sense supported */ ++#define HWF_PHY_LOOPB_MD_SUP 0x20000080UL /* PHY loopback mode supp. */ ++#define HWF_ASF_SUP 0x20000040UL /* ASF support possible */ ++#define HWF_QS_STEPS_1KB 0x20000020UL /* The Rx/Tx queues can be */ ++ /* configured with 1 kB res. */ ++#define HWF_OWN_RAM_PER_PORT 0x20000010UL /* Each port has a separate */ ++ /* RAM buffer */ ++#define HWF_MIN_LED_IF 0x20000008UL /* Minimal LED interface */ ++ /* (e.g. for Yukon-EC) */ ++#define HWF_LIST_ELEMENTS_USED 0x20000004UL /* HW uses list elements */ ++ /* (otherwise desc. are used) */ ++#define HWF_GMAC_INSIDE 0x20000002UL /* Device contains GMAC */ ++#define HWF_TWSI_PRESENT 0x20000001UL /* TWSI sensor bus present */ ++#endif ++ ++/* DWORD 3: still unused */ ++ ++ ++/* ++ * HW_FEATURE() - returns whether the feature is serviced or not ++ */ ++#define HW_FEATURE(pAC, ReqFeature) \ ++ (((pAC)->GIni.HwF.Features[((ReqFeature) & 0x30000000UL) >> 28] &\ ++ ((ReqFeature) & 0x0fffffffUL)) != 0) ++ ++#define HW_FEAT_LIST 0 ++#define HW_DEV_LIST 1 ++#define HW_FEAT_LIST_2 2 ++ ++#define SET_HW_FEATURE_MASK(pAC, List, OffMaskValue, OnMaskValue) { \ ++ if ((List) == HW_FEAT_LIST || (List) == HW_DEV_LIST) { \ ++ (pAC)->GIni.HwF.OffMask[List] = (OffMaskValue); \ ++ (pAC)->GIni.HwF.OnMask[List] = (OnMaskValue); \ ++ } \ ++} ++ ++/* driver access macros for GIni structure ***********************************/ ++ ++#define CHIP_ID_YUKON_2(pAC) ((pAC)->GIni.GIYukon2) ++ ++#define HW_SYNC_TX_SUPPORTED(pAC) \ ++ ((pAC)->GIni.GIChipId != CHIP_ID_YUKON_EC && \ ++ (pAC)->GIni.GIChipId != CHIP_ID_YUKON_FE && \ ++ (pAC)->GIni.GIChipId != CHIP_ID_YUKON_EC_U && \ ++ (pAC)->GIni.GIChipId != CHIP_ID_YUKON_EX) ++ ++#define HW_MS_TO_TICKS(pAC, MsTime) \ ++ ((MsTime) * (62500L/100) * (pAC)->GIni.GIHstClkFact) ++ ++#define HW_IS_8056(pAC) \ ++ ((pAC)->GIni.GIChipId == CHIP_ID_YUKON_EC_U && \ ++ ((pAC)->GIni.GIChipRev == CHIP_REV_YU_EC_U_A1 || \ ++ (pAC)->GIni.GIChipRev == CHIP_REV_YU_EC_U_B0) && \ ++ (pAC)->GIni.GIChipCap == 2 && \ ++ !HW_FEATURE(pAC, HWF_WA_DEV_4200)) ++ ++#define HW_IS_EXT_LE_FORMAT(pAC) ((pAC)->GIni.GIExtLeFormat) ++#define HW_IS_NEW_ASF_FORMAT(pAC) ((pAC)->GIni.GIExtLeFormat) ++#define HW_IS_TCP_JUMBO_SUP(pAC) ((pAC)->GIni.GIJumTcpSegSup) ++ ++#define HW_IS_RAM_IF_AVAIL(pAC) ( \ ++ !((pAC)->GIni.GIChipId == CHIP_ID_YUKON_EC_U || \ ++ (pAC)->GIni.GIChipId == CHIP_ID_YUKON_EX)) ++ ++#define HW_NUM_OF_PATTERN(pAC) ((pAC)->GIni.GINumOfPattern) ++ ++#ifdef XXX ++/* still under construction */ ++#define HW_IS_SINGLE_PORT(pAC) ((pAC)->GIni.GIMacsFound == 1) ++#define HW_NUMBER_OF_PORTS(pAC) ((pAC)->GIni.GIMacsFound) ++ ++#define HW_TX_UDP_CSUM_SUPPORTED(pAC) \ ++ ((((pAC)->GIni.GIChipId >= CHIP_ID_YUKON) && ((pAC)->GIni.GIChipRev != 0)) ++ ++#define HW_DEFAULT_LINESPEED(pAC) \ ++ ((!(pAC)->GIni.GIGenesis && (pAC)->GIni.GICopperType) ? \ ++ SK_LSPEED_AUTO : SK_LSPEED_1000MBPS) ++ ++#define HW_ROLE_PARAM_SUPPORTED(pAC) ((pAC)->GIni.GICopperType) ++ ++#define HW_SPEED1000_SUPPORTED(pAC, Port) \ ++ ((pAC)->GIni.GP[Port].PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) ++ ++#define HW_SPEED100_SUPPORTED(pAC, Port) \ ++ ((pAC)->GIni.GP[Port].PLinkSpeedCap & SK_LSPEED_CAP_100MBPS) ++ ++#define HW_SPEED10_SUPPORTED(pAC, Port) \ ++ ((pAC)->GIni.GP[Port].PLinkSpeedCap & SK_LSPEED_CAP_10MBPS) ++ ++#define HW_AUTONEGSENSE_SUPPORTED(pAC) ((pAC)->GIni.GP[0].PhyType==SK_PHY_XMAC) ++ ++#define HW_FREQ_TO_CARD_TICKS(pAC, AdapterClkSpeed, Freq) \ ++ (((AdapterClkSpeed / 100) * (pAC)->GIni.GIHstClkFact) / Freq) ++ ++#define HW_IS_LINK_UP(pAC, Port) ((pAC)->GIni.GP[Port].PHWLinkUp) ++#define HW_LINK_SPEED_USED(pAC, Port) ((pAC)->GIni.GP[Port].PLinkSpeedUsed) ++#define HW_RAM_SIZE(pAC) ((pAC)->GIni.GIRamSize) ++ ++#define HW_PHY_LP_MODE_SUPPORTED(pAC) (pAC0->??? ++#define HW_ASF_ACTIVE(pAC) ??? ++#define RAWIO_OUT32(pAC, pAC->RegIrqMask, pAC->GIni.GIValIrqMask)... ++ ++/* macro to check whether Tx checksum is supported */ ++#define HW_TX_CSUM_SUPPORTED(pAC) ((pAC)->GIni.GIChipId != CHIP_ID_GENESIS) ++ ++BMU_UDP_CHECK : BMU_TCP_CHECK; ++ ++/* macro for - Own Bit mirrored to DWORD7 (Yukon LP receive descriptor) */ ++#endif /* 0 */ ++ ++ + /* structures *****************************************************************/ + + /* ++ * HW Feature structure ++ */ ++typedef struct s_HwFeatures { ++ SK_U32 Features[4]; /* Feature list */ ++ SK_U32 OffMask[4]; /* Off Mask */ ++ SK_U32 OnMask[4]; /* On Mask */ ++} SK_HW_FEATURES; ++ ++/* + * 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); ++ int (*pFnMacUpdateStats)(SK_AC *, SK_IOC, unsigned int); ++ int (*pFnMacStatistic)(SK_AC *, SK_IOC, unsigned int, SK_U16, SK_U32 SK_FAR *); ++ int (*pFnMacResetCounter)(SK_AC *, SK_IOC, unsigned int); ++ int (*pFnMacOverflow)(SK_AC *, SK_IOC, unsigned int, SK_U16, SK_U64 SK_FAR *); ++ void (*pSkGeSirqIsr)(SK_AC *, SK_IOC, SK_U32); ++#ifdef SK_DIAG ++ int (*pFnMacPhyRead)(SK_AC *, SK_IOC, int, int, SK_U16 SK_FAR *); ++ int (*pFnMacPhyWrite)(SK_AC *, SK_IOC, int, int, SK_U16); ++#endif /* SK_DIAG */ + } SK_GEMACFUNC; + + /* +@@ -311,7 +515,7 @@ + #ifndef SK_DIAG + SK_TIMER PWaTimer; /* Workaround Timer */ + SK_TIMER HalfDupChkTimer; +-#endif /* SK_DIAG */ ++#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 */ +@@ -335,6 +539,7 @@ + int PXaQOff; /* Asynchronous Tx Queue Address Offset */ + int PhyType; /* PHY used on this port */ + int PState; /* Port status (reset, stop, init, run) */ ++ int PPortUsage; /* Driver Port Usage */ + SK_U16 PhyId1; /* PHY Id1 on this port */ + SK_U16 PhyAddr; /* MDIO/MDC PHY address */ + SK_U16 PIsave; /* Saved Interrupt status word */ +@@ -348,7 +553,7 @@ + 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 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 */ +@@ -357,6 +562,7 @@ + SK_U8 PMSCap; /* Master/Slave Capabilities */ + SK_U8 PMSMode; /* Master/Slave Mode */ + SK_U8 PMSStatus; /* Master/Slave Status */ ++ SK_BOOL PEnDetMode; /* Energy Detect Mode */ + SK_BOOL PAutoNegFail; /* Auto-negotiation fail flag */ + SK_U8 PLipaAutoNeg; /* Auto-negotiation possible with Link Partner */ + SK_U8 PCableLen; /* Cable Length */ +@@ -367,7 +573,10 @@ + int PMacJamLen; /* MAC Jam length */ + int PMacJamIpgVal; /* MAC Jam IPG */ + int PMacJamIpgData; /* MAC IPG Jam to Data */ ++ int PMacBackOffLim; /* MAC Back-off Limit */ ++ int PMacDataBlind; /* MAC Data Blinder */ + int PMacIpgData; /* MAC Data IPG */ ++ SK_U16 PMacAddr[3]; /* MAC address */ + SK_BOOL PMacLimit4; /* reset collision counter and backoff algorithm */ + } SK_GEPORT; + +@@ -379,34 +588,50 @@ + int GIChipId; /* Chip Identification Number */ + int GIChipRev; /* Chip Revision Number */ + SK_U8 GIPciHwRev; /* PCI HW Revision Number */ ++ SK_U8 GIPciBus; /* PCI Bus Type (PCI / PCI-X / PCI-Express) */ ++ SK_U8 GIPciMode; /* PCI / PCI-X Mode @ Clock */ ++ SK_U8 GIPexWidth; /* PCI-Express Negotiated Link Width */ + SK_BOOL GIGenesis; /* Genesis adapter ? */ +- SK_BOOL GIYukon; /* YUKON-A1/Bx chip */ ++ SK_BOOL GIYukon; /* YUKON family (1 and 2) */ + SK_BOOL GIYukonLite; /* YUKON-Lite chip */ ++ SK_BOOL GIYukon2; /* YUKON-2 chip (-XL, -EC or -FE) */ ++ SK_U8 GIConTyp; /* Connector Type */ ++ SK_U8 GIPmdTyp; /* PMD Type */ + 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 GIVMainAvail; /* VMAIN available */ + SK_BOOL GIYukon32Bit; /* 32-Bit YUKON adapter */ ++ SK_BOOL GIAsfEnabled; /* ASF subsystem enabled */ ++ SK_BOOL GIAsfRunning; /* ASF subsystem running */ ++ SK_BOOL GIExtLeFormat; /* Extended list element format (Yukon-Ext) */ ++ SK_BOOL GIJumTcpSegSup; /* TCP Segmentation of Jumbo frames supported ?*/ ++ SK_BOOL GIGotoD3Cold; /* System set to D3cold */ + 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 GIChipCap; /* Adapter's Capabilities */ ++ int GIHwResInfo; /* HW Resources / Application Information */ ++ int GIHstClkFact; /* Host Clock Factor (HstClk / 62.5 * 100) */ + 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) */ ++ int GINumOfPattern; /* Number of Pattern supported by HW */ + 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 GIValHwIrqMask; /* Value for HWE Interrupt Mask */ + SK_U32 GITimeStampCnt; /* Time Stamp High Counter (YUKON only) */ + SK_GEPORT GP[SK_MAX_MACS];/* Port Dependent Information */ ++ SK_HW_FEATURES HwF; /* HW Features struct */ + 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_E001 (SK_ERRBASE_HWINIT+1) + #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" +@@ -417,7 +642,7 @@ + #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_E006MSG "SkGeInit() called with illegal Chip Id" + #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) +@@ -433,11 +658,11 @@ + #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_E014MSG "SkGeInitPort(): unknown PortUsage specified" + #define SKERR_HWI_E015 (SKERR_HWI_E014+1) +-#define SKERR_HWI_E015MSG "Illegal Link mode parameter" ++#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_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) +@@ -447,15 +672,19 @@ + #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_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 "" ++#define SKERR_HWI_E025MSG "Link Partner not Auto-Neg. able" ++#define SKERR_HWI_E026 (SKERR_HWI_E025+1) ++#define SKERR_HWI_E026MSG "PEX negotiated Link width not max." ++#define SKERR_HWI_E027 (SKERR_HWI_E026+1) ++#define SKERR_HWI_E027MSG "" + + /* function prototypes ********************************************************/ + +@@ -464,6 +693,30 @@ + /* + * public functions in skgeinit.c + */ ++extern void SkGePortVlan( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ int Port, ++ SK_BOOL Enable); ++ ++extern void SkGeRxRss( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ int Port, ++ SK_BOOL Enable); ++ ++extern void SkGeRxCsum( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ int Port, ++ SK_BOOL Enable); ++ ++extern void SkGePollRxD( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ int Port, ++ SK_BOOL PollRxD); ++ + extern void SkGePollTxD( + SK_AC *pAC, + SK_IOC IoC, +@@ -516,11 +769,28 @@ + int Led, + int Mode); + ++extern void SkGeInitRamIface( ++ SK_AC *pAC, ++ SK_IOC IoC); ++ + extern int SkGeInitAssignRamToQueues( + SK_AC *pAC, +- int ActivePort, ++ int Port, + SK_BOOL DualNet); + ++extern void DoInitRamQueue( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ int QuIoOffs, ++ SK_U32 QuStartAddr, ++ SK_U32 QuEndAddr, ++ int QuType); ++ ++extern int SkYuk2RestartRxBmu( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ int Port); ++ + /* + * public functions in skxmac2.c + */ +@@ -539,6 +809,11 @@ + 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, +@@ -565,6 +840,11 @@ + 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, +@@ -581,7 +861,13 @@ + int Port, + SK_U16 IStatus); + +-extern int SkMacRxTxEnable( ++extern void SkMacSetRxTxEn( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ int Port, ++ int Para); ++ ++extern int SkMacRxTxEnable( + SK_AC *pAC, + SK_IOC IoC, + int Port); +@@ -598,28 +884,34 @@ + int Port, + SK_BOOL Enable); + +-extern void SkXmPhyRead( ++extern void SkMacTimeStamp( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ int Port, ++ SK_BOOL Enable); ++ ++extern int SkXmPhyRead( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Addr, + SK_U16 SK_FAR *pVal); + +-extern void SkXmPhyWrite( ++extern int SkXmPhyWrite( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Addr, + SK_U16 Val); + +-extern void SkGmPhyRead( ++extern int SkGmPhyRead( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Addr, + SK_U16 SK_FAR *pVal); + +-extern void SkGmPhyWrite( ++extern int SkGmPhyWrite( + SK_AC *pAC, + SK_IOC IoC, + int Port, +@@ -633,6 +925,16 @@ + 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, +@@ -677,7 +979,7 @@ + SK_AC *pAC, + SK_IOC IoC, + unsigned int Port, +- SK_U16 IStatus, ++ SK_U16 IStatus, + SK_U64 SK_FAR *pStatus); + + extern int SkGmOverflowStatus( +@@ -693,6 +995,19 @@ + int Port, + SK_BOOL StartTest); + ++#ifdef SK_PHY_LP_MODE ++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); ++#endif /* SK_PHY_LP_MODE */ ++ + #ifdef SK_DIAG + extern void SkGePhyRead( + SK_AC *pAC, +@@ -718,11 +1033,6 @@ + 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, +@@ -735,6 +1045,7 @@ + /* + * public functions in skgeinit.c + */ ++extern void SkGePollRxD(); + extern void SkGePollTxD(); + extern void SkGeYellowLED(); + extern int SkGeCfgSync(); +@@ -744,30 +1055,42 @@ + extern void SkGeDeInit(); + extern int SkGeInitPort(); + extern void SkGeXmitLED(); ++extern void SkGeInitRamIface(); + extern int SkGeInitAssignRamToQueues(); ++extern void SkGePortVlan(); ++extern void SkGeRxCsum(); ++extern void SkGeRxRss(); ++extern void DoInitRamQueue(); ++extern int SkYuk2RestartRxBmu(); + + /* + * public functions in skxmac2.c + */ +-extern void SkMacRxTxDisable(); ++extern void SkMacRxTxDisable(); + extern void SkMacSoftRst(); + extern void SkMacHardRst(); +-extern void SkMacInitPhy(); +-extern int SkMacRxTxEnable(); +-extern void SkMacPromiscMode(); +-extern void SkMacHashing(); +-extern void SkMacIrqDisable(); ++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 SkMacTimeStamp(); + extern void SkXmInitMac(); +-extern void SkXmPhyRead(); +-extern void SkXmPhyWrite(); ++extern int SkXmPhyRead(); ++extern int SkXmPhyWrite(); + extern void SkGmInitMac(); +-extern void SkGmPhyRead(); +-extern void SkGmPhyWrite(); ++extern int SkGmPhyRead(); ++extern int SkGmPhyWrite(); + extern void SkXmClrExactAddr(); ++extern void SkXmInitDupMd(); ++extern void SkXmInitPauseMd(); + extern void SkXmAutoNegLipaXmac(); + extern int SkXmUpdateStats(); + extern int SkGmUpdateStats(); +@@ -778,20 +1101,24 @@ + extern int SkXmOverflowStatus(); + extern int SkGmOverflowStatus(); + extern int SkGmCableDiagStatus(); ++#ifdef SK_PHY_LP_MODE ++extern int SkGmEnterLowPowerMode(); ++extern int SkGmLeaveLowPowerMode(); ++#endif /* SK_PHY_LP_MODE */ + + #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 */ ++#endif /* SK_KR_PROTO */ + + #ifdef __cplusplus + } +-#endif /* __cplusplus */ ++#endif /* __cplusplus */ ++ ++#endif /* __INC_SKGEINIT_H_ */ + +-#endif /* __INC_SKGEINIT_H_ */ +diff -ruN linux/drivers/net/sk98lin/h/skgepnm2.h linux-new/drivers/net/sk98lin/h/skgepnm2.h +--- linux/drivers/net/sk98lin/h/skgepnm2.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skgepnm2.h 2007-01-24 14:03:40.000000000 +0100 +@@ -1,17 +1,18 @@ + /***************************************************************************** + * + * Name: skgepnm2.h +- * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ ++ * Project: Gigabit Ethernet Adapters, PNMI-Module ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Defines for Private Network Management Interface + * + ****************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2007 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 +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -28,10 +30,15 @@ + /* + * General definitions + */ +-#define SK_PNMI_CHIPSET_XMAC 1 /* XMAC11800FP */ +-#define SK_PNMI_CHIPSET_YUKON 2 /* YUKON */ ++#define SK_PNMI_CHIPSET_XMAC 1 /* XMAC11800FP */ ++#define SK_PNMI_CHIPSET_YUKON 2 /* YUKON */ ++#define SK_PNMI_CHIPSET_YUKON_LITE 3 /* YUKON-Lite (Rev. A1-A3) */ ++#define SK_PNMI_CHIPSET_YUKON_LP 4 /* YUKON-LP */ ++#define SK_PNMI_CHIPSET_YUKON_XL 5 /* YUKON-2 XL */ ++#define SK_PNMI_CHIPSET_YUKON_EC 6 /* YUKON-2 EC */ ++#define SK_PNMI_CHIPSET_YUKON_FE 7 /* YUKON-2 FE */ + +-#define SK_PNMI_BUS_PCI 1 /* PCI bus*/ ++#define SK_PNMI_BUS_PCI 1 /* PCI bus*/ + + /* + * Actions +@@ -70,9 +77,9 @@ + /* + * VCT internal status values + */ +-#define SK_PNMI_VCT_PENDING 32 +-#define SK_PNMI_VCT_TEST_DONE 64 +-#define SK_PNMI_VCT_LINK 128 ++#define SK_PNMI_VCT_PENDING 0x20 ++#define SK_PNMI_VCT_TEST_DONE 0x40 ++#define SK_PNMI_VCT_LINK 0x80 + + /* + * Internal table definitions +@@ -147,7 +154,7 @@ + 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, +@@ -185,9 +192,9 @@ + 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 */ + }; + +@@ -196,7 +203,7 @@ + */ + typedef struct s_PnmiStatAddr { + SK_U16 Reg; /* MAC register containing the value */ +- SK_BOOL GetOffset; /* TRUE: Offset managed by PNMI (call GetStatVal())*/ ++ SK_BOOL GetOffset; /* TRUE: Offset managed by PNMI (GetStatVal()) */ + } SK_PNMI_STATADDR; + + +@@ -323,7 +330,7 @@ + vSt, \ + pAC->Pnmi.MacUpdatedFlag, \ + pAC->Pnmi.RlmtUpdatedFlag, \ +- pAC->Pnmi.SirqUpdatedFlag))}} ++ pAC->Pnmi.SirqUpdatedFlag));}} + + #else /* !DEBUG */ + +diff -ruN linux/drivers/net/sk98lin/h/skgepnmi.h linux-new/drivers/net/sk98lin/h/skgepnmi.h +--- linux/drivers/net/sk98lin/h/skgepnmi.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skgepnmi.h 2007-01-24 13:58:34.000000000 +0100 +@@ -1,17 +1,18 @@ + /***************************************************************************** + * + * Name: skgepnmi.h +- * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ ++ * Project: Gigabit Ethernet Adapters, PNMI-Module ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Defines for Private Network Management Interface + * + ****************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2007 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 +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -31,7 +33,7 @@ + #include "h/sktypes.h" + #include "h/skerror.h" + #include "h/sktimer.h" +-#include "h/ski2c.h" ++#include "h/sktwsi.h" + #include "h/skaddr.h" + #include "h/skrlmt.h" + #include "h/skvpd.h" +@@ -41,7 +43,6 @@ + */ + #define SK_PNMI_MDB_VERSION 0x00030001 /* 3.1 */ + +- + /* + * Event definitions + */ +@@ -54,16 +55,13 @@ + #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. */ +- ++#define SK_PNMI_EVT_RLMT_SET_NETS 16 /* Number of nets (1 or 2). */ ++#define SK_PNMI_EVT_VCT_RESET 17 /* VCT port reset timer event started with SET. */ + + /* + * Return values +@@ -78,7 +76,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() +@@ -86,19 +83,17 @@ + #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_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_POWERMGMT (1 << 4) + #define SK_PNMI_TST_PCI (1 << 5) + #define SK_PNMI_TST_MAC (1 << 6) + +- + /* + * RLMT specific definitions + */ +@@ -120,6 +115,10 @@ + /* + * OID definition + */ ++ ++#define SK_PNMI_OID_PSET 0x00400000 ++#define SK_PNMI_OID_SET 0x00800000 ++ + #ifndef _NDIS_ /* Check, whether NDIS already included OIDs */ + + #define OID_GEN_XMIT_OK 0x00020101 +@@ -223,7 +222,17 @@ + #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_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_INTERMEDIATE_SUPPORT 0xFF010160 ++#define OID_SKGE_SET_TEAM_MAC_ADDRESS 0xFF010161 ++#define OID_SKGE_DEVICE_INFORMATION 0xFF010162 + + #define OID_SKGE_SPEED_CAP 0xFF010170 + #define OID_SKGE_SPEED_MODE 0xFF010171 +@@ -231,7 +240,7 @@ + + #define OID_SKGE_BOARDLEVEL 0xFF010180 + +-#define OID_SKGE_SENSOR_NUMBER 0xFF020100 ++#define OID_SKGE_SENSOR_NUMBER 0xFF020100 + #define OID_SKGE_SENSOR_INDEX 0xFF020101 + #define OID_SKGE_SENSOR_DESCR 0xFF020102 + #define OID_SKGE_SENSOR_TYPE 0xFF020103 +@@ -322,13 +331,6 @@ + #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 +@@ -352,6 +354,7 @@ + #define OID_SKGE_VCT_GET 0xFF020200 + #define OID_SKGE_VCT_SET 0xFF020201 + #define OID_SKGE_VCT_STATUS 0xFF020202 ++#define OID_SKGE_VCT_CAPABILITIES 0xFF020203 + + #ifdef SK_DIAG_SUPPORT + /* Defines for driver DIAG mode. */ +@@ -367,22 +370,77 @@ + #define OID_SKGE_PHY_TYPE 0xFF020215 + #define OID_SKGE_PHY_LP_MODE 0xFF020216 + ++/* ++ * Added for new DualNet IM driver V2 ++ */ ++#define OID_SKGE_MAC_COUNT 0xFF020217 ++#define OID_SKGE_DUALNET_MODE 0xFF020218 ++#define OID_SKGE_SET_TAGHEADER 0xFF020219 ++ ++#ifdef SK_ASF ++/* Defines for ASF */ ++#define OID_SKGE_ASF 0xFF02021a ++#define OID_SKGE_ASF_STORE_CONFIG 0xFF02021b ++#define OID_SKGE_ASF_ENA 0xFF02021c ++#define OID_SKGE_ASF_RETRANS 0xFF02021d ++#define OID_SKGE_ASF_RETRANS_INT 0xFF02021e ++#define OID_SKGE_ASF_HB_ENA 0xFF02021f ++#define OID_SKGE_ASF_HB_INT 0xFF020220 ++#define OID_SKGE_ASF_WD_ENA 0xFF020221 ++#define OID_SKGE_ASF_WD_TIME 0xFF020222 ++#define OID_SKGE_ASF_IP_SOURCE 0xFF020223 ++#define OID_SKGE_ASF_MAC_SOURCE 0xFF020224 ++#define OID_SKGE_ASF_IP_DEST 0xFF020225 ++#define OID_SKGE_ASF_MAC_DEST 0xFF020226 ++#define OID_SKGE_ASF_COMMUNITY_NAME 0xFF020227 ++#define OID_SKGE_ASF_RSP_ENA 0xFF020228 ++#define OID_SKGE_ASF_RETRANS_COUNT_MIN 0xFF020229 ++#define OID_SKGE_ASF_RETRANS_COUNT_MAX 0xFF02022a ++#define OID_SKGE_ASF_RETRANS_INT_MIN 0xFF02022b ++#define OID_SKGE_ASF_RETRANS_INT_MAX 0xFF02022c ++#define OID_SKGE_ASF_HB_INT_MIN 0xFF02022d ++#define OID_SKGE_ASF_HB_INT_MAX 0xFF02022e ++#define OID_SKGE_ASF_WD_TIME_MIN 0xFF02022f ++#define OID_SKGE_ASF_WD_TIME_MAX 0xFF020230 ++#define OID_SKGE_ASF_HB_CAP 0xFF020231 ++#define OID_SKGE_ASF_WD_TIMER_RES 0xFF020232 ++#define OID_SKGE_ASF_GUID 0xFF020233 ++#define OID_SKGE_ASF_KEY_OP 0xFF020234 ++#define OID_SKGE_ASF_KEY_ADM 0xFF020235 ++#define OID_SKGE_ASF_KEY_GEN 0xFF020236 ++#define OID_SKGE_ASF_CAP 0xFF020237 ++#define OID_SKGE_ASF_PAR_1 0xFF020238 ++#define OID_SKGE_ASF_OVERALL_OID 0xFF020239 ++#endif /* SK_ASF */ ++ ++ ++/* Defined for Yukon-2 path only */ ++#define OID_SKGE_UPPER_MINIPORT 0xFF02023D ++ ++ ++#ifdef SK_ASF ++/* Defines for ASF */ ++#define OID_SKGE_ASF_FWVER_OID 0xFF020240 ++#define OID_SKGE_ASF_ACPI_OID 0xFF020241 ++#define OID_SKGE_ASF_SMBUS_OID 0xFF020242 ++#endif /* SK_ASF */ ++ + /* 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_U8 CableLen; ++ SK_U32 MdiPairLen[4]; ++ SK_U8 MdiPairSts[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 ++#define SK_PNMI_VCT_NONE 0x00 ++#define SK_PNMI_VCT_OLD_VCT_DATA 0x01 ++#define SK_PNMI_VCT_NEW_VCT_DATA 0x02 ++#define SK_PNMI_VCT_OLD_DSP_DATA 0x04 ++#define SK_PNMI_VCT_NEW_DSP_DATA 0x08 ++#define SK_PNMI_VCT_RUNNING 0x10 + + + /* VCT cable test status. */ +@@ -390,11 +448,16 @@ + #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 SK_PNMI_VCT_IMPEDANCE_MISMATCH 4 ++#define SK_PNMI_VCT_NOT_PRESENT 5 + +-#define OID_SKGE_TRAP_SEN_WAR_LOW 500 ++/* VCT capabilities (needed for OID_SKGE_VCT_CAPABILITIES. */ ++#define SK_PNMI_VCT_SUPPORTED_VERSION 2 ++#define SK_PNMI_VCT_NOT_SUPPORTED 0 ++ ++#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_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 +@@ -412,13 +475,12 @@ + /* + * 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 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 +@@ -452,7 +514,7 @@ + #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_ERR015MSG "Vpd: Internal array for VPD keys too 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) +@@ -494,9 +556,9 @@ + #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_ERR037MSG "Rlmt: SK_RLMT_MODE_CHANGE event returned 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_ERR038MSG "Rlmt: SK_RLMT_PREFPORT_CHANGE event returned 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) +@@ -514,9 +576,9 @@ + #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_ERR047MSG "SirqUpdate: Event function returned not 0" + #define SK_PNMI_ERR048 (SK_ERRBASE_PNMI + 48) +-#define SK_PNMI_ERR048MSG "RlmtUpdate: Event function returns not 0" ++#define SK_PNMI_ERR048MSG "RlmtUpdate: Event function returned 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) +@@ -826,23 +888,25 @@ + } SK_PNMI_STRUCT_DATA; + + #define SK_PNMI_STRUCT_SIZE (sizeof(SK_PNMI_STRUCT_DATA)) ++ ++/* The ReturnStatus field must be located before VpdFreeBytes! */ + #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_EVT_TIMER_CHECK 28125000L /* 28125 ms */ ++ ++#define SK_PNMI_VCT_TIMER_CHECK 4000000L /* 4 sec. */ ++ + #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 +- */ ++/* ++ * SK_PNMI_CNT_NO must have the value of the enum SK_PNMI_MAX_IDX. ++ * Define SK_PNMI_CHECK to check this during init level SK_INIT_IO. ++ */ ++#define SK_PNMI_CNT_NO 66 + + /* + * Estimate data structure +@@ -856,14 +920,6 @@ + + + /* +- * VCT timer data structure +- */ +-typedef struct s_VctTimer { +- SK_TIMER VctTimer; +-} SK_PNMI_VCT_TIMER; +- +- +-/* + * PNMI specific adapter context structure + */ + typedef struct s_PnmiPort { +@@ -933,12 +989,13 @@ + 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]; ++ SK_U8 VctStatus[SK_MAX_MACS]; ++ SK_PNMI_VCT VctBackup[SK_MAX_MACS]; ++ SK_TIMER VctTimeout[SK_MAX_MACS]; + #ifdef SK_DIAG_SUPPORT + SK_U32 DiagAttached; + #endif /* SK_DIAG_SUPPORT */ ++ SK_BOOL VpdKeyReadError; + } SK_PNMI; + + +@@ -946,6 +1003,10 @@ + * 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, +diff -ruN linux/drivers/net/sk98lin/h/skgesirq.h linux-new/drivers/net/sk98lin/h/skgesirq.h +--- linux/drivers/net/sk98lin/h/skgesirq.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skgesirq.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,23 +2,24 @@ + * + * Name: skgesirq.h + * Project: Gigabit Ethernet Adapters, Common Modules +- * Version: $Revision$ +- * Date: $Date$ +- * Purpose: SK specific Gigabit Ethernet special IRQ functions ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Gigabit Ethernet special IRQ functions + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2005 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. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -26,9 +27,9 @@ + #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 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 +@@ -44,10 +45,10 @@ + #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_WA_ACT_TIME 1000000UL /* 1000 msec (1 sec) */ ++#define SK_WA_INA_TIME 100000UL /* 100 msec */ + +-#define SK_HALFDUP_CHK_TIME (10000UL) /* 10 msec */ ++#define SK_HALFDUP_CHK_TIME 10000UL /* 10 msec */ + + /* + * Define the error numbers and messages +@@ -75,9 +76,9 @@ + #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_E012MSG "Unexpected IRQ Master error" + #define SKERR_SIRQ_E013 (SKERR_SIRQ_E012+1) +-#define SKERR_SIRQ_E013MSG "unexpected IRQ Status error" ++#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) +@@ -102,9 +103,35 @@ + #define SKERR_SIRQ_E024MSG "FIFO overflow error" + #define SKERR_SIRQ_E025 (SKERR_SIRQ_E024+1) + #define SKERR_SIRQ_E025MSG "2 Pair Downshift detected" ++#define SKERR_SIRQ_E026 (SKERR_SIRQ_E025+1) ++#define SKERR_SIRQ_E026MSG "Uncorrectable PCI Express error" ++#define SKERR_SIRQ_E027 (SKERR_SIRQ_E026+1) ++#define SKERR_SIRQ_E027MSG "PCI Bus Abort detected" ++#define SKERR_SIRQ_E028 (SKERR_SIRQ_E027+1) ++#define SKERR_SIRQ_E028MSG "Parity error on RAM 1 (read)" ++#define SKERR_SIRQ_E029 (SKERR_SIRQ_E028+1) ++#define SKERR_SIRQ_E029MSG "Parity error on RAM 1 (write)" ++#define SKERR_SIRQ_E030 (SKERR_SIRQ_E029+1) ++#define SKERR_SIRQ_E030MSG "Parity error on RAM 2 (read)" ++#define SKERR_SIRQ_E031 (SKERR_SIRQ_E030+1) ++#define SKERR_SIRQ_E031MSG "Parity error on RAM 2 (write)" ++#define SKERR_SIRQ_E032 (SKERR_SIRQ_E031+1) ++#define SKERR_SIRQ_E032MSG "TCP segmentation error async. queue 1" ++#define SKERR_SIRQ_E033 (SKERR_SIRQ_E032+1) ++#define SKERR_SIRQ_E033MSG "TCP segmentation error sync. queue 1" ++#define SKERR_SIRQ_E034 (SKERR_SIRQ_E033+1) ++#define SKERR_SIRQ_E034MSG "TCP segmentation error async. queue 2" ++#define SKERR_SIRQ_E035 (SKERR_SIRQ_E034+1) ++#define SKERR_SIRQ_E035MSG "TCP segmentation error sync. queue 2" ++#define SKERR_SIRQ_E036 (SKERR_SIRQ_E035+1) ++#define SKERR_SIRQ_E036MSG "CHECK failure polling unit" + + 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); ++extern void SkGeYuSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus); ++extern void SkYuk2SirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus); + + #endif /* _INC_SKGESIRQ_H_ */ ++ +diff -ruN linux/drivers/net/sk98lin/h/skgespi.h linux-new/drivers/net/sk98lin/h/skgespi.h +--- linux/drivers/net/sk98lin/h/skgespi.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/h/skgespi.h 2007-01-24 14:03:40.000000000 +0100 +@@ -0,0 +1,246 @@ ++/****************************************************************************** ++ * ++ * Name: skspi.h ++ * Project: Flash Programmer, Manufacturing and Diagnostic Tools ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Contains SPI-Flash EEPROM specific definitions and constants ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * (C)Copyright 1998-2002 SysKonnect ++ * (C)Copyright 2002-2003 Marvell ++ * ++ * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT ++ * The copyright notice above does not evidence any ++ * actual or intended publication of such source code. ++ * ++ * This Module contains Proprietary Information of SysKonnect ++ * and should be treated as Confidential. ++ * ++ * The information in this file is provided for the exclusive use of ++ * the licensees of SysKonnect. ++ * Such users have the right to use, modify, and incorporate this code ++ * into products for purposes authorized by the license agreement ++ * provided they include this notice and the associated copyright notice ++ * with any such product. ++ * The information in this file is provided "AS IS" without warranty. ++ * ++ ******************************************************************************/ ++ ++#define __INC_SKSPI_H ++ ++/* SPI registers */ ++// CHIP_IDs should be defined in skgehw.h ++#ifndef B2_CHIP_ID ++#define B2_CHIP_ID 0x011b /* Chip Identification Number */ ++#endif ++ ++#ifndef CHIP_ID_GENESIS ++#define CHIP_ID_GENESIS 0x0a /* Chip ID for GENESIS */ ++#endif ++ ++#ifndef CHIP_ID_YUKON ++#define CHIP_ID_YUKON 0xb0 /* Chip ID for YUKON */ ++#endif ++ ++#ifndef CHIP_ID_YUKON_LITE ++#define CHIP_ID_YUKON_LITE 0xb1 /* Chip ID for YUKON-Lite (Rev. A1) */ ++#endif ++ ++#ifndef CHIP_ID_YUKON_LP ++#define CHIP_ID_YUKON_LP 0xb2 /* Chip ID for YUKON-LP */ ++#endif ++ ++#ifndef CHIP_ID_YUKON_XL ++#define CHIP_ID_YUKON_XL 0xb3 /* Chip ID for YUKON-2 XL */ ++#endif ++ ++#ifndef CHIP_ID_YUKON_EC ++#define CHIP_ID_YUKON_EC 0xb6 /* Chip ID for YUKON-2 EC */ ++#endif ++ ++#define SPI_ADR_REG1 0x0120 /* VPD low addr, SPI loader start addr */ ++#define SPI_ADR_REG2 0x0124 /* VPD high addr, PiG loader start addr */ ++#define SPI_CTRL_REG 0x0128 /* SPI control & status register */ ++ ++#define B2_TST_REG1 0x0158 /* Test control register */ ++ ++/* SPI commands and constants */ ++ ++#define SPI_PATTERN 0xffffffffL /* Write value for SPI identification */ ++#define SPI_COMP_MASK 0xfffe0000L /* Compare Mask for SPI identification */ ++ ++#define SPI_VPD_MIN 0x0001f800L /* Min Eprom addr for access via VPD port */ ++#define SPI_VPD_MAX 0xfffff000L /* Max Eprom addr for access via VPD port */ ++ ++#define SPI_LSECT_OFF 0x18000L /* Offset of last sector in SPI eprom */ ++#define SPI_CONF_OFF 0x1c000L /* Offset of config space in SPI eprom */ ++ ++#define SPI_PIG_OFF 0x1f000L /* Plug-In-Go (PiG) Config space */ ++#define SPI_NOC_OFF 0x1f800L /* Normal Oper. Config (NOC) space */ ++#define SPI_VPD_OFF 0x1c000L /* Vital Product Data (VPD) space */ ++#define SPI_PET_OFF 0x1d000L /* Pet Frames space */ ++ ++#define SPI_CHIP_SIZE 0x20000L /* Size of whole SPI eprom */ ++#define SPI_SECT_SIZE 0x8000L /* Size of a sector in SPI eprom */ ++ ++#define SPI_CONF_SIZE 0x4000L /* Size of config area in SPI eprom */ ++#define SPI_PIG_SIZE 0x0800L /* Size of PiG area in SPI eprom */ ++#define SPI_NOC_SIZE 0x0800L /* Size of NOC area in SPI eprom */ ++#define SPI_VPD_SIZE 0x0100L /* Size of VPD area in SPI eprom */ ++#define SPI_PET_SIZE 0x2000L /* Size of PET area in SPI eprom */ ++ ++#define SPI_SECT_ERASE 0x00008000L /* Sector erase command */ ++#define SPI_CHIP_ERASE 0x00001000L /* Chip erase command */ ++#define SPI_VPD_MAP 0x00080000L /* VPD to Eprom mapping flag */ ++#define SPI_TIMER_SET 5 /* SPI timeout value (sec.) */ ++#define SPI_TIMEOUT 0 /* Timeout check flag */ ++#define SPI_READ 1 /* Read flag for spi_flash_manage() */ ++#define SPI_VERIFY 2 /* Verify flag for spi_flash_manage() */ ++#define SPI_WRITE 3 /* Write flag for spi_flash_manage() */ ++ ++/* VPD regs from PCI config reg. file mapped to control reg. file */ ++ ++#define VPD_ADR_REG 0x03d2 /* VPD address register in config file */ ++#define VPD_DATA_PORT 0x03d4 /* VPD data port in configuration file */ ++#define VPD_FLAG_MASK 0x8000 /* VPD read-write flag */ ++ ++#define FT_SPI_UNKNOWN (-1) ++#define FT_SPI 3 /* Flash type */ ++#define FT_SPI_Y2 4 /* Yukon 2/EC SPI flash */ ++ ++/******************************************************************************** ++ * Yukon 2/EC definitions and macros ++ ********************************************************************************/ ++ ++/* SPI EPROM CONTROL REGISTER */ ++#define SPI_Y2_CONTROL_REG 0x60 ++/* SPI EPROM ADDRESS REGISTER */ ++#define SPI_Y2_ADDRESS_REG 0x64 ++/* SPI EPROM DATA REGISTER */ ++#define SPI_Y2_DATA_REG 0x68 ++/* SPI EPROM VENDOR-/DEVICE-ID REGISTER */ ++#define SPI_Y2_VENDOR_DEVICE_ID_REG 0x6c ++/* SPI EPROM FIRST OPCODE REGISTER */ ++#define SPI_Y2_OPCODE_REG1 0x78 ++/* SPI EPROM SECOND OPCODE REGISTER */ ++#define SPI_Y2_OPCODE_REG2 0x7c ++ ++/* SPI EPROM READ INSTRUCTION */ ++#define SPI_Y2_RD (0x09L<<16) ++/* SPI EPROM READ ID INSTRUCTION */ ++#define SPI_Y2_RDID (0x0AL<<16) ++/* SPI EPROM READ STATUS REGISTER INSTRUCTION */ ++#define SPI_Y2_RDST (0x0BL<<16) ++/* SPI EPROM WRITE ENABLE INSTRUCTION */ ++#define SPI_Y2_WEN (0x0CL<<16) ++/* SPI EPROM WRITE INSTRUCTION */ ++#define SPI_Y2_WR (0x0DL<<16) ++/* SPI EPROM SECTOR ERASE INSTRUCTION */ ++#define SPI_Y2_SERS (0x0EL<<16) ++/* SPI EPROM CHIP ERASE INSTRUCTION */ ++#define SPI_Y2_CERS (0x0FL<<16) ++/* SPI EPROM command mask */ ++#define SPI_Y2_CMD_MASK (0x07L<<16) ++ ++/* SPI flash read ID protocol */ ++#define SPI_Y2_RDID_PROT (0x01L<<28) ++ ++/* SPI flash VPD mapping enable */ ++#define SPI_Y2_VPD_ENABLE (0x01L<<29) ++ ++/* SPI EPROM BUSY CHECK */ ++#define SPI_Y2_IS_BUSY(w) ((w)&(1L<<30)) ++#define SPI_Y2_IS_BUSY_WR(w) ((w)&(1)) ++ ++#define SPI_Y2_MAN_ID_MASK 0xff00 ++#define SPI_Y2_DEV_ID_MASK 0x00ff ++ ++/* SPI flash manufacturer ID's */ ++#define SPI_MAN_ID_ATMEL 0x1f ++#define SPI_MAN_ID_SST 0xbf ++#define SPI_MAN_ID_ST_M25P20 0x11 ++#define SPI_MAN_ID_ST_M25P10 0x10 ++ ++/* wait for SPI EPROM to finish write/erase operation */ ++#define SPI_Y2_WAIT_SE_FINISH_WR() { \ ++ unsigned long stat=1; \ ++ SPI_Y2_WAIT_SE_FINISH_CMD(); \ ++ /* wait for write to finish or timeout */ \ ++ spi_timer(SPI_TIMER_SET); \ ++ while( SPI_Y2_IS_BUSY_WR(stat) ){ \ ++ if (spi_timer(SPI_TIMEOUT)) { \ ++ break; \ ++ } \ ++ spi_out32(SPI_Y2_CONTROL_REG, SPI_Y2_RDST); \ ++ SPI_Y2_WAIT_SE_FINISH_CMD() \ ++ spi_in32(SPI_Y2_CONTROL_REG, &stat); \ ++ } \ ++} ++ ++/* wait for SPI EPROM to finish command */ ++#define SPI_Y2_WAIT_SE_FINISH_CMD() { \ ++ unsigned long stat=(1L<<30); \ ++ /* wait for command to finish */ \ ++ spi_timer(SPI_TIMER_SET); \ ++ while( SPI_Y2_IS_BUSY(stat) ){ \ ++ if (spi_timer(SPI_TIMEOUT)) { \ ++ break; \ ++ } \ ++ spi_in32(SPI_Y2_CONTROL_REG, &stat); \ ++ } \ ++} ++ ++#if (defined Core || defined DJGPP || !defined MSDOS) ++#define huge ++#endif /* Core || DJGPP || !MSDOS */ ++ ++/* function prototypes */ ++ ++int flash_check_spi( unsigned long *FlashSize ); ++ ++int spi_flash_erase( ++ unsigned long off, ++ unsigned long len); ++ ++int spi_flash_manage( ++ unsigned char *data, ++ unsigned long off, ++ unsigned long len, ++ int flag); ++ ++int spi_vpd_transfer( ++ char *buf, ++ int addr, ++ int len, ++ int dir); ++ ++int spi_get_pig( ++ unsigned char *data, ++ unsigned long len); ++ ++int spi_get_noc( ++ unsigned char *data, ++ unsigned long len); ++ ++int spi_update_pig( ++ unsigned char *data, ++ unsigned long len); ++ ++int spi_update_noc( ++ unsigned char *data, ++ unsigned long len); ++ ++int spi_update_pet( ++ unsigned char *data, ++ unsigned long len); ++ ++void spi_yuk2_write_enable(void); ++void spi_yuk2_sst_clear_write_protection(void); ++void spi_yuk2_erase_chip(void); ++unsigned short spi_yuk2_read_chip_id(void); ++int spi_yuk2_get_dev_index(void); ++ +diff -ruN linux/drivers/net/sk98lin/h/skgetwsi.h linux-new/drivers/net/sk98lin/h/skgetwsi.h +--- linux/drivers/net/sk98lin/h/skgetwsi.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/h/skgetwsi.h 2007-01-24 13:58:34.000000000 +0100 +@@ -0,0 +1,243 @@ ++/****************************************************************************** ++ * ++ * Name: skgetwsi.h ++ * Project: Gigabit Ethernet Adapters, TWSI-Module ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Special defines for TWSI ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * LICENSE: ++ * (C)Copyright 1998-2002 SysKonnect. ++ * (C)Copyright 2002-2004 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. ++ * /LICENSE ++ * ++ ******************************************************************************/ ++ ++/* ++ * SKGETWSI.H contains all SK-98xx specific defines for the TWSI handling ++ */ ++ ++#ifndef _INC_SKGETWSI_H_ ++#define _INC_SKGETWSI_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 ++ */ ++ ++#define C_PLUS_20 120 / 100 ++#define C_PLUS_15 115 / 100 ++#define C_PLUS_10 110 / 100 ++#define C_PLUS_5 105 / 100 ++#define C_MINUS_5 95 / 100 ++#define C_MINUS_10 90 / 100 ++#define C_MINUS_15 85 / 100 ++ ++/* 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_VAL 3300 /* Voltage VAUX 3.3 Volt */ ++ ++#define SK_SEN_VAUX_3V3_HIGH_ERR (SK_I32)(SK_SEN_VAUX_3V3_VAL * C_PLUS_10) ++#define SK_SEN_VAUX_3V3_HIGH_WARN (SK_I32)(SK_SEN_VAUX_3V3_VAL * C_PLUS_5) ++#define SK_SEN_VAUX_3V3_LOW_WARN (SK_I32)(SK_SEN_VAUX_3V3_VAL * C_MINUS_5) ++#define SK_SEN_VAUX_3V3_LOW_ERR (SK_I32)(SK_SEN_VAUX_3V3_VAL * C_MINUS_10) ++ ++#define SK_SEN_VAUX_RANGE_LIMITER 1000 /* 1000 mV range delimiter */ ++ ++/* ++ * PHY 2V5 voltage ++ */ ++#define SK_SEN_PHY_2V5_VAL 2500 /* Voltage PHY 2.5 Volt */ ++ ++#define SK_SEN_PHY_2V5_HIGH_ERR (SK_I32)(SK_SEN_PHY_2V5_VAL * C_PLUS_10) ++#define SK_SEN_PHY_2V5_HIGH_WARN (SK_I32)(SK_SEN_PHY_2V5_VAL * C_PLUS_5) ++#define SK_SEN_PHY_2V5_LOW_WARN (SK_I32)(SK_SEN_PHY_2V5_VAL * C_MINUS_5) ++#define SK_SEN_PHY_2V5_LOW_ERR (SK_I32)(SK_SEN_PHY_2V5_VAL * C_MINUS_10) ++ ++/* ++ * ASIC Core 1V5 voltage (YUKON only) ++ */ ++#define SK_SEN_CORE_1V5_VAL 1500 /* Voltage ASIC Core 1.5 Volt */ ++ ++#define SK_SEN_CORE_1V5_HIGH_ERR (SK_I32)(SK_SEN_CORE_1V5_VAL * C_PLUS_10) ++#define SK_SEN_CORE_1V5_HIGH_WARN (SK_I32)(SK_SEN_CORE_1V5_VAL * C_PLUS_5) ++#define SK_SEN_CORE_1V5_LOW_WARN (SK_I32)(SK_SEN_CORE_1V5_VAL * C_MINUS_5) ++#define SK_SEN_CORE_1V5_LOW_ERR (SK_I32)(SK_SEN_CORE_1V5_VAL * C_MINUS_10) ++ ++/* ++ * ASIC Core 1V2 (1V3) voltage (YUKON-2 only) ++ */ ++#define SK_SEN_CORE_1V2_VAL 1200 /* Voltage ASIC Core 1.2 Volt */ ++ ++#define SK_SEN_CORE_1V2_HIGH_ERR (SK_I32)(SK_SEN_CORE_1V2_VAL * C_PLUS_20) ++#define SK_SEN_CORE_1V2_HIGH_WARN (SK_I32)(SK_SEN_CORE_1V2_VAL * C_PLUS_15) ++#define SK_SEN_CORE_1V2_LOW_WARN (SK_I32)(SK_SEN_CORE_1V2_VAL * C_MINUS_5) ++#define SK_SEN_CORE_1V2_LOW_ERR (SK_I32)(SK_SEN_CORE_1V2_VAL * C_MINUS_10) ++ ++#define SK_SEN_CORE_1V3_VAL 1300 /* Voltage ASIC Core 1.3 Volt */ ++ ++#define SK_SEN_CORE_1V3_HIGH_ERR (SK_I32)(SK_SEN_CORE_1V3_VAL * C_PLUS_15) ++#define SK_SEN_CORE_1V3_HIGH_WARN (SK_I32)(SK_SEN_CORE_1V3_VAL * C_PLUS_10) ++#define SK_SEN_CORE_1V3_LOW_WARN (SK_I32)(SK_SEN_CORE_1V3_VAL * C_MINUS_5) ++#define SK_SEN_CORE_1V3_LOW_ERR (SK_I32)(SK_SEN_CORE_1V3_VAL * C_MINUS_10) ++ ++/* ++ * 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_SKGETWSI_H */ ++ +diff -ruN linux/drivers/net/sk98lin/h/ski2c.h linux-new/drivers/net/sk98lin/h/ski2c.h +--- linux/drivers/net/sk98lin/h/ski2c.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/ski2c.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,174 +0,0 @@ +-/****************************************************************************** +- * +- * Name: ski2c.h +- * Project: Gigabit Ethernet Adapters, TWSI-Module +- * Version: $Revision$ +- * Date: $Date$ +- * 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); +-#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 -ruN linux/drivers/net/sk98lin/h/skpcidevid.h linux-new/drivers/net/sk98lin/h/skpcidevid.h +--- linux/drivers/net/sk98lin/h/skpcidevid.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/h/skpcidevid.h 2007-01-24 14:03:40.000000000 +0100 +@@ -0,0 +1,135 @@ ++static struct pci_device_id sk98lin_pci_tbl[] __devinitdata = { ++/* { pci_vendor_id, pci_device_id, * SAMPLE ENTRY! * ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, */ ++ ++ /* 1 */ ++ { 0x10B7, 0x1700, /* Generic 3Com 3C940 Gigabit Ethernet Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 2 */ ++ { 0x10B7, 0x80EB, /* Generic 3Com 3C940B Gigabit LOM Ethernet Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 3 */ ++ { 0x1148, 0x4300, /* Generic SysKonnect SK-98xx Gigabit Ethernet Server Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 4 */ ++ { 0x1148, 0x4320, /* Generic SysKonnect SK-98xx V2.0 Gigabit Ethernet Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 5 */ ++ { 0x1148, 0x9000, /* Generic SysKonnect SK-9Sxx 10/100/1000Base-T Server Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 6 */ ++ { 0x1148, 0x9E00, /* Generic SysKonnect SK-9Exx 10/100/1000Base-T Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 7 */ ++ { 0x1186, 0x4001, /* D-Link DGE-550SX PCI-X Gigabit Ethernet Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 8 */ ++ { 0x1186, 0x4346, /* D-Link DGE-560SX Single Fiber Gigabit Ethernet PCI-E Adapter V.A1 */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 9 */ ++ { 0x1186, 0x4B00, /* D-Link DGE-560T PCI Express Gigabit Ethernet Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 10 */ ++ { 0x1186, 0x4B01, /* D-Link DGE-530T V.B1 Gigabit Ethernet Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 11 */ ++ { 0x1186, 0x4B02, /* D-Link DGE-560SX PCI Express Gigabit Ethernet Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 12 */ ++ { 0x1186, 0x4B03, /* D-Link DGE-550T Gigabit Ethernet Adapter V.B1 */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 13 */ ++ { 0x1186, 0x4C00, /* D-Link DGE-530T Gigabit Ethernet Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 14 */ ++ { 0x11AB, 0x4320, /* Generic Marvell Yukon 88E8001/8003/8010 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 15 */ ++ { 0x11AB, 0x4340, /* Generic Marvell Yukon 88E8021 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 16 */ ++ { 0x11AB, 0x4341, /* Generic Marvell Yukon 88E8022 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 17 */ ++ { 0x11AB, 0x4342, /* Generic Marvell Yukon 88E8061 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 18 */ ++ { 0x11AB, 0x4343, /* Generic Marvell Yukon 88E8062 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 19 */ ++ { 0x11AB, 0x4344, /* Generic Marvell Yukon 88E8021 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 20 */ ++ { 0x11AB, 0x4345, /* Generic Marvell Yukon 88E8022 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 21 */ ++ { 0x11AB, 0x4346, /* Generic Marvell Yukon 88E8061 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 22 */ ++ { 0x11AB, 0x4347, /* Generic Marvell Yukon 88E8062 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 23 */ ++ { 0x11AB, 0x4350, /* Generic Marvell Yukon 88E8035 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 24 */ ++ { 0x11AB, 0x4351, /* Generic Marvell Yukon 88E8036 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 25 */ ++ { 0x11AB, 0x4352, /* Generic Marvell Yukon 88E8038 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 26 */ ++ { 0x11AB, 0x4353, /* Generic Marvell Yukon 88E8039 PCI-E Fast Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 27 */ ++ { 0x11AB, 0x4356, /* Generic Marvell Yukon 88EC033 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 28 */ ++ { 0x11AB, 0x4360, /* Generic Marvell Yukon 88E8052 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 29 */ ++ { 0x11AB, 0x4361, /* Generic Marvell Yukon 88E8050 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 30 */ ++ { 0x11AB, 0x4362, /* Generic Marvell Yukon 88E8053 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 31 */ ++ { 0x11AB, 0x4363, /* Generic Marvell Yukon 88E8055 PCI-E Gigabit Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 32 */ ++ { 0x11AB, 0x4364, /* Generic Marvell Yukon 88E8056 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 33 */ ++ { 0x11AB, 0x4365, /* Generic Marvell Yukon 88E8070 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 34 */ ++ { 0x11AB, 0x4366, /* Generic Marvell Yukon 88EC036 PCI-E Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 35 */ ++ { 0x11AB, 0x4367, /* Generic Marvell Yukon 88EC032 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 36 */ ++ { 0x11AB, 0x4368, /* Generic Marvell Yukon 88EC034 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 37 */ ++ { 0x11AB, 0x4369, /* Generic Marvell Yukon 88EC042 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 38 */ ++ { 0x11AB, 0x436A, /* Marvell Yukon 88E8058 PCI-E Gigabit Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 39 */ ++ { 0x11AB, 0x436B, /* Generic Marvell Yukon 88E8071 based Ethernet Controller */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 40 */ ++ { 0x11AB, 0x5005, /* Belkin Gigabit Desktop Card10/100/1000Base-T Adapter, Copper RJ-45 */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 41 */ ++ { 0x1371, 0x434E, /* Generic CNet PowerG-2000 1000/100/10Mbps N-Way PCI-Bus Giga-Card */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 42 */ ++ { 0x1737, 0x1032, /* Linksys EG1032 v2 Instant Gigabit Network Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ /* 43 */ ++ { 0x1737, 0x1064, /* Linksys EG1064 v2 Instant Gigabit Network Adapter */ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, ++ { 0, } ++}; +diff -ruN linux/drivers/net/sk98lin/h/skqueue.h linux-new/drivers/net/sk98lin/h/skqueue.h +--- linux/drivers/net/sk98lin/h/skqueue.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skqueue.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,14 +2,15 @@ + * + * Name: skqueue.h + * Project: Gigabit Ethernet Adapters, Event Scheduler Module +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Defines for the Event queue + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. + * +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -45,6 +47,9 @@ + #define SKGE_RSF 11 /* RSF Aggregation Event Class */ + #define SKGE_MARKER 12 /* MARKER Aggregation Event Class */ + #define SKGE_FD 13 /* FD Distributor Event Class */ ++#ifdef SK_ASF ++#define SKGE_ASF 14 /* ASF Event Class */ ++#endif + + /* + * define event queue as circular buffer +@@ -90,5 +95,11 @@ + #define SKERR_Q_E001MSG "Event queue overflow" + #define SKERR_Q_E002 (SKERR_Q_E001+1) + #define SKERR_Q_E002MSG "Undefined event class" ++#define SKERR_Q_E003 (SKERR_Q_E001+2) ++#define SKERR_Q_E003MSG "Event queued in Init Level 0" ++#define SKERR_Q_E004 (SKERR_Q_E001+3) ++#define SKERR_Q_E004MSG "Error Reported from Event Fuction (Queue Blocked)" ++#define SKERR_Q_E005 (SKERR_Q_E001+4) ++#define SKERR_Q_E005MSG "Event scheduler called in Init Level 0 or 1" + #endif /* _SKQUEUE_H_ */ + +diff -ruN linux/drivers/net/sk98lin/h/skrlmt.h linux-new/drivers/net/sk98lin/h/skrlmt.h +--- linux/drivers/net/sk98lin/h/skrlmt.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skrlmt.h 2007-01-24 13:58:34.000000000 +0100 +@@ -2,14 +2,15 @@ + * + * Name: skrlmt.h + * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Header file for Redundant Link ManagemenT. + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. + * +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +diff -ruN linux/drivers/net/sk98lin/h/sktimer.h linux-new/drivers/net/sk98lin/h/sktimer.h +--- linux/drivers/net/sk98lin/h/sktimer.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/sktimer.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,14 +2,15 @@ + * + * Name: sktimer.h + * Project: Gigabit Ethernet Adapters, Event Scheduler Module +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Defines for the timer functions + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. + * +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +diff -ruN linux/drivers/net/sk98lin/h/sktwsi.h linux-new/drivers/net/sk98lin/h/sktwsi.h +--- linux/drivers/net/sk98lin/h/sktwsi.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/h/sktwsi.h 2007-01-24 14:03:40.000000000 +0100 +@@ -0,0 +1,179 @@ ++/****************************************************************************** ++ * ++ * Name: sktwsi.h ++ * Project: Gigabit Ethernet Adapters, TWSI-Module ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Defines to access Voltage and Temperature Sensor ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * LICENSE: ++ * (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. ++ * /LICENSE ++ * ++ ******************************************************************************/ ++ ++/* ++ * SKTWSI.H contains all TWSI specific defines ++ */ ++ ++#ifndef _SKTWSI_H_ ++#define _SKTWSI_H_ ++ ++typedef struct s_Sensor SK_SENSOR; ++ ++#include "h/skgetwsi.h" ++ ++/* ++ * Define the TWSI 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_SKTWSI_H */ ++ +diff -ruN linux/drivers/net/sk98lin/h/sktypes.h linux-new/drivers/net/sk98lin/h/sktypes.h +--- linux/drivers/net/sk98lin/h/sktypes.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/sktypes.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,8 +2,8 @@ + * + * Name: sktypes.h + * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Define data types for Linux + * + ******************************************************************************/ +@@ -11,7 +11,7 @@ + /****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2005 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 +@@ -22,48 +22,28 @@ + * + ******************************************************************************/ + +-/****************************************************************************** +- * +- * 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 ********************************************************/ ++#define SK_I8 s8 /* 8 bits (1 byte) signed */ ++#define SK_U8 u8 /* 8 bits (1 byte) unsigned */ ++#define SK_I16 s16 /* 16 bits (2 bytes) signed */ ++#define SK_U16 u16 /* 16 bits (2 bytes) unsigned */ ++#define SK_I32 s32 /* 32 bits (4 bytes) signed */ ++#define SK_U32 u32 /* 32 bits (4 bytes) unsigned */ ++#define SK_I64 s64 /* 64 bits (8 bytes) signed */ ++#define SK_U64 u64 /* 64 bits (8 bytes) unsigned */ ++ ++#define SK_UPTR ulong /* casting pointer <-> integral */ ++ ++#define SK_BOOL SK_U8 ++#define SK_FALSE 0 ++#define SK_TRUE (!SK_FALSE) + + #endif /* __INC_SKTYPES_H */ ++ ++/******************************************************************************* ++ * ++ * End of file ++ * ++ ******************************************************************************/ +diff -ruN linux/drivers/net/sk98lin/h/skversion.h linux-new/drivers/net/sk98lin/h/skversion.h +--- linux/drivers/net/sk98lin/h/skversion.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skversion.h 2007-01-24 14:03:40.000000000 +0100 +@@ -1,17 +1,17 @@ + /****************************************************************************** + * +- * Name: version.h ++ * Name: skversion.h + * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ +- * Purpose: SK specific Error log support ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: specific version strings and numbers + * + ******************************************************************************/ + + /****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2005 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 +@@ -22,17 +22,17 @@ + * + ******************************************************************************/ + +-#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" +- ++#define BOOT_STRING "sk98lin: Network Device Driver v10.0.4.3\n" \ ++ "(C)Copyright 1999-2007 Marvell(R)." ++#define VER_STRING "10.0.4.3" ++#define PATCHLEVEL "04" ++#define DRIVER_FILE_NAME "sk98lin" ++#define DRIVER_REL_DATE "Jan-24-2007" ++#define DRV_NAME "sk98lin" ++#define DRV_VERSION "10.0.4.3" + ++/******************************************************************************* ++ * ++ * End of file ++ * ++ ******************************************************************************/ +diff -ruN linux/drivers/net/sk98lin/h/skvpd.h linux-new/drivers/net/sk98lin/h/skvpd.h +--- linux/drivers/net/sk98lin/h/skvpd.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/skvpd.h 2007-01-24 13:58:34.000000000 +0100 +@@ -1,23 +1,25 @@ + /****************************************************************************** + * + * Name: skvpd.h +- * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ ++ * Project: Gigabit Ethernet Adapters, VPD-Module ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Defines and Macros for VPD handling + * + ******************************************************************************/ + + /****************************************************************************** + * +- * (C)Copyright 1998-2003 SysKonnect GmbH. ++ * LICENSE: ++ * (C)Copyright 1998-2002 SysKonnect. ++ * (C)Copyright 2002-2004 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. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -31,7 +33,7 @@ + /* + * Define Resource Type Identifiers and VPD keywords + */ +-#define RES_ID 0x82 /* Resource Type ID String (Product Name) */ ++#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 */ +@@ -40,14 +42,16 @@ + #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_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_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_VB "VB" /* Boot Agent ROM Configuration (SK specific) */ ++#define VPD_VE "VE" /* EFI UNDI Configuration (SK specific) */ + #define VPD_RW "RW" /* Remaining Read / Write Area */ + + /* 'type' values for vpd_setup_para() */ +@@ -55,7 +59,7 @@ + #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 ADD_KEY 1 /* add the key at the pos "RV" or "RW" */ + #define OWR_KEY 2 /* overwrite key if already exists */ + + /* +@@ -64,18 +68,18 @@ + + #define VPD_DEV_ID_GENESIS 0x4300 + +-#define VPD_SIZE_YUKON 256 +-#define VPD_SIZE_GENESIS 512 +-#define VPD_SIZE 512 ++#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_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 +@@ -126,62 +130,78 @@ + /* + * System specific VPD macros + */ +-#ifndef SKDIAG ++#ifndef SK_DIAG + #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_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) ++#define VPD_OUT8(pAC,IoC,Addr,Val) SK_OUT8(IoC,PCI_C(pAC,Addr),Val) ++#define VPD_OUT16(pAC,IoC,Addr,Val) SK_OUT16(IoC,PCI_C(pAC,Addr),Val) ++#define VPD_OUT32(pAC,IoC,Addr,Val) SK_OUT32(IoC,PCI_C(pAC,Addr),Val) ++#define VPD_IN8(pAC,IoC,Addr,pVal) SK_IN8(IoC,PCI_C(pAC,Addr),pVal) ++#define VPD_IN16(pAC,IoC,Addr,pVal) SK_IN16(IoC,PCI_C(pAC,Addr),pVal) ++#define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(pAC,Addr),pVal) + #endif /* VPD_DO_IO */ +-#else /* SKDIAG */ ++#else /* SK_DIAG */ + #define VPD_OUT8(pAC,Ioc,Addr,Val) { \ + if ((pAC)->DgT.DgUseCfgCycle) \ + SkPciWriteCfgByte(pAC,Addr,Val); \ + else \ +- SK_OUT8(pAC,PCI_C(Addr),Val); \ ++ SK_OUT8(pAC,PCI_C(pAC,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); \ ++ SK_OUT16(pAC,PCI_C(pAC,Addr),Val); \ ++ } ++#define VPD_OUT32(pAC,Ioc,Addr,Val) { \ ++ if ((pAC)->DgT.DgUseCfgCycle) \ ++ SkPciWriteCfgDWord(pAC,Addr,Val); \ ++ else \ ++ SK_OUT32(pAC,PCI_C(pAC,Addr),Val); \ + } + #define VPD_IN8(pAC,Ioc,Addr,pVal) { \ +- if ((pAC)->DgT.DgUseCfgCycle) \ ++ if ((pAC)->DgT.DgUseCfgCycle) \ + SkPciReadCfgByte(pAC,Addr,pVal); \ + else \ +- SK_IN8(pAC,PCI_C(Addr),pVal); \ ++ SK_IN8(pAC,PCI_C(pAC,Addr),pVal); \ + } + #define VPD_IN16(pAC,Ioc,Addr,pVal) { \ +- if ((pAC)->DgT.DgUseCfgCycle) \ ++ if ((pAC)->DgT.DgUseCfgCycle) \ + SkPciReadCfgWord(pAC,Addr,pVal); \ + else \ +- SK_IN16(pAC,PCI_C(Addr),pVal); \ ++ SK_IN16(pAC,PCI_C(pAC,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); \ ++ SK_IN32(pAC,PCI_C(pAC,Addr),pVal); \ + } +-#endif /* nSKDIAG */ ++#endif /* SK_DIAG */ + + /* function prototypes ********************************************************/ + + #ifndef SK_KR_PROTO +-#ifdef SKDIAG ++#ifdef SK_DIAG + extern SK_U32 VpdReadDWord( + SK_AC *pAC, + SK_IOC IoC, + int addr); +-#endif /* SKDIAG */ ++#endif /* SK_DIAG */ ++ ++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, +@@ -219,7 +239,17 @@ + SK_AC *pAC, + SK_IOC IoC); + +-#ifdef SKDIAG ++extern void VpdErrLog( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ char *msg); ++ ++int VpdInit( ++ SK_AC *pAC, ++ SK_IOC IoC); ++ ++#if defined(SK_DIAG) || defined(SK_ASF) ++ + extern int VpdReadBlock( + SK_AC *pAC, + SK_IOC IoC, +@@ -233,9 +263,12 @@ + char *buf, + int addr, + int len); +-#endif /* SKDIAG */ ++ ++#endif /* SK_DIAG || SK_ASF */ ++ + #else /* SK_KR_PROTO */ + extern SK_U32 VpdReadDWord(); ++extern int VpdSetupPara(); + extern SK_VPD_STATUS *VpdStat(); + extern int VpdKeys(); + extern int VpdRead(); +@@ -243,6 +276,8 @@ + extern int VpdWrite(); + extern int VpdDelete(); + extern int VpdUpdate(); ++extern void VpdErrLog(); + #endif /* SK_KR_PROTO */ + + #endif /* __INC_SKVPD_H_ */ ++ +diff -ruN linux/drivers/net/sk98lin/h/sky2le.h linux-new/drivers/net/sk98lin/h/sky2le.h +--- linux/drivers/net/sk98lin/h/sky2le.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/h/sky2le.h 2007-01-24 14:03:40.000000000 +0100 +@@ -0,0 +1,954 @@ ++/****************************************************************************** ++ * ++ * Name: sky2le.h ++ * Project: Gigabit Ethernet Adapters, Common Modules ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Common list element definitions and access macros. ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * LICENSE: ++ * (C)Copyright 2002-2006 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. ++ * /LICENSE ++ * ++ ******************************************************************************/ ++ ++#ifndef __INC_SKY2LE_H ++#define __INC_SKY2LE_H ++ ++#ifdef __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++ ++/* defines ********************************************************************/ ++ ++#define MIN_LEN_OF_LE_TAB 128 ++#define MAX_LEN_OF_LE_TAB 4096 ++#ifdef USE_POLLING_UNIT ++#define NUM_LE_POLLING_UNIT 2 ++#endif ++#define MAX_FRAG_OVERHEAD 10 ++ ++/* Macro for aligning a given value */ ++#define SK_ALIGN_SIZE(Value, Alignment, AlignedVal) { \ ++ (AlignedVal) = (((Value) + (Alignment) - 1) & (~((Alignment) - 1)));\ ++} ++ ++/****************************************************************************** ++ * ++ * LE2DWord() - Converts the given Little Endian value to machine order value ++ * ++ * Description: ++ * This function converts the Little Endian value received as an argument to ++ * the machine order value. ++ * ++ * Returns: ++ * The converted value ++ * ++ */ ++ ++#ifdef SK_LITTLE_ENDIAN ++ ++#ifndef SK_USE_REV_DESC ++#define LE2DWord(value) (value) ++#else /* SK_USE_REV_DESC */ ++#define LE2DWord(value) \ ++ ((((value)<<24L) & 0xff000000L) + \ ++ (((value)<< 8L) & 0x00ff0000L) + \ ++ (((value)>> 8L) & 0x0000ff00L) + \ ++ (((value)>>24L) & 0x000000ffL)) ++#endif /* SK_USE_REV_DESC */ ++ ++#else /* !SK_LITTLE_ENDIAN */ ++ ++#ifndef SK_USE_REV_DESC ++#define LE2DWord(value) \ ++ ((((value)<<24L) & 0xff000000L) + \ ++ (((value)<< 8L) & 0x00ff0000L) + \ ++ (((value)>> 8L) & 0x0000ff00L) + \ ++ (((value)>>24L) & 0x000000ffL)) ++#else /* SK_USE_REV_DESC */ ++#define LE2DWord(value) (value) ++#endif /* SK_USE_REV_DESC */ ++ ++#endif /* !SK_LITTLE_ENDIAN */ ++ ++/****************************************************************************** ++ * ++ * DWord2LE() - Converts the given value to a Little Endian value ++ * ++ * Description: ++ * This function converts the value received as an argument to a Little Endian ++ * value on Big Endian machines. If the machine running the code is Little ++ * Endian, then no conversion is done. ++ * ++ * Returns: ++ * The converted value ++ * ++ */ ++ ++#ifdef SK_LITTLE_ENDIAN ++ ++#ifndef SK_USE_REV_DESC ++#define DWord2LE(value) (value) ++#else /* SK_USE_REV_DESC */ ++#define DWord2LE(value) \ ++ ((((value)<<24L) & 0xff000000L) + \ ++ (((value)<< 8L) & 0x00ff0000L) + \ ++ (((value)>> 8L) & 0x0000ff00L) + \ ++ (((value)>>24L) & 0x000000ffL)) ++#endif /* SK_USE_REV_DESC */ ++ ++#else /* !SK_LITTLE_ENDIAN */ ++ ++#ifndef SK_USE_REV_DESC ++#define DWord2LE(value) \ ++ ((((value)<<24L) & 0xff000000L) + \ ++ (((value)<< 8L) & 0x00ff0000L) + \ ++ (((value)>> 8L) & 0x0000ff00L) + \ ++ (((value)>>24L) & 0x000000ffL)) ++#else /* SK_USE_REV_DESC */ ++#define DWord2LE(value) (value) ++#endif /* SK_USE_REV_DESC */ ++#endif /* !SK_LITTLE_ENDIAN */ ++ ++/****************************************************************************** ++ * ++ * LE2Word() - Converts the given Little Endian value to machine order value ++ * ++ * Description: ++ * This function converts the Little Endian value received as an argument to ++ * the machine order value. ++ * ++ * Returns: ++ * The converted value ++ * ++ */ ++ ++#ifdef SK_LITTLE_ENDIAN ++#ifndef SK_USE_REV_DESC ++#define LE2Word(value) (value) ++#else /* SK_USE_REV_DESC */ ++#define LE2Word(value) \ ++ ((((value)<< 8L) & 0xff00) + \ ++ (((value)>> 8L) & 0x00ff)) ++#endif /* SK_USE_REV_DESC */ ++ ++#else /* !SK_LITTLE_ENDIAN */ ++#ifndef SK_USE_REV_DESC ++#define LE2Word(value) \ ++ ((((value)<< 8L) & 0xff00) + \ ++ (((value)>> 8L) & 0x00ff)) ++#else /* SK_USE_REV_DESC */ ++#define LE2Word(value) (value) ++#endif /* SK_USE_REV_DESC */ ++#endif /* !SK_LITTLE_ENDIAN */ ++ ++/****************************************************************************** ++ * ++ * Word2LE() - Converts the given value to a Little Endian value ++ * ++ * Description: ++ * This function converts the value received as an argument to a Little Endian ++ * value on Big Endian machines. If the machine running the code is Little ++ * Endian, then no conversion is done. ++ * ++ * Returns: ++ * The converted value ++ * ++ */ ++ ++#ifdef SK_LITTLE_ENDIAN ++#ifndef SK_USE_REV_DESC ++#define Word2LE(value) (value) ++#else /* SK_USE_REV_DESC */ ++#define Word2LE(value) \ ++ ((((value)<< 8L) & 0xff00) + \ ++ (((value)>> 8L) & 0x00ff)) ++#endif /* SK_USE_REV_DESC */ ++ ++#else /* !SK_LITTLE_ENDIAN */ ++#ifndef SK_USE_REV_DESC ++#define Word2LE(value) \ ++ ((((value)<< 8L) & 0xff00) + \ ++ (((value)>> 8L) & 0x00ff)) ++#else /* SK_USE_REV_DESC */ ++#define Word2LE(value) (value) ++#endif /* SK_USE_REV_DESC */ ++#endif /* !SK_LITTLE_ENDIAN */ ++ ++/****************************************************************************** ++ * ++ * Transmit list element macros ++ * ++ */ ++ ++#define TXLE_SET_ADDR(pLE, Addr) \ ++ ((pLE)->Tx.TxUn.BufAddr = DWord2LE(Addr)) ++#define TXLE_SET_LSLEN(pLE, Len) \ ++ ((pLE)->Tx.TxUn.LargeSend.Length = Word2LE(Len)) ++#define TXLE_SET_STACS(pLE, Start) \ ++ ((pLE)->Tx.TxUn.ChkSum.TxTcpSp = Word2LE(Start)) ++#define TXLE_SET_WRICS(pLE, Write) \ ++ ((pLE)->Tx.TxUn.ChkSum.TxTcpWp = Word2LE(Write)) ++#define TXLE_SET_INICS(pLE, Ini) ((pLE)->Tx.Send.InitCsum = Word2LE(Ini)) ++#define TXLE_SET_LEN(pLE, Len) ((pLE)->Tx.Send.BufLen = Word2LE(Len)) ++#define TXLE_SET_VLAN(pLE, Vlan) ((pLE)->Tx.Send.VlanTag = Word2LE(Vlan)) ++#define TXLE_SET_LCKCS(pLE, Lock) ((pLE)->Tx.ControlFlags = (Lock)) ++#define TXLE_SET_CTRL(pLE, Ctrl) ((pLE)->Tx.ControlFlags = (Ctrl)) ++#define TXLE_SET_OPC(pLE, Opc) ((pLE)->Tx.Opcode = (Opc)) ++ ++#define TXLE_GET_ADDR(pLE) LE2DWord((pLE)->Tx.TxUn.BufAddr) ++#define TXLE_GET_LSLEN(pLE) LE2Word((pLE)->Tx.TxUn.LargeSend.Length) ++#define TXLE_GET_STACS(pLE) LE2Word((pLE)->Tx.TxUn.ChkSum.TxTcpSp) ++#define TXLE_GET_WRICS(pLE) LE2Word((pLE)->Tx.TxUn.ChkSum.TxTcpWp) ++#define TXLE_GET_INICS(pLE) LE2Word((pLE)->Tx.Send.InitCsum) ++#define TXLE_GET_LEN(pLE) LE2Word((pLE)->Tx.Send.BufLen) ++#define TXLE_GET_VLAN(pLE) LE2Word((pLE)->Tx.Send.VlanTag) ++#define TXLE_GET_LCKCS(pLE) ((pLE)->Tx.ControlFlags) ++#define TXLE_GET_CTRL(pLE) ((pLE)->Tx.ControlFlags) ++#define TXLE_GET_OPC(pLE) ((pLE)->Tx.Opcode) ++ ++ /* Yukon-Extreme only */ ++#define TXLE_SET_LSOV2(pLE, Len) \ ++ ((pLE)->Tx.TxUn.LsoV2Len = DWord2LE(Len)) ++#define TXLE_SET_MSSVAL(pLE, Val) \ ++((pLE)->Tx.TxUn.Mss.TxMssVal = Word2LE(Val)) ++ ++#define TXLE_GET_LSOV2(pLE) LE2DWord((pLE)->Tx.TxUn.LsoV2Len) ++#define TXLE_GET_MSSVAL(pLE) LE2Word((pLE)->Tx.TxUn.Mss.TxMssVal) ++ ++/****************************************************************************** ++ * ++ * Receive list element macros ++ * ++ */ ++ ++#define RXLE_SET_ADDR(pLE, Addr) \ ++ ((pLE)->Rx.RxUn.BufAddr = (SK_U32)DWord2LE(Addr)) ++#define RXLE_SET_STACS2(pLE, Offs) \ ++ ((pLE)->Rx.RxUn.ChkSum.RxTcpSp2 = Word2LE(Offs)) ++#define RXLE_SET_STACS1(pLE, Offs) \ ++ ((pLE)->Rx.RxUn.ChkSum.RxTcpSp1 = Word2LE(Offs)) ++#define RXLE_SET_LEN(pLE, Len) ((pLE)->Rx.BufferLength = Word2LE(Len)) ++#define RXLE_SET_CTRL(pLE, Ctrl) ((pLE)->Rx.ControlFlags = (Ctrl)) ++#define RXLE_SET_OPC(pLE, Opc) ((pLE)->Rx.Opcode = (Opc)) ++ ++#define RXLE_GET_ADDR(pLE) LE2DWord((pLE)->Rx.RxUn.BufAddr) ++#define RXLE_GET_STACS2(pLE) LE2Word((pLE)->Rx.RxUn.ChkSum.RxTcpSp2) ++#define RXLE_GET_STACS1(pLE) LE2Word((pLE)->Rx.RxUn.ChkSum.RxTcpSp1) ++#define RXLE_GET_LEN(pLE) LE2Word((pLE)->Rx.BufferLength) ++#define RXLE_GET_CTRL(pLE) ((pLE)->Rx.ControlFlags) ++#define RXLE_GET_OPC(pLE) ((pLE)->Rx.Opcode) ++ ++/****************************************************************************** ++ * ++ * Status list element macros ++ * ++ */ ++ ++#define STLE_SET_OPC(pLE, Opc) ((pLE)->St.Opcode = (Opc)) ++ ++#define STLE_GET_FRSTATUS(pLE) LE2DWord((pLE)->St.StUn.StRxStatWord) ++#define STLE_GET_TIST(pLE) LE2DWord((pLE)->St.StUn.StRxTimeStamp) ++#define STLE_GET_TCP1(pLE) LE2Word((pLE)->St.StUn.StRxTCPCSum.RxTCPSum1) ++#define STLE_GET_TCP2(pLE) LE2Word((pLE)->St.StUn.StRxTCPCSum.RxTCPSum2) ++#define STLE_GET_LEN(pLE) LE2Word((pLE)->St.Stat.BufLen) ++#define STLE_GET_VLAN(pLE) LE2Word((pLE)->St.Stat.VlanTag) ++#define STLE_GET_LINK(pLE) ((pLE)->St.Link) ++#define STLE_GET_OPC(pLE) ((pLE)->St.Opcode) ++#define STLE_GET_DONE_IDX(pLE,LowVal,HighVal) { \ ++ (LowVal) = LE2DWord((pLE)->St.StUn.StTxStatLow); \ ++ (HighVal) = LE2Word((pLE)->St.Stat.StTxStatHi); \ ++} ++ ++#define STLE_GET_RSS(pLE) LE2DWord((pLE)->St.StUn.StRxRssValue) ++#define STLE_GET_IPV6BIT(pLE) ((pLE)->St.Stat.Rss.FlagField & RSS_IPV6_FLAG) ++#define STLE_GET_IPBIT(pLE) ((pLE)->St.Stat.Rss.FlagField & RSS_IP_FLAG) ++#define STLE_GET_TCPBIT(pLE) ((pLE)->St.Stat.Rss.FlagField & RSS_TCP_FLAG) ++ ++/* Yukon-Extreme only */ ++#define STLE_GET_MX_STAT(pLE) ((pLE)->St.StUn.StMacSecWord) ++ ++/* Yukon-Ext CSum Status defines (Rx Status, Link field) */ ++#define CSS_GET_PORT(Link) (Link & CSS_LINK_BIT) ++#define CSS_IS_IPV4(Link) (Link & CSS_ISIPV4) ++#define CSS_IPV4_CSUM_OK(Link) (Link & CSS_IPV4CSUMOK) ++#define CSS_IS_IPV6(Link) (Link & CSS_ISIPV6) ++#define CSS_IS_IPFRAG(Link) (Link & CSS_ISIPFRAG) ++#define CSS_IS_TCP(Link) (Link & CSS_ISTCP) ++#define CSS_IS_UDP(Link) (Link & CSS_ISUDP) ++#define CSS_TCPUDP_CSUM_OK(Link) (Link & CSS_TCPUDPCSOK) ++ ++/* always take both values as a parameter to avoid typos */ ++#define STLE_GET_DONE_IDX_TXA1(LowVal,HighVal) \ ++ (((LowVal) & STLE_TXA1_MSKL) >> STLE_TXA1_SHIFTL) ++#define STLE_GET_DONE_IDX_TXS1(LowVal,HighVal) \ ++ ((LowVal & STLE_TXS1_MSKL) >> STLE_TXS1_SHIFTL) ++#define STLE_GET_DONE_IDX_TXA2(LowVal,HighVal) \ ++ (((LowVal & STLE_TXA2_MSKL) >> STLE_TXA2_SHIFTL) + \ ++ ((HighVal & STLE_TXA2_MSKH) << STLE_TXA2_SHIFTH)) ++#define STLE_GET_DONE_IDX_TXS2(LowVal,HighVal) \ ++ ((HighVal & STLE_TXS2_MSKH) >> STLE_TXS2_SHIFTH) ++ ++ ++#define SK_Y2_RXSTAT_CHECK_PKT(Len, RxStat, IsOk) { \ ++ (IsOk) = (((RxStat) & GMR_FS_RX_OK) != 0) && \ ++ (((RxStat) & GMR_FS_ANY_ERR) == 0); \ ++ \ ++ if ((IsOk) && ((SK_U16)(((RxStat) & GMR_FS_LEN_MSK) >> \ ++ GMR_FS_LEN_SHIFT) != (Len))) { \ ++ /* length in MAC status differs from length in LE */\ ++ (IsOk) = SK_FALSE; \ ++ } \ ++} ++ ++ ++/****************************************************************************** ++ * ++ * Polling unit list element macros ++ * ++ * NOTE: the Idx must be <= 0xfff and PU_PUTIDX_VALID makes them valid ++ * ++ */ ++ ++#ifdef USE_POLLING_UNIT ++ ++#define POLE_SET_OPC(pLE, Opc) ((pLE)->Sa.Opcode = (Opc)) ++#define POLE_SET_LINK(pLE, Port) ((pLE)->Sa.Link = (Port)) ++#define POLE_SET_RXIDX(pLE, Idx) ((pLE)->Sa.RxIdxVld = Word2LE(Idx)) ++#define POLE_SET_TXAIDX(pLE, Idx) ((pLE)->Sa.TxAIdxVld = Word2LE(Idx)) ++#define POLE_SET_TXSIDX(pLE, Idx) ((pLE)->Sa.TxSIdxVld = Word2LE(Idx)) ++ ++#define POLE_GET_OPC(pLE) ((pLE)->Sa.Opcode) ++#define POLE_GET_LINK(pLE) ((pLE)->Sa.Link) ++#define POLE_GET_RXIDX(pLE) LE2Word((pLE)->Sa.RxIdxVld) ++#define POLE_GET_TXAIDX(pLE) LE2Word((pLE)->Sa.TxAIdxVld) ++#define POLE_GET_TXSIDX(pLE) LE2Word((pLE)->Sa.TxSIdxVld) ++ ++#endif /* USE_POLLING_UNIT */ ++ ++/****************************************************************************** ++ * ++ * Debug macros for list elements ++ * ++ */ ++ ++#ifdef DEBUG ++ ++#define SK_DBG_DUMP_RX_LE(pLE) { \ ++ SK_U8 Opcode; \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("=== RX_LIST_ELEMENT @addr: %p cont: %02x %02x %02x %02x %02x %02x %02x %02x\n", \ ++ pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\ ++ ((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5], \ ++ ((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7])); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\t (16bit) %04x %04x %04x %04x\n", \ ++ ((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2], \ ++ ((SK_U16 *) pLE)[3])); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\t (32bit) %08x %08x\n", \ ++ ((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1])); \ ++ Opcode = RXLE_GET_OPC(pLE); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == HW_OWNER) ? \ ++ "Hardware" : "Software")); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOpc: 0x%x ",Opcode)); \ ++ switch (Opcode & (~HW_OWNER)) { \ ++ case OP_BUFFER: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_BUFFER\n")); \ ++ break; \ ++ case OP_PACKET: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_PACKET\n")); \ ++ break; \ ++ case OP_ADDR64: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_ADDR64\n")); \ ++ break; \ ++ case OP_TCPSTART: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_TCPPAR\n")); \ ++ break; \ ++ case SW_OWNER: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tunused LE\n")); \ ++ break; \ ++ default: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tunknown Opcode!!!\n")); \ ++ } \ ++ if ((Opcode & OP_BUFFER) == OP_BUFFER) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tControl: 0x%x\n", RXLE_GET_CTRL(pLE))); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tBufLen: 0x%x\n", RXLE_GET_LEN(pLE))); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tLowAddr: 0x%x\n", RXLE_GET_ADDR(pLE))); \ ++ } \ ++ if ((Opcode & OP_ADDR64) == OP_ADDR64) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tHighAddr: 0x%x\n", RXLE_GET_ADDR(pLE))); \ ++ } \ ++ if ((Opcode & OP_TCPSTART) == OP_TCPSTART) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTCP Sum Start 1 : 0x%x\n", RXLE_GET_STACS1(pLE))); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTCP Sum Start 2 : 0x%x\n", RXLE_GET_STACS2(pLE))); \ ++ } \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("=====================\n")); \ ++} ++ ++#define SK_DBG_DUMP_TX_LE(pLE) { \ ++ SK_U8 Opcode; \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("=== TX_LIST_ELEMENT @addr: %p cont: %02x %02x %02x %02x %02x %02x %02x %02x\n", \ ++ pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\ ++ ((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5], \ ++ ((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7])); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\t (16bit) %04x %04x %04x %04x\n", \ ++ ((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2], \ ++ ((SK_U16 *) pLE)[3])); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\t (32bit) %08x %08x\n", \ ++ ((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1])); \ ++ Opcode = TXLE_GET_OPC(pLE); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == HW_OWNER) ? \ ++ "Hardware" : "Software")); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOpc: 0x%x ",Opcode)); \ ++ switch (Opcode & (~HW_OWNER)) { \ ++ case OP_TCPCHKSUM: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_TCPCHKSUM\n")); \ ++ break; \ ++ case OP_TCPIS: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_TCPIS\n")); \ ++ break; \ ++ case OP_TCPLCK: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_TCPLCK\n")); \ ++ break; \ ++ case OP_TCPLW: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_TCPLW\n")); \ ++ break; \ ++ case OP_TCPLSW: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_TCPLSW\n")); \ ++ break; \ ++ case OP_TCPLISW: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_TCPLISW\n")); \ ++ break; \ ++ case OP_ADDR64: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_ADDR64\n")); \ ++ break; \ ++ case OP_VLAN: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_VLAN\n")); \ ++ break; \ ++ case OP_ADDR64VLAN: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_ADDR64VLAN\n")); \ ++ break; \ ++ case OP_LRGLEN: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_LRGLEN\n")); \ ++ break; \ ++ case OP_LRGLENVLAN: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_LRGLENVLAN\n")); \ ++ break; \ ++ case OP_BUFFER: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_BUFFER\n")); \ ++ break; \ ++ case OP_PACKET: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_PACKET\n")); \ ++ break; \ ++ case OP_LARGESEND: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_LARGESEND\n")); \ ++ break; \ ++ case OP_MSS: /* Yukon-Extreme only */ \ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_MSS\n")) \ ++ break; \ ++ case OP_MSSVLAN: /* Yukon-Extreme only */ \ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_MSSVLAN\n")) \ ++ break; \ ++ case OP_LSOV2: /* Yukon-Extreme only */ \ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_LSOV2\n")) \ ++ break; \ ++ case SW_OWNER: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tunused LE\n")); \ ++ break; \ ++ default: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tunknown Opcode!!!\n")); \ ++ } \ ++ if ((Opcode & OP_BUFFER) == OP_BUFFER) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tControl: 0x%x\n", TXLE_GET_CTRL(pLE))); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tBufLen: 0x%x\n", TXLE_GET_LEN(pLE))); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tLowAddr: 0x%x\n", TXLE_GET_ADDR(pLE))); \ ++ } \ ++ if ((Opcode & OP_ADDR64) == OP_ADDR64) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tHighAddr: 0x%x\n", TXLE_GET_ADDR(pLE))); \ ++ } \ ++ if ((Opcode & OP_VLAN) == OP_VLAN) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tVLAN Id: 0x%x\n", TXLE_GET_VLAN(pLE))); \ ++ } \ ++ if ((Opcode & OP_LRGLEN) == OP_LRGLEN) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tLarge send length: 0x%x\n", TXLE_GET_LSLEN(pLE))); \ ++ } \ ++ if ((Opcode & OP_MSS) == OP_MSS) { /* Yukon-Extreme only */ \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tMSS value: 0x%x\n", TXLE_GET_MSSVAL(pLE))); \ ++ } \ ++ if ((Opcode & OP_LSOV2) == OP_LSOV2) { /* Yukon-Extreme only */ \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tLSOv2 lenght: 0x%x\n", TXLE_GET_LSOV2(pLE))); \ ++ } \ ++ if ((Opcode &(~HW_OWNER)) <= OP_ADDR64) { \ ++ if ((Opcode & OP_TCPWRITE) == OP_TCPWRITE) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTCP Sum Write: 0x%x\n", TXLE_GET_WRICS(pLE))); \ ++ } \ ++ if ((Opcode & OP_TCPSTART) == OP_TCPSTART) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTCP Sum Start: 0x%x\n", TXLE_GET_STACS(pLE))); \ ++ } \ ++ if ((Opcode & OP_TCPINIT) == OP_TCPINIT) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTCP Sum Init: 0x%x\n", TXLE_GET_INICS(pLE))); \ ++ } \ ++ if ((Opcode & OP_TCPLCK) == OP_TCPLCK) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTCP Sum Lock: 0x%x\n", TXLE_GET_LCKCS(pLE))); \ ++ } \ ++ } \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("=====================\n")); \ ++} ++ ++#define SK_DBG_DUMP_ST_LE(pLE) { \ ++ SK_U8 Opcode; \ ++ SK_U16 HighVal; \ ++ SK_U32 LowVal; \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("=== ST_LIST_ELEMENT @addr: %p contains: %02x %02x %02x %02x %02x %02x %02x %02x\n",\ ++ pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\ ++ ((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5], \ ++ ((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7])); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\t (16bit) %04x %04x %04x %04x\n", \ ++ ((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2], \ ++ ((SK_U16 *) pLE)[3])); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\t (32bit) %08x %08x\n", \ ++ ((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1])); \ ++ Opcode = STLE_GET_OPC(pLE); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == SW_OWNER) ? \ ++ "Hardware" : "Software")); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOpc: 0x%x", Opcode)); \ ++ Opcode &= (~HW_OWNER); \ ++ switch (Opcode) { \ ++ case OP_RXSTAT: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_RXSTAT\n")); \ ++ break; \ ++ case OP_RXTIMESTAMP: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_RXTIMESTAMP\n")); \ ++ break; \ ++ case OP_RXVLAN: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_RXVLAN\n")); \ ++ break; \ ++ case OP_RXCHKS: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_RXCHKS\n")); \ ++ break; \ ++ case OP_RXCHKSVLAN: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_RXCHKSVLAN\n")); \ ++ break; \ ++ case OP_RXTIMEVLAN: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_RXTIMEVLAN\n")); \ ++ break; \ ++ case OP_RSS_HASH: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_RSS_HASH\n")); \ ++ break; \ ++ case OP_TXINDEXLE: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_TXINDEXLE\n")); \ ++ break; \ ++ case OP_MACSEC: /* Yukon-Exteme only */ \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_MACSEC\n")); \ ++ break; \ ++ case OP_MACSECVLAN: /* Yukon-Exteme only */ \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_MACSECVLAN\n")); \ ++ break; \ ++ case HW_OWNER: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tunused LE\n")); \ ++ break; \ ++ default: \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tunknown status list element!!!\n")); \ ++ } \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tPort: %c\n", 'A' + (CSS_GET_PORT(STLE_GET_LINK(pLE))))); \ ++ if (Opcode == OP_RXSTAT) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tFrameLen: 0x%x\n", STLE_GET_LEN(pLE))); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tFrameStat: 0x%x\n", STLE_GET_FRSTATUS(pLE))); \ ++ if (HW_IS_EXT_LE_FORMAT(pAc)) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tChecksum Status Field: 0x%x\n", STLE_GET_LINK(pLE)));\ ++ } \ ++ } \ ++ if ((Opcode & OP_RXVLAN) == OP_RXVLAN) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tVLAN Id: 0x%x\n", STLE_GET_VLAN(pLE))); \ ++ } \ ++ if ((Opcode & OP_RXTIMESTAMP) == OP_RXTIMESTAMP) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTimestamp: 0x%x\n", STLE_GET_TIST(pLE))); \ ++ } \ ++ if ((Opcode & OP_RXCHKS) == OP_RXCHKS) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTCP: 0x%x 0x%x\n", STLE_GET_TCP1(pLE), \ ++ STLE_GET_TCP2(pLE))); \ ++ } \ ++ if (Opcode == OP_TXINDEXLE) { \ ++ STLE_GET_DONE_IDX(pLE, LowVal, HighVal); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTx Index TxA1: 0x%x\n", \ ++ STLE_GET_DONE_IDX_TXA1(LowVal,HighVal))); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTx Index TxS1: 0x%x\n", \ ++ STLE_GET_DONE_IDX_TXS1(LowVal,HighVal))); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTx Index TxA2: 0x%x\n", \ ++ STLE_GET_DONE_IDX_TXA2(LowVal,HighVal))); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTx Index TxS2: 0x%x\n", \ ++ STLE_GET_DONE_IDX_TXS2(LowVal,HighVal))); \ ++ } \ ++ if ((Opcode & OP_MACSEC) == OP_MACSEC) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tMACSec Status Field\n", STLE_GET_MX_STAT(pLE))); \ ++ } \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("=====================\n")); \ ++} ++ ++#ifdef USE_POLLING_UNIT ++#define SK_DBG_DUMP_PO_LE(pLE) { \ ++ SK_U8 Opcode; \ ++ SK_U16 Idx; \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("=== PO_LIST_ELEMENT @addr: %p cont: %02x %02x %02x %02x %02x %02x %02x %02x\n", \ ++ pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\ ++ ((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5], \ ++ ((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7])); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\t (16bit) %04x %04x %04x %04x\n", \ ++ ((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2], \ ++ ((SK_U16 *) pLE)[3])); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\t (32bit) %08x %08x\n", \ ++ ((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1])); \ ++ Opcode = POLE_GET_OPC(pLE); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == HW_OWNER) ? \ ++ "Hardware" : "Software")); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOpc: 0x%x ",Opcode)); \ ++ if ((Opcode & ~HW_OWNER) == OP_PUTIDX) { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tOP_PUTIDX\n")); \ ++ } \ ++ else { \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tunknown Opcode!!!\n")); \ ++ } \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tPort %c\n", 'A' + POLE_GET_LINK(pLE))); \ ++ Idx = POLE_GET_TXAIDX(pLE); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTxA Index is 0x%X and %svalid\n", Idx, \ ++ (Idx & PU_PUTIDX_VALID) ? "" : "not ")); \ ++ Idx = POLE_GET_TXSIDX(pLE); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tTxS Index is 0x%X and %svalid\n", Idx, \ ++ (Idx & PU_PUTIDX_VALID) ? "" : "not ")); \ ++ Idx = POLE_GET_RXIDX(pLE); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("\tRx Index is 0x%X and %svalid\n", Idx, \ ++ (Idx & PU_PUTIDX_VALID) ? "" : "not ")); \ ++ SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ ++ ("=====================\n")); \ ++} ++#endif /* USE_POLLING_UNIT */ ++ ++#else /* !DEBUG */ ++ ++#define SK_DBG_DUMP_RX_LE(pLE) ++#define SK_DBG_DUMP_TX_LE(pLE) ++#define SK_DBG_DUMP_ST_LE(pLE) ++#define SK_DBG_DUMP_PO_LE(pLE) ++ ++#endif /* !DEBUG */ ++ ++/****************************************************************************** ++ * ++ * Macros for listelement tables ++ * ++ * ++ */ ++ ++#define LE_SIZE sizeof(SK_HWLE) ++#define LE_TAB_SIZE(NumElements) ((NumElements) * LE_SIZE) ++ ++/* Number of unused list elements in table ++ * this macro always returns the number of free listelements - 1 ++ * this way we want to guarantee that always one LE remains unused ++ */ ++#define NUM_FREE_LE_IN_TABLE(pTable) \ ++ ( ((pTable)->Put >= (pTable)->Done) ? \ ++ (NUM_LE_IN_TABLE(pTable) - (pTable)->Put + (pTable)->Done - 1) :\ ++ ((pTable)->Done - (pTable)->Put - 1) ) ++ ++/* total number of list elements in table */ ++#define NUM_LE_IN_TABLE(pTable) ((pTable)->Num) ++ ++/* get next unused Rx list element */ ++#define GET_RX_LE(pLE, pTable) { \ ++ pLE = &(pTable)->pLETab[(pTable)->Put]; \ ++ (pTable)->Put = ((pTable)->Put + 1) & (NUM_LE_IN_TABLE(pTable) - 1);\ ++} ++ ++/* get next unused Tx list element */ ++#define GET_TX_LE(pLE, pTable) GET_RX_LE(pLE, pTable) ++ ++/* get next status list element expected to be finished by hw */ ++#define GET_ST_LE(pLE, pTable) { \ ++ pLE = &(pTable)->pLETab[(pTable)->Done]; \ ++ (pTable)->Done = ((pTable)->Done +1) & (NUM_LE_IN_TABLE(pTable) - 1);\ ++} ++ ++#ifdef USE_POLLING_UNIT ++/* get next polling unit list element for port */ ++#define GET_PO_LE(pLE, pTable, Port) { \ ++ pLE = &(pTable)->pLETab[(Port)]; \ ++} ++#endif /* USE_POLLING_UNIT */ ++ ++#define GET_PUT_IDX(pTable) ((pTable)->Put) ++ ++#define UPDATE_HWPUT_IDX(pTable) {(pTable)->HwPut = (pTable)->Put; } ++ ++/* ++ * get own bit of next status LE ++ * if the result is != 0 there has been at least one status LE finished ++ */ ++#define OWN_OF_FIRST_LE(pTable) \ ++ (STLE_GET_OPC(&(pTable)->pLETab[(pTable)->Done]) & HW_OWNER) ++ ++#define SET_DONE_INDEX(pTable, Idx) (pTable)->Done = (Idx); ++ ++#define GET_DONE_INDEX(pTable) ((pTable)->Done) ++ ++#ifdef SAFE_BUT_SLOW ++ ++/* check own bit of LE before current done idx */ ++#define CHECK_STLE_OVERFLOW(pTable, IsOk) { \ ++ unsigned i; \ ++ if ((i = (pTable)->Done) == 0) { \ ++ i = NUM_LE_IN_TABLE(pTable); \ ++ } \ ++ else { \ ++ i = i - 1; \ ++ } \ ++ if (STLE_GET_OPC(&(pTable)->pLETab[i]) == HW_OWNER) { \ ++ (IsOk) = SK_TRUE; \ ++ } \ ++ else { \ ++ (IsOk) = SK_FALSE; \ ++ } \ ++ } ++ ++ ++/* ++ * for Yukon-2 the hardware is not polling the list elements, so it ++ * is not necessary to change the own-bit of Rx or Tx LEs before ++ * reusing them ++ * but it might make debugging easier if one simply can see whether ++ * a LE has been worked on ++ */ ++ ++#define CLEAR_LE_OWN(pTable, Idx) \ ++ STLE_SET_OPC(&(pTable)->pLETab[(Idx)], SW_OWNER) ++ ++/* ++ * clear all own bits starting from old done index up to the LE before ++ * the new done index ++ */ ++#define CLEAR_LE_OWN_FROM_DONE_TO(pTable, To) { \ ++ int i; \ ++ i = (pTable)->Done; \ ++ while (i != To) { \ ++ CLEAR_LE_OWN(pTable, i); \ ++ i = (i + 1) & (NUM_LE_IN_TABLE(pTable) - 1); \ ++ } \ ++ } ++ ++#else /* !SAFE_BUT_SLOW */ ++ ++#define CHECK_STLE_OVERFLOW(pTable, IsOk) ++#define CLEAR_LE_OWN(pTable, Idx) ++#define CLEAR_LE_OWN_FROM_DONE_TO(pTable, To) ++ ++#endif /* !SAFE_BUT_SLOW */ ++ ++ ++/* typedefs *******************************************************************/ ++ ++typedef struct s_LetRxTx { ++ SK_U16 VlanId; /* VLAN Id given down last time */ ++ SK_U16 TcpWp; /* TCP Checksum Write Position */ ++ SK_U16 TcpSp1; /* TCP Checksum Calculation Start Position 1 */ ++ SK_U16 TcpSp2; /* TCP Checksum Calculation Start Position 2 */ ++ SK_U16 MssValue; /* Maximum Segment Size */ ++ SK_U16 Reserved1; /* reserved word for furture extensions */ ++ SK_U16 Reserved2; /* reserved word for furture extensions */ ++ SK_U16 Reserved3; /* reserved word for furture extensions */ ++} SK_LET_RX_TX; ++ ++typedef struct s_LetStat { ++ SK_U32 RxTimeStamp; /* Receive Timestamp */ ++ SK_U32 RssHashValue; /* RSS Hash Value */ ++ SK_BOOL RssIsIpV6; /* RSS Hash Value: IPv6 packet detected */ ++ SK_BOOL RssIsIp; /* RSS Hash Value: IP packet detected */ ++ SK_BOOL RssIsTcp; /* RSS Hash Value: IP+TCP packet detected */ ++ SK_U16 VlanId; /* VLAN Id given received by Status BMU */ ++ SK_U16 TcpSum1; /* TCP checksum 1 (status BMU) */ ++ SK_U16 TcpSum2; /* TCP checksum 2 (status BMU) */ ++ SK_U32 MacSecStatus; /* MAC Security status for packet */ ++} SK_LET_STAT; ++ ++typedef union s_LetBmuSpec { ++ SK_LET_RX_TX RxTx; /* Rx/Tx BMU specific variables */ ++ SK_LET_STAT Stat; /* Status BMU specific variables */ ++} SK_LET_BMU_S; ++ ++typedef struct s_le_table { ++ /* all LE's between Done and HWPut are owned by the hardware */ ++ /* all LE's between Put and Done can be used from software */ ++ /* all LE's between HWPut and Put are currently processed in DriverSend */ ++ unsigned Done; /* done index - consumed from HW and available */ ++ unsigned Put; /* put index - to be given to hardware */ ++ unsigned HwPut; /* put index actually given to hardware */ ++ unsigned Num; /* total number of list elements */ ++ SK_HWLE *pLETab; /* virtual address of list element table */ ++ SK_U32 pPhyLETABLow; /* physical address of list element table */ ++ SK_U32 pPhyLETABHigh; /* physical address of list element table */ ++ /* values to remember in order to save some LEs */ ++ SK_U32 BufHighAddr; /* high address given down last time */ ++ SK_LET_BMU_S Bmu; /* contains BMU specific information */ ++ SK_U32 Private; /* driver private variable free usable */ ++ SK_U16 TcpInitCsum; /* init checksum */ ++#if defined(SK_LSO_V2) && defined(SK_EXTREME) ++ unsigned DoneCorrection; /* number of LSOv2 LEs send modulo Num */ ++ unsigned BadDone; /* real done index from HW - in Done is a corrected value */ ++#endif ++} SK_LE_TABLE; ++ ++/* function prototypes ********************************************************/ ++ ++#ifndef SK_KR_PROTO ++ ++/* ++ * public functions in sky2le.c ++ */ ++extern void SkGeY2SetPutIndex( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ SK_U32 StartAddrPrefetchUnit, ++ SK_LE_TABLE *pLETab); ++ ++extern void SkGeY2InitPrefetchUnit( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ unsigned int Queue, ++ SK_LE_TABLE *pLETab); ++ ++extern void SkGeY2InitStatBmu( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ SK_LE_TABLE *pLETab); ++ ++extern void SkGeY2InitPollUnit( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ SK_LE_TABLE *pLETab); ++ ++extern void SkGeY2InitSingleLETable( ++ SK_AC *pAC, ++ SK_LE_TABLE *pLETab, ++ unsigned int NumLE, ++ void *pVMem, ++ SK_U32 PMemLowAddr, ++ SK_U32 PMemHighAddr); ++ ++#else /* SK_KR_PROTO */ ++extern void SkGeY2SetPutIndex(); ++extern void SkGeY2InitPrefetchUnit(); ++extern void SkGeY2InitStatBmu(); ++extern void SkGeY2InitPollUnit(); ++extern void SkGeY2InitSingleLETable(); ++#endif /* SK_KR_PROTO */ ++ ++#ifdef __cplusplus ++} ++#endif /* __cplusplus */ ++ ++#endif /* __INC_SKY2LE_H */ ++ +diff -ruN linux/drivers/net/sk98lin/h/xmac_ii.h linux-new/drivers/net/sk98lin/h/xmac_ii.h +--- linux/drivers/net/sk98lin/h/xmac_ii.h 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/h/xmac_ii.h 2007-01-24 14:03:40.000000000 +0100 +@@ -2,23 +2,24 @@ + * + * Name: xmac_ii.h + * Project: Gigabit Ethernet Adapters, Common Modules +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Defines and Macros for Gigabit Ethernet Controller + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2007 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. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -203,7 +204,7 @@ + + /* 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_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 */ +@@ -371,18 +372,18 @@ + /* 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_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 */ ++#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_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 */ +@@ -390,9 +391,9 @@ + #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_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_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 */ +@@ -401,57 +402,57 @@ + #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_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_MPAUSE_OV (1L<<6) /* Bit 6: Rx Pause MAC Ctrl-F Ov */ ++#define XMR_UC_OK_OV (1L<<5) /* Bit 5: Rx Unicast Frame Cnt Ov */ + #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_OK_LO_OV (1L<<2) /* Bit 2: Octets Rx OK Low Cnt Ov */ ++#define XMR_OK_HI_OV (1L<<1) /* Bit 1: Octets Rx OK High 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_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_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_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_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_OK_LO_OV (1L<<2) /* Bit 2: Octets Tx OK Low Cnt Ov */ ++#define XMT_OK_HI_OV (1L<<1) /* Bit 1: Octets Tx OK High 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_LEN_MSK (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 */ +@@ -469,6 +470,8 @@ + #define XMR_FS_ERR (1L<<1) /* Bit 1: Frame Error */ + #define XMR_FS_MCTRL (1L<<0) /* Bit 0: MAC Control Packet */ + ++#define XMR_FS_LEN_SHIFT 18 ++ + /* + * XMR_FS_ERR will be set if + * XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT, +@@ -488,7 +491,7 @@ + #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_LP 0x05 /* 16 bit r/o Link Partner Ability 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 */ +@@ -505,12 +508,12 @@ + #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_LP 0x05 /* 16 bit r/o Link Partner 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_CTRL 0x09 /* 16 bit r/w 1000Base-T Control 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 */ +@@ -536,29 +539,37 @@ + #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_LP 0x05 /* 16 bit r/o Link Partner 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_CTRL 0x09 /* 16 bit r/w 1000Base-T Control 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_PHY_CTRL 0x10 /* 16 bit r/w PHY Specific Control Reg */ ++#define PHY_MARV_PHY_STAT 0x11 /* 16 bit r/o PHY Specific Status 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_PORT_IRQ 0x17 /* 16 bit r/o Port 0 IRQ (88E1111 only) */ + #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 */ ++#define PHY_MARV_PAGE_ADDR 0x1d /* 16 bit r/w Extended Page Address Reg */ ++#define PHY_MARV_PAGE_DATA 0x1e /* 16 bit r/w Extended Page Data Reg */ ++ ++/* for 10/100 Fast Ethernet PHY (88E3082 only) */ ++#define PHY_MARV_FE_LED_PAR 0x16 /* 16 bit r/w LED Parallel Select Reg. */ ++#define PHY_MARV_FE_LED_SER 0x17 /* 16 bit r/w LED Stream Select S. LED */ ++#define PHY_MARV_FE_VCT_TX 0x1a /* 16 bit r/w VCT Reg. for TXP/N Pins */ ++#define PHY_MARV_FE_VCT_RX 0x1b /* 16 bit r/o VCT Reg. for RXP/N Pins */ ++#define PHY_MARV_FE_SPEC_2 0x1c /* 16 bit r/w Specific Control Reg. 2 */ + + /*----------------------------------------------------------------------------*/ + /* +@@ -569,14 +580,14 @@ + #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_LP 0x05 /* 16 bit r/o Link Partner 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_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 */ ++ /* 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 */ +@@ -585,7 +596,7 @@ + #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 */ ++ /* 0x17 - 0x1c: reserved */ + + /*----------------------------------------------------------------------------*/ + /* +@@ -603,14 +614,14 @@ + /* 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 */ ++ /* 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 */ ++ /* 0x15 - 0x18: reserved */ + #define PHY_NAT_PHY_ADDR 0x19 /* 16 bit r/o PHY Address Register */ + + +@@ -618,7 +629,7 @@ + + /* + * PHY bit definitions +- * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are ++ * Bits defined as PHY_X_..., PHY_B_..., PHY_L_..., PHY_N_... or PHY_M_... are + * XMAC/Broadcom/LevelOne/National/Marvell-specific. + * All other are general. + */ +@@ -629,14 +640,14 @@ + /***** 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_SPS_LSB (1<<13) /* Bit 13: 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_PDOWN (1<<11) /* Bit 11: Power Down Mode */ ++#define PHY_CT_ISOL (1<<10) /* Bit 10: 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 */ ++#define PHY_CT_COL_TST (1<<7) /* Bit 7: Collision Test enabled */ ++#define PHY_CT_SPS_MSB (1<<6) /* Bit 6: Speed select, upper bit */ + /* Bit 5..0: reserved */ + + #define PHY_CT_SP1000 PHY_CT_SPS_MSB /* enable speed of 1000 Mbps */ +@@ -649,25 +660,25 @@ + /***** 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*/ ++ /* (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_PRE_SUP (1<<6) /* Bit 6: 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_JAB_DET (1<<1) /* Bit 1: 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 */ ++/***** 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 */ ++#define PHY_I1_REV_MSK 0xf /* Bit 3.. 0: Revision Number */ + + /* different Broadcom PHY Ids */ + #define PHY_BCOM_ID1_A1 0x6041 +@@ -675,11 +686,22 @@ + #define PHY_BCOM_ID1_C0 0x6044 + #define PHY_BCOM_ID1_C5 0x6047 + ++/* different Marvell PHY Ids */ ++#define PHY_MARV_ID0_VAL 0x0141 /* Marvell Unique Identifier */ ++ ++#define PHY_MARV_ID1_B0 0x0C23 /* Yukon (PHY 88E1040 Rev.C0) */ ++#define PHY_MARV_ID1_B2 0x0C25 /* Yukon-Plus (PHY 88E1040 Rev.D0) */ ++#define PHY_MARV_ID1_C2 0x0CC2 /* Yukon-EC (PHY 88E1111 Rev.B1) */ ++#define PHY_MARV_ID1_Y2 0x0C91 /* Yukon-XL (PHY 88E1112 Rev.B0) */ ++#define PHY_MARV_ID1_FE 0x0C83 /* Yukon-FE (PHY 88E3082 Rev.A1) */ ++#define PHY_MARV_ID1_ECU 0x0CB0 /* Yukon-ECU (PHY 88E1149 Rev.B2?) */ ++#define PHY_MARV_ID1_EX 0x0CB1 /* Yukon-Ext. (PHY 88E1149R Rev.?) */ ++ + + /***** 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_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 */ +@@ -738,7 +760,7 @@ + /* 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. */ ++#define PHY_ANE_LP_CAP (1<<0) /* Bit 0: Link Partner Auto-Neg. Able */ + + /***** PHY_XMAC_NEPG 16 bit r/w Next Page Register *****/ + /***** PHY_BCOM_NEPG 16 bit r/w Next Page Register *****/ +@@ -827,7 +849,7 @@ + #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_EN_LTR (1<<5) /* Bit 5: Enable 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 */ +@@ -981,7 +1003,7 @@ + #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_LLE (7<<4) /* Bit 6..4: 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 */ +@@ -1029,9 +1051,8 @@ + /* 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 */ +- ++#define PHY_L_CIM_ISOL (0xff<<8) /* Bit 15..8: Isolate Count */ ++#define PHY_L_CIM_FALSE_CAR 0xff /* Bit 7..0: False Carrier Count */ + + /* + * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding +@@ -1041,7 +1062,6 @@ + #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 + */ +@@ -1085,23 +1105,25 @@ + * 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 */ ++/***** PHY_MARV_AUNE_LP 16 bit r/w Link Partner Ability Reg *****/ ++#define PHY_M_AN_NXT_PG BIT_15S /* Request Next Page */ ++#define PHY_M_AN_ACK BIT_14S /* (ro) Acknowledge Received */ ++#define PHY_M_AN_RF BIT_13S /* Remote Fault */ ++ /* Bit 12: reserved */ ++#define PHY_M_AN_ASP BIT_11S /* Asymmetric Pause */ ++#define PHY_M_AN_PC BIT_10S /* MAC Pause implemented */ ++#define PHY_M_AN_100_T4 BIT_9S /* Not cap. 100Base-T4 (always 0) */ ++#define PHY_M_AN_100_FD BIT_8S /* Advertise 100Base-TX Full Duplex */ ++#define PHY_M_AN_100_HD BIT_7S /* Advertise 100Base-TX Half Duplex */ ++#define PHY_M_AN_10_FD BIT_6S /* Advertise 10Base-TX Full Duplex */ ++#define PHY_M_AN_10_HD BIT_5S /* Advertise 10Base-TX Half Duplex */ ++#define PHY_M_AN_SEL_MSK (0x1f<<4) /* Bit 4.. 0: Selector Field Mask */ ++ ++/* special defines for FIBER (88E1040S only) */ ++#define PHY_M_AN_ASP_X BIT_8S /* Asymmetric Pause */ ++#define PHY_M_AN_PC_X BIT_7S /* MAC Pause implemented */ ++#define PHY_M_AN_1000X_AHD BIT_6S /* Advertise 10000Base-X Half Duplex */ ++#define PHY_M_AN_1000X_AFD BIT_5S /* 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 */ +@@ -1111,105 +1133,168 @@ + + /***** 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 */ ++#define PHY_M_1000C_MSE BIT_12S /* Manual Master/Slave Enable */ ++#define PHY_M_1000C_MSC BIT_11S /* M/S Configuration (1=Master) */ ++#define PHY_M_1000C_MPD BIT_10S /* Multi-Port Device */ ++#define PHY_M_1000C_AFD BIT_9S /* Advertise Full Duplex */ ++#define PHY_M_1000C_AHD BIT_8S /* 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_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 BIT_11S /* Assert CRS on Transmit */ ++#define PHY_M_PC_FL_GOOD BIT_10S /* 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 BIT_7S /* 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 BIT_4S /* Disable 125 CLK */ ++#define PHY_M_PC_MAC_POW_UP BIT_3S /* MAC Power up */ ++#define PHY_M_PC_SQE_T_ENA BIT_2S /* SQE Test Enabled */ ++#define PHY_M_PC_POL_R_DIS BIT_1S /* Polarity Reversal Disabled */ ++#define PHY_M_PC_DIS_JABBER BIT_0S /* 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_MDI_XMODE(x) (SHIFT5(x) & PHY_M_PC_MDIX_MSK) ++ ++#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 */ + ++/* for Yukon-2/-EC Ultra Gigabit Ethernet PHY (88E1112/88E1149 only) */ ++#define PHY_M_PC_DIS_LINK_P BIT_15S /* Disable Link Pulses */ ++#define PHY_M_PC_DSC_MSK (7<<12) /* Bit 14..12: Downshift Counter */ ++#define PHY_M_PC_DOWN_S_ENA BIT_11S /* Downshift Enable */ ++ /* !!! Errata in spec. (1 = disable) */ ++ ++#define PHY_M_PC_DSC(x) (SHIFT12(x) & PHY_M_PC_DSC_MSK) ++ /* 000=1x; 001=2x; 010=3x; 011=4x */ ++ /* 100=5x; 101=6x; 110=7x; 111=8x */ ++ ++/* for Yukon-EC Ultra Gigabit Ethernet PHY (88E1149 only) */ ++ /* Bit 4: reserved */ ++#define PHY_M_PC_COP_TX_DIS BIT_3S /* Copper Transmitter Disable */ ++#define PHY_M_PC_POW_D_ENA BIT_2S /* Power Down Enable */ ++ ++/* for 10/100 Fast Ethernet PHY (88E3082 only) */ ++#define PHY_M_PC_ENA_DTE_DT BIT_15S /* Enable Data Terminal Equ. (DTE) Detect */ ++#define PHY_M_PC_ENA_ENE_DT BIT_14S /* Enable Energy Detect (sense & pulse) */ ++#define PHY_M_PC_DIS_NLP_CK BIT_13S /* Disable Normal Link Puls (NLP) Check */ ++#define PHY_M_PC_ENA_LIP_NP BIT_12S /* Enable Link Partner Next Page Reg. */ ++#define PHY_M_PC_DIS_NLP_GN BIT_11S /* Disable Normal Link Puls Generation */ ++ ++#define PHY_M_PC_DIS_SCRAMB BIT_9S /* Disable Scrambler */ ++#define PHY_M_PC_DIS_FEFI BIT_8S /* Disable Far End Fault Indic. (FEFI) */ ++ ++#define PHY_M_PC_SH_TP_SEL BIT_6S /* Shielded Twisted Pair Select */ ++#define PHY_M_PC_RX_FD_MSK (3<<2) /* Bit 3.. 2: Rx FIFO Depth Mask */ ++ + /***** 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_SPEED_MSK (3<<14) /* Bit 15..14: Speed Mask */ ++#define PHY_M_PS_SPEED_1000 BIT_15S /* 10 = 1000 Mbps */ ++#define PHY_M_PS_SPEED_100 BIT_14S /* 01 = 100 Mbps */ ++#define PHY_M_PS_SPEED_10 0 /* 00 = 10 Mbps */ ++#define PHY_M_PS_FULL_DUP BIT_13S /* Full Duplex */ ++#define PHY_M_PS_PAGE_REC BIT_12S /* Page Received */ ++#define PHY_M_PS_SPDUP_RES BIT_11S /* Speed & Duplex Resolved */ ++#define PHY_M_PS_LINK_UP BIT_10S /* Link Up */ ++#define PHY_M_PS_CABLE_MSK (7<<7) /* Bit 9.. 7: Cable Length Mask */ ++#define PHY_M_PS_MDI_X_STAT BIT_6S /* MDI Crossover Stat (1=MDIX) */ ++#define PHY_M_PS_DOWNS_STAT BIT_5S /* Downshift Status (1=downshift) */ ++#define PHY_M_PS_ENDET_STAT BIT_4S /* Energy Detect Status (1=sleep) */ ++#define PHY_M_PS_TX_P_EN BIT_3S /* Tx Pause Enabled */ ++#define PHY_M_PS_RX_P_EN BIT_2S /* Rx Pause Enabled */ ++#define PHY_M_PS_POL_REV BIT_1S /* Polarity Reversed */ ++#define PHY_M_PS_JABBER BIT_0S /* Jabber */ + + #define PHY_M_PS_PAUSE_MSK (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN) + ++/* for 10/100 Fast Ethernet PHY (88E3082 only) */ ++#define PHY_M_PS_DTE_DETECT BIT_15S /* Data Terminal Equipment (DTE) Detected */ ++#define PHY_M_PS_RES_SPEED BIT_14S /* Resolved Speed (1=100 Mbps, 0=10 Mbps */ ++ + /***** 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_IS_AN_ERROR BIT_15S /* Auto-Negotiation Error */ ++#define PHY_M_IS_LSP_CHANGE BIT_14S /* Link Speed Changed */ ++#define PHY_M_IS_DUP_CHANGE BIT_13S /* Duplex Mode Changed */ ++#define PHY_M_IS_AN_PR BIT_12S /* Page Received */ ++#define PHY_M_IS_AN_COMPL BIT_11S /* Auto-Negotiation Completed */ ++#define PHY_M_IS_LST_CHANGE BIT_10S /* Link Status Changed */ ++#define PHY_M_IS_SYMB_ERROR BIT_9S /* Symbol Error */ ++#define PHY_M_IS_FALSE_CARR BIT_8S /* False Carrier */ ++#define PHY_M_IS_FIFO_ERROR BIT_7S /* FIFO Overflow/Underrun Error */ ++#define PHY_M_IS_MDI_CHANGE BIT_6S /* MDI Crossover Changed */ ++#define PHY_M_IS_DOWNSH_DET BIT_5S /* Downshift Detected */ ++#define PHY_M_IS_END_CHANGE BIT_4S /* Energy Detect Changed */ ++ /* Bit 3: reserved */ ++#define PHY_M_IS_DTE_CHANGE BIT_2S /* DTE Power Det. Status Changed */ ++ /* (88E1111 only) */ ++#define PHY_M_IS_POL_CHANGE BIT_1S /* Polarity Changed */ ++#define PHY_M_IS_JABBER BIT_0S /* 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_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR | \ ++ PHY_M_IS_END_CHANGE) + + /***** 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_ENA_BC_EXT BIT_15S /* Enable Block Carr. Ext. (88E1111 only) */ ++#define PHY_M_EC_ENA_LIN_LB BIT_14S /* Enable Line Loopback (88E1111 only) */ ++ /* Bit 13: reserved */ ++#define PHY_M_EC_DIS_LINK_P BIT_12S /* Disable Link Pulses (88E1111 only) */ ++#define PHY_M_EC_M_DSC_MSK (3<<10) /* Bit 11..10: Master Downshift Counter */ ++ /* (88E1040 Rev.C0 only) */ ++#define PHY_M_EC_S_DSC_MSK (3<<8) /* Bit 9.. 8: Slave Downshift Counter */ ++ /* (88E1040 Rev.C0 only) */ ++#define PHY_M_EC_DSC_MSK_2 (7<<9) /* Bit 11.. 9: Downshift Counter */ ++ /* (88E1040 Rev.D0 and higher) */ ++#define PHY_M_EC_DOWN_S_ENA BIT_8S /* Downshift Enable (88E1040 Rev.D0 and */ ++ /* 88E1111 !!! Errata in spec. (1=dis.) */ ++#define PHY_M_EC_RX_TIM_CT BIT_7S /* RGMII Rx Timing Control*/ + #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 PHY_M_EC_FIB_AN_ENA BIT_3S /* Fiber Auto-Neg. Enable 88E1040S only) */ ++#define PHY_M_EC_DTE_D_ENA BIT_2S /* DTE Detect Enable (88E1111 only) */ ++#define PHY_M_EC_TX_TIM_CT BIT_1S /* RGMII Tx Timing Control */ ++#define PHY_M_EC_TRANS_DIS BIT_0S /* Transmitter Disable (88E1111 only) */ ++ ++#define PHY_M_EC_M_DSC(x) (SHIFT10(x) & PHY_M_EC_M_DSC_MSK) ++ /* 00=1x; 01=2x; 10=3x; 11=4x */ ++#define PHY_M_EC_S_DSC(x) (SHIFT8(x) & PHY_M_EC_S_DSC_MSK) ++ /* 00=dis; 01=1x; 10=2x; 11=3x */ ++#define PHY_M_EC_MAC_S(x) (SHIFT4(x) & PHY_M_EC_MAC_S_MSK) ++ /* 01X=0; 110=2.5; 111=25 (MHz) */ ++ ++#define PHY_M_EC_DSC_2(x) (SHIFT9(x) & PHY_M_EC_DSC_MSK_2) ++ /* 000=1x; 001=2x; 010=3x; 011=4x */ ++ /* 100=5x; 101=6x; 110=7x; 111=8x */ + #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_LEDC_DIS_LED BIT_15S /* Disable LED */ ++#define PHY_M_LEDC_PULS_MSK (7<<12) /* Bit 14..12: Pulse Stretch Mask */ ++#define PHY_M_LEDC_F_INT BIT_11S /* Force Interrupt */ ++#define PHY_M_LEDC_BL_R_MSK (7<<8) /* Bit 10.. 8: Blink Rate Mask */ ++#define PHY_M_LEDC_DP_C_LSB BIT_7S /* Duplex Control (LSB, 88E1111 only) */ ++#define PHY_M_LEDC_TX_C_LSB BIT_6S /* Tx Control (LSB, 88E1111 only) */ ++#define PHY_M_LEDC_LK_C_MSK (7<<3) /* Bit 5.. 3: Link Control Mask */ ++ /* (88E1111 only) */ ++ /* Bit 7.. 5: reserved (88E1040 only) */ ++#define PHY_M_LEDC_LINK_MSK (3<<3) /* Bit 4.. 3: Link Control Mask */ ++ /* (88E1040 only) */ ++#define PHY_M_LEDC_DP_CTRL BIT_2S /* Duplex Control */ ++#define PHY_M_LEDC_DP_C_MSB BIT_2S /* Duplex Control (MSB, 88E1111 only) */ ++#define PHY_M_LEDC_RX_CTRL BIT_1S /* Rx Activity / Link */ ++#define PHY_M_LEDC_TX_CTRL BIT_0S /* Tx Activity / Link */ ++#define PHY_M_LEDC_TX_C_MSB BIT_0S /* Tx Control (MSB, 88E1111 only) */ + +-#define PHY_M_LED_PULS_DUR(x) SHIFT12(x) /* Pulse Stretch Duration */ ++#define PHY_M_LED_PULS_DUR(x) (SHIFT12(x) & PHY_M_LEDC_PULS_MSK) + +-#define PULS_NO_STR 0 /* no pulse stretching */ +-#define PULS_21MS 1 /* 21 ms to 42 ms */ ++#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 */ +@@ -1217,7 +1302,7 @@ + #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 PHY_M_LED_BLINK_RT(x) (SHIFT8(x) & PHY_M_LEDC_BL_R_MSK) + + #define BLINK_42MS 0 /* 42 ms */ + #define BLINK_84MS 1 /* 84 ms */ +@@ -1227,6 +1312,8 @@ + /* values 5 - 7: reserved */ + + /***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/ ++#define PHY_M_LED_MO_SGMII(x) SHIFT14(x) /* Bit 15..14: SGMII AN Timer */ ++ /* Bit 13..12: reserved */ + #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 */ +@@ -1240,30 +1327,48 @@ + #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 */ ++ /* Bit 15.. 7: reserved */ ++#define PHY_M_EC2_FI_IMPED BIT_6S /* Fiber Input Impedance */ ++#define PHY_M_EC2_FO_IMPED BIT_5S /* Fiber Output Impedance */ ++#define PHY_M_EC2_FO_M_CLK BIT_4S /* Fiber Mode Clock Enable */ ++#define PHY_M_EC2_FO_BOOST BIT_3S /* 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_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/ ++#define PHY_M_FC_AUTO_SEL BIT_15S /* Fiber/Copper Auto Sel. Dis. */ ++#define PHY_M_FC_AN_REG_ACC BIT_14S /* Fiber/Copper AN Reg. Access */ ++#define PHY_M_FC_RESOLUTION BIT_13S /* Fiber/Copper Resolution */ ++#define PHY_M_SER_IF_AN_BP BIT_12S /* Ser. IF AN Bypass Enable */ ++#define PHY_M_SER_IF_BP_ST BIT_11S /* Ser. IF AN Bypass Status */ ++#define PHY_M_IRQ_POLARITY BIT_10S /* IRQ polarity */ ++#define PHY_M_DIS_AUT_MED BIT_9S /* Disable Aut. Medium Reg. Selection */ ++ /* (88E1111 only) */ ++ /* Bit 9.. 4: reserved (88E1040 only) */ ++#define PHY_M_UNDOC1 BIT_7S /* undocumented bit !! */ ++#define PHY_M_DTE_POW_STAT BIT_4S /* DTE Power Status (88E1111 only) */ ++#define PHY_M_MODE_MASK 0xf /* 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 */ ++#define PHY_M_CABD_ENA_TEST BIT_15S /* Enable Test (Page 0) */ ++#define PHY_M_CABD_DIS_WAIT BIT_15S /* Disable Waiting Period (Page 1) */ ++ /* (88E1111 only) */ ++ ++#define PHY_M_CABD_COMPLETE BIT_14S /* Test Completed (88E1149 only) */ ++ ++#define PHY_M_CABD_MODE_MSK (3<<6) /* Bit 7.. 6: Mode Mask */ ++#define PHY_M_CABD_TEST_MODE(x) (SHIFT6(x) & PHY_M_CABD_MODE_MSK) ++ ++#define PHY_M_CABD_PWID_MSK (3<<10) /* Bit 11..10: Pulse Width Mask */ ++#define PHY_M_CABD_PAMP_MSK (3<<10) /* Bit 9.. 8: Pulse Ampl. Mask */ ++ ++#define PHY_M_CABD_PULS_WIDT(x) (SHIFT10(x) & PHY_M_CABD_PWID_MSK) ++#define PHY_M_CABD_PULS_AMPL(x) (SHIFT8(x) & PHY_M_CABD_PAMP_MSK) ++ ++#define PHY_M_CABD_STAT_MSK (3<<13) /* Bit 14..13: Status Mask */ ++ ++#define PHY_M_CABD_AMPL_MSK (0x7f<<8) /* Bit 14.. 8: Amplitude Mask */ ++ /* (88E1149 only) */ ++#define PHY_M_CABD_DIST_MSK 0xff /* Bit 7.. 0: Distance Mask */ + + /* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */ + #define CABD_STAT_NORMAL 0 +@@ -1271,6 +1376,79 @@ + #define CABD_STAT_OPEN 2 + #define CABD_STAT_FAIL 3 + ++/* for 10/100 Fast Ethernet PHY (88E3082 only) */ ++/***** PHY_MARV_FE_LED_PAR 16 bit r/w LED Parallel Select Reg. *****/ ++ /* Bit 15..12: reserved (used internally) */ ++#define PHY_M_FELP_LED2_MSK (0xf<<8) /* Bit 11.. 8: LED2 Mask (LINK) */ ++#define PHY_M_FELP_LED1_MSK (0xf<<4) /* Bit 7.. 4: LED1 Mask (ACT) */ ++#define PHY_M_FELP_LED0_MSK 0xf /* Bit 3.. 0: LED0 Mask (SPEED) */ ++ ++#define PHY_M_FELP_LED2_CTRL(x) (SHIFT8(x) & PHY_M_FELP_LED2_MSK) ++#define PHY_M_FELP_LED1_CTRL(x) (SHIFT4(x) & PHY_M_FELP_LED1_MSK) ++#define PHY_M_FELP_LED0_CTRL(x) (SHIFT0(x) & PHY_M_FELP_LED0_MSK) ++ ++#define LED_PAR_CTRL_COLX 0x00 ++#define LED_PAR_CTRL_ERROR 0x01 ++#define LED_PAR_CTRL_DUPLEX 0x02 ++#define LED_PAR_CTRL_DP_COL 0x03 ++#define LED_PAR_CTRL_SPEED 0x04 ++#define LED_PAR_CTRL_LINK 0x05 ++#define LED_PAR_CTRL_TX 0x06 ++#define LED_PAR_CTRL_RX 0x07 ++#define LED_PAR_CTRL_ACT 0x08 ++#define LED_PAR_CTRL_LNK_RX 0x09 ++#define LED_PAR_CTRL_LNK_AC 0x0a ++#define LED_PAR_CTRL_ACT_BL 0x0b ++#define LED_PAR_CTRL_TX_BL 0x0c ++#define LED_PAR_CTRL_RX_BL 0x0d ++#define LED_PAR_CTRL_COL_BL 0x0e ++#define LED_PAR_CTRL_INACT 0x0f ++ ++/***** PHY_MARV_FE_SPEC_2 16 bit r/w Specific Control Reg. 2 *****/ ++#define PHY_M_FESC_DIS_WAIT BIT_2S /* Disable TDR Waiting Period */ ++#define PHY_M_FESC_ENA_MCLK BIT_1S /* Enable MAC Rx Clock in sleep mode */ ++#define PHY_M_FESC_SEL_CL_A BIT_0S /* Select Class A driver (100B-TX) */ ++ ++/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */ ++/***** PHY_MARV_PHY_CTRL (page 1) 16 bit r/w Fiber Specific Ctrl *****/ ++#define PHY_M_FIB_FORCE_LNK BIT_10S /* Force Link Good */ ++#define PHY_M_FIB_SIGD_POL BIT_9S /* SIGDET Polarity */ ++#define PHY_M_FIB_TX_DIS BIT_3S /* Transmitter Disable */ ++ ++/***** PHY_MARV_PHY_CTRL (page 2) 16 bit r/w MAC Specific Ctrl *****/ ++#define PHY_M_MAC_MD_MSK (7<<7) /* Bit 9.. 7: Mode Select Mask */ ++#define PHY_M_MAC_GMIF_PUP BIT_3S /* GMII Power Up (88E1149 only) */ ++ ++#define PHY_M_MAC_MD_AUTO 3 /* Auto Copper/1000Base-X */ ++#define PHY_M_MAC_MD_COPPER 5 /* Copper only */ ++#define PHY_M_MAC_MD_1000BX 7 /* 1000Base-X only */ ++#define PHY_M_MAC_MODE_SEL(x) (SHIFT7(x) & PHY_M_MAC_MD_MSK) ++ ++/***** PHY_MARV_PHY_CTRL (page 3) 16 bit r/w LED Control Reg. *****/ ++#define PHY_M_LEDC_LOS_MSK (0xf<<12) /* Bit 15..12: LOS LED Ctrl. Mask */ ++#define PHY_M_LEDC_INIT_MSK (0xf<<8) /* Bit 11.. 8: INIT LED Ctrl. Mask */ ++#define PHY_M_LEDC_STA1_MSK (0xf<<4) /* Bit 7.. 4: STAT1 LED Ctrl. Mask */ ++#define PHY_M_LEDC_STA0_MSK 0xf /* Bit 3.. 0: STAT0 LED Ctrl. Mask */ ++ ++#define PHY_M_LEDC_LOS_CTRL(x) (SHIFT12(x) & PHY_M_LEDC_LOS_MSK) ++#define PHY_M_LEDC_INIT_CTRL(x) (SHIFT8(x) & PHY_M_LEDC_INIT_MSK) ++#define PHY_M_LEDC_STA1_CTRL(x) (SHIFT4(x) & PHY_M_LEDC_STA1_MSK) ++#define PHY_M_LEDC_STA0_CTRL(x) (SHIFT0(x) & PHY_M_LEDC_STA0_MSK) ++ ++/***** PHY_MARV_PHY_STAT (page 3) 16 bit r/w Polarity Control Reg. *****/ ++#define PHY_M_POLC_LS1M_MSK (0xf<<12) /* Bit 15..12: LOS,STAT1 Mix % Mask */ ++#define PHY_M_POLC_IS0M_MSK (0xf<<8) /* Bit 11.. 8: INIT,STAT0 Mix % Mask */ ++#define PHY_M_POLC_LOS_MSK (0x3<<6) /* Bit 7.. 6: LOS Pol. Ctrl. Mask */ ++#define PHY_M_POLC_INIT_MSK (0x3<<4) /* Bit 5.. 4: INIT Pol. Ctrl. Mask */ ++#define PHY_M_POLC_STA1_MSK (0x3<<2) /* Bit 3.. 2: STAT1 Pol. Ctrl. Mask */ ++#define PHY_M_POLC_STA0_MSK 0x3 /* Bit 1.. 0: STAT0 Pol. Ctrl. Mask */ ++ ++#define PHY_M_POLC_LS1_P_MIX(x) (SHIFT12(x) & PHY_M_POLC_LS1M_MSK) ++#define PHY_M_POLC_IS0_P_MIX(x) (SHIFT8(x) & PHY_M_POLC_IS0M_MSK) ++#define PHY_M_POLC_LOS_CTRL(x) (SHIFT6(x) & PHY_M_POLC_LOS_MSK) ++#define PHY_M_POLC_INIT_CTRL(x) (SHIFT4(x) & PHY_M_POLC_INIT_MSK) ++#define PHY_M_POLC_STA1_CTRL(x) (SHIFT2(x) & PHY_M_POLC_STA1_MSK) ++#define PHY_M_POLC_STA0_CTRL(x) (SHIFT0(x) & PHY_M_POLC_STA0_MSK) + + /* + * GMAC registers +@@ -1431,141 +1609,184 @@ + */ + + /* 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 */ +- ++#define GM_GPSR_SPEED BIT_15S /* Port Speed (1 = 100 Mbps) */ ++#define GM_GPSR_DUPLEX BIT_14S /* Duplex Mode (1 = Full) */ ++#define GM_GPSR_FC_TX_DIS BIT_13S /* Tx Flow-Control Mode Disabled */ ++#define GM_GPSR_LINK_UP BIT_12S /* Link Up Status */ ++#define GM_GPSR_PAUSE BIT_11S /* Pause State */ ++#define GM_GPSR_TX_ACTIVE BIT_10S /* Tx in Progress */ ++#define GM_GPSR_EXC_COL BIT_9S /* Excessive Collisions Occured */ ++#define GM_GPSR_LAT_COL BIT_8S /* Late Collisions Occured */ ++ /* Bit 7.. 6: reserved */ ++#define GM_GPSR_PHY_ST_CH BIT_5S /* PHY Status Change */ ++#define GM_GPSR_GIG_SPEED BIT_4S /* Gigabit Speed (1 = 1000 Mbps) */ ++#define GM_GPSR_PART_MODE BIT_3S /* Partition mode */ ++#define GM_GPSR_FC_RX_DIS BIT_2S /* Rx Flow-Control Mode Disabled */ ++ /* Bit 2.. 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_RMII_PH_ENA BIT_15S /* Enable RMII for PHY (Yukon-FE only) */ ++#define GM_GPCR_RMII_LB_ENA BIT_14S /* Enable RMII Loopback (Yukon-FE only) */ ++#define GM_GPCR_FC_TX_DIS BIT_13S /* Disable Tx Flow-Control Mode */ ++#define GM_GPCR_TX_ENA BIT_12S /* Enable Transmit */ ++#define GM_GPCR_RX_ENA BIT_11S /* Enable Receive */ ++ /* Bit 10: reserved */ ++#define GM_GPCR_LOOP_ENA BIT_9S /* Enable MAC Loopback Mode */ ++#define GM_GPCR_PART_ENA BIT_8S /* Enable Partition Mode */ ++#define GM_GPCR_GIGS_ENA BIT_7S /* Gigabit Speed (1000 Mbps) */ ++#define GM_GPCR_FL_PASS BIT_6S /* Force Link Pass */ ++#define GM_GPCR_DUP_FULL BIT_5S /* Full Duplex Mode */ ++#define GM_GPCR_FC_RX_DIS BIT_4S /* Disable Rx Flow-Control Mode */ ++#define GM_GPCR_SPEED_100 BIT_3S /* Port Speed 100 Mbps */ ++#define GM_GPCR_AU_DUP_DIS BIT_2S /* Disable Auto-Update Duplex */ ++#define GM_GPCR_AU_FCT_DIS BIT_1S /* Disable Auto-Update Flow-C. */ ++#define GM_GPCR_AU_SPD_DIS BIT_0S /* 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 (7<<10) /* Bit 12..10: Collision Threshold */ ++#define GM_TXCR_FORCE_JAM BIT_15S /* Force Jam / Flow-Control */ ++#define GM_TXCR_CRC_DIS BIT_14S /* Disable insertion of CRC */ ++#define GM_TXCR_PAD_DIS BIT_13S /* Disable padding of packets */ ++#define GM_TXCR_COL_THR_MSK (7<<10) /* Bit 12..10: Collision Threshold Mask */ ++ /* Bit 9.. 8: reserved */ ++#define GM_TXCR_PAD_PAT_MSK 0xff /* Bit 7.. 0: Padding Pattern Mask */ ++ /* (Yukon-2 only) */ + + #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 */ +- ++#define GM_RXCR_UCF_ENA BIT_15S /* Enable Unicast filtering */ ++#define GM_RXCR_MCF_ENA BIT_14S /* Enable Multicast filtering */ ++#define GM_RXCR_CRC_DIS BIT_13S /* Remove 4-byte CRC */ ++#define GM_RXCR_PASS_FC BIT_12S /* Pass FC packets to FIFO (Yukon-1 only) */ ++ /* Bit 11.. 0: reserved */ ++ + /* 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 GM_TXPA_JAMLEN_MSK (3<<14) /* Bit 15..14: Jam Length Mask */ ++#define GM_TXPA_JAMIPG_MSK (0x1f<<9) /* Bit 13.. 9: Jam IPG Mask */ ++#define GM_TXPA_JAMDAT_MSK (0x1f<<4) /* Bit 8.. 4: IPG Jam to Data Mask */ ++#define GM_TXPA_BO_LIM_MSK 0x0f /* Bit 3.. 0: Backoff Limit Mask */ ++ /* (Yukon-2 only) */ + + #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_BACK_OFF_LIM(x) ((x) & GM_TXPA_BO_LIM_MSK) + + #define TX_JAM_LEN_DEF 0x03 + #define TX_JAM_IPG_DEF 0x0b + #define TX_IPG_JAM_DEF 0x1c ++#define TX_BOF_LIM_DEF 0x04 + + /* 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 GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder */ ++ /* r/o on Yukon, r/w on Yukon-EC */ ++#define GM_SMOD_LIMIT_4 BIT_10S /* 4 consecutive Tx trials */ ++#define GM_SMOD_VLAN_ENA BIT_9S /* Enable VLAN (Max. Frame Len) */ ++#define GM_SMOD_JUMBO_ENA BIT_8S /* 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_VAL(x) (x & GM_SMOD_IPG_MSK) ++#define DATA_BLIND_DEF 0x04 + #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_OP_RD BIT_5S /* OpCode Read (0=Write) */ ++#define GM_SMI_CT_RD_VAL BIT_4S /* Read Valid (Read completed) */ ++#define GM_SMI_CT_BUSY BIT_3S /* 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 */ +- ++/* GM_PHY_ADDR 16 bit r/w GPHY Address Register */ ++ /* Bit 15.. 6: reserved */ ++#define GM_PAR_MIB_CLR BIT_5S /* Set MIB Clear Counter Mode */ ++#define GM_PAR_MIB_TST BIT_4S /* 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 */ ++#define GMR_FS_LKUP_BIT2 BIT_31 /* MACSec Lookup entry b2 (Yukon-Ext only)*/ ++#define GMR_FS_LEN_MSK (0x7fffUL<<16) /* Bit 30..16: Rx Frame Length */ ++#define GMR_FS_LKUP_BIT1 BIT_15 /* MACSec Lookup entry b1 (Yukon-Ext only)*/ ++#define GMR_FS_LKUP_BIT0 BIT_14 /* MACSec Lookup entry b0 (Yukon-Ext only)*/ ++#define GMR_FS_VLAN BIT_13 /* VLAN Packet */ ++#define GMR_FS_JABBER BIT_12 /* Jabber Packet */ ++#define GMR_FS_UN_SIZE BIT_11 /* Undersize Packet */ ++#define GMR_FS_MC BIT_10 /* Multicast Packet */ ++#define GMR_FS_BC BIT_9 /* Broadcast Packet */ ++#define GMR_FS_RX_OK BIT_8 /* Receive OK (Good Packet) */ ++#define GMR_FS_GOOD_FC BIT_7 /* Good Flow-Control Packet */ ++#define GMR_FS_BAD_FC BIT_6 /* Bad Flow-Control Packet */ ++#define GMR_FS_MII_ERR BIT_5 /* MII Error */ ++#define GMR_FS_LONG_ERR BIT_4 /* Too Long Packet */ ++#define GMR_FS_FRAGMENT BIT_3 /* Fragment */ ++#define GMR_FS_LKUP_HIT BIT_2 /* MACSec Lookup tab hit (Yukon-Ext only) */ ++#define GMR_FS_CRC_ERR BIT_1 /* CRC Error */ ++#define GMR_FS_RX_FF_OV BIT_0 /* Rx FIFO Overflow */ ++ ++/* Yukon-Ext only */ ++#define GMR_FS_MACSEC_BITS ( \ ++ GMR_FS_LKUP_BIT2 |\ ++ GMR_FS_LKUP_BIT1 |\ ++ GMR_FS_LKUP_BIT0 |\ ++ GMR_FS_LKUP_HIT) ++ ++#define GMR_FS_LEN_SHIFT 16 + + /* + * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR) + */ +-#define GMR_FS_ANY_ERR (GMR_FS_CRC_ERR | \ +- GMR_FS_LONG_ERR | \ ++#ifdef SK_DIAG ++#define GMR_FS_ANY_ERR ( \ ++ GMR_FS_RX_FF_OV | \ ++ GMR_FS_CRC_ERR | \ ++ GMR_FS_FRAGMENT | \ + 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 | \ ++#else ++#define GMR_FS_ANY_ERR ( \ + GMR_FS_RX_FF_OV | \ ++ GMR_FS_CRC_ERR | \ ++ GMR_FS_FRAGMENT | \ ++ GMR_FS_LONG_ERR | \ + GMR_FS_MII_ERR | \ + GMR_FS_BAD_FC | \ + GMR_FS_GOOD_FC | \ + GMR_FS_UN_SIZE | \ + GMR_FS_JABBER) ++#endif ++ ++/* Rx GMAC FIFO Flush Mask (default) */ ++#define RX_FF_FL_DEF_MSK GMR_FS_ANY_ERR ++ ++/* ++ * MAC Security macros (Yukon-Ext only) ++ */ ++/* EAPOL frame: hit + tab entry == 0 */ ++#define GMR_IS_EAPOL_FRAME(status) (\ ++ ((status) & GMR_FS_MACSEC_BITS) == GMR_FS_LKUP_HIT) ++ ++/* Uncontrolled port frame: no table hit */ ++#define GMR_IS_UNCON_FRAME(status) (\ ++ ((status) & GMR_FS_LKUP_HIT) == 0) ++ ++/* Controlled port: check key number: key = {1, 2}, key = tab entry */ ++#define GMR_IS_SECKEY_MATCH(status, key) (\ ++ (status) & GMR_FS_MACSEC_BITS) == (GMR_FS_LKUP_HIT | ((key) << 14))) ++ + + /* typedefs *******************************************************************/ + +@@ -1577,3 +1798,4 @@ + #endif /* __cplusplus */ + + #endif /* __INC_XMAC_H */ ++ +diff -ruN linux/drivers/net/sk98lin/Makefile linux-new/drivers/net/sk98lin/Makefile +--- linux/drivers/net/sk98lin/Makefile 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/Makefile 2007-08-07 20:15:43.279419872 +0200 +@@ -1,6 +1,71 @@ ++#****************************************************************************** + # +-# Makefile for the SysKonnect SK-98xx device driver. ++# Name: skge.c ++# Project: GEnesis, PCI Gigabit Ethernet Adapter ++# Version: $Revision$ ++# Date: $Date$ ++# Purpose: The main driver source module + # ++#****************************************************************************** ++ ++#****************************************************************************** ++# ++# (C)Copyright 1998-2002 SysKonnect GmbH. ++# (C)Copyright 2002-2005 Marvell. ++# ++# Makefile for Marvell Yukon chipset and SysKonnect Gigabit Ethernet ++# Server Adapter driver. (Kernel 2.6) ++# ++# Author: Mirko Lindner (mlindner@syskonnect.de) ++# Ralph Roesler (rroesler@syskonnect.de) ++# ++# Address all question to: linux@syskonnect.de ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# The information in this file is provided "AS IS" without warranty. ++# ++#****************************************************************************** ++ ++#****************************************************************************** ++# ++# History: ++# ++# $Log$ ++# Revision 1.1.4.3 2006/12/14 15:23:13 mlindner ++# Add: Enable Yukon Extreme. Define SK_EXTREME enabled ++# ++# Revision 1.1.4.2 2006/08/28 12:44:39 mlindner ++# Add: install.sh script handling added ++# ++# Revision 1.1.4.1 2006/08/28 09:01:59 mlindner ++# Add: Initial IPMI kernel 2.4 and 2.6 support ++# ++# Revision 1.1 2006/07/19 15:37:22 amock ++# Imported/updated from Release Server GELIN_V8_35_02 ++# ++# Revision 1.9.2.1 2005/04/11 09:01:18 mlindner ++# Fix: Copyright year changed ++# ++# Revision 1.9 2004/07/13 15:54:50 rroesler ++# Add: file skethtool.c ++# Fix: corrected header regarding copyright ++# Fix: minor typos corrected ++# ++# Revision 1.8 2004/06/08 08:39:38 mlindner ++# Fix: Add CONFIG_SK98LIN_ZEROCOPY as default ++# ++# Revision 1.7 2004/06/03 16:06:56 mlindner ++# Fix: Added compile flag SK_DIAG_SUPPORT ++# ++# Revision 1.6 2004/06/02 08:02:59 mlindner ++# Add: Changed header information and inserted a GPL statement ++# ++# ++#****************************************************************************** + + + # +@@ -9,25 +74,43 @@ + # SKPARAM += -DSK_KERNEL_24_26 + # SKPARAM += -DSK_KERNEL_26 + # SKPARAM += -DSK_KERNEL_22_24 ++# ASFPARAM += -DSK_ASF ++ ++ifdef ASFPARAM ++ ASF_OPS += \ ++ skgeasf.o \ ++ skgeasfconv.o \ ++ skgespi.o \ ++ skgespilole.o \ ++ skfops.o ++else ++ ASF_OPS += ++endif ++ ++ + + obj-$(CONFIG_SK98LIN) += sk98lin.o + sk98lin-objs := \ + skge.o \ ++ sky2.o \ + skethtool.o \ ++ sky2le.o \ + skdim.o \ + skaddr.o \ + skgehwt.o \ + skgeinit.o \ + skgepnmi.o \ + skgesirq.o \ +- ski2c.o \ ++ sktwsi.o \ + sklm80.o \ + skqueue.o \ + skrlmt.o \ + sktimer.o \ + skvpd.o \ +- skxmac2.o +- ++ skxmac2.o \ ++ skproc.o \ ++ skcsum.o \ ++ $(ASF_OPS) + # DBGDEF = \ + # -DDEBUG + +@@ -75,13 +158,11 @@ + # SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources + # SK_DBGCAT_DRV_EVENT 0x08000000 driver events + +-EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM) ++EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_USE_CSUM -DSK_DIAG_SUPPORT \ ++ -DGENESIS -DYUKON -DYUK2 -DCONFIG_SK98LIN_ZEROCOPY \ ++ -DSK_EXTREME $(DBGDEF) $(SKPARAM) $(ASFPARAM) + + clean: + rm -f core *.o *.a *.s + + +- +- +- +- +diff -ruN linux/drivers/net/sk98lin/skaddr.c linux-new/drivers/net/sk98lin/skaddr.c +--- linux/drivers/net/sk98lin/skaddr.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skaddr.c 2007-01-24 14:03:39.000000000 +0100 +@@ -2,16 +2,17 @@ + * + * Name: skaddr.c + * Project: Gigabit Ethernet Adapters, ADDR-Module +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode. + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2005 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 +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -44,7 +46,7 @@ + + #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) + static const char SysKonnectFileId[] = +- "@(#) $Id$ (C) Marvell."; ++ "@(#) $Id$ (C) Marvell."; + #endif /* DEBUG ||!LINT || !SK_SLIM */ + + #define __SKADDR_C +@@ -58,11 +60,10 @@ + + /* 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 ++#define SK_MC_BIT 0x01 + + /* Error numbers and messages. */ + +@@ -79,7 +80,7 @@ + + /* 64-bit hash values with all bits set. */ + +-static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; ++SK_U16 OnesHash[4] = {0xffff, 0xffff, 0xffff, 0xffff}; + + /* local variables ************************************************************/ + +@@ -87,21 +88,6 @@ + static int Next0[SK_MAX_MACS] = {0}; + #endif /* DEBUG */ + +-static int SkAddrGmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, +- SK_MAC_ADDR *pMc, int Flags); +-static int SkAddrGmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, +- int Flags); +-static int SkAddrGmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); +-static int SkAddrGmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, +- SK_U32 PortNumber, int NewPromMode); +-static int SkAddrXmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, +- SK_MAC_ADDR *pMc, int Flags); +-static int SkAddrXmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, +- int Flags); +-static int SkAddrXmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); +-static int SkAddrXmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, +- SK_U32 PortNumber, int NewPromMode); +- + /* functions ******************************************************************/ + + /****************************************************************************** +@@ -151,13 +137,12 @@ + + switch (Level) { + case SK_INIT_DATA: +- SK_MEMSET((char *) &pAC->Addr, (SK_U8) 0, +- (SK_U16) sizeof(SK_ADDR)); ++ 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; +@@ -174,7 +159,7 @@ + /* pAC->Addr.InitDone = SK_INIT_DATA; */ + break; + +- case SK_INIT_IO: ++ 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; +@@ -188,7 +173,7 @@ + } + } + #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]; +@@ -206,11 +191,11 @@ + 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). */ ++ /* Set logical MAC address for net 2 to. */ + if (!pAC->Addr.Net[1].CurrentMacAddressSet) { + pAC->Addr.Net[1].PermanentMacAddress = + pAC->Addr.Net[0].PermanentMacAddress; +- pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3; ++ pAC->Addr.Net[1].PermanentMacAddress.a[5] += 1; + /* Set the current logical MAC address to the permanent one. */ + pAC->Addr.Net[1].CurrentMacAddress = + pAC->Addr.Net[1].PermanentMacAddress; +@@ -228,8 +213,8 @@ + 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])) +- ++ 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, +@@ -238,7 +223,7 @@ + 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])) ++ pAC->Addr.Net[i].CurrentMacAddress.a[5])); + } + #endif /* DEBUG */ + +@@ -281,8 +266,8 @@ + pAPort->PermanentMacAddress.a[2], + pAPort->PermanentMacAddress.a[3], + pAPort->PermanentMacAddress.a[4], +- pAPort->PermanentMacAddress.a[5])) +- ++ 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], +@@ -290,7 +275,7 @@ + pAPort->CurrentMacAddress.a[2], + pAPort->CurrentMacAddress.a[3], + pAPort->CurrentMacAddress.a[4], +- pAPort->CurrentMacAddress.a[5])) ++ pAPort->CurrentMacAddress.a[5])); + #endif /* DEBUG */ + } + /* pAC->Addr.InitDone = SK_INIT_IO; */ +@@ -314,7 +299,7 @@ + } + + return (SK_ADDR_SUCCESS); +- ++ + } /* SkAddrInit */ + + #ifndef SK_SLIM +@@ -348,16 +333,20 @@ + 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) { ++#ifdef GENESIS + ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags); ++#endif + } + else { ++#ifdef YUKON + ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags); ++#endif + } + + return (ReturnCode); +@@ -367,7 +356,7 @@ + #endif /* !SK_SLIM */ + + #ifndef SK_SLIM +- ++#ifdef GENESIS + /****************************************************************************** + * + * SkAddrXmacMcClear - clear the multicast table +@@ -387,7 +376,7 @@ + * SK_ADDR_SUCCESS + * SK_ADDR_ILLEGAL_PORT + */ +-static int SkAddrXmacMcClear( ++int SkAddrXmacMcClear( + SK_AC *pAC, /* adapter context */ + SK_IOC IoC, /* I/O context */ + SK_U32 PortNumber, /* Index of affected port */ +@@ -417,13 +406,13 @@ + } + + return (SK_ADDR_SUCCESS); +- +-} /* SkAddrXmacMcClear */ + ++} /* SkAddrXmacMcClear */ ++#endif /* GENESIS */ + #endif /* !SK_SLIM */ + + #ifndef SK_SLIM +- ++#ifdef YUKON + /****************************************************************************** + * + * SkAddrGmacMcClear - clear the multicast table +@@ -444,7 +433,7 @@ + * SK_ADDR_SUCCESS + * SK_ADDR_ILLEGAL_PORT + */ +-static int SkAddrGmacMcClear( ++int SkAddrGmacMcClear( + SK_AC *pAC, /* adapter context */ + SK_IOC IoC, /* I/O context */ + SK_U32 PortNumber, /* Index of affected port */ +@@ -462,38 +451,37 @@ + 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])) ++ 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", +@@ -504,19 +492,20 @@ + 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])) ++ 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 */ ++#endif /* YUKON */ + + #ifndef SK_ADDR_CHEAT +- ++#ifdef GENESIS + /****************************************************************************** + * + * SkXmacMcHash - hash multicast address +@@ -534,7 +523,7 @@ + * Returns: + * Hash value of multicast address. + */ +-static SK_U32 SkXmacMcHash( ++SK_U32 SkXmacMcHash( + unsigned char *pMc) /* Multicast address */ + { + SK_U32 Idx; +@@ -553,8 +542,9 @@ + return (Crc & ((1 << HASH_BITS) - 1)); + + } /* SkXmacMcHash */ ++#endif /* GENESIS */ + +- ++#ifdef YUKON + /****************************************************************************** + * + * SkGmacMcHash - hash multicast address +@@ -572,7 +562,7 @@ + * Returns: + * Hash value of multicast address. + */ +-static SK_U32 SkGmacMcHash( ++SK_U32 SkGmacMcHash( + unsigned char *pMc) /* Multicast address */ + { + SK_U32 Data; +@@ -585,7 +575,7 @@ + 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++) { +@@ -597,7 +587,7 @@ + } + TmpData >>= 1; + } +- ++ + Crc ^= (Data << 24); + for (Bit = 0; Bit < 8; Bit++) { + if (Crc & 0x80000000) { +@@ -608,11 +598,11 @@ + } + } + } +- ++ + return (Crc & ((1 << HASH_BITS) - 1)); + + } /* SkGmacMcHash */ +- ++#endif /* YUKON */ + #endif /* !SK_ADDR_CHEAT */ + + /****************************************************************************** +@@ -647,23 +637,27 @@ + int Flags) /* permanent/non-permanent */ + { + int ReturnCode; +- ++ + if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { + return (SK_ADDR_ILLEGAL_PORT); + } +- ++ + if (pAC->GIni.GIGenesis) { ++#ifdef GENESIS + ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); ++#endif + } + else { ++#ifdef YUKON + ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); ++#endif + } + + return (ReturnCode); + + } /* SkAddrMcAdd */ + +- ++#ifdef GENESIS + /****************************************************************************** + * + * SkAddrXmacMcAdd - add a multicast address to a port +@@ -687,7 +681,7 @@ + * SK_MC_ILLEGAL_ADDRESS + * SK_MC_RLMT_OVERFLOW + */ +-static int SkAddrXmacMcAdd( ++int SkAddrXmacMcAdd( + SK_AC *pAC, /* adapter context */ + SK_IOC IoC, /* I/O context */ + SK_U32 PortNumber, /* Port Number */ +@@ -708,7 +702,7 @@ + return (SK_MC_RLMT_OVERFLOW); + } + #endif /* DEBUG */ +- ++ + if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt > + SK_ADDR_LAST_MATCH_RLMT) { + return (SK_MC_RLMT_OVERFLOW); +@@ -729,7 +723,7 @@ + return (SK_MC_RLMT_OVERFLOW); + } + #endif /* DEBUG */ +- ++ + if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) { + + /* Set exact match entry. */ +@@ -773,8 +767,9 @@ + } + + } /* SkAddrXmacMcAdd */ ++#endif /* GENESIS */ + +- ++#ifdef YUKON + /****************************************************************************** + * + * SkAddrGmacMcAdd - add a multicast address to a port +@@ -793,7 +788,7 @@ + * SK_MC_FILTERING_INEXACT + * SK_MC_ILLEGAL_ADDRESS + */ +-static int SkAddrGmacMcAdd( ++int SkAddrGmacMcAdd( + SK_AC *pAC, /* adapter context */ + SK_IOC IoC, /* I/O context */ + SK_U32 PortNumber, /* Port Number */ +@@ -804,28 +799,29 @@ + #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", +@@ -836,20 +832,21 @@ + 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])) ++ 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", +@@ -860,22 +857,22 @@ + 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])) ++ 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 */ + ++} /* SkAddrGmacMcAdd */ ++#endif /* YUKON */ + #endif /* !SK_SLIM */ + + /****************************************************************************** +@@ -907,7 +904,8 @@ + SK_IOC IoC, /* I/O context */ + SK_U32 PortNumber) /* Port Number */ + { +- int ReturnCode = 0; ++ int ReturnCode = SK_ADDR_ILLEGAL_PORT; ++ + #if (!defined(SK_SLIM) || defined(DEBUG)) + if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { + return (SK_ADDR_ILLEGAL_PORT); +@@ -952,7 +950,7 @@ + * SK_MC_FILTERING_INEXACT + * SK_ADDR_ILLEGAL_PORT + */ +-static int SkAddrXmacMcUpdate( ++int SkAddrXmacMcUpdate( + SK_AC *pAC, /* adapter context */ + SK_IOC IoC, /* I/O context */ + SK_U32 PortNumber) /* Port Number */ +@@ -963,13 +961,13 @@ + SK_ADDR_PORT *pAPort; + + SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, +- ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber)) +- ++ ("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])) ++ ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])); + #endif /* DEBUG */ + + /* Start with 0 to also program the logical MAC address. */ +@@ -981,7 +979,7 @@ + + /* 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); + } +@@ -993,7 +991,7 @@ + + /* 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); + } +@@ -1003,18 +1001,18 @@ + } + + 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); + } +@@ -1029,7 +1027,7 @@ + + /* Set port's current physical MAC address. */ + OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; +- ++ + XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); + + #ifdef xDEBUG +@@ -1039,9 +1037,9 @@ + + /* 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", +@@ -1058,7 +1056,7 @@ + pAPort->Exact[i].a[2], + pAPort->Exact[i].a[3], + pAPort->Exact[i].a[4], +- pAPort->Exact[i].a[5])) ++ pAPort->Exact[i].a[5])); + } + #endif /* DEBUG */ + +@@ -1069,7 +1067,7 @@ + else { + return (SK_MC_FILTERING_INEXACT); + } +- ++ + } /* SkAddrXmacMcUpdate */ + + #endif /* GENESIS */ +@@ -1097,7 +1095,7 @@ + * SK_MC_FILTERING_INEXACT + * SK_ADDR_ILLEGAL_PORT + */ +-static int SkAddrGmacMcUpdate( ++int SkAddrGmacMcUpdate( + SK_AC *pAC, /* adapter context */ + SK_IOC IoC, /* I/O context */ + SK_U32 PortNumber) /* Port Number */ +@@ -1110,37 +1108,37 @@ + SK_ADDR_PORT *pAPort; + + SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, +- ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber)) +- ++ ("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])) ++ ("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) { +- ++ ++ 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 { ++ else { + /* Enable Hashing. */ + SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); + } +- ++ + if (pAPort->PromMode != SK_PROM_MODE_NONE) { + (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); + } +@@ -1151,19 +1149,19 @@ + + /* 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", +@@ -1172,8 +1170,8 @@ + pAPort->Exact[0].a[2], + pAPort->Exact[0].a[3], + pAPort->Exact[0].a[4], +- pAPort->Exact[0].a[5])) +- ++ 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], +@@ -1181,9 +1179,9 @@ + pAPort->CurrentMacAddress.a[2], + pAPort->CurrentMacAddress.a[3], + pAPort->CurrentMacAddress.a[4], +- pAPort->CurrentMacAddress.a[5])) ++ pAPort->CurrentMacAddress.a[5])); + #endif /* DEBUG */ +- ++ + #ifndef SK_SLIM + /* Determine return value. */ + if (Inexact == 0 && pAPort->PromMode == 0) { +@@ -1195,7 +1193,7 @@ + #else /* SK_SLIM */ + return (SK_MC_FILTERING_INEXACT); + #endif /* SK_SLIM */ +- ++ + } /* SkAddrGmacMcUpdate */ + + #endif /* YUKON */ +@@ -1290,26 +1288,46 @@ + (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); + } ++ } + ++ /* ++ * In dual net mode it should be possible to set all MAC ++ * addresses independently. Therefore the equality checks ++ * against the locical address of the same port and the ++ * physical address of the other port are suppressed here. ++ */ ++#ifndef SK_NO_RLMT ++ if (pAC->Rlmt.NumNets == 1) { ++#endif /* SK_NO_RLMT */ + 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.Net[NetNumber].CurrentMacAddress.a)) { ++ return (SK_ADDR_DUPLICATE_ADDRESS); ++ } ++ ++ for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { ++ 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); ++ } + } + } ++#ifndef SK_NO_RLMT + } ++ else { ++ if (SK_ADDR_EQUAL(pNewAddr->a, ++ pAC->Addr.Port[PortNumber].CurrentMacAddress.a)) { ++ return (SK_ADDR_SUCCESS); ++ } ++ } ++#endif /* SK_NO_RLMT */ + + pAC->Addr.Port[PortNumber].PreviousMacAddress = + pAC->Addr.Port[PortNumber].CurrentMacAddress; +@@ -1340,18 +1358,32 @@ + 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 dual net mode on Yukon-2 adapters the physical address ++ * of port 0 and the logical address of port 1 are equal - in ++ * this case the equality check of the physical address leads ++ * to an error and is suppressed here. ++ */ ++#ifndef SK_NO_RLMT ++ if (pAC->Rlmt.NumNets == 1) { ++#endif /* SK_NO_RLMT */ ++ for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { ++ if (SK_ADDR_EQUAL(pNewAddr->a, ++ pAC->Addr.Port[i].CurrentMacAddress.a)) { ++ return (SK_ADDR_DUPLICATE_ADDRESS); ++ } + } ++#ifndef SK_NO_RLMT + } +- ++#endif /* SK_NO_RLMT */ ++ + /* + * In case that the physical and the logical MAC addresses are equal + * we must also change the physical MAC address here. +@@ -1360,11 +1392,11 @@ + */ + 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; +@@ -1372,7 +1404,7 @@ + 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]. +@@ -1388,8 +1420,8 @@ + 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])) +- ++ 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], +@@ -1397,17 +1429,16 @@ + 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])) ++ pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5])); + #endif /* DEBUG */ + +- /* Write address to first exact match entry of active port. */ +- (void) SkAddrMcUpdate(pAC, IoC, PortNumber); ++ /* Write address to first exact match entry of active port. */ ++ (void)SkAddrMcUpdate(pAC, IoC, PortNumber); + } + + return (SK_ADDR_SUCCESS); +- +-} /* SkAddrOverride */ + ++} /* SkAddrOverride */ + + #endif /* SK_NO_MAO */ + +@@ -1439,7 +1470,8 @@ + SK_U32 PortNumber, /* port whose promiscuous mode changes */ + int NewPromMode) /* new promiscuous mode */ + { +- int ReturnCode = 0; ++ int ReturnCode = SK_ADDR_ILLEGAL_PORT; ++ + #if (!defined(SK_SLIM) || defined(DEBUG)) + if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { + return (SK_ADDR_ILLEGAL_PORT); +@@ -1483,7 +1515,7 @@ + * SK_ADDR_SUCCESS + * SK_ADDR_ILLEGAL_PORT + */ +-static int SkAddrXmacPromiscuousChange( ++int SkAddrXmacPromiscuousChange( + SK_AC *pAC, /* adapter context */ + SK_IOC IoC, /* I/O context */ + SK_U32 PortNumber, /* port whose promiscuous mode changes */ +@@ -1504,17 +1536,18 @@ + /* 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 */ +@@ -1537,7 +1570,7 @@ + + 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); + +@@ -1573,9 +1606,9 @@ + /* Clear Promiscuous Mode */ + SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE); + } +- ++ + return (SK_ADDR_SUCCESS); +- ++ + } /* SkAddrXmacPromiscuousChange */ + + #endif /* GENESIS */ +@@ -1600,7 +1633,7 @@ + * SK_ADDR_SUCCESS + * SK_ADDR_ILLEGAL_PORT + */ +-static int SkAddrGmacPromiscuousChange( ++int SkAddrGmacPromiscuousChange( + SK_AC *pAC, /* adapter context */ + SK_IOC IoC, /* I/O context */ + SK_U32 PortNumber, /* port whose promiscuous mode changes */ +@@ -1622,22 +1655,25 @@ + CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC); + } + ++ /* dummy read after GM_IN16() */ ++ SK_IN16(IoC, B0_RAP, &ReceiveControl); ++ + 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 */ + +@@ -1651,19 +1687,19 @@ + + 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 */ +@@ -1735,33 +1771,33 @@ + 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++) { +@@ -1772,12 +1808,12 @@ + /* 20001207 RA: Was "ToPortNumber;". */ + } + } +- ++ + (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber); + (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber); + + return (SK_ADDR_SUCCESS); +- ++ + } /* SkAddrSwap */ + + #endif /* !SK_SLIM */ +diff -ruN linux/drivers/net/sk98lin/skcsum.c linux-new/drivers/net/sk98lin/skcsum.c +--- linux/drivers/net/sk98lin/skcsum.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/skcsum.c 2007-01-24 14:03:40.000000000 +0100 +@@ -0,0 +1,873 @@ ++/****************************************************************************** ++ * ++ * Name: skcsum.c ++ * Project: GEnesis, PCI Gigabit Ethernet Adapter ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Store/verify Internet checksum in send/receive packets. ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * LICENSE: ++ * (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. ++ * /LICENSE ++ * ++ ******************************************************************************/ ++ ++#ifdef SK_USE_CSUM /* Check if CSUM is to be used. */ ++ ++#ifndef lint ++static const char SysKonnectFileId[] = ++ "@(#) $Id$ (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 -ruN linux/drivers/net/sk98lin/skdim.c linux-new/drivers/net/sk98lin/skdim.c +--- linux/drivers/net/sk98lin/skdim.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skdim.c 2007-01-24 14:03:43.000000000 +0100 +@@ -1,17 +1,25 @@ + /****************************************************************************** + * +- * Name: skdim.c +- * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ +- * Purpose: All functions to maintain interrupt moderation ++ * Name: skdim.c ++ * Project: GEnesis, PCI Gigabit Ethernet Adapter ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: All functions regardig interrupt moderation + * + ******************************************************************************/ + + /****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2005 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 + * + * 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 +@@ -20,723 +28,360 @@ + * + * 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$ (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 +- +-/******************************************************************************* +-** +-** Defines +-** +-*******************************************************************************/ +- +-/******************************************************************************* +-** +-** Typedefs +-** +-*******************************************************************************/ ++/****************************************************************************** ++ * ++ * Local Function Prototypes ++ * ++ *****************************************************************************/ + +-/******************************************************************************* +-** +-** 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); ++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); + +-/******************************************************************************* +-** +-** Global variables +-** +-*******************************************************************************/ ++#define M_DIMINFO pAC->DynIrqModInfo + +-/******************************************************************************* +-** +-** Local variables +-** +-*******************************************************************************/ ++/****************************************************************************** ++ * ++ * Global Functions ++ * ++ *****************************************************************************/ + +-/******************************************************************************* +-** +-** Global functions +-** +-*******************************************************************************/ ++/***************************************************************************** ++ * ++ * SkDimModerate - Moderates the IRQs depending on the current needs ++ * ++ * Description: ++ * Moderation of IRQs depends on the number of occurred IRQs with ++ * respect to the previous moderation cycle. ++ * ++ * Returns: N/A ++ * ++ */ ++void SkDimModerate( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ SK_U64 IsrCalls = getIsrCalls(pAC); ++ ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==> SkDimModerate\n")); ++ ++ if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) { ++ if (isIntModEnabled(pAC)) { ++ if (IsrCalls < M_DIMINFO.MaxModIntsPerSecLowerLimit) { ++ disableIntMod(pAC); ++ } ++ } else { ++ if (IsrCalls > M_DIMINFO.MaxModIntsPerSecUpperLimit) { ++ enableIntMod(pAC); ++ } ++ } ++ } ++ setCurrIntCtr(pAC); + +-/******************************************************************************* +-** 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; ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("<== SkDimModerate\n")); ++} + +-#define M_DIMINFO pAC->DynIrqModInfo ++/***************************************************************************** ++ * ++ * SkDimStartModerationTimer - Starts the moderation timer ++ * ++ * Description: ++ * Dynamic interrupt moderation is regularly checked using the ++ * so-called moderation timer. This timer is started with this function. ++ * ++ * Returns: N/A ++ */ ++void SkDimStartModerationTimer( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ SK_EVPARA EventParam; /* Event struct for timer event */ ++ ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, ++ ("==> SkDimStartModerationTimer\n")); + +- 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 useful +- */ +- if (M_DIMINFO.AutoSizing) { +- ResizeDimTimerDuration(pAC); +- } +- } +- } +- } +- +- /* +- ** Some information to the log... +- */ +- if (M_DIMINFO.DisplayStats) { +- DisplaySelectedModerationType(pAC); +- DisplaySelectedModerationMask(pAC); +- DisplayDescrRatio(pAC); +- } ++ if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) { ++ SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam)); ++ EventParam.Para32[0] = SK_DRV_MODERATION_TIMER; ++ SkTimerStart(pAC, pAC->IoBase, ++ &pAC->DynIrqModInfo.ModTimer, ++ pAC->DynIrqModInfo.DynIrqModSampleInterval * 1000000, ++ SKGE_DRV, SK_DRV_TIMER, EventParam); ++ } + +- M_DIMINFO.NbrProcessedDescr = 0; +- SetCurrIntCtr(pAC); ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, ++ ("<== SkDimStartModerationTimer\n")); + } + +-/******************************************************************************* +-** 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); +-} ++/***************************************************************************** ++ * ++ * SkDimEnableModerationIfNeeded - Enables or disables any moderationtype ++ * ++ * Description: ++ * This function effectively initializes the IRQ moderation of a network ++ * adapter. Depending on the configuration, this might be either static ++ * or dynamic. If no moderation is configured, this function will do ++ * nothing. ++ * ++ * Returns: N/A ++ */ ++void SkDimEnableModerationIfNeeded( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, ++ ("==> SkDimEnableModerationIfNeeded\n")); ++ ++ if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_NONE) { ++ if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) { ++ enableIntMod(pAC); ++ } else { /* must be C_INT_MOD_DYNAMIC */ ++ SkDimStartModerationTimer(pAC); ++ } ++ } + +-/******************************************************************************* +-** 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"); +- } +- } ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, ++ ("<== SkDimEnableModerationIfNeeded\n")); + } + +-/******************************************************************************* +-** Function : SkDimDisplayModerationSettings +-** Description : Displays the current settings regarding interrupt moderation +-** Programmer : Ralph Roesler +-** Last Modified: 22-mar-03 +-** Returns : void (!) +-** Notes : - +-*******************************************************************************/ +- +-void +-SkDimDisplayModerationSettings(SK_AC *pAC) { +- DisplaySelectedModerationType(pAC); +- DisplaySelectedModerationMask(pAC); +-} ++/***************************************************************************** ++ * ++ * SkDimDisableModeration - disables moderation if it is enabled ++ * ++ * Description: ++ * Disabling of the moderation requires that is enabled already. ++ * ++ * Returns: N/A ++ */ ++void SkDimDisableModeration( ++SK_AC *pAC, /* pointer to adapter control context */ ++int CurrentModeration) /* type of current moderation */ ++{ ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, ++ ("==> SkDimDisableModeration\n")); ++ ++ if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_NONE) { ++ if (CurrentModeration == C_INT_MOD_STATIC) { ++ disableIntMod(pAC); ++ } else { /* must be C_INT_MOD_DYNAMIC */ ++ SkTimerStop(pAC, pAC->IoBase, &M_DIMINFO.ModTimer); ++ disableIntMod(pAC); ++ } ++ } + +-/******************************************************************************* +-** +-** Local functions +-** +-*******************************************************************************/ ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, ++ ("<== SkDimDisableModeration\n")); ++} + +-/******************************************************************************* +-** 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; ++/****************************************************************************** ++ * ++ * Local Functions ++ * ++ *****************************************************************************/ + +- /* unsigned int NbrCpu = 0; */ ++/***************************************************************************** ++ * ++ * getIsrCalls - evaluate the number of IRQs handled in mod interval ++ * ++ * Description: ++ * Depending on the selected moderation mask, this function will return ++ * the number of interrupts handled in the previous moderation interval. ++ * This evaluated number is based on the current number of interrupts ++ * stored in PNMI-context and the previous stored interrupts. ++ * ++ * Returns: ++ * the number of IRQs handled ++ */ ++static SK_U64 getIsrCalls( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ SK_U64 RxPort0IntDiff = 0, RxPort1IntDiff = 0; ++ SK_U64 TxPort0IntDiff = 0, TxPort1IntDiff = 0; ++ SK_U64 StatusPort0IntDiff = 0, StatusPort1IntDiff = 0; ++ ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==>getIsrCalls\n")); ++ ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ if ((M_DIMINFO.MaskIrqModeration == IRQ_MASK_TX_ONLY) || ++ (M_DIMINFO.MaskIrqModeration == IRQ_MASK_SP_TX)) { ++ if (pAC->GIni.GIMacsFound == 2) { ++ TxPort1IntDiff = ++ pAC->Pnmi.Port[1].TxIntrCts - ++ M_DIMINFO.PrevPort1TxIntrCts; ++ } ++ TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - ++ M_DIMINFO.PrevPort0TxIntrCts; ++ } else if ((M_DIMINFO.MaskIrqModeration == IRQ_MASK_RX_ONLY) || ++ (M_DIMINFO.MaskIrqModeration == IRQ_MASK_SP_RX)) { ++ if (pAC->GIni.GIMacsFound == 2) { ++ RxPort1IntDiff = ++ pAC->Pnmi.Port[1].RxIntrCts - ++ M_DIMINFO.PrevPort1RxIntrCts; ++ } ++ RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - ++ M_DIMINFO.PrevPort0RxIntrCts; ++ } else { ++ if (pAC->GIni.GIMacsFound == 2) { ++ RxPort1IntDiff = ++ pAC->Pnmi.Port[1].RxIntrCts - ++ M_DIMINFO.PrevPort1RxIntrCts; ++ TxPort1IntDiff = ++ pAC->Pnmi.Port[1].TxIntrCts - ++ M_DIMINFO.PrevPort1TxIntrCts; ++ } ++ RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - ++ M_DIMINFO.PrevPort0RxIntrCts; ++ TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - ++ M_DIMINFO.PrevPort0TxIntrCts; ++ } ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, ++ ("==>getIsrCalls (!CHIP_ID_YUKON_2)\n")); ++ return (RxPort0IntDiff + RxPort1IntDiff + ++ TxPort0IntDiff + TxPort1IntDiff); ++ } + + /* +- ** 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 ++ ** We have a Yukon2 compliant chipset if we come up to here + ** +- ** 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; +- ** } ++ if (pAC->GIni.GIMacsFound == 2) { ++ StatusPort1IntDiff = pAC->Pnmi.Port[1].StatusLeIntrCts - ++ M_DIMINFO.PrevPort1StatusIntrCts; ++ } ++ StatusPort0IntDiff = pAC->Pnmi.Port[0].StatusLeIntrCts - ++ M_DIMINFO.PrevPort0StatusIntrCts; + */ +- 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); ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, ++ ("==>getIsrCalls (CHIP_ID_YUKON_2)\n")); ++ return (StatusPort0IntDiff + StatusPort1IntDiff); ++} + +- if (M_DIMINFO.DisplayStats) { +- printk("Current system load is: %u\n", SystemLoad); ++/***************************************************************************** ++ * ++ * setCurrIntCtr - stores the current number of interrupts ++ * ++ * Description: ++ * Stores the current number of occurred interrupts in the adapter ++ * context. This is needed to evaluate the umber of interrupts within ++ * the moderation interval. ++ * ++ * Returns: N/A ++ * ++ */ ++static void setCurrIntCtr( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==>setCurrIntCtr\n")); ++ ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ if (pAC->GIni.GIMacsFound == 2) { ++ M_DIMINFO.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts; ++ M_DIMINFO.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts; ++ } ++ M_DIMINFO.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts; ++ M_DIMINFO.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts; ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, ++ ("<== setCurrIntCtr (!CHIP_ID_YUKON_2)\n")); ++ return; + } + +- M_DIMINFO.PrevTotalTime = TotalTime; +- M_DIMINFO.PrevUsedTime = UsedTime; +- +- return (SystemLoad); ++ /* ++ ** We have a Yukon2 compliant chipset if we come up to here ++ ** ++ if (pAC->GIni.GIMacsFound == 2) { ++ M_DIMINFO.PrevPort1StatusIntrCts = pAC->Pnmi.Port[1].StatusLeIntrCts; ++ } ++ M_DIMINFO.PrevPort0StatusIntrCts = pAC->Pnmi.Port[0].StatusLeIntrCts; ++ */ ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, ++ ("<== setCurrIntCtr (CHIP_ID_YUKON_2)\n")); + } + +-/******************************************************************************* +-** 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); ++/***************************************************************************** ++ * ++ * isIntModEnabled - returns the current state of interrupt moderation ++ * ++ * Description: ++ * This function retrieves the current value of the interrupt moderation ++ * command register. Its content determines whether any moderation is ++ * running or not. ++ * ++ * Returns: ++ * SK_TRUE : IRQ moderation is currently active ++ * SK_FALSE: No IRQ moderation is active ++ */ ++static SK_BOOL isIntModEnabled( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ unsigned long CtrCmd; ++ ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==>isIntModEnabled\n")); ++ ++ SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd); ++ if ((CtrCmd & TIM_START) == TIM_START) { ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, ++ ("<== isIntModEnabled (SK_TRUE)\n")); ++ return SK_TRUE; ++ } ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, ++ ("<== isIntModEnabled (SK_FALSE)\n")); ++ return SK_FALSE; + } + +-/******************************************************************************* +-** 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; ++/***************************************************************************** ++ * ++ * enableIntMod - enables the interrupt moderation ++ * ++ * Description: ++ * Enabling the interrupt moderation is done by putting the desired ++ * moderation interval in the B2_IRQM_INI register, specifying the ++ * desired maks in the B2_IRQM_MSK register and finally starting the ++ * IRQ moderation timer using the B2_IRQM_CTRL register. ++ * ++ * Returns: N/A ++ * ++ */ ++static void enableIntMod( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ unsigned long ModBase; + +- return (RxPort0IntDiff + RxPort1IntDiff); +-} ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==> enableIntMod\n")); ++ ModBase = ((62500L/100) * pAC->GIni.GIHstClkFact * 1000) / M_DIMINFO.MaxModIntsPerSec; + +-/******************************************************************************* +-** 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; +-} ++ SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase); ++ SK_OUT32(pAC->IoBase, B2_IRQM_MSK, M_DIMINFO.MaskIrqModeration); ++ SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START); + +-/******************************************************************************* +-** 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; +- } ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("<== enableIntMod\n")); + } + +-/******************************************************************************* +-** 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); +- } +-} ++/***************************************************************************** ++ * ++ * disableIntMod - disables the interrupt moderation ++ * ++ * Description: ++ * Disabling the interrupt moderation is done by stopping the ++ * IRQ moderation timer using the B2_IRQM_CTRL register. ++ * ++ * Returns: N/A ++ * ++ */ ++static void disableIntMod( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==> disableIntMod\n")); + +-/******************************************************************************* +-** Function : DisableIntMod() +-** Description : Disables 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"); +- } +-} ++ SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP); + +-/******************************************************************************* +-** 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); ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("<== disableIntMod\n")); + } + + /******************************************************************************* +-** 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 +-** +-*******************************************************************************/ ++ * ++ * End of file ++ * ++ ******************************************************************************/ +diff -ruN linux/drivers/net/sk98lin/skethtool.c linux-new/drivers/net/sk98lin/skethtool.c +--- linux/drivers/net/sk98lin/skethtool.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skethtool.c 2007-01-24 14:03:43.000000000 +0100 +@@ -2,8 +2,8 @@ + * + * Name: skethtool.c + * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: All functions regarding ethtool handling + * + ******************************************************************************/ +@@ -11,7 +11,7 @@ + /****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2004 Marvell. ++ * (C)Copyright 2002-2005 Marvell. + * + * Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet + * Server Adapters. +@@ -21,9 +21,6 @@ + * + * 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 +@@ -36,10 +33,25 @@ + #include "h/skdrv1st.h" + #include "h/skdrv2nd.h" + #include "h/skversion.h" +- + #include ++#include + #include +-#include ++ ++/****************************************************************************** ++ * ++ * Local Functions ++ * ++ *****************************************************************************/ ++static void toggleLeds(unsigned long ptr); ++ ++/****************************************************************************** ++ * ++ * External Functions and Data ++ * ++ *****************************************************************************/ ++ ++extern void SkDimDisableModeration(SK_AC *pAC, int CurrentModeration); ++extern void SkDimEnableModerationIfNeeded(SK_AC *pAC); + + /****************************************************************************** + * +@@ -47,6 +59,12 @@ + * + *****************************************************************************/ + ++#ifndef ETHT_STATSTRING_LEN ++#define ETHT_STATSTRING_LEN 32 ++#endif ++ ++#define SK98LIN_STAT(m) sizeof(((SK_AC *)0)->m),offsetof(SK_AC, m) ++ + #define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \ + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \ + SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \ +@@ -65,59 +83,137 @@ + ADVERTISED_FIBRE | \ + ADVERTISED_Autoneg) + ++struct sk98lin_stats { ++ char stat_string[ETHT_STATSTRING_LEN]; ++ int sizeof_stat; ++ int stat_offset; ++}; ++ ++static struct sk98lin_stats sk98lin_etht_stats_port0[] = { ++ { "rx_packets" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxOkCts) }, ++ { "tx_packets" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxOkCts) }, ++ { "rx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxOctetsOkCts) }, ++ { "tx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxOctetsOkCts) }, ++ { "rx_errors" , SK98LIN_STAT(PnmiStruct.InErrorsCts) }, ++ { "tx_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxSingleCollisionCts) }, ++ { "rx_dropped" , SK98LIN_STAT(PnmiStruct.RxNoBufCts) }, ++ { "tx_dropped" , SK98LIN_STAT(PnmiStruct.TxNoBufCts) }, ++ { "multicasts" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxMulticastOkCts) }, ++ { "collisions" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxSingleCollisionCts) }, ++ { "rx_length_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxRuntCts) }, ++ { "rx_buffer_overflow_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxFifoOverflowCts) }, ++ { "rx_crc_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxFcsCts) }, ++ { "rx_frame_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxFramingCts) }, ++ { "rx_too_short_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxShortsCts) }, ++ { "rx_too_long_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxTooLongCts) }, ++ { "rx_carrier_extension_errors", SK98LIN_STAT(PnmiStruct.Stat[0].StatRxCextCts) }, ++ { "rx_symbol_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxSymbolCts) }, ++ { "rx_llc_mac_size_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxIRLengthCts) }, ++ { "rx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxCarrierCts) }, ++ { "rx_jabber_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxJabberCts) }, ++ { "rx_missed_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxMissedCts) }, ++ { "tx_abort_collision_errors" , SK98LIN_STAT(stats.tx_aborted_errors) }, ++ { "tx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxCarrierCts) }, ++ { "tx_buffer_underrun_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxFifoUnderrunCts) }, ++ { "tx_heartbeat_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxCarrierCts) } , ++ { "tx_window_errors" , SK98LIN_STAT(stats.tx_window_errors) } ++}; ++ ++static struct sk98lin_stats sk98lin_etht_stats_port1[] = { ++ { "rx_packets" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxOkCts) }, ++ { "tx_packets" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxOkCts) }, ++ { "rx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxOctetsOkCts) }, ++ { "tx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxOctetsOkCts) }, ++ { "rx_errors" , SK98LIN_STAT(PnmiStruct.InErrorsCts) }, ++ { "tx_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxSingleCollisionCts) }, ++ { "rx_dropped" , SK98LIN_STAT(PnmiStruct.RxNoBufCts) }, ++ { "tx_dropped" , SK98LIN_STAT(PnmiStruct.TxNoBufCts) }, ++ { "multicasts" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxMulticastOkCts) }, ++ { "collisions" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxSingleCollisionCts) }, ++ { "rx_length_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxRuntCts) }, ++ { "rx_buffer_overflow_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxFifoOverflowCts) }, ++ { "rx_crc_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxFcsCts) }, ++ { "rx_frame_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxFramingCts) }, ++ { "rx_too_short_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxShortsCts) }, ++ { "rx_too_long_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxTooLongCts) }, ++ { "rx_carrier_extension_errors", SK98LIN_STAT(PnmiStruct.Stat[1].StatRxCextCts) }, ++ { "rx_symbol_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxSymbolCts) }, ++ { "rx_llc_mac_size_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxIRLengthCts) }, ++ { "rx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxCarrierCts) }, ++ { "rx_jabber_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxJabberCts) }, ++ { "rx_missed_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxMissedCts) }, ++ { "tx_abort_collision_errors" , SK98LIN_STAT(stats.tx_aborted_errors) }, ++ { "tx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxCarrierCts) }, ++ { "tx_buffer_underrun_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxFifoUnderrunCts) }, ++ { "tx_heartbeat_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxCarrierCts) } , ++ { "tx_window_errors" , SK98LIN_STAT(stats.tx_window_errors) } ++}; ++ ++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 } ++}; ++ ++#define SK98LIN_STATS_LEN sizeof(sk98lin_etht_stats_port0) / sizeof(struct sk98lin_stats) ++ ++static int nbrBlinkQuarterSeconds; ++static int currentPortIndex; ++static SK_BOOL isLocateNICrunning = SK_FALSE; ++static SK_BOOL isDualNetCard = SK_FALSE; ++static SK_BOOL doSwitchLEDsOn = SK_FALSE; ++static SK_BOOL boardWasDown[2] = { SK_FALSE, SK_FALSE }; ++static struct timer_list locateNICtimer; + + /****************************************************************************** + * +- * Local Functions ++ * Ethtool Functions + * + *****************************************************************************/ + + /***************************************************************************** + * +- * getSettings - retrieves the current settings of the selected adapter ++ * SkGeGetSettings - 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 ++ * Returns: N/A + * + */ +-static int getSettings(struct net_device *dev, struct ethtool_cmd *ecmd) ++int SkGeGetSettings(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 } +- }; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ int port = pNet->PortNr; ++ SK_GEPORT *pPort = &pAC->GIni.GP[port]; + + ecmd->phy_address = port; + ecmd->speed = SpeedConfMap[pPort->PLinkSpeedUsed][1]; +@@ -137,12 +233,10 @@ + 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]; +@@ -152,324 +246,416 @@ + } else { + ecmd->advertising = ecmd->supported; + } +- +- if (ecmd->autoneg == AUTONEG_ENABLE) ++ if (ecmd->autoneg == AUTONEG_ENABLE) { + ecmd->advertising |= ADVERTISED_Autoneg; ++ } else { ++ ecmd->advertising = ADVERTISED_TP; ++ } + } else { + ecmd->port = PORT_FIBRE; +- ecmd->supported = SUPP_FIBRE_ALL; +- ecmd->advertising = ADV_FIBRE_ALL; ++ ecmd->supported = (SUPP_FIBRE_ALL); ++ ecmd->advertising = (ADV_FIBRE_ALL); + } +- return 0; ++ return(0); + } + +-/* +- * MIB infrastructure uses instance value starting at 1 +- * based on board and port. ++ ++ ++/***************************************************************************** ++ * ++ * SkGeGetDrvInfo - 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 inline u32 pnmiInstance(const DEV_NET *pNet) ++void SkGeGetDrvInfo(struct net_device *dev, ++ struct ethtool_drvinfo *ecmd) + { +- return 1 + (pNet->pAC->RlmtNets == 2) + pNet->PortNr; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ char versionString[32]; ++ ++ snprintf(versionString, 32, "%s (%s)", VER_STRING, PATCHLEVEL); ++ strncpy(ecmd->driver, DRIVER_FILE_NAME , 32); ++ strncpy(ecmd->version, versionString , 32); ++ strncpy(ecmd->fw_version, "N/A", 32); ++ strncpy(ecmd->bus_info, pci_name(pAC->PciDev), 32); ++ ++ ecmd->n_stats = SK98LIN_STATS_LEN; + } + + /***************************************************************************** + * +- * setSettings - configures the settings of a selected adapter ++ * SkGeGetWolSettings - retrieves the WOL settings of the ++ * selected adapter + * + * Description: +- * Possible settings that may be altered are a)speed, b)duplex or +- * c)autonegotiation. ++ * All current WOL settings of a selected adapter are placed in the ++ * passed ethtool_wolinfo structure and are returned to the caller. ++ * ++ * Returns: N/A + * +- * 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) ++void SkGeGetWolSettings(struct net_device *dev, ++ struct ethtool_wolinfo *ecmd) + { +- DEV_NET *pNet = netdev_priv(dev); +- SK_AC *pAC = pNet->pAC; +- u32 instance; +- char buf[4]; +- int len = 1; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; + +- if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100 +- && ecmd->speed != SPEED_1000) +- return -EINVAL; ++ ecmd->supported = pAC->WolInfo.SupportedWolOptions; ++ ecmd->wolopts = pAC->WolInfo.ConfiguredWolOptions; ++} + +- if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL) +- return -EINVAL; ++/***************************************************************************** ++ * ++ * SkGeGetPauseParam - 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 ++ * ++ */ ++void SkGeGetPauseParam(struct net_device *dev, ++ struct ethtool_pauseparam *ecmd) ++{ ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ int port = pNet->PortNr; ++ SK_GEPORT *pPort = &pAC->GIni.GP[port]; ++ ++ /* Get the pause parameters */ ++ ecmd->rx_pause = 0; ++ ecmd->tx_pause = 0; ++ ++ if (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND) { ++ ecmd->tx_pause = 1; ++ } ++ if ((pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) || ++ (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM)) { ++ ecmd->tx_pause = 1; ++ ecmd->rx_pause = 1; ++ } + +- if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE) +- return -EINVAL; ++ if ((ecmd->rx_pause == 0) && (ecmd->tx_pause == 0)) { ++ ecmd->autoneg = SK_FALSE; ++ } else { ++ ecmd->autoneg = SK_TRUE; ++ } ++} + +- 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; +- } ++/***************************************************************************** ++ * ++ * SkGeGetCoalesce - retrieves the IRQ moderation settings ++ * ++ * Description: ++ * All current IRQ moderation settings of a selected adapter are placed ++ * in the passed ethtool_coalesce structure and are returned. ++ * ++ * Returns: N/A ++ * ++ */ ++int SkGeGetCoalesce(struct net_device *dev, ++ struct ethtool_coalesce *ecmd) ++{ ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; + +- if (SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, +- &buf, &len, instance, pNet->NetNr) != SK_PNMI_ERR_OK) +- return -EINVAL; ++ DIM_INFO *Info = &pAC->DynIrqModInfo; ++ SK_BOOL UseTxIrqModeration = SK_FALSE; ++ SK_BOOL UseRxIrqModeration = SK_FALSE; ++ ++ if (Info->IntModTypeSelect != C_INT_MOD_NONE) { ++ if (CHIP_ID_YUKON_2(pAC)) { ++ UseRxIrqModeration = SK_TRUE; ++ UseTxIrqModeration = SK_TRUE; ++ } else { ++ if ((Info->MaskIrqModeration == IRQ_MASK_RX_ONLY) || ++ (Info->MaskIrqModeration == IRQ_MASK_SP_RX) || ++ (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) { ++ UseRxIrqModeration = SK_TRUE; ++ } ++ if ((Info->MaskIrqModeration == IRQ_MASK_TX_ONLY) || ++ (Info->MaskIrqModeration == IRQ_MASK_SP_TX) || ++ (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) { ++ UseTxIrqModeration = SK_TRUE; ++ } ++ } + +- return 0; ++ if (UseRxIrqModeration) { ++ ecmd->rx_coalesce_usecs = 1000000 / Info->MaxModIntsPerSec; ++ } ++ if (UseTxIrqModeration) { ++ ecmd->tx_coalesce_usecs = 1000000 / Info->MaxModIntsPerSec; ++ } ++ if (Info->IntModTypeSelect == C_INT_MOD_DYNAMIC) { ++ ecmd->rate_sample_interval = Info->DynIrqModSampleInterval; ++ if (UseRxIrqModeration) { ++ ecmd->use_adaptive_rx_coalesce = 1; ++ ecmd->rx_coalesce_usecs_low = ++ 1000000 / Info->MaxModIntsPerSecLowerLimit; ++ ecmd->rx_coalesce_usecs_high = ++ 1000000 / Info->MaxModIntsPerSecUpperLimit; ++ } ++ if (UseTxIrqModeration) { ++ ecmd->use_adaptive_tx_coalesce = 1; ++ ecmd->tx_coalesce_usecs_low = ++ 1000000 / Info->MaxModIntsPerSecLowerLimit; ++ ecmd->tx_coalesce_usecs_high = ++ 1000000 / Info->MaxModIntsPerSecUpperLimit; ++ } ++ } ++ } ++ return(0); + } + + /***************************************************************************** + * +- * getDriverInfo - returns generic driver and adapter information ++ * SkGeGetRxCsum - retrieves the RxCsum parameters + * + * 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'). +- * ++ * All current RxCsum parameters of a selected adapter are placed ++ * in the passed net_device structure and are returned. ++ * + * Returns: N/A + * + */ +-static void getDriverInfo(struct net_device *dev, struct ethtool_drvinfo *info) ++SK_U32 SkGeGetRxCsum(struct net_device *dev) + { +- 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); ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ int port = pNet->PortNr; ++ ++ return pAC->RxPort[port].UseRxCsum; + } + +-static void getStrings(struct net_device *dev, u32 stringset, u8 *data) ++ ++/***************************************************************************** ++ * ++ * SkGeGetStrings - retrieves the statistic strings ++ * ++ * Description: ++ * N/A ++ * ++ * Returns: N/A ++ * ++ */ ++void SkGeGetStrings(struct net_device *dev, ++ u32 stringset, ++ u8 *strings) + { ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ int port = pNet->PortNr; ++ int i; ++ ++ struct sk98lin_stats *sk98lin_etht_stats = ++ (port == 0) ? sk98lin_etht_stats_port0 : sk98lin_etht_stats_port1; ++ + switch(stringset) { +- case ETH_SS_STATS: +- memcpy(data, *StringsStats, sizeof(StringsStats)); +- break; ++ case ETH_SS_STATS: { ++ for(i=0; i < SK98LIN_STATS_LEN; i++) { ++ memcpy(&strings[i * ETHT_STATSTRING_LEN], ++ &(sk98lin_etht_stats[i].stat_string), ++ ETHT_STATSTRING_LEN); ++ } ++ 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 ++ * SkGeGetStatsLen - retrieves the statistic count + * + * Description: +- * This function changes the current state of all LEDs of an adapter so +- * that it can be located by a user. ++ * N/A + * + * Returns: N/A + * + */ +-static void toggleLeds(DEV_NET *pNet, int on) ++int SkGeGetStatsLen(struct net_device *dev) + { +- 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); +- } ++ return SK98LIN_STATS_LEN; + } + ++ ++ ++ + /***************************************************************************** + * +- * skGeBlinkTimer - Changes the LED state of an adapter ++ * SkGeGetEthStats - retrieves the card statistics + * + * 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. ++ * All current statistics of a selected adapter are placed ++ * in the passed ethtool_stats structure and are returned. + * + * Returns: N/A + * + */ +-void SkGeBlinkTimer(unsigned long data) ++void SkGeGetEthStats(struct net_device *dev, ++ struct ethtool_stats *stats, ++ u64 *data) + { +- struct net_device *dev = (struct net_device *) data; +- DEV_NET *pNet = netdev_priv(dev); +- SK_AC *pAC = pNet->pAC; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ SK_U32 Size = sizeof(SK_PNMI_STRUCT_DATA); ++ SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct; ++ int port = pNet->PortNr; ++ int i; + +- toggleLeds(pNet, pAC->LedsOn); ++ struct sk98lin_stats *sk98lin_etht_stats = ++ (port == 0) ? sk98lin_etht_stats_port0 : sk98lin_etht_stats_port1; + +- pAC->LedsOn = !pAC->LedsOn; +- mod_timer(&pAC->BlinkTimer, jiffies + HZ/4); ++ if (netif_running(pAC->dev[port])) { ++ SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, port); ++ } ++ ++ for(i = 0; i < SK98LIN_STATS_LEN; i++) { ++ if (netif_running(pAC->dev[port])) { ++ data[i] = (sk98lin_etht_stats[i].sizeof_stat == ++ sizeof(uint64_t)) ? ++ *(uint64_t *)((char *)pAC + ++ sk98lin_etht_stats[i].stat_offset) : ++ *(uint32_t *)((char *)pAC + ++ sk98lin_etht_stats[i].stat_offset); ++ } else { ++ data[i] = (sk98lin_etht_stats[i].sizeof_stat == ++ sizeof(uint64_t)) ? (uint64_t) 0 : (uint32_t) 0; ++ } ++ } + } + ++ + /***************************************************************************** + * +- * locateDevice - start the locate NIC feature of the elected adapter ++ * SkGeSetSettings - configures the settings of a selected 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 ++ * 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 locateDevice(struct net_device *dev, u32 data) ++int SkGeSetSettings(struct net_device *dev, ++ struct ethtool_cmd *ecmd) + { +- DEV_NET *pNet = netdev_priv(dev); +- SK_AC *pAC = pNet->pAC; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ int port = pNet->PortNr; ++ ++ SK_U32 Instance; ++ char Buf[4]; ++ unsigned int Len = 1; ++ int Ret; + +- if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) +- data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); ++ if (port == 0) { ++ Instance = (pAC->RlmtNets == 2) ? 1 : 2; ++ } else { ++ Instance = (pAC->RlmtNets == 2) ? 2 : 3; ++ } + +- /* start blinking */ +- pAC->LedsOn = 0; +- mod_timer(&pAC->BlinkTimer, jiffies); +- msleep_interruptible(data * 1000); +- del_timer_sync(&pAC->BlinkTimer); +- toggleLeds(pNet, 0); ++ if (((ecmd->autoneg == AUTONEG_DISABLE) || (ecmd->autoneg == AUTONEG_ENABLE)) && ++ ((ecmd->duplex == DUPLEX_FULL) || (ecmd->duplex == DUPLEX_HALF))) { ++ if (ecmd->autoneg == AUTONEG_DISABLE) { ++ if (ecmd->duplex == DUPLEX_FULL) { ++ *Buf = (char) SK_LMODE_FULL; ++ } else { ++ *Buf = (char) SK_LMODE_HALF; ++ } ++ } else { ++ /* Autoneg on. Enable autoparam */ ++ *Buf = (char) SK_LMODE_AUTOBOTH; ++ } + +- return 0; ++ Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE, ++ &Buf, &Len, Instance, pNet->NetNr); ++ ++ if (Ret != SK_PNMI_ERR_OK) { ++ return -EINVAL; ++ } ++ } else if (ecmd->autoneg == AUTONEG_ENABLE) { ++ /* Set default values */ ++ *Buf = (char) SK_LMODE_AUTOFULL; ++ Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE, ++ &Buf, &Len, Instance, pNet->NetNr); ++ } ++ ++ if ((ecmd->speed == SPEED_1000) || ++ (ecmd->speed == SPEED_100) || ++ (ecmd->speed == SPEED_10)) { ++ ++ if (ecmd->autoneg == AUTONEG_ENABLE) { ++ *Buf = (char) SK_LSPEED_AUTO; ++ } else if (ecmd->speed == SPEED_1000) { ++ *Buf = (char) SK_LSPEED_1000MBPS; ++ } else if (ecmd->speed == SPEED_100) { ++ *Buf = (char) SK_LSPEED_100MBPS; ++ } else { ++ *Buf = (char) SK_LSPEED_10MBPS; ++ } ++ ++ Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, ++ &Buf, &Len, Instance, pNet->NetNr); ++ ++ if (Ret != SK_PNMI_ERR_OK) { ++ return -EINVAL; ++ } ++ } else if (ecmd->autoneg == AUTONEG_ENABLE) { ++ *Buf = (char) SK_LSPEED_AUTO; ++ Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, ++ &Buf, &Len, Instance, pNet->NetNr); ++ } else { ++ return -EINVAL; ++ } ++ ++ return(0); + } + + /***************************************************************************** + * +- * getPauseParams - retrieves the pause parameters ++ * SkGeSetWolSettings - configures the WOL settings of a selected adapter + * + * Description: +- * All current pause parameters of a selected adapter are placed +- * in the passed ethtool_pauseparam structure and are returned. +- * +- * Returns: N/A ++ * The WOL settings of a selected adapter are configured regarding ++ * the parameters in the passed ethtool_wolinfo structure. ++ * Note that currently only wake on magic packet is supported! + * ++ * Returns: ++ * ==0: everything fine, no error ++ * !=0: the return value is the error code of the failure + */ +-static void getPauseParams(struct net_device *dev, struct ethtool_pauseparam *epause) ++int SkGeSetWolSettings(struct net_device *dev, ++ struct ethtool_wolinfo *ecmd) + { +- DEV_NET *pNet = netdev_priv(dev); +- SK_AC *pAC = pNet->pAC; +- SK_GEPORT *pPort = &pAC->GIni.GP[pNet->PortNr]; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; + +- epause->rx_pause = (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) || +- (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM); ++ if (ecmd->wolopts != WAKE_MAGIC && ecmd->wolopts != 0) ++ return -EOPNOTSUPP; + +- epause->tx_pause = epause->rx_pause || (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND); +- epause->autoneg = epause->rx_pause || epause->tx_pause; ++ if (((ecmd->wolopts & WAKE_MAGIC) == WAKE_MAGIC) || (ecmd->wolopts == 0)) { ++ pAC->WolInfo.ConfiguredWolOptions = ecmd->wolopts; ++ return 0; ++ } ++ return -EFAULT; + } + ++ + /***************************************************************************** + * +- * setPauseParams - configures the pause parameters of an adapter ++ * SkGeSetPauseParam - configures the pause parameters of an adapter + * + * Description: + * This function sets the Rx or Tx pause parameters +@@ -478,151 +664,598 @@ + * ==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) ++int SkGeSetPauseParam(struct net_device *dev, ++ struct ethtool_pauseparam *ecmd) + { +- 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; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ int port = pNet->PortNr; ++ SK_GEPORT *pPort = &pAC->GIni.GP[port]; ++ int PrevSpeedVal = pPort->PLinkSpeedUsed; ++ SK_U32 Instance; ++ char Buf[4]; ++ int Ret; ++ SK_BOOL prevAutonegValue = SK_TRUE; ++ int prevTxPause = 0; ++ int prevRxPause = 0; ++ unsigned int Len = 1; ++ ++ ++ if (port == 0) { ++ Instance = (pAC->RlmtNets == 2) ? 1 : 2; ++ } else { ++ Instance = (pAC->RlmtNets == 2) ? 2 : 3; ++ } + + /* + ** we have to determine the current settings to see if + ** the operator requested any modification of the flow + ** control parameters... + */ +- getPauseParams(dev, &old); ++ if (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND) { ++ prevTxPause = 1; ++ } ++ if ((pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) || ++ (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM)) { ++ prevTxPause = 1; ++ prevRxPause = 1; ++ } ++ ++ if ((prevRxPause == 0) && (prevTxPause == 0)) { ++ prevAutonegValue = SK_FALSE; ++ } ++ + + /* + ** 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; ++ if (ecmd->autoneg != prevAutonegValue) { ++ if (ecmd->autoneg == AUTONEG_DISABLE) { ++ *Buf = (char) SK_FLOW_MODE_NONE; ++ } else { ++ *Buf = (char) SK_FLOW_MODE_SYMMETRIC; ++ } ++ } else { ++ if(ecmd->rx_pause && ecmd->tx_pause) { ++ *Buf = (char) SK_FLOW_MODE_SYMMETRIC; ++ } else if (ecmd->rx_pause && !ecmd->tx_pause) { ++ *Buf = (char) SK_FLOW_MODE_SYM_OR_REM; ++ } else if(!ecmd->rx_pause && ecmd->tx_pause) { ++ *Buf = (char) SK_FLOW_MODE_LOC_SEND; ++ } else { ++ *Buf = (char) SK_FLOW_MODE_NONE; ++ } + } + +- ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE, +- &buf, &len, instance, pNet->NetNr); ++ Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE, ++ &Buf, &Len, Instance, pNet->NetNr); + +- if (ret != SK_PNMI_ERR_OK) { ++ 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; ++ ("ethtool (sk98lin): error changing rx/tx pause (%i)\n", Ret)); ++ } else { ++ Len = 1; /* set buffer length to correct value */ + } + + /* + ** 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)); ++ *Buf = (char) PrevSpeedVal; ++ ++ Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_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 setting speed (%i)\n", Ret)); ++ } ++ return 0; ++} ++ ++ ++/***************************************************************************** ++ * ++ * SkGeSetCoalesce - configures the IRQ moderation of an adapter ++ * ++ * Description: ++ * Depending on the desired IRQ moderation parameters, either a) static, ++ * b) dynamic or c) no moderation is configured. ++ * ++ * Returns: ++ * ==0: everything fine, no error ++ * !=0: the return value is the error code of the failure ++ * ++ * Notes: ++ * The supported timeframe for the coalesced interrupts ranges from ++ * 33.333us (30 IntsPerSec) down to 25us (40.000 IntsPerSec). ++ * Any requested value that is not in this range will abort the request! ++ */ ++int SkGeSetCoalesce(struct net_device *dev, ++ struct ethtool_coalesce *ecmd) ++{ ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ DIM_INFO *Info = &pAC->DynIrqModInfo; ++ int PrevModeration = Info->IntModTypeSelect; ++ ++ Info->IntModTypeSelect = C_INT_MOD_NONE; /* initial default */ ++ ++ if ((ecmd->rx_coalesce_usecs) || (ecmd->tx_coalesce_usecs)) { ++ if (ecmd->rx_coalesce_usecs) { ++ if ((ecmd->rx_coalesce_usecs < 25) || ++ (ecmd->rx_coalesce_usecs > 33333)) { ++ return -EINVAL; ++ } ++ } ++ if (ecmd->tx_coalesce_usecs) { ++ if ((ecmd->tx_coalesce_usecs < 25) || ++ (ecmd->tx_coalesce_usecs > 33333)) { ++ return -EINVAL; ++ } ++ } ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ if ((Info->MaskIrqModeration == IRQ_MASK_SP_RX) || ++ (Info->MaskIrqModeration == IRQ_MASK_SP_TX) || ++ (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) { ++ Info->MaskIrqModeration = IRQ_MASK_SP_ONLY; ++ } ++ } ++ Info->IntModTypeSelect = C_INT_MOD_STATIC; ++ if (ecmd->rx_coalesce_usecs) { ++ Info->MaxModIntsPerSec = ++ 1000000 / ecmd->rx_coalesce_usecs; ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ if (Info->MaskIrqModeration == IRQ_MASK_TX_ONLY) { ++ Info->MaskIrqModeration = IRQ_MASK_TX_RX; ++ } ++ if (Info->MaskIrqModeration == IRQ_MASK_SP_ONLY) { ++ Info->MaskIrqModeration = IRQ_MASK_SP_RX; ++ } ++ if (Info->MaskIrqModeration == IRQ_MASK_SP_TX) { ++ Info->MaskIrqModeration = IRQ_MASK_RX_TX_SP; ++ } ++ } else { ++ Info->MaskIrqModeration = Y2_IRQ_MASK; ++ } ++ } ++ if (ecmd->tx_coalesce_usecs) { ++ Info->MaxModIntsPerSec = ++ 1000000 / ecmd->tx_coalesce_usecs; ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ if (Info->MaskIrqModeration == IRQ_MASK_RX_ONLY) { ++ Info->MaskIrqModeration = IRQ_MASK_TX_RX; ++ } ++ if (Info->MaskIrqModeration == IRQ_MASK_SP_ONLY) { ++ Info->MaskIrqModeration = IRQ_MASK_SP_TX; ++ } ++ if (Info->MaskIrqModeration == IRQ_MASK_SP_RX) { ++ Info->MaskIrqModeration = IRQ_MASK_RX_TX_SP; ++ } ++ } else { ++ Info->MaskIrqModeration = Y2_IRQ_MASK; ++ } ++ } ++ } ++ if ((ecmd->rate_sample_interval) || ++ (ecmd->rx_coalesce_usecs_low) || ++ (ecmd->tx_coalesce_usecs_low) || ++ (ecmd->rx_coalesce_usecs_high)|| ++ (ecmd->tx_coalesce_usecs_high)) { ++ if (ecmd->rate_sample_interval) { ++ if ((ecmd->rate_sample_interval < 1) || ++ (ecmd->rate_sample_interval > 10)) { ++ return -EINVAL; ++ } ++ } ++ if (ecmd->rx_coalesce_usecs_low) { ++ if ((ecmd->rx_coalesce_usecs_low < 25) || ++ (ecmd->rx_coalesce_usecs_low > 33333)) { ++ return -EINVAL; ++ } ++ } ++ if (ecmd->rx_coalesce_usecs_high) { ++ if ((ecmd->rx_coalesce_usecs_high < 25) || ++ (ecmd->rx_coalesce_usecs_high > 33333)) { ++ return -EINVAL; ++ } ++ } ++ if (ecmd->tx_coalesce_usecs_low) { ++ if ((ecmd->tx_coalesce_usecs_low < 25) || ++ (ecmd->tx_coalesce_usecs_low > 33333)) { ++ return -EINVAL; ++ } ++ } ++ if (ecmd->tx_coalesce_usecs_high) { ++ if ((ecmd->tx_coalesce_usecs_high < 25) || ++ (ecmd->tx_coalesce_usecs_high > 33333)) { ++ return -EINVAL; ++ } ++ } ++ ++ Info->IntModTypeSelect = C_INT_MOD_DYNAMIC; ++ if (ecmd->rate_sample_interval) { ++ Info->DynIrqModSampleInterval = ++ ecmd->rate_sample_interval; ++ } ++ if (ecmd->rx_coalesce_usecs_low) { ++ Info->MaxModIntsPerSecLowerLimit = ++ 1000000 / ecmd->rx_coalesce_usecs_low; ++ } ++ if (ecmd->tx_coalesce_usecs_low) { ++ Info->MaxModIntsPerSecLowerLimit = ++ 1000000 / ecmd->tx_coalesce_usecs_low; ++ } ++ if (ecmd->rx_coalesce_usecs_high) { ++ Info->MaxModIntsPerSecUpperLimit = ++ 1000000 / ecmd->rx_coalesce_usecs_high; ++ } ++ if (ecmd->tx_coalesce_usecs_high) { ++ Info->MaxModIntsPerSecUpperLimit = ++ 1000000 / ecmd->tx_coalesce_usecs_high; ++ } ++ } ++ ++ if ((PrevModeration == C_INT_MOD_NONE) && ++ (Info->IntModTypeSelect != C_INT_MOD_NONE)) { ++ SkDimEnableModerationIfNeeded(pAC); ++ } ++ if (PrevModeration != C_INT_MOD_NONE) { ++ SkDimDisableModeration(pAC, PrevModeration); ++ if (Info->IntModTypeSelect != C_INT_MOD_NONE) { ++ SkDimEnableModerationIfNeeded(pAC); ++ } + } +- err: +- return ret ? -EIO : 0; ++ ++ return 0; + } + +-/* Only Yukon supports checksum offload. */ +-static int setScatterGather(struct net_device *dev, u32 data) ++ ++/***************************************************************************** ++ * ++ * SkGeSetSG - set the SG parameters ++ * ++ * Description: ++ * This function sets the SG parameters ++ * ++ * Returns: ++ * ==0: everything fine, no error ++ * !=0: the return value is the error code of the failure ++ */ ++int SkGeSetSG(struct net_device *dev, ++ u32 data) + { +- DEV_NET *pNet = netdev_priv(dev); +- SK_AC *pAC = pNet->pAC; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; + +- if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) ++ if (pAC->GIni.GIGenesis) + return -EOPNOTSUPP; ++ + return ethtool_op_set_sg(dev, data); + } + +-static int setTxCsum(struct net_device *dev, u32 data) ++ ++ ++ ++/***************************************************************************** ++ * ++ * SkGeSetTxCsum - set the TxCsum parameters ++ * ++ * Description: ++ * This function sets the TxCsum parameters ++ * ++ * Returns: ++ * ==0: everything fine, no error ++ * !=0: the return value is the error code of the failure ++ */ ++int SkGeSetTxCsum(struct net_device *dev, ++ u32 data) + { +- DEV_NET *pNet = netdev_priv(dev); +- SK_AC *pAC = pNet->pAC; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; + +- if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) ++ if (pAC->GIni.GIGenesis) + return -EOPNOTSUPP; + + return ethtool_op_set_tx_csum(dev, data); + } + +-static u32 getRxCsum(struct net_device *dev) ++ ++/***************************************************************************** ++ * ++ * SkGeSetRxCsum - set the SkGeSetRxCsum parameters ++ * ++ * Description: ++ * This function sets the RxCsum parameters ++ * ++ * Returns: ++ * ==0: everything fine, no error ++ * !=0: the return value is the error code of the failure ++ */ ++int SkGeSetRxCsum(struct net_device *dev, ++ u32 data) + { +- DEV_NET *pNet = netdev_priv(dev); +- SK_AC *pAC = pNet->pAC; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ int port = pNet->PortNr; ++ ++ if (pAC->GIni.GIGenesis && data) ++ return -EOPNOTSUPP; + +- return pAC->RxPort[pNet->PortNr].RxCsum; ++ pAC->RxPort[port].UseRxCsum = data; ++ return 0; + } + +-static int setRxCsum(struct net_device *dev, u32 data) ++/***************************************************************************** ++ * ++ * SkGePhysId - 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 ++ * ++ */ ++int SkGePhysId(struct net_device *dev, ++ u32 data) + { +- DEV_NET *pNet = netdev_priv(dev); +- SK_AC *pAC = pNet->pAC; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ SK_IOC IoC = pAC->IoBase; ++ int port = pNet->PortNr; ++ struct SK_NET_DEVICE *pDev = pAC->dev[port]; ++ int OtherPort = (port) ? 0 : 1; ++ struct SK_NET_DEVICE *pOtherDev = pAC->dev[OtherPort]; + +- if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) +- return -EOPNOTSUPP; ++ if (isLocateNICrunning) { ++ return -EFAULT; ++ } ++ isLocateNICrunning = SK_TRUE; ++ currentPortIndex = port; ++ isDualNetCard = (pDev != pOtherDev) ? SK_TRUE : SK_FALSE; ++ doSwitchLEDsOn = SK_FALSE; ++ ++ if (netif_running(pAC->dev[port])) { ++ boardWasDown[0] = SK_FALSE; ++ } else { ++ (*pDev->open)(pDev); ++ boardWasDown[0] = SK_TRUE; ++ } ++ ++ if (isDualNetCard) { ++ if (netif_running(pAC->dev[OtherPort])) { ++ boardWasDown[1] = SK_FALSE; ++ } else { ++ (*pOtherDev->open)(pOtherDev); ++ boardWasDown[1] = SK_TRUE; ++ } ++ } ++ ++ if ( (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) || ++ (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) ) { ++ SkMacClearRst(pAC, IoC, port); ++ } ++ ++ ++ if ((data < 1) || (data > 30)) { ++ data = 3; /* three seconds default */ ++ } ++ nbrBlinkQuarterSeconds = 4*data; ++ ++ init_timer(&locateNICtimer); ++ locateNICtimer.function = toggleLeds; ++ locateNICtimer.data = (unsigned long) pNet; ++ locateNICtimer.expires = jiffies + HZ; /* initially 1sec */ ++ add_timer(&locateNICtimer); + +- pAC->RxPort[pNet->PortNr].RxCsum = data != 0; + return 0; + } + +-static int getRegsLen(struct net_device *dev) ++/***************************************************************************** ++ * ++ * 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. 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 ++ * ++ */ ++static void toggleLeds( ++unsigned long ptr) /* holds the pointer to adapter control context */ ++{ ++ DEV_NET *pNet = (DEV_NET*) ptr; ++ SK_AC *pAC = pNet->pAC; ++ int port = pNet->PortNr; ++ SK_IOC IoC = pAC->IoBase; ++ struct SK_NET_DEVICE *pDev = pAC->dev[port]; ++ int OtherPort = (port) ? 0 : 1; ++ struct SK_NET_DEVICE *pOtherDev = pAC->dev[OtherPort]; ++ SK_U16 PageSelect; ++ SK_BOOL YukLedState; ++ ++ SK_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)); ++ SK_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) | ++ PHY_M_LED_MO_TX(MO_LED_OFF)); ++ ++ nbrBlinkQuarterSeconds--; ++ if (nbrBlinkQuarterSeconds <= 0) { ++ /* ++ * We have to stop the device again in case the device has no ++ * been up. ++ */ ++ ++ if (!boardWasDown[0]) { ++ /* ++ * The board is already up as we bring it up in case it is not. ++ */ ++ } else { ++ (*pDev->stop)(pDev); ++ } ++ if (isDualNetCard) { ++ if (!boardWasDown[1]) { ++ /* ++ * The board is already up as we bring it up in case it is not. ++ */ ++ } else { ++ (*pOtherDev->stop)(pOtherDev); ++ } ++ ++ } ++ ++ isDualNetCard = SK_FALSE; ++ isLocateNICrunning = SK_FALSE; ++ return; ++ } ++ doSwitchLEDsOn = (doSwitchLEDsOn) ? SK_FALSE : SK_TRUE; ++ ++ if (doSwitchLEDsOn) { ++ if (pAC->GIni.GIGenesis) { ++ SK_OUT8(IoC,MR_ADDR(port,LNK_LED_REG),(SK_U8)SK_LNK_ON); ++ SkGeYellowLED(pAC,IoC,LED_ON >> 1); ++ SkGeXmitLED(pAC,IoC,MR_ADDR(port,RX_LED_INI),SK_LED_TST); ++ if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM) { ++ SkXmPhyWrite(pAC,IoC,port,PHY_BCOM_P_EXT_CTRL,PHY_B_PEC_LED_ON); ++ } else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE) { ++ SkXmPhyWrite(pAC,IoC,port,PHY_LONE_LED_CFG,0x0800); ++ } else { ++ SkGeXmitLED(pAC,IoC,MR_ADDR(port,TX_LED_INI),SK_LED_TST); ++ } ++ } else { ++ if ( (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) || ++ (pAC->GIni.GIChipId == CHIP_ID_YUKON_2(pAC)) || ++ (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) ) { ++ ++ YukLedOn = 0; ++ YukLedState = 1; ++ YukLedOn |= PHY_M_LEDC_INIT_CTRL(YukLedState ? 9 : 8); ++ YukLedState = 1; ++ YukLedOn |= PHY_M_LEDC_STA1_CTRL(YukLedState ? 9 : 8); ++ YukLedState = 1; ++ YukLedOn |= PHY_M_LEDC_STA0_CTRL(YukLedState ? 9 : 8); ++ YukLedState = 1; ++ YukLedOn |= PHY_M_LEDC_LOS_CTRL(YukLedState ? 9 : 8); ++ ++ /* save page register */ ++ SkGmPhyRead(pAC, IoC, port, PHY_MARV_EXT_ADR, &PageSelect); ++ ++ /* select page 3 for LED control */ ++ SkGmPhyWrite(pAC, IoC, port, PHY_MARV_EXT_ADR, 3); ++ ++ SkGmPhyWrite(pAC, IoC, port, PHY_MARV_PHY_CTRL, YukLedOn); ++ ++ /* restore page register */ ++ SkGmPhyWrite(pAC, IoC, port, PHY_MARV_EXT_ADR, PageSelect); ++ } ++ else { ++ SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_OVER,YukLedOn); ++ } ++ } ++ } else { ++ if (pAC->GIni.GIGenesis) { ++ ++ SK_OUT8(IoC,MR_ADDR(port,LNK_LED_REG),(SK_U8)SK_LNK_OFF); ++ SkGeYellowLED(pAC,IoC,LED_OFF >> 1); ++ SkGeXmitLED(pAC,IoC,MR_ADDR(port,RX_LED_INI),SK_LED_DIS); ++ if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM) { ++ SkXmPhyWrite(pAC,IoC,port,PHY_BCOM_P_EXT_CTRL,PHY_B_PEC_LED_OFF); ++ } else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE) { ++ SkXmPhyWrite(pAC,IoC,port,PHY_LONE_LED_CFG,PHY_L_LC_LEDT); ++ } else { ++ SkGeXmitLED(pAC,IoC,MR_ADDR(port,TX_LED_INI),SK_LED_DIS); ++ } ++ } else { ++ if ( (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) || ++ (pAC->GIni.GIChipId == CHIP_ID_YUKON_2(pAC)) || ++ (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) ) { ++ ++ YukLedOn = 0; ++ YukLedState = 1; ++ YukLedOn |= PHY_M_LEDC_INIT_CTRL(YukLedState ? 9 : 8); ++ YukLedState = 1; ++ YukLedOn |= PHY_M_LEDC_STA1_CTRL(YukLedState ? 9 : 8); ++ YukLedState = 1; ++ YukLedOn |= PHY_M_LEDC_STA0_CTRL(YukLedState ? 9 : 8); ++ YukLedState = 1; ++ YukLedOn |= PHY_M_LEDC_LOS_CTRL(YukLedState ? 9 : 8); ++ ++ /* save page register */ ++ SkGmPhyRead(pAC, IoC, port, PHY_MARV_EXT_ADR, &PageSelect); ++ ++ /* select page 3 for LED control */ ++ SkGmPhyWrite(pAC, IoC, port, PHY_MARV_EXT_ADR, 3); ++ ++ SkGmPhyWrite(pAC, IoC, port, PHY_MARV_PHY_CTRL, YukLedOff); ++ ++ /* restore page register */ ++ SkGmPhyWrite(pAC, IoC, port, PHY_MARV_EXT_ADR, PageSelect); ++ } ++ else { ++ SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_OVER,YukLedOff); ++ } ++ } ++ } ++ ++ locateNICtimer.function = toggleLeds; ++ locateNICtimer.data = (unsigned long) pNet; ++ locateNICtimer.expires = jiffies + (HZ/4); ++ add_timer(&locateNICtimer); ++} ++ ++#ifdef NETIF_F_TSO ++/***************************************************************************** ++ * ++ * SkGeSetTSO - set the TSO parameters ++ * ++ * Description: ++ * This function sets the TSO parameters ++ * ++ * Returns: ++ * ==0: everything fine, no error ++ * !=0: the return value is the error code of the failure ++ */ ++int SkGeSetTSO(struct net_device *dev, ++ u32 data) + { +- return 0x4000; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ if (data) { ++ dev->features |= NETIF_F_TSO; ++ } else { ++ dev->features &= ~NETIF_F_TSO; ++ } ++ return 0; ++ } ++ return -EOPNOTSUPP; ++ + } ++#endif + +-/* +- * Returns copy of whole control register region +- * Note: skip RAM address register because accessing it will +- * cause bus hangs! +- */ +-static void getRegs(struct net_device *dev, struct ethtool_regs *regs, +- void *p) +-{ +- DEV_NET *pNet = netdev_priv(dev); +- const void __iomem *io = pNet->pAC->IoBase; +- +- regs->version = 1; +- memset(p, 0, regs->len); +- memcpy_fromio(p, io, B3_RAM_ADDR); +- +- memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1, +- regs->len - B3_RI_WTO_R1); +-} +- +-const 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, +- .get_link = ethtool_op_get_link, +- .get_perm_addr = ethtool_op_get_perm_addr, +- .get_sg = ethtool_op_get_sg, +- .set_sg = setScatterGather, +- .get_tx_csum = ethtool_op_get_tx_csum, +- .set_tx_csum = setTxCsum, +- .get_rx_csum = getRxCsum, +- .set_rx_csum = setRxCsum, +- .get_regs = getRegs, +- .get_regs_len = getRegsLen, +-}; ++ ++ ++ ++/******************************************************************************* ++ * ++ * End of file ++ * ++ ******************************************************************************/ +diff -ruN linux/drivers/net/sk98lin/skfops.c linux-new/drivers/net/sk98lin/skfops.c +--- linux/drivers/net/sk98lin/skfops.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/skfops.c 2007-01-24 14:03:40.000000000 +0100 +@@ -0,0 +1,273 @@ ++/****************************************************************************** ++ * ++ * Name: skfops.c ++ * Project: Gigabit Ethernet Adapters, Common Modules ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Kernel mode file read 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. ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * Description: ++ * ++ * This module is intended to handle all file read functions ++ * ++ * Include File Hierarchy: ++ * ++ * "h/skdrv1st.h" ++ * "h/skdrv2nd.h" ++ * ++ ******************************************************************************/ ++ ++/* ++ Event queue and dispatcher ++*/ ++#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) ++static const char SysKonnectFileId[] = ++"$Header$" ; ++#endif ++ ++#include "h/sktypes.h" ++#include "h/skdrv1st.h" ++#include "h/skdrv2nd.h" ++#include ++#include ++#include ++ ++ ++/******************************************************** ++ Local Variables ++********************************************************/ ++ ++ ++ ++/******************************************************** ++ Global Variables ++********************************************************/ ++ ++ ++ ++/******************************************************** ++ Local Functions ++********************************************************/ ++ ++/** ++ * @brief This function opens/create a file in kernel mode. ++ * ++ * @param filename Name of the file to be opened ++ * @param flags File flags ++ * @param mode File permissions ++ * @return file pointer if successful or NULL if failed. ++ */ ++static struct file * sk_fopen(const char * filename, ++ unsigned int flags, ++ int mode) ++{ ++ int orgfsuid, orgfsgid; ++ struct file * file_ret; ++ ++ /* Save uid and gid used for filesystem access. */ ++ orgfsuid = current->fsuid; ++ orgfsgid = current->fsgid; ++ ++ /* Set user and group to 0 (root) */ ++ current->fsuid = 0; ++ current->fsgid = 0; ++ ++ /* Open the file in kernel mode */ ++ file_ret = filp_open(filename, flags, mode); ++ ++ /* Restore the uid and gid */ ++ current->fsuid = orgfsuid; ++ current->fsgid = orgfsgid; ++ ++ /* Check if the file was opened successfully ++ and return the file pointer of it was. ++ */ ++ return ((IS_ERR(file_ret)) ? NULL : file_ret); ++} ++ ++ ++ ++/** ++ * @brief This function closes a file in kernel mode. ++ * ++ * @param file_ptr File pointer ++ * @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE ++ */ ++static int sk_fclose(struct file * file_ptr) ++{ ++ int orgfsuid, orgfsgid; ++ int file_ret; ++ ++ if((NULL == file_ptr) || (IS_ERR(file_ptr))) ++ return -ENOENT; ++ ++ /* Save uid and gid used for filesystem access. */ ++ orgfsuid = current->fsuid; ++ orgfsgid = current->fsgid; ++ ++ /* Set user and group to 0 (root) */ ++ current->fsuid = 0; ++ current->fsgid = 0; ++ ++ /* Close the file in kernel mode (user_id = 0) */ ++ file_ret = filp_close(file_ptr, 0); ++ ++ /* Restore the uid and gid */ ++ current->fsuid = orgfsuid; ++ current->fsgid = orgfsgid; ++ ++ return (file_ret); ++} ++ ++ ++ ++/** ++ * @brief This function reads data from files in kernel mode. ++ * ++ * @param file_ptr File pointer ++ * @param buf Buffers to read data into ++ * @param len Length of buffer ++ * @return number of characters read ++ */ ++static int sk_fread(struct file * file_ptr, char * buf, int len) ++{ ++ int orgfsuid, orgfsgid; ++ int file_ret; ++ mm_segment_t orgfs; ++ ++ /* Check if the file pointer is valid */ ++ if((NULL == file_ptr) || (IS_ERR(file_ptr))) ++ return -ENOENT; ++ ++ /* Check for a valid file read function */ ++ if(file_ptr->f_op->read == NULL) ++ return -ENOSYS; ++ ++ /* Check for access permissions */ ++ if(((file_ptr->f_flags & O_ACCMODE) & (O_RDONLY | O_RDWR)) == 0) ++ return -EACCES; ++ ++ /* Check if there is a valid length */ ++ if(0 >= len) ++ return -EINVAL; ++ ++ /* Save uid and gid used for filesystem access. */ ++ orgfsuid = current->fsuid; ++ orgfsgid = current->fsgid; ++ ++ /* Set user and group to 0 (root) */ ++ current->fsuid = 0; ++ current->fsgid = 0; ++ ++ /* Save FS register and set FS register to kernel ++ space, needed for read and write to accept ++ buffer in kernel space. */ ++ orgfs = get_fs(); ++ ++ /* Set the FS register to KERNEL mode. */ ++ set_fs(KERNEL_DS); ++ ++ /* Read the actual data from the file */ ++ file_ret = file_ptr->f_op->read(file_ptr, buf, len, &file_ptr->f_pos); ++ ++ /* Restore the FS register */ ++ set_fs(orgfs); ++ ++ /* Restore the uid and gid */ ++ current->fsuid = orgfsuid; ++ current->fsgid = orgfsgid; ++ ++ return (file_ret); ++} ++ ++ ++ ++/******************************************************** ++ Global Functions ++********************************************************/ ++ ++/** ++ * @brief This function reads FW/Helper. ++ * ++ * @param name File name ++ * @param addr Pointer to buffer storing FW/Helper ++ * @param len Pointer to length of FW/Helper ++ * @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE ++ */ ++SK_BOOL fw_read( SK_AC *pAC, /* Pointer to adapter context */ ++ char *name, SK_U8 **addr, SK_U32 *len ) ++{ ++ struct file *fp; ++ SK_BOOL ret; ++ SK_U8 *ptr; ++ ++ fp = sk_fopen(name, O_RDWR, 0 ); ++ ++ if ( fp == NULL ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("fw_read: Could not open file:%s\n", name)); ++ return SK_FALSE; ++ } ++ ++ /*calculate file length*/ ++ *len = fp->f_dentry->d_inode->i_size - fp->f_pos; ++ ++ ptr = (SK_U8 *)kmalloc( *len, GFP_KERNEL ); ++ ++ if ( ptr == NULL ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("fw_read: vmalloc failure!\n")); ++ return SK_FALSE; ++ } ++ if(sk_fread(fp, ptr,*len) > 0) { ++ *addr = ptr; ++ ret = SK_TRUE; ++ } else { ++ kfree(ptr); ++ *addr = NULL; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("fw_read: failed to read file:%s\n", name)); ++ ret = SK_FALSE; ++ } ++ ++ sk_fclose( fp ); ++ return ret; ++} ++ ++ ++/** ++ * @brief This function checks whether the file 'name' exists. ++ * ++ * @param name File name ++ * @return SK_TRUE or SK_FALSE ++ */ ++SK_BOOL fw_file_exists( SK_AC *pAC, /* Pointer to adapter context */ ++ char *name ) ++{ ++ struct file *fp; ++ ++ fp = sk_fopen(name, O_RDONLY | O_LARGEFILE, 0 ); ++ ++ if ( fp == NULL ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("fw_file_exists: Could not open file:%s\n", name)); ++ return SK_FALSE; ++ } ++ sk_fclose( fp ); ++ return SK_TRUE; ++} ++ +diff -ruN linux/drivers/net/sk98lin/skgeasf.c linux-new/drivers/net/sk98lin/skgeasf.c +--- linux/drivers/net/sk98lin/skgeasf.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/skgeasf.c 2007-01-24 13:58:33.000000000 +0100 +@@ -0,0 +1,5434 @@ ++/****************************************************************************** ++ * ++ * Name: skgeasf.c ++ * Project: Gigabit Ethernet Adapters, Common Modules ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: ASF Handler. ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * (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 handle all the asf functions ++ * ++ * Include File Hierarchy: ++ * ++ * "h/skdrv1st.h" ++ * "h/skdrv2nd.h" ++ * ++ ******************************************************************************/ ++ ++/* ++ Event queue and dispatcher ++*/ ++#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) ++static const char SysKonnectFileId[] = ++"$Header$" ; ++#endif ++ ++#define __SKASF_C ++ ++#ifdef __cplusplus ++extern "C" { ++#endif /* cplusplus */ ++ ++ ++// #include ++// #include ++ ++ ++#include "h/sktypes.h" ++#include "h/skdrv1st.h" ++#include "h/skdrv2nd.h" ++#include "h/skgeasf.h" ++#include "h/skgespi.h" ++#include "h/skfops.h" ++#include ++ ++//#include "h/yuk.h" ++//#include "h/skvpd.h" ++ ++//#include ++ ++static char *AsfFileName = "/etc/sk98lin/AcpiAsf.bin"; ++static char *IpmiFileNameS1 = "/etc/sk98lin/ipmiyk2-s1.bin"; ++static char *IpmiFileNameS2 = "/etc/sk98lin/ipmiyk2-s2.bin"; ++// static char *SimuAsfTab = "/etc/sk98lin/AcpiAsf.bin"; ++ ++// ARP pattern 40 byte (5 bytes in mask) ++// this pattern length corresponds with YLCI_MACRXFIFOTHRES ++// Pattern mask for ARP Frames ++#ifdef ASF_ONLY_ARP_REQUEST ++static SK_U8 ARP_FRAME_PATTERN[] = ++{ ++ /* MAC Header - 14 bytes */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*Dest MAC Addr */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*Src MAC Addr */ ++ 0x08, 0x06, /*Frame Type */ ++ /* ARP Header - 28 bytes */ ++ 0x00, 0x01, /* hard type */ ++ 0x08, 0x00, /* prot type */ ++ 0x06, /* hard size */ ++ 0x04, /* prot size */ ++ 0x00, 0x01, /* op = request */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* senders mac */ ++ 0x00, 0x00, 0x00, 0x00, /* senders ip */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* target mac */ ++ 0x00, 0x00}; ++static SK_U8 ARP_PATTERN_MASK[] = { 0x00, 0xF0, 0x3F, 0x00, 0x00 }; ++#else ++static SK_U8 ARP_FRAME_PATTERN[] = ++{ ++ /* MAC Header - 14 bytes */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*Dest MAC Addr */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*Src MAC Addr */ ++ 0x08, 0x06, /*Frame Type */ ++ /* ARP Header - 28 bytes */ ++ 0x00, 0x01, /* hard type */ ++ 0x08, 0x00, /* prot type */ ++ 0x06, /* hard size */ ++ 0x04, /* prot size */ ++ 0x00, 0x00, /* op = request */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* senders mac */ ++ 0x00, 0x00, 0x00, 0x00, /* senders ip */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* target mac */ ++ 0x00, 0x00}; ++static SK_U8 ARP_PATTERN_MASK[] = { 0x00, 0xF0, 0x00, 0x00, 0x00 }; ++#endif ++ ++// RSP pattern - 40 bytes (this makes 5 bytes in RSP_PATTERN_MASK) ++// this pattern length corresponds with YLCI_MACRXFIFOTHRES ++static SK_U8 RSP_FRAME_PATTERN[] = ++{ /* MAC Header (14 bytes) */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*Dest MAC Addr*/ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*Src MAC Addr */ ++ 0x08, 0x00, /*Frame Type */ ++ /* IP Header (20 bytes) */ ++ 0x45, 0x00, 0x00, 0x00, /* Version & Header Length */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x11, 0x00, 0x00, /* Protocol */ ++ 0x00, 0x00, 0x00, 0x00, /*Src IP address*/ ++ 0x00, 0x00, 0x00, 0x00, /*My IP address*/ ++ /* part of UDP Header (6 bytes) */ ++ 0x00, 0x00, /* src port */ ++ 0x02, 0x98, /* dest. port */ ++ 0x00, 0x00}; /* length */ ++ ++// Pattern mask for RSP Frames ++static SK_U8 RSP_PATTERN_MASK[] = { 0x00, 0x70, 0x80, 0x00, 0x30 }; ++ ++// RMCP pattern (unsecure port) ++// this pattern length corresponds with YLCI_MACRXFIFOTHRES ++static SK_U8 RMCP_FRAME_PATTERN[] = ++{ /* MAC Header */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*Dest MAC Addr*/ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*Src MAC Addr */ ++ 0x08, 0x00, /*Frame Type */ ++ /* IP Header */ ++ 0x45, 0x00, 0x00, 0x00, /* Version & Header Length */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x11, 0x00, 0x00, /* Protocol */ ++ 0x00, 0x00, 0x00, 0x00, /*Src IP address*/ ++ 0x00, 0x00, 0x00, 0x00, /*My IP address*/ ++ /* UDP Header */ ++ 0x00, 0x00, /* src port */ ++ 0x02, 0x6f, /* unsecure dest. port */ ++ 0x00, 0x00}; ++ ++// Pattern mask for RMCP Frames ++static SK_U8 RMCP_PATTERN_MASK[] = { 0x00, 0x70, 0x80, 0x00, 0x30 }; ++ ++ ++/***************************************************************************** ++* ++* SkAsfRestorePattern - interface function (global symbol) ++* ++* Description: ++* restores pattern for ASF and IPMI ++* ++* Returns: ++* Always 0 ++*/ ++ ++int SkAsfRestorePattern ( ++ SK_AC *pAC , /* Pointer to adapter context */ ++ SK_IOC IoC) /* IO context handle */ ++{ ++ if (pAC->AsfData.OpMode == SK_GEASF_MODE_ASF) { ++ ++ // asf mode -> we are running on ++ // yukon ec with only one port ++ AsfSetUpPattern(pAC, IoC, 0); ++ ++ } else { ++ if (pAC->AsfData.OpMode == SK_GEASF_MODE_IPMI) { ++ // ipmi mode -> we are running on ++ // yukon 2 with at least one port ++ AsfSetUpPattern(pAC, IoC, 0); // port A ++ ++ if (pAC->AsfData.DualMode == SK_GEASF_Y2_DUALPORT) { ++ AsfSetUpPattern(pAC, IoC, 1); // port B ++ } ++ } ++ } ++ ++ return (SK_ASF_PNMI_ERR_OK); ++} ++ ++/***************************************************************************** ++* ++* SkAsfInit - Init function of ASF ++* ++* Description: ++* SK_INIT_DATA: Initialises the data structures ++* SK_INIT_IO: Resets the XMAC statistics, determines the device and ++* connector type. ++* SK_INIT_RUN: Starts a timer event for port switch per hour ++* calculation. ++* ++* Returns: ++* Always 0 ++*/ ++int SkAsfInit( ++ SK_AC *pAC, /* Pointer to adapter context */ ++ SK_IOC IoC, /* IO context handle */ ++ int Level) /* Initialization level */ ++{ ++ SK_U32 TmpVal32; ++ SK_U32 FlashOffset = 0; ++ SK_U32 i; ++ ++ SK_U32 FileLengthS1; ++ SK_U32 FileLengthS2; ++ char *FwFileNameS1 = NULL; ++ char *FwFileNameS2 = NULL; ++ SK_U8 *pAsfFwS1 = NULL; ++ SK_U8 *pAsfFwS2 = NULL; ++ ++ SK_U8 FlashOk; ++ int RetCode; ++ SK_BOOL DoUpdate = SK_FALSE; ++ SK_U8 lRetCode; ++ SK_U32 FwImageCsOk; ++ SK_U32 FwFlashCsOk; ++ SK_U32 FwImageCs = 0; ++ SK_U32 FwFlashCs = 0; ++ SK_U32 FwCs; ++ SK_U32 *pTmp32; ++ SK_U8 *pHciRecBuf; ++ SK_EVPARA EventParam; /* Event struct for timer event */ ++ unsigned long FlashSize; ++ unsigned long EraseOff = 0; ++ SK_U32 SpiRetVal; ++ SK_U8 Tmp1Val8, Tmp2Val8; ++ SK_BOOL YukonEcA1; ++ SK_U8 OldGuid[16]; ++ SK_U8 AsfFlag = 0, IpmiFlag = 0; ++ SK_U8 AsfHintBit = 0, IpmiHintBit = 0, NoHintBit = 0; ++ ++ RetCode = SK_ASF_PNMI_ERR_OK; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ++ ("ASF: SkAsfInit: Called, level=%d sizof ASF-MIB:0x%x Bytes\n", Level, sizeof(STR_ASF_MIB) ) ); ++ ++ /* YukonEcA1 introduced by rschmidt */ ++ YukonEcA1 = (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC && pAC->GIni.GIChipRev == CHIP_REV_YU_EC_A1); ++ ++ switch(Level) ++ { ++ case SK_INIT_DATA: ++ /* Set structure to zero */ ++ // This will be done in function "AsfReadConfiguration" ++ // SK_MEMSET((char *)&pAC->AsfData, 0, sizeof(pAC->AsfData)); ++ ++ pAC->AsfData.ActivePort = 0; ++ pAC->AsfData.OpMode = SK_GEASF_MODE_IPMI; ++ pAC->AsfData.ChipMode = SK_GEASF_CHIP_UNKNOWN; ++ ++ pAC->AsfData.InitState = ASF_INIT_UNDEFINED; ++ break; ++ ++ case SK_INIT_IO: ++ /* Set OS Present Flag in ASF Status and Command Register */ ++#if (0) ++ SK_IN32( IoC, REG_ASF_STATUS_CMD, &TmpVal32 ); ++ TmpVal32 |= BIT_4; ++ SK_OUT32( IoC, REG_ASF_STATUS_CMD, TmpVal32 ); ++#endif ++ ++#ifdef ASF_CHECK_HIDDEN_ID // here we will check hidden id _and_ chip id ++ ++ /* check chip id */ ++ SK_IN8( IoC, B2_CHIP_ID, &Tmp1Val8 ); ++ switch(Tmp1Val8) ++ { ++ case CHIP_ID_YUKON_EC: ++ /* YUKON_EC */ ++ /* chip-id is ok, check hidden id */ ++ SK_IN8( IoC, B2_MAC_CFG, &Tmp2Val8 ); ++ Tmp2Val8 &= 0x03; ++ if( (Tmp2Val8 != 1) && // 88E8052 ++ (Tmp2Val8 != 3) ) { // 88E8050 ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ } else { ++ pAC->AsfData.ChipMode = SK_GEASF_CHIP_EC; ++ } ++ break; ++ case CHIP_ID_YUKON_XL: ++ /* YUKON_2 */ ++ /* chip-id is ok, check hidden id */ ++ SK_IN8( IoC, B2_MAC_CFG, &Tmp2Val8 ); ++ Tmp2Val8 &= 0x03; ++ if(Tmp2Val8 != 0) { ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ } else { ++ pAC->AsfData.ChipMode = SK_GEASF_CHIP_Y2; ++ } ++ break; ++ default: ++ /* Nothing to do. Chip id does not match */ ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ break; ++ } ++ ++ if (RetCode != SK_ASF_PNMI_ERR_OK) { ++ ++ pAC->AsfData.InitState = ASF_INIT_ERROR_CHIP_ID; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** ASF/IPMI NOT SUPPORTED ***\n")); ++ ++ /* hidden ID doesn't match (which card do we access?) ++ // do not set any registers ++ ++ AsfDisable(pAC, IoC); ++ ++ AsfResetCpu(IoC); // reset cpu ++ ++ // disable all pattern for asf/ipmi ++ YlciDisablePattern(pAC, IoC, 0, 4); ++ YlciDisablePattern(pAC, IoC, 0, 5); ++ YlciDisablePattern(pAC, IoC, 0, 6); ++ ++ if ( (CHIP_ID_YUKON_2(pAC)) && (pAC->GIni.GIMacsFound == 2) ) { ++ // do not forget the second link ++ // disable all pattern for asf/ipmi ++ YlciDisablePattern(pAC, IoC, 1, 4); ++ YlciDisablePattern(pAC, IoC, 1, 5); ++ YlciDisablePattern(pAC, IoC, 1, 6); ++ } ++ */ ++ break; ++ } ++ ++#endif ++ /* CHECK the ASF hint bits... ++ * all YukonII: ++ * Application Information Register auf 0x011e, Bit 7:6 ++ * ++ * Kodierung: ++ * 0b00 kein "hint"; jetziger Zustand ++ * 0b01 customer wants ASF to be loaded ++ * 0b10 customer wants IPMI to be loaded ++ * 0b11 customer does not want ASF or IPMI to go in here ++ * ++ * Alle bisherigen EEPROM Versionen bringen 0b00. ++ */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** CHECK ASF hint bits ***\n")); ++ SK_IN32(IoC, B2_Y2_HW_RES, &TmpVal32); ++ switch(TmpVal32 & 0xc0) { ++ case 0xc0: ++ AsfHintBit = 0; ++ IpmiHintBit = 0; ++ NoHintBit = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** ASF hint bits: NO ASF/IPMI ***\n")); ++ break; ++ case 0x40: ++ AsfHintBit = 1; ++ IpmiHintBit = 0; ++ NoHintBit = 0; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** ASF hint bits: ASF ***\n")); ++ break; ++ case 0x80: ++ AsfHintBit = 0; ++ IpmiHintBit = 1; ++ NoHintBit = 0; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** ASF hint bits: IPMI ***\n")); ++ break; ++ default: ++ AsfHintBit = 0; ++ IpmiHintBit = 0; ++ NoHintBit = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** ASF hint bits: Default ASF/IPMI ***\n")); ++ break; ++ } ++ ++ /* here we do not know which firmware we must load (ipmi or asf)... */ ++ pAC->AsfData.OpMode = SK_GEASF_MODE_UNKNOWN; ++ AsfFlag = 0; ++ IpmiFlag = 0; ++ ++ /* try to open the ASF binary */ ++ if ( fw_file_exists(pAC, AsfFileName) ) { ++ /* here we have found the asf binary */ ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** ASF binary file found...\n")); ++ AsfFlag = 1; ++ FwFileNameS1 = AsfFileName; ++ FwFileNameS2 = NULL; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("*** AsfFlag = 1 ***\n")); ++ } else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** ASF binary file _NOT_ found!\n")); ++ } ++ ++ /* try to open IPMI binary */ ++ if ( fw_file_exists(pAC, IpmiFileNameS1) && ++ fw_file_exists(pAC, IpmiFileNameS2) ) { ++ /* here we have found the ipmi binary */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** IPMI binary file found...\n")); ++ IpmiFlag = 1; ++ FwFileNameS1 = IpmiFileNameS1; ++ FwFileNameS2 = IpmiFileNameS2; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("*** IpmiFlag = 1 ***\n")); ++ } else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** IPMI binary file _NOT_ found!\n")); ++ } ++ ++ /* set the operation mode */ ++ if ( (AsfFlag == 1) && ( (AsfHintBit == 1) && (IpmiHintBit == 0) && (NoHintBit == 0) ) ) { ++ /* we are in the ASF mode */ ++ if ( (pAC->AsfData.ChipMode == SK_GEASF_CHIP_EC) || ++ (pAC->AsfData.ChipMode == SK_GEASF_CHIP_Y2) ) { ++ /* ASF can run on YukonEC and Yukon2 */ ++ pAC->AsfData.OpMode = SK_GEASF_MODE_ASF; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** SK_GEASF_MODE_ASF ***\n")); ++ YlciDisablePattern(pAC, IoC, 0, 5); // Disable ARP pattern, OS is now responsible for ARP handling ++ } ++ } else { ++ /* are we in the ipmi mode ? */ ++ if ( (IpmiFlag == 1) && ( (IpmiHintBit == 1) && (AsfHintBit == 0) && (NoHintBit == 0) ) ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("*** Ipmi bits OK - ChipMode: %x ***\n", pAC->AsfData.ChipMode)); ++ if (pAC->AsfData.ChipMode == SK_GEASF_CHIP_Y2) { ++ /* IPMI can run only on Yukon2 */ ++ pAC->AsfData.OpMode = SK_GEASF_MODE_IPMI; ++ ++ /* set ASF enable bit in general register (0x0004) ++ * and set the AsfEnable byte in pAC structure ++ * (pAC->GIni.GIAsfEnabled = SK_TRUE) ++ */ ++ AsfEnable(pAC, IoC); ++ ++ /* check if we have a dual port adapter */ ++ if ( (CHIP_ID_YUKON_2(pAC)) && (pAC->GIni.GIMacsFound == 2) ) { ++ pAC->AsfData.DualMode = SK_GEASF_Y2_DUALPORT; ++ } else { ++ pAC->AsfData.DualMode = SK_GEASF_Y2_SINGLEPORT; ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ++ ("SkAsfInit: *** SK_GEASF_MODE_IPMI (%d) ***\n", pAC->AsfData.DualMode)); ++ ++#if 0 ++ /* Disable ARP pattern, OS is now responsible for ARP handling */ ++ YlciDisablePattern(pAC, IoC, 0, 5); ++ // AsfSetUpPattern(pAC, IoC, 0); ++ ++ if (pAC->AsfData.DualMode == SK_GEASF_Y2_DUALPORT) { ++ /* Disable ARP pattern, OS is now responsible for ARP handling */ ++ YlciDisablePattern(pAC, IoC, 1, 5); ++ // AsfSetUpPattern(pAC, IoC, 1); ++ } ++#endif ++ } ++ } ++ } ++ ++ if (pAC->AsfData.OpMode == SK_GEASF_MODE_UNKNOWN) { ++ if( (pAC->AsfData.ChipMode == SK_GEASF_CHIP_EC) && (AsfFlag == 1) && (NoHintBit == 1) ) { ++ /* ASF can run on YukonEC without hint bits */ ++ pAC->AsfData.OpMode = SK_GEASF_MODE_ASF; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** SK_GEASF_MODE_ASF EC ***\n")); ++ YlciDisablePattern(pAC, IoC, 0, 5); // Disable ARP pattern, OS is now responsible for ARP handling ++ } else { ++ /* error - we could not find our operation mode! */ ++ pAC->AsfData.InitState = ASF_INIT_ERROR_OPMODE; ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfInit: *** ASF/IPMI UNKNOWN OPMODE ***\n")); ++ ++ AsfDisable(pAC, IoC); // disable pattern matching for ASF/IPMI ++ ++ AsfResetCpu(IoC); // reset cpu ++ ++ /* disable all pattern for asf/ipmi */ ++ YlciDisablePattern(pAC, IoC, 0, 4); ++ YlciDisablePattern(pAC, IoC, 0, 5); ++ YlciDisablePattern(pAC, IoC, 0, 6); ++ ++ if ( (CHIP_ID_YUKON_2(pAC)) && (pAC->GIni.GIMacsFound == 2) ) { ++ /* do not forget the second link ++ * disable all pattern for asf/ipmi ++ */ ++ YlciDisablePattern(pAC, IoC, 1, 4); ++ YlciDisablePattern(pAC, IoC, 1, 5); ++ YlciDisablePattern(pAC, IoC, 1, 6); ++ } ++ break; // leave "case SK_INIT_IO" ++ } ++ } ++ ++ /* Send CheckAlive command to CPU */ ++ if ( ((pAC->AsfData.OpMode == SK_GEASF_MODE_ASF) || ++ (pAC->AsfData.OpMode == SK_GEASF_MODE_IPMI)) && ++ (RetCode == SK_ASF_PNMI_ERR_OK) ) { ++ ++ if( AsfCheckAliveCpu( pAC, IoC ) != 1 ) { // Not alive ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" ******************************\n")); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfInit: * CPU is NOT running ! *\n")); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" ******************************\n")); ++ pAC->AsfData.CpuAlive = 0; ++ } else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" ******************************\n")); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfInit: * CPU is running *\n")); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" ******************************\n")); ++ pAC->AsfData.CpuAlive = 1; ++ } ++ } ++ ++ /* START FLASH PROC */ ++ /* Try to open the FW image file */ ++ if (fw_read(pAC,FwFileNameS1,&pAsfFwS1,&FileLengthS1) && ++ fw_read(pAC,FwFileNameS2,&pAsfFwS2,&FileLengthS2)) { ++ /* Set the flash offset to 128k */ ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Flash files opened:\n")); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" %s: size: 0x%d offs:0x%x\n", FwFileNameS1, FileLengthS1, FlashOffset)); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" %s: size: 0x%d offs:0x%x\n", FwFileNameS2, FileLengthS2, FlashOffset)); ++ ++ /* calculate CS of the FW image */ ++ pTmp32 = (SK_U32 *) pAsfFwS1; ++ for( i=0, FwCs=0; i O.K. ++ FwImageCsOk = 1; ++ FwImageCs = *(pTmp32 - 1); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" FW Image Checksum O.K. \n")); ++ } else { ++ FwImageCsOk = 0; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error: FW Image Checksum:0x%x\n", FwCs)); ++ } ++ ++ pAC->AsfData.DriverVersion[0] = 'v'; ++ pAC->AsfData.DriverVersion[1] = '1'; ++ pAC->AsfData.DriverVersion[2] = '.'; ++ pAC->AsfData.DriverVersion[3] = '1'; ++ pAC->AsfData.DriverVersion[4] = '0'; ++ ++ for( i=0; i<5; i++ ) ++ pAC->AsfData.FileFwVersion[i] = *(pAsfFwS2 + ASF_FLASH_OFFS_VER - 65536 + i); ++ ++ pAC->AsfData.FileFwRev = *(pAsfFwS2 + ASF_FLASH_OFFS_REV - 65536); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" FW Image:%c%c%c%c %c Driver:%c%c%c%c\n", ++ pAC->AsfData.FileFwVersion[1], pAC->AsfData.FileFwVersion[2], ++ pAC->AsfData.FileFwVersion[3], pAC->AsfData.FileFwVersion[4], ++ pAC->AsfData.FileFwRev, ++ pAC->AsfData.DriverVersion[1], pAC->AsfData.DriverVersion[2], ++ pAC->AsfData.DriverVersion[3], pAC->AsfData.DriverVersion[4] )); ++ ++ ++ /* check, whether the FW file version suits the driver version */ ++ if( (pAC->AsfData.FileFwVersion[1] == pAC->AsfData.DriverVersion[1]) && ++ (pAC->AsfData.FileFwVersion[3] == pAC->AsfData.DriverVersion[3]) && ++ (pAC->AsfData.FileFwVersion[4] == pAC->AsfData.DriverVersion[4]) && ++ (FwImageCsOk == 1) ) { ++ ++ /* read the flash (upper 128k) */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" FW suits the driver´s version\n")); ++ ++ if (YukonEcA1) { // was if (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_A1) before ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Chip Rev. A1 -> Do reset !!\n")); ++ ++ ++ // TMP_OU ++ AsfResetCpu(IoC); ++ // AsfSmartResetCpu( pAC, IoC, ASF_RESET_HOT ); // fixed in A2 ++ } else { ++ /* ++ * just in case the FW is not running !! ++ * (shouldn´t happen with A2 and later versions) ++ */ ++ if( !pAC->AsfData.CpuAlive ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** FW is not running !! *** \n")); ++ // TMP_OU ++ AsfResetCpu(IoC); ++ // AsfSmartResetCpu( pAC, IoC, ASF_RESET_HOT ); ++ // AsfRunCpu( IoC ); ++ } ++ } ++ ++ if (!YukonEcA1) { ++ SK_OUT8(IoC, GPHY_CTRL + 2, 1); // Lock the SPI access ++ } ++ ++ spi_init_pac( pAC ); ++ flash_check_spi( &FlashSize ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Flash found with size of %d\n", FlashSize)); ++ /* Read flash low pages */ ++ SpiRetVal = spi_flash_manage( pAC->AsfData.FlashBuffer, ASF_FLASH_OFFS, ASF_FLASH_SIZE, SPI_READ ); ++ ++ if( SpiRetVal == 0 ) { ++ /* calculate CS of the FW flash */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Flash low pages loaded. Calculate the CS of the FW flash.\n")); ++ ++ pTmp32 = (SK_U32 *) pAC->AsfData.FlashBuffer; ++ for( i=0, FwCs=0; iAsfData.FlashBuffer, ASF_FLASH_OFFS + 65536, ASF_FLASH_SIZE, SPI_READ ); ++ ++ if (!YukonEcA1) { ++ SK_OUT8(IoC, GPHY_CTRL + 2, 0); // Unlock the SPI access ++ } ++ ++ if (( SpiRetVal == 0 ) && (!RetCode)) { ++ /* calculate CS of the FW flash */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Flash high pages loaded. Calculate the CS of the FW flash.\n")); ++ ++ pTmp32 = (SK_U32 *) pAC->AsfData.FlashBuffer; ++ for( i=0; i O.K. ++ FwFlashCsOk = 1; ++ FwFlashCs = *(pTmp32 - 1); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" FW Flash Checksum O.K. \n")); ++ } else { ++ FwFlashCsOk = 0; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error: FW Flash Checksum:0x%x\n", FwCs)); ++ } ++ ++ ++ /* read the FW flash version/rev */ ++ for( i=0; i<5; i++ ) { ++ pAC->AsfData.FlashFwVersion[i] = pAC->AsfData.FlashBuffer[ASF_FLASH_OFFS_VER - 65536 + i]; ++ } ++ ++ pAC->AsfData.FlashFwRev = pAC->AsfData.FlashBuffer[ASF_FLASH_OFFS_REV - 65536 ]; ++ ++ /* read the GUID from flash */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** GUID ***\n")); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" ")); ++ for( i=0; i<16; i++ ) { ++ pAC->AsfData.Mib.Guid[i] = pAC->AsfData.FlashBuffer[ASF_FLASH_OFFS_GUID - 65536 +i]; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("%x ", pAC->AsfData.Mib.Guid[i])); ++ OldGuid[i] = pAC->AsfData.FlashBuffer[ASF_FLASH_OFFS_GUID - 65536 +i]; ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n")); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" FW Flash:>>%c%c%c%c %c<<\n", ++ pAC->AsfData.FlashFwVersion[1], pAC->AsfData.FlashFwVersion[2], ++ pAC->AsfData.FlashFwVersion[3], pAC->AsfData.FlashFwVersion[4], ++ pAC->AsfData.FlashFwRev )); ++ ++ ++ /* check the FW version/rev and update the flash if necessary */ ++ if( (pAC->AsfData.FlashFwVersion[1] != pAC->AsfData.DriverVersion[1]) || ++ (pAC->AsfData.FlashFwVersion[3] != pAC->AsfData.DriverVersion[3]) || ++ (pAC->AsfData.FlashFwVersion[4] != pAC->AsfData.DriverVersion[4]) || ++ (pAC->AsfData.FlashFwRev != pAC->AsfData.FileFwRev) || ++ (pAC->AsfData.FileFwRev == 'x') || // Rev == 'x' means: do allways a flash update ! (for test purposes) ++ (FwFlashCsOk != 1)) // Checksum error in flash ++ { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Updating flash\n")); ++ // AsfResetCpu( IoC ); ++ for( i=0; iAsfData.FlashBuffer[i] = *(pAsfFwS1 + FlashOffset + i); ++ ++ /* flash erase, determine flash size and select area to be erased */ ++ switch (FlashSize) { ++ case ASF_FLASH_SIZE * 4: /* 256 kB */ ++ EraseOff = ASF_FLASH_OFFS; ++ break; ++ case ASF_FLASH_SIZE * 2: /* 128 kB */ ++ EraseOff = 0; ++ break; ++ default: /* unsupported */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Unsupported Flash Size: %lu\n", FlashSize )); ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ break; ++ } ++ if (!RetCode) ++ DoUpdate = SK_TRUE; ++ } else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Flash is up to date\n")); ++ } ++ ++ ++ if (DoUpdate) { ++ printk("sk98lin: Starting the flash process\n"); ++ ++ if (spi_flash_erase( EraseOff, ASF_FLASH_SIZE * 2) == 0 ) { ++ /* ++ * Handle sector 1 ++ * (first flash file) ++ */ ++ /* write sector 1 buffer to flash and check the buffer */ ++ if (spi_flash_manage( pAC->AsfData.FlashBuffer, ASF_FLASH_OFFS, ASF_FLASH_SIZE, SPI_WRITE ) == 0 ) { ++ /* read buffer back */ ++ if( spi_flash_manage( pAC->AsfData.FlashBuffer, ASF_FLASH_OFFS, ASF_FLASH_SIZE, SPI_READ ) == 0 ) { ++ /* compare buffer with content of flash image file */ ++ for( i=0,FlashOk=1; iAsfData.FlashBuffer[i] != *(pAsfFwS1 + FlashOffset + i) ) ++ FlashOk = 0; ++ } ++ ++ if( FlashOk ) { ++ /* read the GUID from flash */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Flash successfully updated (Sector1)\n")); ++ } else { ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error: compare flash content (Sector1)\n")); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_ASF_E007, SKERR_ASF_E007MSG); ++ } ++ } else { ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error: Flash reread (Sector1)\n")); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_ASF_E006, SKERR_ASF_E006MSG); ++ } ++ } else { ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error: Flash write (Sector1)\n")); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_ASF_E004, SKERR_ASF_E004MSG); ++ } ++ ++ ++ /* ++ * Handle sector 2 ++ * (second flash file) ++ */ ++ FlashOk = 1; ++ for( i=0; iAsfData.FlashBuffer[i] = *(pAsfFwS2 + FlashOffset + i); ++ ++ /* write sector 2 buffer to flash and check the buffer */ ++ if (spi_flash_manage( pAC->AsfData.FlashBuffer, ASF_FLASH_OFFS + 65536, ASF_FLASH_SIZE, SPI_WRITE ) == 0 ) { ++ /* read buffer back */ ++ if( spi_flash_manage( pAC->AsfData.FlashBuffer, ASF_FLASH_OFFS + 65536, ASF_FLASH_SIZE, SPI_READ ) == 0 ) { ++ /* compare buffer with content of flash image file */ ++ for( i=0,FlashOk=1; iAsfData.FlashBuffer[i] != *(pAsfFwS2 + FlashOffset + i) ) ++ FlashOk = 0; ++ } ++ ++ if( FlashOk ) { ++ /* read the GUID from flash */ ++ for( i=0; i<16; i++ ) ++ pAC->AsfData.Mib.Guid[i] = pAC->AsfData.FlashBuffer[ASF_FLASH_OFFS_GUID - 65536 +i]; ++ ++ /* check if new GUID */ ++ for( i=0; i<16; i++) { ++ if(OldGuid[i] != pAC->AsfData.Mib.Guid[i]) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** NEW GUID (%x)***\n", pAC->AsfData.Mib.Guid[i])); ++ pAC->AsfData.NewGuid = 1; ++ break; ++ } ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Flash successfully updated (Sector2)\n")); ++ } else { ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error: compare flash content (Sector2)\n")); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_ASF_E007, SKERR_ASF_E007MSG); ++ } ++ } else { ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error: Flash reread (Sector2)\n")); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_ASF_E006, SKERR_ASF_E006MSG); ++ } ++ } else { ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error: Flash write (Sector2)\n")); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_ASF_E004, SKERR_ASF_E004MSG); ++ } ++ } else { ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error: Flash erase\n")); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_ASF_E003, SKERR_ASF_E003MSG); ++ } ++ /* write pattern etc. */ ++ if (pAC->AsfData.OpMode == SK_GEASF_MODE_IPMI) { ++ /* ipmi on yukon2 */ ++ AsfSetUpPattern(pAC, IoC, 0); ++ if (pAC->AsfData.DualMode == SK_GEASF_Y2_DUALPORT) { ++ AsfSetUpPattern(pAC, IoC, 1); ++ } ++ } ++ ++ /* run cpu */ ++ AsfRunCpu( IoC ); ++ } /* if DoUpdate */ ++ } else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error: SPI read\n")); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_ASF_E002, SKERR_ASF_E002MSG); ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ } ++ } ++ ++ /* Clear the buffer */ ++ if (pAsfFwS1 != NULL) ++ kfree(pAsfFwS1); ++ if (pAsfFwS2 != NULL) ++ kfree(pAsfFwS2); ++ } ++ ++ break; ++ ++ case SK_INIT_RUN: ++ if( pAC->AsfData.InitState != ASF_INIT_UNDEFINED ) ++ break; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfInit: SK_INIT_RUN\n")); ++ ++ YlciDisablePattern(pAC, IoC, 0, 5); // Disable ARP pattern, OS is now responsible for ARP handling ++ ++ if (pAC->AsfData.DualMode == SK_GEASF_Y2_DUALPORT) { ++ YlciDisablePattern(pAC, IoC, 1, 5); // Disable ARP pattern, OS is now responsible for ARP handling ++ } ++ ++ /* write pattern etc. */ ++ if (pAC->AsfData.OpMode == SK_GEASF_MODE_IPMI) { ++ // ipmi on yukon2 ++ AsfSetUpPattern(pAC, IoC, 0); ++ if (pAC->AsfData.DualMode == SK_GEASF_Y2_DUALPORT) { ++ AsfSetUpPattern(pAC, IoC, 1); ++ } ++ } ++ ++ ++ if( !pAC->AsfData.CpuAlive ) { ++ AsfResetCpu(IoC); ++ AsfRunCpu( IoC ); ++ } ++ ++ /* ASF MIB parameter to default values */ ++ pAC->AsfData.Mib.WdTimeMax = ASF_DEF_WATCHDOG_TIME_MAX; ++ pAC->AsfData.Mib.WdTimeMin = ASF_DEF_WATCHDOG_TIME_MIN; ++ pAC->AsfData.Mib.RetransCountMin = ASF_DEF_RETRANS_COUNT_MIN; ++ pAC->AsfData.Mib.RetransCountMax = ASF_DEF_RETRANS_COUNT_MAX; ++ pAC->AsfData.Mib.RetransIntMin = ASF_DEF_RETRANS_INT_MIN; ++ pAC->AsfData.Mib.RetransIntMax = ASF_DEF_RETRANS_INT_MAX; ++ pAC->AsfData.Mib.HbIntMin = ASF_DEF_HB_INT_MIN; ++ pAC->AsfData.Mib.HbIntMax = ASF_DEF_HB_INT_MAX; ++ pAC->AsfData.Mib.Ena = ASF_DEF_ASF_ENA; ++ pAC->AsfData.Mib.RspEnable = 0; ++ pAC->AsfData.Mib.Retrans = ASF_DEF_RETRANS; ++ pAC->AsfData.Mib.RetransInt = ASF_DEF_RETRANS_INT; ++ pAC->AsfData.Mib.HbEna = ASF_DEF_HB_ENA; ++ pAC->AsfData.Mib.HbInt = ASF_DEF_HB_INT; ++ pAC->AsfData.Mib.WdEna = ASF_DEF_WATCHDOG_ENA; ++ pAC->AsfData.Mib.WdTime = ASF_DEF_WATCHDOG_TIME; ++ pAC->AsfData.Mib.CommunityName[0] = 0x00; ++ pAC->AsfData.Mib.RlmtMode = 0xff; // only for IPMI op mode ++ pAC->AsfData.Mib.PattUpReq = 0; // update pattern request flag ++ ++ /* Start ASF timer */ ++ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); ++ SkTimerStart(pAC, IoC, &pAC->AsfData.AsfTimer, ++ 5000000, SKGE_ASF, SK_ASF_EVT_TIMER_EXPIRED, ++ EventParam); ++ // initialize the FW WD functionality ++ pAC->AsfData.FwWdIntervall = 120; ++ ++ if( RetCode == SK_ASF_PNMI_ERR_OK ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Check FW Ramsize\n")); ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_ASF_RAMSIZE, 0, 0, 1, ASF_HCI_WAIT, 2 ); ++ ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ pAC->AsfData.FwRamSize = ((SK_U16)*(pHciRecBuf+2)) << 8; ++ pAC->AsfData.FwRamSize |= ((SK_U16)*(pHciRecBuf+3)) << 0; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** FW RamSize: %dkB \n", pAC->AsfData.FwRamSize)); ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** error\n")); ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ } ++ } ++ ++ if( RetCode == SK_ASF_PNMI_ERR_OK ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** ASF Init O.K. *** (%d)\n", pAC->GIni.GIRamSize)); ++ pAC->AsfData.InitState = ASF_INIT_OK; ++ pAC->GIni.GIRamSize -= pAC->AsfData.FwRamSize; // shorten RAM buffer by FwRamSize ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** New RAM value (%dk)\n", pAC->GIni.GIRamSize)); ++ } else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** ASF Init failed ***\n")); ++ ++ AsfSmartResetCpu( pAC, IoC, ASF_RESET_HOT ); ++ pAC->AsfData.InitState = ASF_INIT_ERROR; // disable ASF functionality ++ // after reset the cpu clean up some important registers ++ AsfSetSMBusRegister(IoC); ++ } ++ ++ /* fetch the home MAC address from adapter */ ++ for (i = 0; i < 6; i++) { ++ SK_IN8(IoC, (B2_MAC_1 + i), &pAC->AsfData.Mib.MacSource[i] ); ++ } ++ ++ break; ++ ++ default: ++ break; /* Nothing todo */ ++ } ++ ++ return( RetCode ); ++} ++ ++/***************************************************************************** ++* ++* AsfSetSMBusRegister - cleaning up register for SMBus ++* ++* Description: If the ASF FW goes into smart reset, this function is ++* cleaning up the SMBus register. ++* ++* Returns: ++*/ ++ ++void AsfSetSMBusRegister( ++ SK_IOC IoC) /* IO context handle */ ++{ ++ ++ SK_U32 TmpVal32; ++ SK_U32 mask; ++ ++ // get register ++ SK_IN32(IoC, REG_ASF_SMBUS_CFG, &TmpVal32); ++ ++ // delete bit 4: SMBC_IE ++ // delete bit 5: SMBC_EA ++ // delete bit 6: SMBC_GCE ++ // delete bit 7: SMBC_DAE ++ // delete bit 8: SMBC_SAE ++ ++ mask = 0x000001f0; ++ TmpVal32 &= (~mask); ++ ++ // set register ++ SK_OUT32(IoC, REG_ASF_SMBUS_CFG, TmpVal32); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** ASF cleaning up SMBusRegister 0x%x with 0x%x ***\n", REG_ASF_SMBUS_CFG, TmpVal32)); ++} ++ ++ ++/***************************************************************************** ++* ++* SkAsfDeInit - DeInit function of ASF ++* ++* Description: ++* ++* Returns: ++* Always 0 ++*/ ++int SkAsfDeInit( ++SK_AC *pAC, /* Pointer to adapter context */ ++SK_IOC IoC ) { /* IO context handle */ ++ ++ SK_U32 TmpVal32; ++ ++ /* Reset OS Present Flag in ASF Status and Command Register */ ++ SK_IN32( IoC, REG_ASF_STATUS_CMD, &TmpVal32 ); ++ TmpVal32 &= ~BIT_4; ++ SK_OUT32( IoC, REG_ASF_STATUS_CMD, TmpVal32 ); ++ ++ if( pAC->AsfData.InitState == ASF_INIT_OK ) { ++ ++ if (pAC->AsfData.OpMode == SK_GEASF_MODE_ASF) { ++ // Enable ARP pattern, ASF FW is now responsible for ARP handling ++ YlciEnablePattern ( pAC, IoC, 0, 5 ); ++ } ++ ++ if (pAC->AsfData.OpMode == SK_GEASF_MODE_IPMI) { ++ // Enable ARP pattern, ASF FW is now responsible for ARP handling ++ YlciEnablePattern ( pAC, IoC, 0, 5 ); ++ ++ if (pAC->AsfData.DualMode == SK_GEASF_Y2_DUALPORT) { ++ YlciEnablePattern ( pAC, IoC, 1, 5 ); ++ } ++ } ++ ++ // Inform the FW that the driver will be unloaded ++ AsfHciSendCommand( pAC, IoC, YASF_HOSTCMD_DRV_GOODBYE, 0, 0, 0, ASF_HCI_WAIT, 2 ); ++ } ++ ++ return( 0 ); ++} ++ ++/***************************************************************************** ++* ++* SkAsfDeInitStandBy - StandBy -DeInit function of ASF ++* ++* Description: ++* ++* Returns: ++* Always 0 ++*/ ++int SkAsfDeInitStandBy( ++SK_AC *pAC, /* Pointer to adapter context */ ++SK_IOC IoC ) { /* IO context handle */ ++ ++ if( pAC->AsfData.InitState == ASF_INIT_OK ) { ++ // Enable ARP pattern, ASF FW is now responsible for ARP handling ++ YlciEnablePattern ( pAC, IoC, pAC->AsfData.ActivePort, 5 ); ++ // Inform the FW that the driver will be unloaded ++ AsfHciSendCommand( pAC, IoC, YASF_HOSTCMD_DRV_STANDBY, 0, 0, 0, ASF_HCI_WAIT, 2 ); ++ } ++ ++ return( 0 ); ++} ++ ++/***************************************************************************** ++* ++* SkAsfInitStandBy - StandBy - Init function of ASF ++* ++* Description: ++* ++* Returns: ++* Always 0 ++*/ ++int SkAsfInitStandBy( ++SK_AC *pAC, /* Pointer to adapter context */ ++SK_IOC IoC, /* IO context handle */ ++int Level) { /* Initialization level */ ++ SK_U32 TmpVal32; ++ SK_EVPARA EventParam; /* Event struct for timer event */ ++ ++ if( pAC->AsfData.InitState == ASF_INIT_OK ) { ++ switch(Level) ++ { ++ case SK_INIT_DATA: ++ /* Set OS Present Flag in ASF Status and Command Register */ ++ SK_IN32( IoC, REG_ASF_STATUS_CMD, &TmpVal32 ); ++ TmpVal32 |= BIT_4; ++ // Disable ARP pattern, host system takes over the ARP handling ++ YlciDisablePattern ( pAC, IoC, pAC->AsfData.ActivePort, 5 ); ++ // Inform the FW that the driver will be activated again ++ // Schlechte Idee, schaltet ASF beim laden des Treibers ab ++ // AsfHciSendCommand( pAC, IoC, YASF_HOSTCMD_DRV_HELLO, 0, 0, 0, ASF_HCI_WAIT, 2 ); ++ break; ++ ++ case SK_INIT_IO: ++ break; ++ ++ case SK_INIT_RUN: ++ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); ++ SkTimerStart(pAC, IoC, &pAC->AsfData.AsfTimer, ++ 5000000, SKGE_ASF, SK_ASF_EVT_TIMER_EXPIRED, EventParam); ++ break; ++ } // switch( Level ) ++ } // if( pAC->AsfData.InitState == ASF_INIT_OK ) ++ ++ return( 0 ); ++} ++ ++ ++/****************************************************************************** ++* ++* SkAsfSeprom2Mib reads ASF MIB config data from SEPROM ++* ++* Context: ++* ++* ++* Returns: 0: successful ++* 1: error ++*/ ++ ++SK_I8 SkAsfSeprom2Mib( ++SK_AC *pAC, /* Pointer to adapter context */ ++SK_IOC IoC ) { /* IO context handle */ ++ ++ SK_U8 ind; ++ SK_U8 i; ++ SK_U8 version; ++ SK_I8 RetCode; ++ SK_U32 our_reg2; ++ SK_U32 Len; ++ ++ ind = 0; ++ ++ VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2); ++ pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14); ++ ++ Len = VpdReadBlock( pAC, IoC, &pAC->AsfData.VpdConfigBuf[0], ASF_VPD_CONFIG_BASE, ASF_VPD_CONFIG_SIZE ); ++ if( Len == ASF_VPD_CONFIG_SIZE ) { ++ RetCode = SK_ASF_PNMI_ERR_OK; ++ /* check, whether the signature is valid */ ++ if( pAC->AsfData.VpdConfigBuf[0] == 'A' && ++ pAC->AsfData.VpdConfigBuf[1] == 'S' && ++ pAC->AsfData.VpdConfigBuf[2] == 'F' && ++ pAC->AsfData.VpdConfigBuf[3] == '!' ) { ++ ind = 4; ++ version = pAC->AsfData.VpdConfigBuf[ind++]; ++ switch( version ) { ++ case 1: ++ pAC->AsfData.Mib.Ena = pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.RspEnable = pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.Retrans = (SK_U16) pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.Retrans |= (SK_U16) (pAC->AsfData.VpdConfigBuf[ind++] << 8); ++ pAC->AsfData.Mib.RetransInt = (SK_U32) pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.RetransInt |= (SK_U32) (pAC->AsfData.VpdConfigBuf[ind++] << 8); ++ pAC->AsfData.Mib.RetransInt |= (SK_U32) (pAC->AsfData.VpdConfigBuf[ind++] << 16); ++ pAC->AsfData.Mib.RetransInt |= (SK_U32) (pAC->AsfData.VpdConfigBuf[ind++] << 24); ++ pAC->AsfData.Mib.HbEna = pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.HbInt = (SK_U32) pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.HbInt |= (SK_U32) (pAC->AsfData.VpdConfigBuf[ind++] << 8); ++ pAC->AsfData.Mib.HbInt |= (SK_U32) (pAC->AsfData.VpdConfigBuf[ind++] << 16); ++ pAC->AsfData.Mib.HbInt |= (SK_U32) (pAC->AsfData.VpdConfigBuf[ind++] << 24); ++ pAC->AsfData.Mib.WdEna = pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.WdTime = (SK_U32) pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.WdTime |= (SK_U32) (pAC->AsfData.VpdConfigBuf[ind++] << 8); ++ pAC->AsfData.Mib.WdTime |= (SK_U32) (pAC->AsfData.VpdConfigBuf[ind++] << 16); ++ pAC->AsfData.Mib.WdTime |= (SK_U32) (pAC->AsfData.VpdConfigBuf[ind++] << 24); ++ for( i=0; i<4; i++ ) ++ pAC->AsfData.Mib.IpDest[i] = pAC->AsfData.VpdConfigBuf[ind++]; ++ for( i=0; i<4; i++ ) ++ pAC->AsfData.Mib.IpSource[i] = pAC->AsfData.VpdConfigBuf[ind++]; ++ for( i=0; i<6; i++ ) ++ pAC->AsfData.Mib.MacDest[i] = pAC->AsfData.VpdConfigBuf[ind++]; ++ for( i=0; i<64; i++ ) ++ pAC->AsfData.Mib.CommunityName[i] = pAC->AsfData.VpdConfigBuf[ind++]; ++ for( i=0; i<6; i++ ) ++ pAC->AsfData.Mib.Reserved[i] = pAC->AsfData.VpdConfigBuf[ind++]; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" O.K.\n")); ++ break; ++ ++ case 2: ++ pAC->AsfData.Mib.Ena = pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.RspEnable = pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.Retrans = (SK_U16) pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.RetransInt = (SK_U32) pAC->AsfData.VpdConfigBuf[ind++] * 10; ++ pAC->AsfData.Mib.HbEna = pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.HbInt = (SK_U32) pAC->AsfData.VpdConfigBuf[ind++] * 10; ++ pAC->AsfData.Mib.WdEna = pAC->AsfData.VpdConfigBuf[ind++]; ++ pAC->AsfData.Mib.WdTime = (SK_U32) pAC->AsfData.VpdConfigBuf[ind++] * 10; ++ for( i=0; i<4; i++ ) ++ pAC->AsfData.Mib.IpDest[i] = pAC->AsfData.VpdConfigBuf[ind++]; ++ for( i=0; i<4; i++ ) ++ pAC->AsfData.Mib.IpSource[i] = pAC->AsfData.VpdConfigBuf[ind++]; ++ for( i=0; i<6; i++ ) ++ pAC->AsfData.Mib.MacDest[i] = pAC->AsfData.VpdConfigBuf[ind++]; ++ for( i=0; i<10; i++ ) ++ pAC->AsfData.Mib.CommunityName[i] = pAC->AsfData.VpdConfigBuf[ind++]; ++ for( i=0; i<6; i++ ) ++ pAC->AsfData.Mib.Reserved[i] = pAC->AsfData.VpdConfigBuf[ind++]; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" O.K.\n")); ++ break; ++ ++ default: ++ // invalidate ASF signature, this causes a new formating of the SEEPROM ++ pAC->AsfData.VpdConfigBuf[0] = 'x'; ++ pAC->AsfData.VpdConfigBuf[1] = 'x'; ++ pAC->AsfData.VpdConfigBuf[2] = 'x'; ++ pAC->AsfData.VpdConfigBuf[3] = 'x'; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" unknown version: 0x%x\n", version )); ++ break; ++ } // switch( version ) { ++ } ++ else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error: Signature not valid\n")); ++ } ++ } // if( Len == .. ) ++ else { ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** failed\n")); ++ } ++ ++ return( RetCode ); ++} ++ ++/****************************************************************************** ++* ++* SkAsfMib2Seprom writes ASF MIB config data to SEPROM ++* ++* Context: ++* ++* ++* Returns: 0: successful ++* 1: error ++*/ ++ ++SK_I8 SkAsfMib2Seprom( ++SK_AC *pAC, /* Pointer to adapter context */ ++SK_IOC IoC ) { /* IO context handle */ ++ ++ SK_U8 ind; ++ SK_U8 i; ++ SK_I8 RetCode; ++ SK_U32 our_reg2; ++ SK_U32 Len; ++ SK_U8 version; ++ ++ version = 2; ++ ++ ind = 0; ++ pAC->AsfData.VpdConfigBuf[ind++] = 'A'; ++ pAC->AsfData.VpdConfigBuf[ind++] = 'S'; ++ pAC->AsfData.VpdConfigBuf[ind++] = 'F'; ++ pAC->AsfData.VpdConfigBuf[ind++] = '!'; ++ pAC->AsfData.VpdConfigBuf[ind++] = version; ++ switch( version ) { ++ case 1: // 101 Bytes ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.Ena; ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.RspEnable; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.Retrans >> 0) & 0x00ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.Retrans >> 8) & 0x00ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.RetransInt >> 0) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.RetransInt >> 8) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.RetransInt >> 16) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.RetransInt >> 24) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.HbEna; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.HbInt >> 0) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.HbInt >> 8) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.HbInt >> 16) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.HbInt >> 24) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.WdEna; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.WdTime >> 0) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.WdTime >> 8) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.WdTime >> 16) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.WdTime >> 24) & 0x000000ff; ++ for( i=0; i<4; i++ ) ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.IpDest[i]; ++ for( i=0; i<4; i++ ) ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.IpSource[i]; ++ for( i=0; i<6; i++ ) ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.MacDest[i]; ++ for( i=0; i<64; i++ ) ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.CommunityName[i]; ++ for( i=0; i<6; i++ ) ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.Reserved[i]; ++ break; ++ ++ case 2: // 40 Bytes ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.Ena; ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.RspEnable; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) pAC->AsfData.Mib.Retrans & 0x00ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.RetransInt / 10) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.HbEna; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.HbInt / 10) & 0x000000ff; ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.WdEna; ++ pAC->AsfData.VpdConfigBuf[ind++] = (SK_U8) (pAC->AsfData.Mib.WdTime / 10) & 0x000000ff; ++ for( i=0; i<4; i++ ) ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.IpDest[i]; ++ for( i=0; i<4; i++ ) ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.IpSource[i]; ++ for( i=0; i<6; i++ ) ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.MacDest[i]; ++ for( i=0; i<10; i++ ) ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.CommunityName[i]; ++ for( i=0; i<6; i++ ) ++ pAC->AsfData.VpdConfigBuf[ind++] = pAC->AsfData.Mib.Reserved[i]; ++ break; ++ ++ default: ++ break; ++ } // switch( version ) { ++ ++ ++ ++ VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2); ++ pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14); ++ ++ // enable Config write Reg 0x158 ++ // SK_IN8( IoC, B2_TST_REG1, &TmpVal8 ) ++ // TmpVal8 &= ~0x03; ++ // TmpVal8 |= 0x02; ++ // SK_OUT8( IoC, B2_TST_REG1, TmpVal8 ) ++ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfMib2Seprom \n")); ++ Len = VpdWriteBlock(pAC,IoC, &pAC->AsfData.VpdConfigBuf[0], ASF_VPD_CONFIG_BASE, ASF_VPD_CONFIG_SIZE ); ++ if( Len == ASF_VPD_CONFIG_SIZE ) { ++ RetCode = SK_ASF_PNMI_ERR_OK; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" O.K. \n")); ++ } ++ else { ++ RetCode = SK_ASF_PNMI_ERR_GENERAL; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** failed \n")); ++ } ++ ++ // disable Config write Reg 0x158 ++ // SK_IN8( IoC, B2_TST_REG1, &TmpVal8 ) ++ // TmpVal8 &= ~0x03; ++ // TmpVal8 |= 0x01; ++ // SK_OUT8( IoC, B2_TST_REG1, TmpVal8 ) ++ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); ++ ++ return( RetCode ); ++} ++ ++ ++/****************************************************************************** ++* ++* SkAsfTriggerPetFrames ++* ++* Context: ++* init, pageable ++* ++* Returns: void ++*/ ++ ++void SkAsfTriggerPetFrames (SK_IOC IoC, SK_U32 *TmpVal32) ++{ ++ ++ return; ++} ++ ++/****************************************************************************** ++* ++* SkAsfPreSetOid - ++* ++* Context: ++* init, pageable ++* ++* Returns: ++*/ ++int SkAsfPreSetOid( ++ SK_AC *pAC, /* the adapter context */ ++ SK_IOC IoC, /* I/O context */ ++ SK_U32 Id, /* OID */ ++ SK_U32 Inst, ++ SK_U8 *pBuf, ++ unsigned int *pLen) ++{ ++ SK_U32 RetCode = SK_ASF_PNMI_ERR_OK; ++ ++ ++ switch( Id ) { ++ case OID_SKGE_ASF_ENA: ++ break; ++ ++ default: ++ *pLen = 0; ++ RetCode = SK_ASF_PNMI_ERR_NOT_SUPPORTED; ++ break; ++ } ++ ++ return(RetCode); ++} ++ ++/****************************************************************************** ++* ++* SkAsfSetOid - ++* ++* Context: ++* init, pageable ++* ++* Returns: ++*/ ++int SkAsfSetOid( ++ SK_AC *pAC, /* the adapter context */ ++ SK_IOC IoC, /* I/O context */ ++ SK_U32 Id, /* OID */ ++ SK_U32 Inst, ++ SK_U8 *pBuf, ++ unsigned int *pLen) ++{ ++ SK_U16 i; ++ ++ SK_U32 RetCode = SK_ASF_PNMI_ERR_OK; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfSetOid -> OID:0x%x Len:%d ***********************\n", Id, *pLen )); ++ ++ if( pAC->AsfData.InitState != ASF_INIT_OK ) { ++ return( SK_ASF_PNMI_ERR_GENERAL ); ++ } ++ ++ switch( Id ) { ++ case OID_SKGE_ASF_STORE_CONFIG: ++ pAC->AsfData.Mib.NewParam = 4; ++ break; ++ ++ case OID_SKGE_ASF_ENA: ++ if( *pLen == 1 ) { ++ if( *pBuf != pAC->AsfData.Mib.Ena ) ++ pAC->AsfData.Mib.ConfigChange |= 0x01; ++ pAC->AsfData.Mib.Ena = *pBuf; ++ *pLen = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_ENA: %d\n", pAC->AsfData.Mib.Ena )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_RETRANS: ++ if( *pLen == 2 ) { ++ pAC->AsfData.Mib.Retrans = *( (SK_U16 *) pBuf ); ++ *pLen = 2; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RETRANS: %d\n", pAC->AsfData.Mib.Retrans )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_RETRANS_INT: ++ if( *pLen == 2 ) { ++ pAC->AsfData.Mib.RetransInt = *( (SK_U16 *) pBuf ) * ASF_GUI_TSF; ++ *pLen = 2; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RETRANS_INT: %d\n", pAC->AsfData.Mib.RetransInt )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_HB_ENA: ++ if( *pLen == 1 ) { ++ pAC->AsfData.Mib.HbEna = *pBuf; ++ *pLen = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_HB_ENA: %d\n", pAC->AsfData.Mib.HbEna )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_HB_INT: ++ if( *pLen == 4 ) { ++ pAC->AsfData.Mib.HbInt = *( (SK_U32 *) pBuf ) * ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_HB_INT: %d\n", pAC->AsfData.Mib.HbInt )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_WD_ENA: ++ if( *pLen == 1 ) { ++ pAC->AsfData.Mib.WdEna = *pBuf; ++ *pLen = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_WD_ENA: %d\n", pAC->AsfData.Mib.WdEna )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_WD_TIME: ++ if( *pLen == 4 ) { ++ pAC->AsfData.Mib.WdTime = *( (SK_U32 *) pBuf ) * ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_WD_TIME: %d\n", pAC->AsfData.Mib.WdTime )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_IP_DEST: ++ if( AsfAsci2Ip( pBuf, *pLen, pAC->AsfData.Mib.IpDest ) == 1 ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_IP_DEST: %d.%d.%d.%d\n", ++ pAC->AsfData.Mib.IpDest[0], pAC->AsfData.Mib.IpDest[1], ++ pAC->AsfData.Mib.IpDest[2], pAC->AsfData.Mib.IpDest[3] )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_GENERAL; ++ break; ++ ++ case OID_SKGE_ASF_MAC_DEST: ++ if( AsfAsci2Mac( pBuf, *pLen, pAC->AsfData.Mib.MacDest ) == 1 ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_MAC_DEST: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ pAC->AsfData.Mib.MacDest[0], pAC->AsfData.Mib.MacDest[1], ++ pAC->AsfData.Mib.MacDest[2], pAC->AsfData.Mib.MacDest[3], ++ pAC->AsfData.Mib.MacDest[4], pAC->AsfData.Mib.MacDest[5] )); ++#ifdef ASF_FW_ARP_RESOLVE ++ // just for FW-ARP-Resolve testing purposes ++// for( i=0; i<6; i++ ) ++// pAC->AsfData.Mib.MacDest[i] = 0; ++#endif // ASF_FW_ARP_RESOLVE ++ ++ } ++ else ++ RetCode = SK_PNMI_ERR_GENERAL; ++ break; ++ ++ case OID_SKGE_ASF_COMMUNITY_NAME: ++ for( i=0; (i<*pLen)&&(i<63); i++ ) ++ pAC->AsfData.Mib.CommunityName[i] = *(pBuf + i); ++ pAC->AsfData.Mib.CommunityName[i] = 0; ++ break; ++ ++ case OID_SKGE_ASF_RSP_ENA: ++ if( *pLen == 1 ) { ++ if( *pBuf != pAC->AsfData.Mib.RspEnable ) ++ pAC->AsfData.Mib.ConfigChange |= 0x02; ++ ++ pAC->AsfData.Mib.RspEnable = *pBuf; ++ *pLen = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RSP_ENA: %d\n", pAC->AsfData.Mib.RspEnable )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_RETRANS_COUNT_MIN: ++ if( *pLen == 4 ) { ++ pAC->AsfData.Mib.RetransCountMin = *( (SK_U32 *) pBuf ); ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RETRANS_COUNT_MIN: %d\n", pAC->AsfData.Mib.RetransCountMin )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_RETRANS_COUNT_MAX: ++ if( *pLen == 4 ) { ++ pAC->AsfData.Mib.RetransCountMax = *( (SK_U32 *) pBuf ); ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RETRANS_COUNT_MAX: %d\n", pAC->AsfData.Mib.RetransCountMax )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_RETRANS_INT_MIN: ++ if( *pLen == 4 ) { ++ pAC->AsfData.Mib.RetransIntMin = *( (SK_U32 *) pBuf ) * ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RETRANS_INT_MIN: %d\n", pAC->AsfData.Mib.RetransIntMin )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_RETRANS_INT_MAX: ++ if( *pLen == 4 ) { ++ pAC->AsfData.Mib.RetransIntMax = *( (SK_U32 *) pBuf ) * ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RETRANS_INT_MAX: %d\n", pAC->AsfData.Mib.RetransIntMax )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_HB_INT_MIN: ++ if( *pLen == 4 ) { ++ pAC->AsfData.Mib.HbIntMin = *( (SK_U32 *) pBuf ) * ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_HB_INT_MIN: %d\n", pAC->AsfData.Mib.HbIntMin )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_HB_INT_MAX: ++ if( *pLen == 4 ) { ++ pAC->AsfData.Mib.HbIntMax = *( (SK_U32 *) pBuf ) * ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_HB_INT_MAX: %d\n", pAC->AsfData.Mib.HbIntMax )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_WD_TIME_MIN: ++ if( *pLen == 4 ) { ++ pAC->AsfData.Mib.WdTimeMin = *( (SK_U32 *) pBuf ) * ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_WD_TIME_MIN: %d\n", pAC->AsfData.Mib.WdTimeMin )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_WD_TIME_MAX: ++ if( *pLen == 4 ) { ++ pAC->AsfData.Mib.WdTimeMax = *( (SK_U32 *) pBuf ) * ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_WD_TIME_MAX: %d\n", pAC->AsfData.Mib.WdTimeMax )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_KEY_OP: ++ if( *pLen == (RSP_KEYLENGTH*2) ) { ++ AsfHex2Array( pBuf, *pLen, pAC->AsfData.Mib.KeyOperator ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_KEY_OP:\n >")); ++ for( i=0; iAsfData.Mib.KeyOperator[i] )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("<\n")); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_KEY_ADM: ++ if( *pLen == (RSP_KEYLENGTH*2) ) { ++ AsfHex2Array( pBuf, *pLen, pAC->AsfData.Mib.KeyAdministrator ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_KEY_ADM:\n >")); ++ for( i=0; iAsfData.Mib.KeyAdministrator[i] )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("<\n")); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_KEY_GEN: ++ if( *pLen == (RSP_KEYLENGTH*2) ) { ++ AsfHex2Array( pBuf, *pLen, pAC->AsfData.Mib.KeyGenerator ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_KEY_GEN:\n >")); ++ for( i=0; iAsfData.Mib.KeyGenerator[i] )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("<\n")); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_PAR_1: ++ if( *pLen == 1 ) { ++ pAC->AsfData.Mib.Reserved[Id-OID_SKGE_ASF_PAR_1] = *pBuf; ++ *pLen = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_PAR_X: ---\n" )); ++ } ++ else ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ break; ++ ++ case OID_SKGE_ASF_IP_SOURCE: ++ *pLen = 0; ++ break; ++ ++ case OID_SKGE_ASF_FWVER_OID: ++ // fall through ++ case OID_SKGE_ASF_ACPI_OID: ++ // fall through ++ case OID_SKGE_ASF_SMBUS_OID: ++ // these OIDs are read only - they cannot be set ++ *pLen = 0; ++ break; ++ ++ default: ++ *pLen = 0; ++ RetCode = SK_ASF_PNMI_ERR_NOT_SUPPORTED; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID not supported \n" )); ++ break; ++ } ++ ++ if( RetCode != SK_ASF_PNMI_ERR_OK ) { // No bytes used ++ if( RetCode == SK_PNMI_ERR_TOO_SHORT ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error Length: %d \n", *pLen )); ++ } ++ else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Error ???\n", *pLen )); ++ } ++ *pLen = 0; ++ } ++ else ++ pAC->AsfData.Mib.NewParam = 2; // Trigger SEPROM Update ++ ++ ++ return(RetCode); ++} ++ ++ ++/****************************************************************************** ++* ++* SkAsfGetOid - ++* ++* Context: ++* init, pageable ++* ++* Returns: ++*/ ++int SkAsfGetOid( ++ SK_AC *pAC, /* the adapter context */ ++ SK_IOC IoC, /* I/O context */ ++ SK_U32 Id, /* OID */ ++ SK_U32 Inst, ++ SK_U8 *pBuf, ++ unsigned int *pLen) ++{ ++ SK_U32 TmpVal32; ++ SK_U32 RetCode = SK_ASF_PNMI_ERR_OK; ++ SK_U8 i; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfGetOid -> OID:0x%x Len:%d\n", Id, *pLen )); ++ ++ if( pAC->AsfData.InitState != ASF_INIT_OK ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfSetOid -> Get OID denied, ASF not initialized !\n", Id, *pLen )); ++ if( Id != OID_SKGE_ASF_CAP ) ++ return( SK_ASF_PNMI_ERR_GENERAL ); ++ } ++ ++ switch( Id ) { ++ case OID_SKGE_ASF_CAP: ++ if( *pLen >= 4 ) { ++ TmpVal32 = 0; ++ if( (pAC->AsfData.InitState != ASF_INIT_UNDEFINED) && ++ (pAC->AsfData.InitState != ASF_INIT_ERROR_CHIP_ID) ) ++ TmpVal32 |= BIT_0; // ASF capable ++ if( pAC->AsfData.InitState == ASF_INIT_OK ) ++ TmpVal32 |= BIT_1; // ASF Init OK ++ if( pAC->AsfData.Mib.Ena ) ++ TmpVal32 |= BIT_2; // ASF enable ++ *( (SK_U32 *) pBuf ) = TmpVal32; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_ENA: %d\n", pAC->AsfData.Mib.Ena )); ++ } ++ else { ++ *pLen = 4; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_ENA: ++ if( *pLen >= 1 ) { ++ *( (SK_U8 *) pBuf ) = pAC->AsfData.Mib.Ena; ++ *pLen = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_ENA: %d\n", pAC->AsfData.Mib.Ena )); ++ } ++ else { ++ *pLen = 1; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_RETRANS: ++ if( *pLen >= 2 ) { ++ *( (SK_U16 *) pBuf ) = pAC->AsfData.Mib.Retrans; ++ *pLen = 2; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RETRANS: %d\n", pAC->AsfData.Mib.Retrans )); ++ } ++ else { ++ *pLen = 2; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_RETRANS_INT: ++ if( *pLen >= 4 ) { ++ *( (SK_U32 *) pBuf ) = pAC->AsfData.Mib.RetransInt / ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RETRANS_INT: %d\n", pAC->AsfData.Mib.RetransInt )); ++ } ++ else { ++ *pLen = 4; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_HB_ENA: ++ if( *pLen >= 1 ) { ++ *( (SK_U8 *) pBuf ) = pAC->AsfData.Mib.HbEna; ++ *pLen = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_HB_ENA: %d\n", pAC->AsfData.Mib.HbEna )); ++ } ++ else { ++ *pLen = 1; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_HB_INT: ++ if( *pLen >= 4 ) { ++ *( (SK_U32 *) pBuf ) = pAC->AsfData.Mib.HbInt / ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_HB_INT: %d\n", pAC->AsfData.Mib.HbInt )); ++ } ++ else { ++ *pLen = 4; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_WD_ENA: ++ if( *pLen >= 1 ) { ++ *( (SK_U8 *) pBuf ) = pAC->AsfData.Mib.WdEna; ++ *pLen = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_WD_ENA: %d\n", pAC->AsfData.Mib.WdEna )); ++ } ++ else { ++ *pLen = 1; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_WD_TIME: ++ if( *pLen >= 4 ) { ++ *( (SK_U32 *) pBuf ) = pAC->AsfData.Mib.WdTime / ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_WD_TIME: %d\n", pAC->AsfData.Mib.WdTime )); ++ } ++ else { ++ *pLen = 4; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_IP_SOURCE: ++ if( *pLen >= 16 ) { ++ AsfIp2Asci( pBuf+1, pLen, pAC->AsfData.Mib.IpSource ); ++ *pBuf = (SK_U8) *pLen; ++ (*pLen)++; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_IP_SOURCE: %d.%d.%d.%d\n", ++ pAC->AsfData.Mib.IpSource[0], pAC->AsfData.Mib.IpSource[1], ++ pAC->AsfData.Mib.IpSource[2], pAC->AsfData.Mib.IpSource[3] )); ++ } ++ else { ++ *pLen = 16; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_IP_DEST: ++ if( *pLen >= 16 ) { ++ AsfIp2Asci( pBuf+1, pLen, pAC->AsfData.Mib.IpDest ); ++ *pBuf = (SK_U8) *pLen; ++ (*pLen)++; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_IP_DEST: %d.%d.%d.%d\n", ++ pAC->AsfData.Mib.IpDest[0], pAC->AsfData.Mib.IpDest[1], ++ pAC->AsfData.Mib.IpDest[2], pAC->AsfData.Mib.IpDest[3] )); ++ } ++ else { ++ *pLen = 16; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_MAC_DEST: ++ if( *pLen >= 18 ) { ++ AsfMac2Asci( pBuf+1, pLen, pAC->AsfData.Mib.MacDest ); ++ *pBuf = (SK_U8) *pLen; ++ (*pLen)++; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_MAC_DEST: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ pAC->AsfData.Mib.MacDest[0], pAC->AsfData.Mib.MacDest[1], ++ pAC->AsfData.Mib.MacDest[2], pAC->AsfData.Mib.MacDest[3], ++ pAC->AsfData.Mib.MacDest[4], pAC->AsfData.Mib.MacDest[5] )); ++ } ++ else { ++ *pLen = 18; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_MAC_SOURCE: ++ if( *pLen >= 18 ) { ++ AsfMac2Asci( pBuf+1, pLen, pAC->AsfData.Mib.MacSource ); ++ *pBuf = (SK_U8) *pLen; ++ (*pLen)++; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_MAC_SOURCE: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ pAC->AsfData.Mib.MacSource[0], pAC->AsfData.Mib.MacSource[1], ++ pAC->AsfData.Mib.MacSource[2], pAC->AsfData.Mib.MacSource[3], ++ pAC->AsfData.Mib.MacSource[4], pAC->AsfData.Mib.MacSource[5] )); ++ } ++ else { ++ *pLen = 18; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_COMMUNITY_NAME: ++ if( *pLen >= 64 ) { ++ for( *pLen=0; *pLen<63; (*pLen)++ ) { ++ *(pBuf + *pLen + 1 ) = pAC->AsfData.Mib.CommunityName[*pLen]; ++ ++ if( pAC->AsfData.Mib.CommunityName[*pLen] != 0 ) { ++ *(pBuf + *pLen + 1 ) = pAC->AsfData.Mib.CommunityName[*pLen]; ++ } ++ else { ++ break; ++ } ++ } ++ *pBuf = (SK_U8) *pLen; ++ (*pLen)++; ++ } ++ else { ++ *pLen = 64; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_RSP_ENA: ++ if( *pLen >= 1 ) { ++ *( (SK_U8 *) pBuf ) = pAC->AsfData.Mib.RspEnable; ++ *pLen = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RSP_ENA: %d\n", pAC->AsfData.Mib.RspEnable )); ++ } ++ else { ++ *pLen = 1; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_RETRANS_COUNT_MIN: ++ if( *pLen >= 4 ) { ++ *( (SK_U32 *) pBuf ) = pAC->AsfData.Mib.RetransCountMin; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RETRANS_COUNT_MIN: %d\n", pAC->AsfData.Mib.RetransCountMin )); ++ } ++ else { ++ *pLen = 4; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_RETRANS_COUNT_MAX: ++ if( *pLen >= 4 ) { ++ *( (SK_U32 *) pBuf ) = pAC->AsfData.Mib.RetransCountMax; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RETRANS_COUNT_MAX: %d\n", pAC->AsfData.Mib.RetransCountMax )); ++ } ++ else { ++ *pLen = 4; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_RETRANS_INT_MIN: ++ if( *pLen >= 4 ) { ++ *( (SK_U32 *) pBuf ) = pAC->AsfData.Mib.RetransIntMin / ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RETRANS_INT_MIN: %d\n", pAC->AsfData.Mib.RetransIntMin )); ++ } ++ else { ++ *pLen = 4; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_RETRANS_INT_MAX: ++ if( *pLen >= 4 ) { ++ *( (SK_U32 *) pBuf ) = pAC->AsfData.Mib.RetransIntMax / ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_RETRANS_INT_MAX: %d\n", pAC->AsfData.Mib.RetransIntMax )); ++ } ++ else { ++ *pLen = 4; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_HB_INT_MIN: ++ if( *pLen >= 4 ) { ++ *( (SK_U32 *) pBuf ) = pAC->AsfData.Mib.HbIntMin / ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_HB_INT_MIN: %d\n", pAC->AsfData.Mib.HbIntMin )); ++ } ++ else { ++ *pLen = 4; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_HB_INT_MAX: ++ if( *pLen >= 4 ) { ++ *( (SK_U32 *) pBuf ) = pAC->AsfData.Mib.HbIntMax / ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_HB_INT_MAX: %d\n", pAC->AsfData.Mib.HbIntMax )); ++ } ++ else { ++ *pLen = 4; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_WD_TIME_MIN: ++ if( *pLen >= 4 ) { ++ *( (SK_U32 *) pBuf ) = pAC->AsfData.Mib.WdTimeMin / ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_WD_TIME_MIN: %d\n", pAC->AsfData.Mib.WdTimeMin )); ++ } ++ else { ++ *pLen = 4; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_WD_TIME_MAX: ++ if( *pLen >= 4 ) { ++ *( (SK_U32 *) pBuf ) = pAC->AsfData.Mib.WdTimeMax / ASF_GUI_TSF; ++ *pLen = 4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_WD_TIME_MAX: %d\n", pAC->AsfData.Mib.WdTimeMax )); ++ } ++ else { ++ *pLen = 4; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_GUID: ++ if( *pLen >= 33 ) { ++ AsfArray2Hex( pBuf+1, 16, pAC->AsfData.Mib.Guid ); ++ *pBuf = 32; ++ *pLen = 33; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_GUID\n" )); ++ } ++ else { ++ *pLen = 33; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_KEY_OP: ++ if( *pLen >= 41 ) { ++ AsfArray2Hex( pBuf+1, 40, pAC->AsfData.Mib.KeyOperator ); ++ *pBuf = (SK_U8) 40; ++ *pLen = 41; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_KEY_OP:\n >")); ++ for( i=0; iAsfData.Mib.KeyOperator[i] )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("<\n")); ++ } ++ else { ++ *pLen = 41; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_KEY_ADM: ++ if( *pLen >= 41 ) { ++ AsfArray2Hex( pBuf+1, 40, pAC->AsfData.Mib.KeyAdministrator ); ++ *pBuf = (SK_U8) 40; ++ *pLen = 41; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_KEY_ADM:\n >")); ++ for( i=0; iAsfData.Mib.KeyAdministrator[i] )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("<\n")); ++ } ++ else { ++ *pLen = 41; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_KEY_GEN: ++ if( *pLen >= 41 ) { ++ AsfArray2Hex( pBuf+1, 40, pAC->AsfData.Mib.KeyGenerator ); ++ *pBuf = (SK_U8) 40; ++ *pLen = 41; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_KEY_GEN:\n >")); ++ for( i=0; iAsfData.Mib.KeyGenerator[i] )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("<\n")); ++ } ++ else { ++ *pLen = 41; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_PAR_1: ++ if( *pLen >= 1 ) { ++ *( (SK_U8 *) pBuf ) = pAC->AsfData.Mib.Reserved[Id-OID_SKGE_ASF_PAR_1]; ++ *pLen = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_PAR_X: --\n")); ++ } ++ else { ++ *pLen = 1; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_FWVER_OID: ++ // returns the firmware revision to GUI ++ if (*pLen >= ASF_FWVER_MAXBUFFLENGTH) { ++ for (i=0; i < ASF_FWVER_MAXBUFFLENGTH; i++ ) { ++ // maybe we should lock the access to FwVersionString against reading/writing at the same time? ++ *((SK_U8 *)pBuf+i) = pAC->AsfData.FwVersionString[i]; ++ } ++ *pLen = ASF_FWVER_MAXBUFFLENGTH; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_FWVER_OID: %d\n", *pLen)); ++ } ++ else { ++ // set the right length ++ *pLen = ASF_FWVER_MAXBUFFLENGTH; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ break; ++ ++ case OID_SKGE_ASF_ACPI_OID: ++ // returns ACPI/ASF table (ASF_ACPI_MAXBUFFLENGTH bytes) to GUI ++ if ( (pAC->AsfData.Mib.Acpi.length > 0) && (pAC->AsfData.Mib.Acpi.length <= ASF_ACPI_MAXBUFFLENGTH) ) { ++ if (*pLen >= pAC->AsfData.Mib.Acpi.length) { ++ // there is enough space in buffer for reporting ACPI buffer ++ for (i=0; i < pAC->AsfData.Mib.Acpi.length; i++) { ++ // maybe we should lock the access to Acpi.buffer against reading/writing at the same time? ++ *((SK_U8 *)pBuf+i) = pAC->AsfData.Mib.Acpi.buffer[i]; ++ } ++ *pLen = pAC->AsfData.Mib.Acpi.length; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_ACPI_OID: %d\n", *pLen)); ++ } ++ else { ++ // there is not enough space in buffer to report ACPI buffer ++ *pLen = ASF_ACPI_MAXBUFFLENGTH; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ } ++ else { ++ // no buffer to report ++ *pLen = 0; ++ } ++ break; ++ ++ case OID_SKGE_ASF_SMBUS_OID: ++ // set a request flag, that smbus info must be updated ++ pAC->AsfData.Mib.SMBus.UpdateReq = 1; ++ // returns SMBus table GUI ++ if ( (pAC->AsfData.Mib.SMBus.length > 0) && (pAC->AsfData.Mib.SMBus.length <= ASF_SMBUS_MAXBUFFLENGTH) ) { ++ if (*pLen >= pAC->AsfData.Mib.SMBus.length) { ++ // there is enough space in buffer for reporting ACPI buffer ++ for (i=0; i < pAC->AsfData.Mib.SMBus.length; i++) { ++ // maybe we should lock the access to SMBus.buffer against reading/writing at the same time? ++ *((SK_U8 *)pBuf+i) = pAC->AsfData.Mib.SMBus.buffer[i]; ++ } ++ *pLen = pAC->AsfData.Mib.SMBus.length; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID_SKGE_ASF_SMBUS_OID: %d\n", *pLen)); ++ } ++ else { ++ // there is not enough space in buffer to report SMBus buffer ++ *pLen = ASF_SMBUS_MAXBUFFLENGTH; ++ RetCode = SK_PNMI_ERR_TOO_SHORT; ++ } ++ } ++ else { ++ // no buffer to report ++ *pLen = 0; ++ } ++ break; ++ ++ case OID_SKGE_ASF_HB_CAP: ++ // oid not used ++ *pLen = 0; ++ break; ++ ++ default: ++ *pLen = 0; ++ RetCode = SK_ASF_PNMI_ERR_NOT_SUPPORTED; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OID not supported\n", pAC->AsfData.Mib.Ena )); ++ break; ++ } ++ ++ return(RetCode); ++} ++ ++ ++/****************************************************************************** ++* ++* SkAsfGet - ++* ++* Context: ++* init, pageable ++* ++* Returns: ++*/ ++int SkAsfGet( ++ SK_AC *pAC, /* the adapter context */ ++ SK_IOC IoC, /* I/O context */ ++ SK_U8 *pBuf, ++ unsigned int *pLen) ++{ ++ SK_U32 RetCode = SK_ASF_PNMI_ERR_OK; ++ ++ return(RetCode) ; ++} ++ ++ ++/****************************************************************************** ++* ++* SkAsfPreSet - ++* ++* Context: ++* init, pageable ++* ++* Returns: ++*/ ++int SkAsfPreSet( ++ SK_AC *pAC, /* the adapter context */ ++ SK_IOC IoC, /* I/O context */ ++ SK_U8 *pBuf, ++ unsigned int *pLen) ++{ ++ /* preset the Return code to error */ ++ SK_U32 RetCode = SK_ASF_PNMI_ERR_OK; ++ ++ return(RetCode); ++} ++ ++/****************************************************************************** ++* ++* SkAsfSet - ++* ++* Context: ++* init, pageable ++* ++* Returns: ++*/ ++int SkAsfSet( ++ SK_AC *pAC, /* the adapter context */ ++ SK_IOC IoC, /* I/O context */ ++ SK_U8 *pBuf, ++ unsigned int *pLen) ++{ ++ SK_U32 RetCode = SK_ASF_PNMI_ERR_OK; ++ ++ return(RetCode); ++} ++ ++SK_I8 SkAsfStartWriteDeferredFlash( SK_AC *pAC, SK_IOC IoC ) { ++ SK_I8 RetCode; ++ SK_EVPARA EventParam; ++ ++ RetCode = 1; ++ if( pAC->AsfData.StateWrSpi == 0 ) { ++ pAC->AsfData.StateWrSpi++; ++ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); ++ SkTimerStart(pAC, IoC, &pAC->AsfData.AsfTimerWrSpi, ++ 10000, SKGE_ASF, SK_ASF_EVT_TIMER_SPI_EXPIRED, ++ EventParam); ++ RetCode = 0; ++ } ++ ++ return( RetCode ); ++} ++ ++SK_I8 SkAsfWriteDeferredFlash( SK_AC *pAC, SK_IOC IoC ) { ++ SK_I8 RetCode; ++ SK_U8 StartAgain; ++ ++ RetCode = 1; // unsuccessfull ++ StartAgain = 0; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" WriteDeferredFlash: State:%d\n", pAC->AsfData.StateWrSpi )); ++ ++#ifdef _XXX_ ++ ++ switch( pAC->AsfData.StateWrSpi ) { ++ case 0: // idle State ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" WriteDeferredFlash: idle\n")); ++ break; ++ ++ case 1: // erase SPI flash sector ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" WriteDeferredFlash: Erase flash\n")); ++ if (spi_flash_erase(pAC, ASF_SPI_SECTOR, ASF_SPI_SECTOR_SIZE) == 0 ) { // successfull ++ RetCode = 0; ++ StartAgain = 1; ++ pAC->AsfData.StateWrSpi++; ++ } ++ else ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" WriteDeferredFlash: Error Erase flash\n")); ++ break; ++ ++ default: ++ // 128 * 0x100 (256) Bytes ++ if( pAC->AsfData.StateWrSpi <= 129 ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, (" WriteDeferredFlash: Write addr:0x%x size:0x%x\n", ++ ASF_SPI_SECTOR+((pAC->AsfData.StateWrSpi-2)*0x100), 0x100 )); ++ if (spi_flash_manage(pAC, ++ &pAC->AsfData.SpiBuf[(pAC->AsfData.StateWrSpi-2)*0x100], ++ ASF_SPI_SECTOR+((pAC->AsfData.StateWrSpi-2)*0x100), ++ 0x100, SPI_WRITE) == 0 ) { ++ RetCode = 0; ++ StartAgain = 1; ++ pAC->AsfData.StateWrSpi++; ++ } ++ else ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" WriteDeferredFlash: Error Write addr:0x%x size:0x%x\n", ++ ASF_SPI_SECTOR+((pAC->AsfData.StateWrSpi-2)*0x100), 0x100 )); ++ } ++ else { ++ // Finish ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" WriteDeferredFlash: Finish\n")); ++ RetCode = 1; ++ } ++ break; ++ ++ } // switch( pAC->AsfData.StateWrSpi ) ++ ++ if( StartAgain ) { ++ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); ++ SkTimerStart(pAC, IoC, &pAC->AsfData.AsfTimerWrSpi, ++ 10000, SKGE_ASF, SK_ASF_EVT_TIMER_SPI_EXPIRED, ++ EventParam); ++ } ++ else { ++ pAC->AsfData.StateWrSpi = 0; ++ pAC->AsfData.Mib.WriteToFlash = 0; ++ } ++ ++#endif // _XXX_ ++ ++ return( RetCode ); ++} ++ ++ ++/***************************************************************************** ++* ++* SkAsfEvent - Event handler ++* ++* Description: ++* Handles the following events: ++* SK_ASF_EVT_TIMER_EXPIRED When a hardware counter overflows an ++* ++* Returns: ++* Always 0 ++*/ ++int SkAsfEvent( ++ SK_AC *pAC, /* Pointer to adapter context */ ++ SK_IOC IoC, /* IO context handle */ ++ SK_U32 Event, /* Event-Id */ ++ SK_EVPARA Param) /* Event dependent parameter */ ++{ ++ ++ switch(Event) ++ { ++ case SK_ASF_EVT_TIMER_EXPIRED: ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("ASF: SkAsfEvent -> Timer expired\n" )); ++ SkAsfTimer( pAC, IoC ); ++ break; ++ ++ case SK_ASF_EVT_TIMER_SPI_EXPIRED: ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("ASF: SkAsfEvent -> TimerWrSpi expired State:%d\n", ++ // pAC->AsfData.StateWrSpi )); ++ SkAsfWriteDeferredFlash( pAC, IoC ); ++ break; ++ ++ case SK_ASF_EVT_TIMER_HCI_EXPIRED: ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("ASF: SkAsfEvent -> TimerWrHci expired GlHciState:%d\n", ++ // pAC->AsfData.GlHciState )); ++ SkAsfHci( pAC, IoC, 1 ); ++ break; ++ ++ default: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("ASF: SkAsfEvent -> Unknown Event:0x%x\n", Event )); ++ break; ++ } ++ return(0); /* Success. */ ++} /* SkAsfEvent */ ++ ++/***************************************************************************** ++* ++* SkAsfTimer - general ASF timer ++* ++* Description: ++* ++* Returns: ++* Always 0 ++*/ ++void SkAsfTimer( ++SK_AC *pAC, /* Pointer to adapter context */ ++SK_IOC IoC ) /* IO context handle */ { ++ ++ SK_EVPARA EventParam; ++ SK_U8 i, NewAddr; ++ SK_U8 lRetCode; ++ SK_U8 TmpBuffer[128]; ++ SK_U8 Ind; ++ SK_U8 Length; ++ SK_U8 *pHciRecBuf; ++ ++ AsfWatchCpu(pAC, IoC, 50 ); ++ ++ pHciRecBuf = NULL; ++ ++ // check, whether IP address has changed ++ NewAddr = 0; ++ for( i=0; i<4; i++ ) { ++ if( pAC->IpAddr[i] != pAC->AsfData.Mib.IpSource[i] ) { ++ NewAddr = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: New IP Addr detected\n")); ++ } ++ } ++ ++ if( pAC->AsfData.Mib.NewParam > 1 ) { ++ pAC->AsfData.Mib.NewParam--; ++ } ++ ++ switch( pAC->AsfData.GlHciState ) { ++ /*------------------------------------------------------------------------------------------------------ ++ * check for changes in config data ++ *----------------------------------------------------------------------------------------------------*/ ++ case 0: ++ if (pAC->AsfData.OpMode == SK_GEASF_MODE_ASF) { ++ if(pAC->AsfData.LastGlHciState == 255) { ++ pAC->AsfData.LastGlHciState = 0; ++ pAC->AsfData.GlHciState = 100; // Fetch ASF configuration from FW ++ pAC->AsfData.Mib.PattUpReq = 1; // ...and update pattern ram ++ } ++ else { ++ if ( (pAC->AsfData.Mib.SMBus.UpdateReq >= 1) && (pAC->AsfData.GlHciState == 0) ) { ++ // lock this mechanism, if the GlHciState goes really to the "SMBus update state" ++ // pAC->AsfData.Mib.SMBus.UpdateReq = 0; ++ ++ // go to SMBus update state ++ pAC->AsfData.GlHciState = 20; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("Go to State 20\n")); ++ } ++ ++ if ( (pAC->AsfData.Mib.NewParam == 1) || (NewAddr && pAC->AsfData.Mib.Ena)) { ++ pAC->AsfData.GlHciState = 50; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: Start Update ASF config data\n")); ++ } ++ ++ if ( pAC->AsfData.VpdInitOk == 0 ) { ++ pAC->AsfData.GlHciState = 1; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: Start Init Vpd \n")); ++ } ++ } ++ #ifdef ASF_FW_WD ++ // FW WD functionality ++ if( pAC->AsfData.FwWdIntervall > 1 ) ++ pAC->AsfData.FwWdIntervall--; ++ if( pAC->AsfData.FwWdIntervall == 1 ) { ++ pAC->AsfData.GlHciState = 1; // go to check alive ++ } ++ #endif ++ } ++ else { ++ if (pAC->AsfData.OpMode == SK_GEASF_MODE_IPMI) { ++ ++ if ( (NewAddr == 1) || ++ (pAC->AsfData.ActivePort != (SK_U8)(pAC->ActivePort & 0xff)) || ++ (pAC->AsfData.PrefPort != (SK_U8)(pAC->Rlmt.Net[0].PrefPort & 0xff)) || ++ (pAC->AsfData.Mib.RlmtMode != (SK_U8)(pAC->Rlmt.NumNets & 0xff)) ) { ++ ++ // config has changed for IPMI ++ pAC->AsfData.GlHciState = 30; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ++ ("SkAsfTimer: IPMI update config with %d 0x%08x 0x%08x\n", ++ NewAddr, pAC->ActivePort, pAC->Rlmt.Net[0].PrefPort, pAC->Rlmt.NumNets)); ++ } ++ ++ // check the ipmi firmware ++ if( pAC->AsfData.FwWdIntervall > 1 ) { ++ pAC->AsfData.FwWdIntervall--; ++ } ++ else { ++ pAC->AsfData.GlHciState = 1; // go to check alive ++ } ++ } ++ } ++ break; ++ ++ /*------------------------------------------------------------------------------------------------------ ++ * Do VPD init ++ * Due to the SPI/VPD problem (A1), VpdInit MUST NOT be invoked while the ASF FW is running from flash. ++ * Therefore we do it here, while the ASF FW is running in the RamIdleLoop ++ *----------------------------------------------------------------------------------------------------*/ ++ case 1: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CHECK_ALIVE, 0, 0, 0, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ pAC->AsfData.GlHciState++; ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ++ // ("SkAsfTimer: *** CPU is running (%d) ***\n", pAC->AsfData.OpMode)); ++ // CheckAlive was initiated by WD ++ if( pAC->AsfData.FwWdIntervall == 1 ) { ++ pAC->AsfData.GlHciState = 0; ++ pAC->AsfData.FwWdIntervall = 10; ++ } ++ } ++ if( lRetCode == HCI_EN_CMD_ERROR ) { ++ pAC->AsfData.GlHciState = 255; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: *** CPU is NOT running !!! ***\n")); ++ AsfResetCpu( IoC ); ++ AsfRunCpu( IoC ); ++ // CheckAlive was initiated by WD ++ if( pAC->AsfData.FwWdIntervall == 1 ) { ++ pAC->AsfData.GlHciState = 0; ++ pAC->AsfData.FwWdIntervall = 60; ++ } ++ } ++ break; ++ ++ case 2: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_ENTER_RAM_IDLE, 0, 0, 0, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ pAC->AsfData.GlHciState++; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sent ENTER_RAM_IDLE \n")); ++ } ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 3: ++ if( pAC->AsfData.VpdInitOk == 0 ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: VpdInit\n")); ++ if (VpdInit(pAC, IoC) == 0) { ++ pAC->AsfData.VpdInitOk = 1; ++ pAC->AsfData.GlHciState++; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfTimer: VPD init o.k.\n")); ++ } ++ else ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfTimer: VPD init error\n")); ++ } ++ else ++ pAC->AsfData.GlHciState++; ++ break; ++ case 4: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_LEAVE_RAM_IDLE, 0, 0, 0, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ pAC->AsfData.GlHciState++; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sent LEAVE_RAM_IDLE \n")); ++ } ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ case 5: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_UPDATE_OWN_MACADDR, 0, 0, 0, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ if(pAC->AsfData.NewGuid) ++ pAC->AsfData.GlHciState = 50; // Write default parameters to SEEPROM ++ else { ++ pAC->AsfData.GlHciState = 100; // Fetch ASF configuration from FW ++ pAC->AsfData.Mib.PattUpReq = 1; // ...and update pattern ram ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sent LEAVE_RAM_IDLE \n")); ++ } ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ ++ /*------------------------------------------------------------------------------------------------------ ++ * updates SMBus structure via HCI ++ *----------------------------------------------------------------------------------------------------*/ ++ case 20: ++ // If there is a request for updating, we work it out and go to idle state. ++ pAC->AsfData.Mib.SMBus.UpdateReq = 0; ++ ++ // get SMBus infos from FW ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_SMBUS_INFOS, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ Length = *(pHciRecBuf + 1); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: SMBus info update via HCI l:%d\n", Length)) ++ ++ pAC->AsfData.Mib.SMBus.length = 0; ++ for( i=0; (iAsfData.Mib.SMBus.length += 1; ++ pAC->AsfData.Mib.SMBus.buffer[i] = *(pHciRecBuf+2+i); ++ } ++ pAC->AsfData.GlHciState = 0; // go to idle ++ } ++ if (lRetCode == HCI_EN_CMD_ERROR) { ++ pAC->AsfData.GlHciState = 255; ++ } ++ break; ++ ++ ++ /*------------------------------------------------------------------------------------------------------ ++ * IPMI states 30...36 ++ *----------------------------------------------------------------------------------------------------*/ ++ ++ case 30: ++ // RLMT mode has changed (only relevant in IPMI operation mode) ++ // in IPMI operation mode, we use the YASF_HOSTCMD_CFG_SET_RSP_ENABLE message ++ // as indicator for RLMT mode / Dual Net mode ++ // pAC->AsfData.Mib.RlmtMode > 1 => Dual Net Mode On ++ // else => RLMT Mode On ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ++ ("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_RSP_ENABLE 0x%x -> 0x%x\n", pAC->AsfData.Mib.RlmtMode, pAC->Rlmt.NumNets)); ++ ++ pAC->AsfData.Mib.RlmtMode = (SK_U8)(pAC->Rlmt.NumNets & 0xff); ++ ++ if (pAC->AsfData.Mib.RlmtMode > 1) { ++ // switch to Dual net mode ++ if (pAC->AsfData.DualMode == SK_GEASF_Y2_DUALPORT) { ++ // enable pattern for port b ++ YlciEnablePattern(pAC, IoC, 1, 4); // RSP pattern ++ YlciEnablePattern(pAC, IoC, 1, 6); // RMCP pattern ++ } ++ ++ // enable pattern for port a ++ YlciEnablePattern(pAC, IoC, 0, 4); // RSP pattern ++ YlciEnablePattern(pAC, IoC, 0, 6); // RMCP pattern ++ } ++ ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_RSP_ENABLE; ++ TmpBuffer[Ind++] = 1 + 2; // Length ++ TmpBuffer[Ind++] = pAC->AsfData.Mib.RlmtMode; ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ ++ case 31: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 32: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_ACTIVE_PORT act 0x%x -> 0x%x pref 0x%x -> 0x%x\n", pAC->AsfData.ActivePort, pAC->ActivePort, pAC->AsfData.PrefPort, pAC->Rlmt.Net[0].PrefPort)); ++ ++ pAC->AsfData.ActivePort = (SK_U8)(pAC->ActivePort & 0xff); ++ pAC->AsfData.PrefPort = (SK_U8)(pAC->Rlmt.Net[0].PrefPort & 0xff); ++ ++ // write always pattern enable for the active port ++ if (pAC->AsfData.Mib.RlmtMode <= 1) { ++ // we are in rlmt mode ++ if (pAC->AsfData.ActivePort == 1) { ++ if (pAC->AsfData.DualMode == SK_GEASF_Y2_DUALPORT) { ++ // enable pattern for port b ++ YlciEnablePattern(pAC, IoC, 1, 4); // RSP pattern ++ YlciEnablePattern(pAC, IoC, 1, 6); // RMCP pattern ++ } ++ ++ // disable pattern for port a ++ YlciDisablePattern(pAC, IoC, 0, 4); // RSP pattern ++ YlciDisablePattern(pAC, IoC, 0, 6); // RMCP pattern ++ } ++ else { ++ // enable pattern for port a ++ YlciEnablePattern(pAC, IoC, 0, 4); // RSP pattern ++ YlciEnablePattern(pAC, IoC, 0, 6); // RMCP pattern ++ ++ if (pAC->AsfData.DualMode == SK_GEASF_Y2_DUALPORT) { ++ // disable pattern for port b ++ YlciDisablePattern(pAC, IoC, 1, 4); // RSP pattern ++ YlciDisablePattern(pAC, IoC, 1, 6); // RMCP pattern ++ } ++ } ++ } ++ ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_ACTIVE_PORT; ++ TmpBuffer[Ind++] = 1 + 3; // Length ++ TmpBuffer[Ind++] = pAC->AsfData.ActivePort; ++ ++ // preferred port ++ if (pAC->AsfData.PrefPort == 2) { ++ // note: 0 = "auto", 1 = port A, 2 = port B, ++ TmpBuffer[Ind++] = 1; // port B ++ } ++ else { ++ TmpBuffer[Ind++] = 0; // port A ++ } ++ ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ ++ case 33: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE) ) { ++ pAC->AsfData.GlHciState++; // next state ++ } ++ if( lRetCode == HCI_EN_CMD_ERROR ) { ++ pAC->AsfData.GlHciState = 255; // error state ++ } ++ break; ++ ++ case 34: ++ // Comment: Error? Empty IpAddr! -> No SW-Assignment for the BMC-IP ++ // printk("Omitting Command 34 <- not implemented\n"); ++ pAC->AsfData.GlHciState++; ++ break; ++ ++ case 35: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) { ++ pAC->AsfData.GlHciState++; // finisch ++ } ++ if( lRetCode == HCI_EN_CMD_ERROR ) { ++ pAC->AsfData.GlHciState = 255; // error ++ } ++ break; ++ ++ case 36: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_FW_VERSION_STRING, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ Length = *(pHciRecBuf + 1); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_FW_VERSION_STRING l:%d\n",Length)) ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" >")) ++ for( i=0; (i<79)&&(iAsfData.FwVersionString[i] = *(pHciRecBuf+2+i); ++ pAC->AsfData.FwVersionString[i+1] = 0; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("%c",pAC->AsfData.FwVersionString[i])) ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("<\n")) ++ pAC->AsfData.GlHciState = 254; // go to finish ++ } ++ if( lRetCode == HCI_EN_CMD_ERROR ) { ++ pAC->AsfData.GlHciState = 255; // error state ++ } ++ break; ++ ++ /*------------------------------------------------------------------------------------------------------ ++ * Send new ASF configuration data to FW (SEEPROM) ++ *----------------------------------------------------------------------------------------------------*/ ++ /* YASF_HOSTCMD_CFG_SET_ASF_ENABLE */ ++ case 50: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_ASF_ENABLE\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_ASF_ENABLE; ++ TmpBuffer[Ind++] = 1 + 2; // Length ++ TmpBuffer[Ind++] = pAC->AsfData.Mib.Ena; ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 51: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_RSP_ENABLE */ ++ case 52: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_RSP_ENABLE\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_RSP_ENABLE; ++ TmpBuffer[Ind++] = 1 + 2; // Length ++ TmpBuffer[Ind++] = pAC->AsfData.Mib.RspEnable; ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 53: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_RETRANS */ ++ case 54: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_RETRANS\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_RETRANS; ++ TmpBuffer[Ind++] = 1 + 2; // Length ++ TmpBuffer[Ind++] = (SK_U8) pAC->AsfData.Mib.Retrans; ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 55: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_RETRANS_INT */ ++ case 56: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_RETRANS_INT\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_RETRANS_INT; ++ TmpBuffer[Ind++] = 2 + 2; // Length ++ TmpBuffer[Ind++] = (SK_U8)((pAC->AsfData.Mib.RetransInt >> 8) & 0x000000FF); ++ TmpBuffer[Ind++] = (SK_U8)((pAC->AsfData.Mib.RetransInt >> 0) & 0x000000FF); ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 57: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_HB_ENABLE */ ++ case 58: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_HB_ENABLE\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_HB_ENABLE; ++ TmpBuffer[Ind++] = 1 + 2; // Length ++ TmpBuffer[Ind++] = (SK_U8) pAC->AsfData.Mib.HbEna; ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 59: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_HB_INT */ ++ case 60: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_HB_INT\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_HB_INT; ++ TmpBuffer[Ind++] = 2 + 2; // Length ++ TmpBuffer[Ind++] = (SK_U8)((pAC->AsfData.Mib.HbInt >> 8) & 0x000000FF); ++ TmpBuffer[Ind++] = (SK_U8)((pAC->AsfData.Mib.HbInt >> 0) & 0x000000FF); ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 61: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_DRWD_ENABLE */ ++ case 62: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_DRWD_ENABLE\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_DRWD_ENABLE; ++ TmpBuffer[Ind++] = 1 + 2; // Length ++ TmpBuffer[Ind++] = (SK_U8) pAC->AsfData.Mib.WdEna; ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 63: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_DRWD_INT */ ++ case 64: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_DRWD_INT\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_DRWD_INT; ++ TmpBuffer[Ind++] = 2 + 2; // Length ++ TmpBuffer[Ind++] = (SK_U8)((pAC->AsfData.Mib.WdTime >> 8) & 0x000000FF); ++ TmpBuffer[Ind++] = (SK_U8)((pAC->AsfData.Mib.WdTime >> 0) & 0x000000FF); ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 65: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_IP_DESTINATION */ ++ case 66: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_IP_DESTINATION\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_IP_DESTINATION; ++ TmpBuffer[Ind++] = 4 + 2; // Length ++ for( i=0; i<4; i++ ) ++ TmpBuffer[Ind++] = pAC->AsfData.Mib.IpDest[i]; ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 67: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_IP_SOURCE */ ++ case 68: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_IP_SOURCE\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_IP_SOURCE; ++ TmpBuffer[Ind++] = 4 + 2; // Length ++ for( i=0; i<4; i++ ) ++ TmpBuffer[Ind++] = pAC->IpAddr[i]; ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 69: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) { ++ for( i=0; i<4; i++ ) ++ pAC->AsfData.Mib.IpSource[i] = pAC->IpAddr[i]; ++ #ifdef ASF_FW_ARP_RESOLVE ++ pAC->AsfData.GlHciState = 150; // do ARP resolve ++ #else ++ pAC->AsfData.GlHciState++; ++ #endif ++ } ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_MAC_DESTINATION */ ++ case 70: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_MAC_DESTINATION\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_MAC_DESTINATION; ++ TmpBuffer[Ind++] = 6 + 2; // Length ++ for( i=0; i<6; i++ ) ++ TmpBuffer[Ind++] = pAC->AsfData.Mib.MacDest[i]; ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 71: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_COMMUNITY_NAME */ ++ case 72: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_COMMUNITY_NAME\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_COMMUNITY_NAME; ++ TmpBuffer[Ind++] = 2; // Length ++ for( i=0; i<64; i++ ) { ++ TmpBuffer[1]++; ++ TmpBuffer[Ind++] = pAC->AsfData.Mib.CommunityName[i]; ++ if( TmpBuffer[Ind-1] == 0 ) ++ break; ++ } ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 73: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_RSP_KEY_1 */ ++ case 74: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_RSP_KEY_1\n >")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_RSP_KEY_1; ++ TmpBuffer[Ind++] = 20 + 2; // Length ++ for( i=0; i<20; i++ ) { ++ TmpBuffer[Ind++] = pAC->AsfData.Mib.KeyOperator[i]; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("%02x",pAC->AsfData.Mib.KeyOperator[i] )); ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n" )); ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 75: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_RSP_KEY_2 */ ++ case 76: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_RSP_KEY_2\n >")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_RSP_KEY_2; ++ TmpBuffer[Ind++] = 20 + 2; // Length ++ for( i=0; i<20; i++ ) { ++ TmpBuffer[Ind++] = pAC->AsfData.Mib.KeyAdministrator[i]; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("%02x",pAC->AsfData.Mib.KeyAdministrator[i] )); ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n" )); ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 77: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ /* YASF_HOSTCMD_CFG_SET_RSP_KEY_3 */ ++ case 78: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_RSP_KEY_3\n >")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_RSP_KEY_3; ++ TmpBuffer[Ind++] = 20 + 2; // Length ++ for( i=0; i<20; i++ ) { ++ TmpBuffer[Ind++] = pAC->AsfData.Mib.KeyGenerator[i]; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("%02x",pAC->AsfData.Mib.KeyGenerator[i] )); ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n" )); ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 79: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)){ ++ if(pAC->AsfData.ChipMode == SK_GEASF_CHIP_Y2) { ++ pAC->AsfData.GlHciState++; ++ } ++ else { ++ pAC->AsfData.GlHciState+=2; ++ } ++ } ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ case 80: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending YASF_HOSTCMD_CFG_SET_ACTIVE_PORT\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_CFG_SET_ACTIVE_PORT; ++ TmpBuffer[Ind++] = 1 + 3; // Length ++ TmpBuffer[Ind++] = pAC->AsfData.ActivePort; ++ TmpBuffer[Ind++] = pAC->AsfData.ActivePort; // Preferred port not set directly in RLMT ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 0, ASF_HCI_NOWAIT, 0 ); ++ pAC->AsfData.GlHciState++; ++ break; ++ case 81: ++ lRetCode = AsfHciGetState( pAC ); ++ if( (lRetCode == HCI_EN_CMD_READY) || (lRetCode == HCI_EN_CMD_IDLE)) ++ pAC->AsfData.GlHciState++; ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ case 82: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_STORE_CONFIG, 0, 0, 0, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sent YASF_HOSTCMD_CFG_STORE_CONFIG\n")); ++ pAC->AsfData.GlHciState = 100; ++ // check, whether ASF Enable has changed ++ if( pAC->AsfData.Mib.ConfigChange & 0x01 ) { ++ // set/reset asf enable ++ if( pAC->AsfData.Mib.Ena ) { ++ AsfEnable(pAC, IoC ); ++ /* Force initialization of the pattern ram ++ * (important for the very first enable of ASF) ++ */ ++ pAC->AsfData.Mib.ConfigChange |= 0x02; ++ } ++ else { ++ AsfDisable(pAC, IoC ); ++ } ++ } ++ // check, whether RSP Enable has changed ++ if( pAC->AsfData.Mib.ConfigChange & 0x02 ) { ++ AsfSetUpPattern( pAC, IoC, 0 ); // Port 0 ++ if(pAC->AsfData.ChipMode == SK_GEASF_CHIP_Y2) { ++ AsfSetUpPattern( pAC, IoC, 1 ); // Port 1 ++ } ++ } ++ pAC->AsfData.Mib.ConfigChange = 0; ++ pAC->AsfData.Mib.NewParam = 0; ++ } ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ /*------------------------------------------------------------------------------------------------------ ++ * Get ASF configuration data from FW (SEEPROM) ++ *----------------------------------------------------------------------------------------------------*/ ++ ++ case 100: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_ASF_ENABLE, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ pAC->AsfData.Mib.Ena = *(pHciRecBuf+2); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_ASF_ENABLE:0x%x \n", ++ pAC->AsfData.Mib.Ena )); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 101: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_RSP_ENABLE, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ pAC->AsfData.Mib.RspEnable = *(pHciRecBuf+2); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_RSP_ENABLE:0x%x \n", ++ pAC->AsfData.Mib.RspEnable )); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 102: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_RETRANS, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ pAC->AsfData.Mib.Retrans = *(pHciRecBuf+2); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_RETRANS:0x%x \n", ++ pAC->AsfData.Mib.Retrans )); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 103: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_RETRANS_INT, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ pAC->AsfData.Mib.RetransInt = ((SK_U32)*(pHciRecBuf+2)) << 8; ++ pAC->AsfData.Mib.RetransInt |= ((SK_U32)*(pHciRecBuf+3)) << 0; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_RETRANS_INT:0x%x \n", ++ pAC->AsfData.Mib.RetransInt )); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 104: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_HB_ENABLE, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ pAC->AsfData.Mib.HbEna = *(pHciRecBuf+2); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_HB_ENABLE:0x%x \n", ++ pAC->AsfData.Mib.HbEna )); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 105: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_HB_INT, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ pAC->AsfData.Mib.HbInt = ((SK_U32)*(pHciRecBuf+2)) << 8; ++ pAC->AsfData.Mib.HbInt |= ((SK_U32)*(pHciRecBuf+3)) << 0; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_HB_INT:0x%x \n", ++ pAC->AsfData.Mib.HbInt)); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 106: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_DRWD_ENABLE, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ pAC->AsfData.Mib.WdEna = *(pHciRecBuf+2); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_DRWD_ENABLE:0x%x \n", ++ pAC->AsfData.Mib.WdEna )); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 107: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_DRWD_INT, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ pAC->AsfData.Mib.WdTime = ((SK_U32)*(pHciRecBuf+2)) << 8; ++ pAC->AsfData.Mib.WdTime |= ((SK_U32)*(pHciRecBuf+3)) << 0; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_DRWD_INT:0x%x \n", ++ pAC->AsfData.Mib.HbInt)); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 108: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_IP_DESTINATION, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ for( i=0; i<4; i++ ) ++ pAC->AsfData.Mib.IpDest[i] = *(pHciRecBuf+2+i); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_IP_DESTINATION %d.%d.%d.%d\n", ++ pAC->AsfData.Mib.IpDest[0], pAC->AsfData.Mib.IpDest[1], ++ pAC->AsfData.Mib.IpDest[2], pAC->AsfData.Mib.IpDest[3])); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 109: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_IP_SOURCE, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ for( i=0; i<4; i++ ) ++ pAC->AsfData.Mib.IpSource[i] = *(pHciRecBuf+2+i); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_IP_SOURCE %d.%d.%d.%d\n", ++ pAC->AsfData.Mib.IpSource[0], pAC->AsfData.Mib.IpSource[1], ++ pAC->AsfData.Mib.IpSource[2], pAC->AsfData.Mib.IpSource[3])); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 110: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_MAC_DESTINATION, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ for( i=0; i<6; i++ ) ++ pAC->AsfData.Mib.MacDest[i] = *(pHciRecBuf+2+i); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ++ ("SkAsfTimer: YASF_HOSTCMD_CFG_GET_MAC_DESTINATION %02x-%02x-%02x-%02x-%02x-%02x\n", ++ pAC->AsfData.Mib.MacDest[0], pAC->AsfData.Mib.MacDest[1], pAC->AsfData.Mib.MacDest[2], ++ pAC->AsfData.Mib.MacDest[3], pAC->AsfData.Mib.MacDest[4], pAC->AsfData.Mib.MacDest[5])); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 111: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_COMMUNITY_NAME, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ Length = *(pHciRecBuf + 1); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_COMMUNITY_NAME l:%d >",Length)) ++ for( i=0; (i<63)&&(iAsfData.Mib.CommunityName[i] = *(pHciRecBuf+2+i); ++ pAC->AsfData.Mib.CommunityName[i+1] = 0; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("%c",pAC->AsfData.Mib.CommunityName[i])) ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("<\n")) ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 112: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_RSP_KEY_1, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ Length = *(pHciRecBuf + 1); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_RSP_KEY_1: (%d)\n >", Length)); ++ for( i=0; (i<20)&&(iAsfData.Mib.KeyOperator[i] = *(pHciRecBuf+2+i); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("%02x", pAC->AsfData.Mib.KeyOperator[i])); ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("<\n")); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 113: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_RSP_KEY_2, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ Length = *(pHciRecBuf + 1); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_RSP_KEY_2: (%d)\n >", Length)); ++ for( i=0; (i<20)&&(iAsfData.Mib.KeyAdministrator[i] = *(pHciRecBuf+2+i); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("%02x", pAC->AsfData.Mib.KeyAdministrator[i])); ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("<\n")); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 114: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_RSP_KEY_3, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ Length = *(pHciRecBuf + 1); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_RSP_KEY_3: (%d)\n >", Length)); ++ for( i=0; (i<20)&&(iAsfData.Mib.KeyGenerator[i] = *(pHciRecBuf+2+i); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("%02x", pAC->AsfData.Mib.KeyGenerator[i])); ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("<\n")); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 115: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_FW_VERSION_STRING, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ Length = *(pHciRecBuf + 1); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_FW_VERSION_STRING l:%d\n",Length)) ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" >")) ++ for( i=0; (i<79)&&(iAsfData.FwVersionString[i] = *(pHciRecBuf+2+i); ++ pAC->AsfData.FwVersionString[i+1] = 0; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("%c",pAC->AsfData.FwVersionString[i])) ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("<\n")) ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 116: ++ // get SMBus infos from FW ++ ++ // do not ask twice ++ pAC->AsfData.Mib.SMBus.UpdateReq = 0; ++ ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_SMBUS_INFOS, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ Length = *(pHciRecBuf + 1); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: YASF_HOSTCMD_CFG_GET_SMBUS_INFOS l:%d\n", Length)) ++ ++ pAC->AsfData.Mib.SMBus.length = 0; ++ for( i=0; (iAsfData.Mib.SMBus.length += 1; ++ pAC->AsfData.Mib.SMBus.buffer[i] = *(pHciRecBuf+2+i); ++ if ( (i%16) != 0) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" 0x%02x", pAC->AsfData.Mib.SMBus.buffer[i])) ++ } ++ else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n > 0x%02x", pAC->AsfData.Mib.SMBus.buffer[i])) ++ } ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n\n")) ++ if(pAC->AsfData.ChipMode == SK_GEASF_CHIP_Y2) { ++ pAC->AsfData.GlHciState++; ++ } ++ else { ++ pAC->AsfData.GlHciState+=2; ++ } ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ ++ if( lRetCode == HCI_EN_CMD_ERROR ) { ++ pAC->AsfData.GlHciState = 255; ++ } ++ break; ++ ++ case 117: ++ lRetCode = AsfHciSendCommand(pAC, IoC, YASF_HOSTCMD_CFG_GET_ACTIVE_PORT, 0, 0, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ Length = *(pHciRecBuf + 1); ++ pAC->AsfData.ActivePort = *(pHciRecBuf + 2); ++ pAC->AsfData.PrefPort = *(pHciRecBuf + 3); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ++ ("SkAsfTimer: YASF_HOSTCMD_CFG_GET_ACTIVE_PORT: %d %d\n >", ++ pAC->AsfData.ActivePort, pAC->AsfData.PrefPort)); ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) ++ pAC->AsfData.GlHciState = 255; ++ break; ++ ++ case 118: ++ if (pAC->AsfData.Mib.PattUpReq != 0) { ++ pAC->AsfData.Mib.PattUpReq = 0; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ++ ("SkAsfTimer: update pattern in state %d with rsp %d\n", ++ pAC->AsfData.GlHciState, pAC->AsfData.Mib.RspEnable)); ++ ++ AsfSetUpPattern(pAC, IoC, 0); // Port 0 ++ if(pAC->AsfData.ChipMode == SK_GEASF_CHIP_Y2) { ++ AsfSetUpPattern(pAC, IoC, 1); // Port 1 ++ } ++ } ++ pAC->AsfData.GlHciState = 254; ++ break; ++ ++ /*------------------------------------------------------------------------------------------------------ ++ * ARP resolve ++ *----------------------------------------------------------------------------------------------------*/ ++ ++ case 150: ++ ++#ifdef ASF_FW_ARP_RESOLVE ++ if (pAC->AsfData.OpMode == SK_GEASF_MODE_ASF) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: sending ARP REQUEST\n")); ++ Ind = 0; ++ TmpBuffer[Ind++] = YASF_HOSTCMD_ARP_RESOLVE; ++ TmpBuffer[Ind++] = 4 + 2; // Length ++ for( i=0; i<4; i++ ) ++ TmpBuffer[Ind++] = pAC->AsfData.Mib.IpDest[i]; ++ AsfSetUpPattern( pAC, IoC, pAC->AsfData.ActivePort ); // prepare pattern logik for ARP handling ++ YlciEnablePattern ( pAC, IoC, pAC->AsfData.ActivePort, 5 ); // enable the ARP pattern ++ AsfEnable(pAC, IoC ); // enable ASF logik for receiving ARP response ++ lRetCode = AsfHciSendData(pAC, IoC, TmpBuffer, 1, ASF_HCI_NOWAIT, 0 ); ++ if( lRetCode == HCI_EN_CMD_READY ) { ++ YlciDisablePattern ( pAC, IoC, pAC->AsfData.ActivePort, 5 ); // disable the ARP pattern ++ if( pAC->AsfData.Mib.Ena == 0 ) ++ AsfDisable(pAC, IoC ); ++ // Fetch received data from HCI interface ++ AsfHciGetData( pAC, &pHciRecBuf ); ++ for( i=0; i<6; i++ ) ++ pAC->AsfData.Mib.MacDest[i] = *(pHciRecBuf+2+i); ++ ++ if( (pAC->AsfData.Mib.MacDest[0] == 0) && (pAC->AsfData.Mib.MacDest[1] == 0) && ++ (pAC->AsfData.Mib.MacDest[2] == 0) && (pAC->AsfData.Mib.MacDest[3] == 0) && ++ (pAC->AsfData.Mib.MacDest[4] == 0) && (pAC->AsfData.Mib.MacDest[5] == 0) ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ++ ("SkAsfTimer: YASF_HOSTCMD_ARP_RESOLVE NOT RESOLVED !!\n")); ++ } ++ else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ++ ("SkAsfTimer: YASF_HOSTCMD_ARP_RESOLVE %02x-%02x-%02x-%02x-%02x-%02x\n", ++ pAC->AsfData.Mib.MacDest[0], pAC->AsfData.Mib.MacDest[1], pAC->AsfData.Mib.MacDest[2], ++ pAC->AsfData.Mib.MacDest[3], pAC->AsfData.Mib.MacDest[4], pAC->AsfData.Mib.MacDest[5])); ++ ++ } ++ ++ pAC->AsfData.GlHciState++; ++ } // if( lRetCode == HCI_EN_CMD_READY ) ++ if( lRetCode == HCI_EN_CMD_ERROR ) { ++ pAC->AsfData.GlHciState = 255; ++ YlciDisablePattern ( pAC, IoC, pAC->AsfData.ActivePort, 5 ); // disable the ARP pattern ++ if( pAC->AsfData.Mib.Ena == 0 ) ++ AsfDisable(pAC, IoC ); ++ } ++ } ++ else { ++ pAC->AsfData.GlHciState++; ++ } ++ ++#else // ASF_FW_ARP_RESOLVE ++ ++ pAC->AsfData.GlHciState++; ++ ++#endif ++ break; ++ ++ case 151: ++ pAC->AsfData.GlHciState = 70; ++ break; ++ ++ /*------------------------------------------------------------------------------------------------------ ++ * Finish state ++ *----------------------------------------------------------------------------------------------------*/ ++ case 254: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: ***** Finish *****\n")); ++ pAC->AsfData.FwError = 0; ++ pAC->AsfData.GlHciState = 0; ++ pAC->AsfData.Mib.NewParam = 0; ++ pAC->AsfData.LastGlHciState = pAC->AsfData.GlHciState; ++ break; ++ ++ /*------------------------------------------------------------------------------------------------------ ++ * Error handling ++ *----------------------------------------------------------------------------------------------------*/ ++ case 255: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: ***** ERROR *****\n")); ++ pAC->AsfData.FwError++; ++ if(pAC->AsfData.FwError > 2) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("***** CPU RESET *****\n")); ++ AsfSmartResetCpu( pAC, IoC, ASF_RESET_HOT ); ++ AsfRunCpu( IoC ); ++ } ++ pAC->AsfData.LastGlHciState = pAC->AsfData.GlHciState; // Store Error State ++ pAC->AsfData.GlHciState = 0; ++ pAC->AsfData.Mib.NewParam = 0; ++ pAC->AsfData.Hci.Status = HCI_EN_CMD_IDLE; ++ break; ++ } // switch( &pAC->AsfData.GlHciState == 0 ) { ++ ++ if( pAC->AsfData.GlHciState != pAC->AsfData.LastGlHciState ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfTimer: New State %d -> %d\n", pAC->AsfData.LastGlHciState, pAC->AsfData.GlHciState)); ++ if( pAC->AsfData.LastGlHciState != 255 ) { // Don't overwrite Error State, it will be checked in case 0 ++ pAC->AsfData.LastGlHciState = pAC->AsfData.GlHciState; ++ } ++ } ++ ++ if( pAC->AsfData.GlHciState == 0 ) { // idle ++ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); ++ SkTimerStart(pAC, IoC, &pAC->AsfData.AsfTimer, ++ 1000000, SKGE_ASF, SK_ASF_EVT_TIMER_EXPIRED, ++ EventParam); ++ } ++ else { ++ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); ++ SkTimerStart(pAC, IoC, &pAC->AsfData.AsfTimer, ++ 30000, SKGE_ASF, SK_ASF_EVT_TIMER_EXPIRED, ++ EventParam); ++ } ++ ++ return; ++} ++ ++#if (0) ++/***************************************************************************** ++* ++* AsfReadConfiguration ++* ++* Description: ++* ++* Returns: ++* ++*/ ++NDIS_STATUS AsfReadConfiguration( ++IN SK_AC *pAc, ++IN NDIS_HANDLE ConfigHandle, ++IN NDIS_HANDLE WrapperConfigContext) ++{ ++ SK_DBG_MSG(pAc, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ++ ("AsfReadConfiguration (No data loaded !)\n" )); ++ ++ return (NDIS_STATUS_SUCCESS); ++} ++#endif ++ ++ ++/***************************************************************************** ++* ++* SkAsfShowMib ++* ++* Description: ++* ++* Returns: ++* ++*/ ++void SkAsfShowMib( SK_AC *pAC ) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("ASF MIB (h):\n") ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, ("------------\n") ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, (" Ena: %d\n", pAC->AsfData.Mib.Ena ) ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, (" Retrans: %d Int:%d\n", pAC->AsfData.Mib.Retrans, ++ pAC->AsfData.Mib.RetransInt ) ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, (" HbEna: %d Int:%d\n", pAC->AsfData.Mib.HbEna, ++ pAC->AsfData.Mib.HbInt ) ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, (" WdEna: %d Time:%d\n", pAC->AsfData.Mib.WdEna, ++ pAC->AsfData.Mib.WdTime ) ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, (" IpDest (d): %d.%d.%d.%d\n", ++ pAC->AsfData.Mib.IpDest[0], pAC->AsfData.Mib.IpDest[1], ++ pAC->AsfData.Mib.IpDest[2], pAC->AsfData.Mib.IpDest[3] ) ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, (" IpSource (d): %d.%d.%d.%d\n", ++ pAC->AsfData.Mib.IpSource[0], pAC->AsfData.Mib.IpSource[1], ++ pAC->AsfData.Mib.IpSource[2], pAC->AsfData.Mib.IpSource[3] ) ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, (" MacDest: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ pAC->AsfData.Mib.MacDest[0], pAC->AsfData.Mib.MacDest[1], ++ pAC->AsfData.Mib.MacDest[2], pAC->AsfData.Mib.MacDest[3], ++ pAC->AsfData.Mib.MacDest[4], pAC->AsfData.Mib.MacDest[5] ) ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, (" MacSource: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ pAC->AsfData.Mib.MacSource[0], pAC->AsfData.Mib.MacSource[1], ++ pAC->AsfData.Mib.MacSource[2], pAC->AsfData.Mib.MacSource[3], ++ pAC->AsfData.Mib.MacSource[4], pAC->AsfData.Mib.MacSource[5] ) ); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL, (" CommunityName: >%s<\n", pAC->AsfData.Mib.CommunityName ) ); ++} ++ ++/***************************************************************************** ++* ++* AsfCpuState ++* ++* Description: ++* ++* Returns: ++* ++*/ ++SK_U8 AsfCpuState( SK_IOC IoC ) { ++ SK_U32 TmpVal32; ++ ++ SK_IN32( IoC, REG_ASF_STATUS_CMD, &TmpVal32 ); ++ ++ if( TmpVal32 & BIT_3 ) ++ return( ASF_CPU_STATE_RESET ); ++ ++ if( TmpVal32 & BIT_2 ) ++ return( ASF_CPU_STATE_RUNNING ); ++ ++ return( ASF_CPU_STATE_UNKNOWN ); ++} ++ ++/***************************************************************************** ++* ++* AsfResetCpu ++* ++* Description: ++* ++* Returns: ++* ++*/ ++void AsfResetCpu(SK_IOC IoC) { ++ SK_U32 TmpVal32; ++ ++ SK_IN32( IoC, REG_ASF_STATUS_CMD, &TmpVal32 ); ++ TmpVal32 &= ~(BIT_2 | BIT_3); ++ TmpVal32 |= BIT_3; ++ SK_OUT32( IoC, REG_ASF_STATUS_CMD, TmpVal32 ); ++} ++ ++/***************************************************************************** ++* ++* AsfSmartResetCpu ++* ++* Description: ++* ++* Returns: ++* ++*/ ++SK_U8 AsfSmartResetCpu( SK_AC *pAC, SK_IOC IoC, SK_U8 Cold ) { ++SK_U64 StartTime, CurrTime; ++SK_U8 ResetCommand; ++ ++ if( Cold ) ++ ResetCommand = YASF_HOSTCMD_RESET_COLD; ++ else ++ ResetCommand = YASF_HOSTCMD_RESET; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("AsfSmartResetCpu -> \n")); ++ ++ // check, whether cpu is already in reset state... ++ if( AsfCpuState( IoC ) != ASF_CPU_STATE_RESET ) { ++ // ...if not, try SmartReset ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("AsfSmartResetCpu -> Send reset command\n")); ++ if( AsfHciSendCommand( pAC, IoC, ResetCommand, 0, 0, 0, ASF_HCI_WAIT, 2 ) != HCI_EN_CMD_READY ) { ++ // if Smart Reset fails, do hard reset ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("AsfSmartResetCpu -> Do hard reset\n")); ++ AsfResetCpu( IoC ); ++ } ++ StartTime = SkOsGetTime(pAC); ++ while( AsfCpuState( IoC ) != ASF_CPU_STATE_RESET ) { ++ CurrTime = SkOsGetTime(pAC); ++ if ( (CurrTime - StartTime) > (SK_TICKS_PER_SEC*1) ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("AsfSmartResetCpu -> Error: CPU is not in reset state - Do hard reset\n")); ++ AsfResetCpu( IoC ); ++ break; ++ } ++ } // while( AsfCpuState( IoC ) != ASF_CPU_STATE_RESET ) { ++ ++ if( AsfCpuState( IoC ) == ASF_CPU_STATE_RESET ) ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("AsfSmartResetCpu -> CPU is in reset state\n")); ++ ++ } // if( AsfCpuState( IoC ) != ASF_CPU_STATE_RESET ) { ++ else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("AsfSmartResetCpu -> Cpu already in reset state\n")); ++ } ++ ++ return( 1 ); ++} ++ ++/***************************************************************************** ++* ++* AsfSmartResetStateCpu ++* ++* Description: ++* ++* Returns: ++* ++*/ ++SK_U8 AsfSmartResetStateCpu( SK_AC *pAC, SK_IOC IoC ) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("Send AsfSmartResetStateCpu\n")); ++ return( AsfHciSendCommand( pAC, IoC, YASF_HOSTCMD_RESET_STATE, 0, 0, 0, ASF_HCI_WAIT, 3 ) ); ++} ++ ++/***************************************************************************** ++* ++* AsfRunCpu ++* ++* Description: ++* ++* Returns: ++* ++*/ ++void AsfRunCpu( SK_IOC IoC ) { ++ SK_U32 TmpVal32; ++ ++ SK_IN32( IoC, REG_ASF_STATUS_CMD, &TmpVal32 ); ++ TmpVal32 &= ~(BIT_2 | BIT_3); ++ TmpVal32 |= BIT_3; // Set to Reset state (Clk running) ++ SK_OUT32( IoC, REG_ASF_STATUS_CMD, TmpVal32 ); ++ TmpVal32 &= ~(BIT_2 | BIT_3); ++ TmpVal32 |= BIT_2; // Set to running state ++ SK_OUT32( IoC, REG_ASF_STATUS_CMD, TmpVal32 ); ++} ++ ++ ++/***************************************************************************** ++* ++* AsfCheckAliveCpu ++* ++* Description: ++* ++* Returns: ++* ++*/ ++SK_U8 AsfCheckAliveCpu( SK_AC *pAC, SK_IOC IoC ) { ++SK_U8 Alive; ++ ++ //SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("AsfCheckAliveCpu -> \n")); ++ Alive = 0; // Not alive ++ // check, whether cpu is in reset state... ++ if( AsfCpuState( IoC ) != ASF_CPU_STATE_RESET ) { ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("AsfSmartResetCpu -> Send Check Alive command\n")); ++ if( AsfHciSendCommand( pAC, IoC, YASF_HOSTCMD_CHECK_ALIVE, 0, 0, 0, ASF_HCI_WAIT, 2 ) != HCI_EN_CMD_READY ) { ++ // if Smart Reset fails, do hard reset ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("AsfCheckAliveCpu -> Not alive\n")); ++ } ++ else ++ Alive = 1; ++ } // if( AsfCpuState( IoC ) != ASF_CPU_STATE_RESET ) { ++ else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("AsfCheckAliveCpu -> *** CPU is in reset state ***\n")); ++ } ++ ++ return( Alive ); ++} ++ ++/***************************************************************************** ++* ++* SkAsfHci ++* ++* Description: ++* ++* Returns: ++* ++*/ ++void SkAsfHci( ++SK_AC *pAC, /* Pointer to adapter context */ ++SK_IOC IoC, ++SK_U8 ToEna ) /* IO context handle */ { ++ ++ SK_EVPARA EventParam; ++ SK_U32 Cmd; ++ SK_U32 SendValue; ++ SK_U32 RecValue; ++ ++ if (pAC->AsfData.Hci.Status == HCI_EN_CMD_IDLE) ++ return; ++ ++ pAC->AsfData.Hci.Cycles++; ++ ++ // Check, whether there is something to do ++ SK_IN32( IoC, ASF_HCI_CMDREG, &Cmd ); ++ if( pAC->AsfData.Hci.OldCmdReg != Cmd ) { ++ pAC->AsfData.Hci.OldCmdReg = Cmd; ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfHci CmdReg: 0x%x\n", Cmd )); ++ } ++ ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" CmdReg: 0x%x\n", Cmd )); ++ ++ if ((Cmd & (ASF_HCI_READ | ASF_HCI_WRITE | ASF_HCI_CMD_RD_READY | ASF_HCI_CMD_WR_READY | ASF_HCI_UNSUCCESS)) == 0) ++ { ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfHci State: 0x%x\n", pAC->AsfData.Hci.Status )); ++ switch( pAC->AsfData.Hci.Status ) { ++ ++ case HCI_EN_CMD_WRITING: ++ SendValue = 0; ++ if (pAC->AsfData.Hci.SendLength > 0) ++ { ++ pAC->AsfData.Hci.SendLength--; ++ SendValue = ((SK_U32)pAC->AsfData.Hci.TransmitBuf[pAC->AsfData.Hci.SendIndex +0]) << 24; ++ if (pAC->AsfData.Hci.SendLength > 0) ++ { ++ pAC->AsfData.Hci.SendLength--; ++ SendValue += ((SK_U32)pAC->AsfData.Hci.TransmitBuf[pAC->AsfData.Hci.SendIndex +1]) << 16; ++ if (pAC->AsfData.Hci.SendLength > 0) ++ { ++ pAC->AsfData.Hci.SendLength--; ++ SendValue += ((SK_U32)pAC->AsfData.Hci.TransmitBuf[pAC->AsfData.Hci.SendIndex +2]) << 8; ++ if (pAC->AsfData.Hci.SendLength > 0) ++ { ++ pAC->AsfData.Hci.SendLength--; ++ SendValue += ((SK_U32)pAC->AsfData.Hci.TransmitBuf[pAC->AsfData.Hci.SendIndex +3]) << 0; ++ } ++ } ++ } ++ } ++ ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" SendValue: 0x%x l:%d\n", ++ // SendValue, pAC->AsfData.Hci.SendLength )); ++ SK_OUT32( IoC, ASF_HCI_DATAREG, SendValue); ++ if (pAC->AsfData.Hci.SendLength == 0) ++ { ++ SK_OUT32( IoC, ASF_HCI_CMDREG, ASF_HCI_WRITE | ASF_HCI_CMD_WR_READY | ASF_HCI_UNSUCCESS | (pAC->AsfData.Hci.SendIndex/4)); ++ pAC->AsfData.Hci.Status = HCI_EN_CMD_WAIT; ++ } ++ else ++ { ++ SK_OUT32( IoC, ASF_HCI_CMDREG, ASF_HCI_WRITE | ASF_HCI_UNSUCCESS | (pAC->AsfData.Hci.SendIndex/4)); ++ pAC->AsfData.Hci.SendIndex += 4; ++ } ++ break; ++ ++ case HCI_EN_CMD_WAIT: ++ if( pAC->AsfData.Hci.ExpectResponse ) { ++ pAC->AsfData.Hci.Status = HCI_EN_CMD_READING; ++ pAC->AsfData.Hci.ReceiveIndex = 0; ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Wait for response\n" )); ++ SK_OUT32( IoC, ASF_HCI_CMDREG, ASF_HCI_READ | ASF_HCI_UNSUCCESS | (pAC->AsfData.Hci.ReceiveIndex/4)); ++ } ++ else { ++ pAC->AsfData.Hci.Status = HCI_EN_CMD_READY; ++ pAC->AsfData.Hci.ReceiveBuf[1] = 0; /*Length*/ ++ } ++ break; ++ ++ case HCI_EN_CMD_READING: ++ SK_IN32( IoC, ASF_HCI_DATAREG, &RecValue ); ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" RecValue: 0x%x\n", RecValue )); ++ pAC->AsfData.Hci.ReceiveBuf[pAC->AsfData.Hci.ReceiveIndex+3] = (SK_U8) (RecValue >> 0) & 0x000000ff; ++ pAC->AsfData.Hci.ReceiveBuf[pAC->AsfData.Hci.ReceiveIndex+2] = (SK_U8) (RecValue >> 8) & 0x000000ff; ++ pAC->AsfData.Hci.ReceiveBuf[pAC->AsfData.Hci.ReceiveIndex+1] = (SK_U8) (RecValue >> 16) & 0x000000ff; ++ pAC->AsfData.Hci.ReceiveBuf[pAC->AsfData.Hci.ReceiveIndex+0] = (SK_U8) (RecValue >> 24) & 0x000000ff; ++ pAC->AsfData.Hci.ReceiveIndex += 4; ++ //SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" RecValue: 0x%x RecIndex:%d l:%d\n", ++ // RecValue,pAC->AsfData.Hci.ReceiveIndex, pAC->AsfData.Hci.ReceiveBuf[1] )); ++ if( pAC->AsfData.Hci.ReceiveBuf[1] > pAC->AsfData.Hci.ReceiveIndex ) { /* check length*/ ++ SK_OUT32( IoC, ASF_HCI_CMDREG, ASF_HCI_READ | ASF_HCI_UNSUCCESS | (pAC->AsfData.Hci.ReceiveIndex/4)); ++ } ++ else { ++ SK_OUT32( IoC, ASF_HCI_CMDREG, ASF_HCI_CMD_RD_READY ); ++ pAC->AsfData.Hci.Status = HCI_EN_CMD_READY; ++ } ++ break; ++ ++ case HCI_EN_CMD_READY: ++ break; ++ ++ } // switch( pAC->AsfData.Hci.Status ) { ++ ++ pAC->AsfData.Hci.To = 0; ++ ++ } // if ((Cmd & (ASF_HCI_READ | ASF_HCI_WRITE | ASF_HCI_CMD_RD_READY | ASF_HCI_CMD_WR_READY)) == 0) ++ else { ++ ++ if( ToEna ) ++ pAC->AsfData.Hci.To++; ++ /* Timeout ! */ ++ if( pAC->AsfData.Hci.To > ASF_HCI_TO ) { ++ pAC->AsfData.Hci.Status = HCI_EN_CMD_ERROR; ++ } ++ } ++ ++ if( ToEna ) { ++ if( pAC->AsfData.Hci.Status != HCI_EN_CMD_IDLE && ++ pAC->AsfData.Hci.Status != HCI_EN_CMD_READY && ++ pAC->AsfData.Hci.Status != HCI_EN_CMD_ERROR ) { ++ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); ++ SkTimerStart(pAC, IoC, &pAC->AsfData.Hci.AsfTimerHci, /* 10ms */ ++ 10000, SKGE_ASF, SK_ASF_EVT_TIMER_HCI_EXPIRED, ++ EventParam); ++ } ++ } ++ ++ return; ++} ++ ++ ++/***************************************************************************** ++* ++* AsfHciGetData ++* ++* Description: ++* ++* Returns: ++* ++*/ ++SK_U8 AsfHciGetData( SK_AC *pAC, SK_U8 **pHciRecBuf ) { ++ *pHciRecBuf = pAC->AsfData.Hci.ReceiveBuf; ++ return( 1 ); ++} ++ ++/***************************************************************************** ++* ++* AsfHciGetState ++* ++* Description: ++* ++* Returns: ++* ++*/ ++SK_U8 AsfHciGetState( SK_AC *pAC ) { ++ SK_U8 Stat; ++ SK_U64 DiffTime; ++ ++ Stat = pAC->AsfData.Hci.Status; ++ if( Stat == HCI_EN_CMD_READY ) { ++ pAC->AsfData.Hci.Status = HCI_EN_CMD_IDLE; ++ DiffTime = SkOsGetTime(pAC) - pAC->AsfData.Hci.Time; ++// SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" *** Cycles:%d Time:%lums\n", ++// pAC->AsfData.Hci.Cycles, DiffTime / (10*1000) )); ++ } ++ return( Stat ); ++} ++ ++ ++/***************************************************************************** ++* ++* AsfHciSendCommand ++* ++* Description: ++* ++* Returns: ++* ++*/ ++SK_U8 AsfHciSendCommand( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U8 Command, ++SK_U8 Par1, ++SK_U8 Par2, ++SK_U8 ExpectResponse, ++SK_U8 Wait, ++SK_U8 Retry ) { ++ SK_U8 RetCode; ++ SK_U8 Message[4]; ++ SK_U64 StartTime; ++ SK_U64 CurrTime; ++ SK_U64 TmpTime; ++ ++ do { ++ if( pAC->AsfData.Hci.Status == HCI_EN_CMD_IDLE ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Send Command cmd:0x%x p1:0x%x p2:0x%x wait:%d Retry:%d\n", ++ Command, Par1, Par2, Wait, Retry )); ++ Message[0] = Command; ++ Message[1] = 2; // Length ++ Message[2] = Par1; ++ Message[3] = Par2; ++ RetCode = AsfHciSendMessage(pAC, IoC, Message, 4, ExpectResponse, Wait ); ++ } ++ ++ if( Wait ) { ++ StartTime = SkOsGetTime(pAC); ++ ++ TmpTime = StartTime + 1; ++ do { ++ CurrTime = SkOsGetTime(pAC); ++ if( CurrTime > TmpTime ) { ++ SkAsfHci( pAC, IoC, 0 ); ++ ++ TmpTime = CurrTime + 1; ++ } ++ RetCode = AsfHciGetState( pAC ); ++ ++ if ( (CurrTime - StartTime) > (SK_TICKS_PER_SEC*1) ) { ++ RetCode = HCI_EN_CMD_ERROR; ++ break; ++ } ++ } while( (RetCode != HCI_EN_CMD_READY) && (RetCode != HCI_EN_CMD_ERROR) ); ++ ++ if( (RetCode != HCI_EN_CMD_READY) ) { ++ pAC->AsfData.Hci.Status = HCI_EN_CMD_IDLE; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Command not confirmed RetCode:0x%x\n", RetCode )); ++ } ++ } // if( wait... ++ else { ++ RetCode = AsfHciGetState( pAC ); ++ if( (RetCode == HCI_EN_CMD_ERROR) ) { ++ pAC->AsfData.Hci.Status = HCI_EN_CMD_IDLE; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Command not confirmed RetCode:0x%x\n", RetCode )); ++ } ++ } ++ ++ if( Retry > 0 ) ++ Retry--; ++ else ++ break; ++ ++ } while ( Wait && (RetCode != HCI_EN_CMD_READY) ); ++ ++ if( (RetCode == HCI_EN_CMD_READY) ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Command successfully conveyed\n")); ++#if (0) ++ if (Wait) ++ printk(" Time required: %lu\n", (CurrTime-StartTime)); ++#endif ++ } ++ ++ return( RetCode ); ++} ++ ++/***************************************************************************** ++* ++* AsfHciSendData ++* ++* Description: ++* ++* Returns: ++* ++*/ ++SK_U8 AsfHciSendData( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U8 *Buffer, ++SK_U8 ExpectResponse, ++SK_U8 Wait, ++SK_U8 Retry ) { ++ SK_U8 RetCode; ++ SK_U64 StartTime; ++ SK_U64 CurrTime; ++ SK_U64 TmpTime; ++ SK_U8 Length; ++ SK_U8 Command; ++ ++ do { ++ if( pAC->AsfData.Hci.Status == HCI_EN_CMD_IDLE ) { ++ Command = *(Buffer + 0 ); ++ Length = *(Buffer + 1); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Send Data cmd:0x%x Length:%d wait:%d Retry:%d\n", ++ Command, Length, Wait, Retry )); ++ RetCode = AsfHciSendMessage(pAC, IoC, Buffer, Length, ExpectResponse, Wait ); ++ } ++ if( Wait ) { ++ StartTime = SkOsGetTime(pAC); ++ TmpTime = StartTime + 1; ++ do { ++ CurrTime = SkOsGetTime(pAC); ++ if( CurrTime > TmpTime ) { ++ SkAsfHci( pAC, IoC, 0 ); ++ TmpTime = CurrTime + 1; ++ } ++ RetCode = AsfHciGetState( pAC ); ++ if ( (CurrTime - StartTime) > (SK_TICKS_PER_SEC*1) ) { ++ RetCode = HCI_EN_CMD_ERROR; ++ break; ++ } ++ } while ( (RetCode == HCI_EN_CMD_WRITING) || (RetCode == HCI_EN_CMD_WAIT) ); ++ ++ if( RetCode != HCI_EN_CMD_READY ) { ++ pAC->AsfData.Hci.Status = HCI_EN_CMD_IDLE; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Data not confirmed RetCode:0x%x\n", RetCode )); ++ } ++ } // if( wait... ++ else { ++ RetCode = AsfHciGetState( pAC ); ++ if( RetCode == HCI_EN_CMD_ERROR ) { ++ pAC->AsfData.Hci.Status = HCI_EN_CMD_IDLE; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Data not confirmed RetCode:0x%x\n", RetCode )); ++ } ++ } ++ if( Retry > 0 ) ++ Retry--; ++ else ++ break; ++ } while ( Wait && (RetCode != HCI_EN_CMD_READY) ); ++ ++ if( RetCode == HCI_EN_CMD_READY ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Data successfully conveyed\n")); ++ } ++ ++ return( RetCode ); ++} ++ ++/***************************************************************************** ++* ++* AsfHciSendMessage ++* ++* Description: ++* ++* Returns: ++* ++*/ ++SK_U8 AsfHciSendMessage( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U8 *message, ++SK_U8 length, ++SK_U8 ExpectResponse, ++SK_U8 Wait ) { ++ SK_U8 RetCode; ++ SK_U8 i; ++ SK_EVPARA EventParam; ++ ++ RetCode = 0; ++ ++ if( length > ASF_HCI_TRA_BUF_SIZE ) ++ return( RetCode ); ++ ++ if( pAC->AsfData.Hci.Status == HCI_EN_CMD_IDLE ) ++ { ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Send Message\n" )); ++ ++ SK_OUT32( IoC, ASF_HCI_CMDREG, (SK_U32) 0 ); ++ SK_OUT32( IoC, ASF_HCI_DATAREG, (SK_U32) 0 ); ++ for( i=0; iAsfData.Hci.TransmitBuf[i] = message[i]; ++ pAC->AsfData.Hci.SendLength = length; ++ if( ExpectResponse ) ++ pAC->AsfData.Hci.ExpectResponse = 1; ++ else ++ pAC->AsfData.Hci.ExpectResponse = 0; ++ pAC->AsfData.Hci.Status = HCI_EN_CMD_WRITING; ++ pAC->AsfData.Hci.OldCmdReg = 0; ++ pAC->AsfData.Hci.SendIndex = 0; ++ pAC->AsfData.Hci.Cycles = 0; ++ pAC->AsfData.Hci.Time = SkOsGetTime( pAC ); ++ RetCode = 1; // successfull ++ } ++ else ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Send Message -> Not Idle\n" )); ++ ++ ++ if( !Wait ) { ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Send Message -> Start Timer\n" )); ++ SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); ++ SkTimerStart(pAC, IoC, &pAC->AsfData.Hci.AsfTimerHci, ++ 10000, SKGE_ASF, SK_ASF_EVT_TIMER_HCI_EXPIRED, ++ EventParam); ++ } ++ ++ return( RetCode ); ++} ++ ++ ++void AsfWatchCpu( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U32 par ) { ++ ++#ifdef _XXX_ ++SK_U32 FwAlive, LastFetch; ++ ++ SK_IN32( IoC, B28_Y2_DATA_REG_4, &FwAlive ); ++ SK_IN32( IoC, 0x64, &LastFetch ); ++ if( LastFetch < 0x20000 ) ++ pAC->AsfData.FwError++; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("(%d) AsfWatchCpu: FwAlive:0x%x LastFetch:0x%x Err:%d\n", ++ par, FwAlive , LastFetch, pAC->AsfData.FwError )); ++#endif // _XXX_ ++ ++ return; ++} ++ ++ ++void AsfEnable( ++SK_AC *pAC, ++SK_IOC IoC ) { ++ SK_U32 TmpVal32; ++ ++ SK_IN32(IoC, B0_CTST, &TmpVal32); ++ TmpVal32 &= ~0x00003000; // clear bit13, bit12 ++ TmpVal32 |= 0x00002000; // set bit13 ++ SK_OUT32(IoC, B0_CTST, TmpVal32); ++ SK_OUT32(IoC, B0_CTST, Y2_ASF_ENABLE); ++ ++ pAC->GIni.GIAsfEnabled = SK_TRUE; // update asf flag for common modules ++} ++ ++void AsfDisable( ++SK_AC *pAC, ++SK_IOC IoC ) { ++ SK_U32 TmpVal32; ++ ++ SK_IN32(IoC, B0_CTST, &TmpVal32); ++ TmpVal32 &= ~0x00003000; // clear bit13, bit12 ++ TmpVal32 |= 0x00001000; // set bit13 ++ SK_OUT32(IoC, B0_CTST, TmpVal32); ++ SK_OUT32(IoC, B0_CTST, Y2_ASF_DISABLE); ++ ++ pAC->GIni.GIAsfEnabled = SK_FALSE; // update asf flag for common modules ++} ++ ++ ++ ++/***************************************************************************** ++* ++* AsfWriteIpmiPattern ++* ++* Description: write all 3 pattern for IPMI to pattern ram ++* ++* Notes: none ++* ++* Context: none ++* ++* Returns: YLCI_SUCCESS ++* YLCI_ERROR ++* ++*/ ++ ++SK_I8 AsfWriteIpmiPattern( ++ SK_AC *pAC, ++ SK_IOC IoC, ++ SK_U8 port) ++{ ++ SK_I8 RetVal; ++ SK_U8 i, j; ++ SK_U32 idx; ++ SK_U32 PattRamCluster[ASF_YEC_PATTRAM_CLUSTER_WORDS]; ++ SK_U8 PattSrcByte[2]; // 2 pattern bytes to read/write in one cluster ++ SK_U32 TmpVal32; ++ SK_U32 mask; ++ SK_U8 pattern_no; ++ ++ RetVal = 1; // success ++ ++ if (RetVal == 1) { ++ ++ for (i = 0; (i < ASF_YEC_PATTRAM_CLUSTER_SIZE) && (RetVal == 1); i++) { ++ // pattern ram is organized into cluster (i is cluster index) ++ // _after_ writing a whole cluster (= 128bit), the pattern will be written into ram! ++ ++ // read a cluster ++ for (j=0; j < ASF_YEC_PATTRAM_CLUSTER_WORDS; j++) { ++ PattRamCluster[j] = 0; ++ } ++ ++ //----------------------- ++ // read source pattern 6 ++ //----------------------- ++ pattern_no = 6; ++ for (j=0; j < 2; j++) { ++ // we have 2 pattern bytes to read/write for one cluster ++ // i is cluster index ++ // j is byte index ++ idx = 2*i+j; ++ if (idx < 40) { ++ // we can read from our pattern pointer ++ PattSrcByte[j] = RMCP_FRAME_PATTERN[idx]; ++ ++ // read from our enable mask pointer ++ TmpVal32 = RMCP_PATTERN_MASK[idx/8]; ++ mask = 0x01 << (idx % 8); ++ ++ if ( (TmpVal32 & mask) != 0 ) { ++ // enable byte ++ PattRamCluster[j*2+1] |= (BIT_24 << pattern_no); ++ } ++ else { ++ // disable byte ++ PattRamCluster[j*2+1] &= ~(BIT_24 << pattern_no); ++ } ++ } ++ else { ++ // fill up with zeros ++ PattSrcByte[j] = 0; ++ // disable byte ++ PattRamCluster[j*2+1] &= ~(BIT_24 << pattern_no); ++ } ++ } ++ ++ // upper words are interesting here ++ idx = 1; ++ ++ // first byte ++ mask = 0x000000ff; ++ j = pattern_no % 4; ++ PattRamCluster[idx] &= ~(mask << 8 * j); // delete byte in word ++ mask = PattSrcByte[0]; ++ PattRamCluster[idx] |= (mask << 8 * j); // write pattern byte ++ ++ // second byte ++ mask = 0x000000ff; ++ PattRamCluster[idx+2] &= ~(mask << 8 * j); // delete byte in word ++ mask = PattSrcByte[1]; ++ PattRamCluster[idx+2] |= (mask << 8 * j); // write pattern byte ++ ++ //----------------------- ++ // read source pattern 5 ++ //----------------------- ++ pattern_no = 5; ++ for (j=0; j < 2; j++) { ++ // we have 2 pattern bytes to read/write for one cluster ++ // i is cluster index ++ // j is byte index ++ idx = 2*i+j; ++ if (idx < 40) { ++ // we can read from our pattern pointer ++ PattSrcByte[j] = ARP_FRAME_PATTERN[idx]; ++ ++ // read from our enable mask pointer ++ TmpVal32 = ARP_PATTERN_MASK[idx/8]; ++ mask = 0x01 << (idx % 8); ++ ++ if ( (TmpVal32 & mask) != 0 ) { ++ // enable byte ++ PattRamCluster[j*2+1] |= (BIT_24 << pattern_no); ++ } ++ else { ++ // disable byte ++ PattRamCluster[j*2+1] &= ~(BIT_24 << pattern_no); ++ } ++ } ++ else { ++ // fill up with zeros ++ PattSrcByte[j] = 0; ++ // disable byte ++ PattRamCluster[j*2+1] &= ~(BIT_24 << pattern_no); ++ } ++ } ++ ++ // upper words are interesting here ++ idx = 1; ++ ++ // first byte ++ mask = 0x000000ff; ++ j = pattern_no % 4; ++ PattRamCluster[idx] &= ~(mask << 8 * j); // delete byte in word ++ mask = PattSrcByte[0]; ++ PattRamCluster[idx] |= (mask << 8 * j); // write pattern byte ++ ++ // second byte ++ mask = 0x000000ff; ++ PattRamCluster[idx+2] &= ~(mask << 8 * j); // delete byte in word ++ mask = PattSrcByte[1]; ++ PattRamCluster[idx+2] |= (mask << 8 * j); // write pattern byte ++ ++ //----------------------- ++ // read source pattern 4 ++ //----------------------- ++ pattern_no = 4; ++ for (j=0; j < 2; j++) { ++ // we have 2 pattern bytes to read/write for one cluster ++ // i is cluster index ++ // j is byte index ++ idx = 2*i+j; ++ if (idx < 40) { ++ // we can read from our pattern pointer ++ PattSrcByte[j] = RSP_FRAME_PATTERN[idx]; ++ ++ // read from our enable mask pointer ++ TmpVal32 = RSP_PATTERN_MASK[idx/8]; ++ mask = 0x01 << (idx % 8); ++ ++ if ( (TmpVal32 & mask) != 0 ) { ++ // enable byte ++ PattRamCluster[j*2+1] |= (BIT_24 << pattern_no); ++ } ++ else { ++ // disable byte ++ PattRamCluster[j*2+1] &= ~(BIT_24 << pattern_no); ++ } ++ } ++ else { ++ // fill up with zeros ++ PattSrcByte[j] = 0; ++ // disable byte ++ PattRamCluster[j*2+1] &= ~(BIT_24 << pattern_no); ++ } ++ } ++ ++ // upper words are interesting here ++ idx = 1; ++ ++ // first byte ++ mask = 0x000000ff; ++ j = pattern_no % 4; ++ PattRamCluster[idx] &= ~(mask << 8 * j); // delete byte in word ++ mask = PattSrcByte[0]; ++ PattRamCluster[idx] |= (mask << 8 * j); // write pattern byte ++ ++ // second byte ++ mask = 0x000000ff; ++ PattRamCluster[idx+2] &= ~(mask << 8 * j); // delete byte in word ++ mask = PattSrcByte[1]; ++ PattRamCluster[idx+2] |= (mask << 8 * j); // write pattern byte ++ ++ // write a cluster ++ // after writing the last cluster word, the hardware will trigger writing all cluster words ++ for (j=0; j < ASF_YEC_PATTRAM_CLUSTER_WORDS; j++) { ++ idx = ASF_YEC_PATTRAM_CLUSTER_WORDS*ASF_YEC_PATTRAM_CLUSTER_BYTES*i + ASF_YEC_PATTRAM_CLUSTER_BYTES*j; ++ ++ if( port == 0 ) { ++ SK_OUT32( IoC, WOL_PATT_RAM_1+idx, PattRamCluster[j] ); ++ } ++ else { ++ SK_OUT32( IoC, WOL_PATT_RAM_2+idx, PattRamCluster[j] ); ++ } ++ } ++ } ++ } ++ ++ return (RetVal); ++} ++ ++void AsfSetUpPattern( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U8 port ) { ++ ++ SK_U8 TmpVal8; ++ SK_U16 TmpVal16; ++ SK_U32 TmpVal32; ++ ++ if( port > 1 ) ++ return; ++ ++ switch (pAC->AsfData.OpMode) { ++ case SK_GEASF_MODE_ASF: ++ // see "problems.txt" note #344 ++ // set MAC Rx fifo flush threshold register ++ // (please refer also to note #yuk_hw01) ++ SK_IN32(IoC, ASF_YEC_MAC_FIFO_FLUSHTHRES1+(port*0x80), &TmpVal32); ++ TmpVal32 &= ~0x7f; // delete bit 6:0 ++ TmpVal32 |= ASF_YLCI_MACRXFIFOTHRES; ++ SK_OUT32(IoC, ASF_YEC_MAC_FIFO_FLUSHTHRES1+(port*0x80), TmpVal32); ++ ++ // disable Wake Up Frame Unit before write to pattern ram ++ SK_IN16(IoC, ASF_YEC_PATTERN_CTRL1+(port*0x80), &TmpVal16); ++ TmpVal16 &= ~0x03; // clear bit 0, bit1 ++ TmpVal16 |= 0x01; // set bit 0 ++ SK_OUT16(IoC, ASF_YEC_PATTERN_CTRL1+(port*0x80), TmpVal16); ++ ++ // Set new pattern for ASF ++ // This will override the driver WOL pattern, but the driver is going to set ++ // the WOL pattern again before it "shut down" or "stand by" ++ if( pAC->AsfData.Mib.RspEnable ) { ++ // security is on - write ARP and RSP pattern ++ AsfWritePatternRam(pAC, IoC, port, 5, 6, 40, 40, ++ ARP_PATTERN_MASK, ARP_FRAME_PATTERN, ++ RSP_PATTERN_MASK, RSP_FRAME_PATTERN); ++ } ++ else { ++ // security is off - write ARP and RMCP pattern ++ AsfWritePatternRam(pAC, IoC, port, 5, 6, 40, 40, ++ ARP_PATTERN_MASK, ARP_FRAME_PATTERN, ++ RMCP_PATTERN_MASK, RMCP_FRAME_PATTERN); ++ } ++ ++ // set pattern length register ++ SK_IN32(IoC, ASF_YEC_PATTERN_LENGTH_R1_H+(port*0x80), &TmpVal32); ++ TmpVal32 &= ~(0x0000007f << 8*(5%4)); ++ TmpVal32 |= (40-1) << 8*(5%4); // write length-1 to pattern length register ++ SK_OUT32(IoC, ASF_YEC_PATTERN_LENGTH_R1_H+(port*0x80), TmpVal32); ++ // set pattern length register ++ SK_IN32(IoC, ASF_YEC_PATTERN_LENGTH_R1_H+(port*0x80), &TmpVal32); ++ TmpVal32 &= ~(0x0000007f << 8*(6%4)); ++ TmpVal32 |= (40-1) << 8*(6%4); // write length-1 to pattern length register ++ SK_OUT32(IoC, ASF_YEC_PATTERN_LENGTH_R1_H+(port*0x80), TmpVal32); ++ ++ // set ASF match enable register (incomming packets will redirect to ASF queue) ++ SK_IN8(IoC, ASF_YEC_PATTERN_MATCHENA1+(port*0x80), &TmpVal8); ++ TmpVal8 |= 0x40; // pattern 6 enable ++ SK_OUT8(IoC, ASF_YEC_PATTERN_MATCHENA1+(port*0x80), TmpVal8); ++ ++ // enable pattern pattno ++ SK_IN8(IoC, ASF_YEC_PATTERN_ENA1+(port*0x80), &TmpVal8); ++ TmpVal8 |= 0x40; // pattern 6 enable ++ SK_OUT8(IoC, ASF_YEC_PATTERN_ENA1+(port*0x80), TmpVal8); ++ ++ // enable Wake Up Frame Unit ++ SK_IN16(IoC, ASF_YEC_PATTERN_CTRL1+(port*0x80), &TmpVal16); ++ TmpVal16 &= ~0x03; // delete bit 0 and 1 ++ TmpVal16 |= 0x02; // set bit 1 ++ SK_OUT16(IoC, ASF_YEC_PATTERN_CTRL1+(port*0x80), TmpVal16); ++ break; ++ case SK_GEASF_MODE_IPMI: ++ // disable Wake Up Frame Unit before write to pattern ram ++ SK_IN16(IoC, ASF_YEC_PATTERN_CTRL1+(port*0x80), &TmpVal16); ++ TmpVal16 &= ~0x03; // clear bit 0, bit1 ++ TmpVal16 |= 0x01; // set bit 0 ++ SK_OUT16(IoC, ASF_YEC_PATTERN_CTRL1+(port*0x80), TmpVal16); ++ ++ // write all 3 pattern (RMCP, RSP and ARP) ++ AsfWriteIpmiPattern(pAC, IoC, port); ++ ++ // set pattern length register ++ SK_IN32(IoC, ASF_YEC_PATTERN_LENGTH_R1_H+(port*0x80), &TmpVal32); ++ TmpVal32 &= 0xff000000; // delete length for pattern 4, 5 and 6 ++ TmpVal32 |= 0x00272727; // set new length for pattern 4, 5 and 6 ++ SK_OUT32(IoC, ASF_YEC_PATTERN_LENGTH_R1_H+(port*0x80), TmpVal32); ++ ++ // set ASF match enable register (incomming packets will redirect to ASF queue) ++ SK_IN8(IoC, ASF_YEC_PATTERN_MATCHENA1+(port*0x80), &TmpVal8); ++ TmpVal8 = 0x50; // enable pattern 4 and 6 (do not enable arp pattern) ++ SK_OUT8(IoC, ASF_YEC_PATTERN_MATCHENA1+(port*0x80), TmpVal8); ++ ++ // enable pattern pattno ++ SK_IN8(IoC, ASF_YEC_PATTERN_ENA1+(port*0x80), &TmpVal8); ++ TmpVal8 = 0x50; // enable pattern 4 and 6 (do not enable arp pattern) ++ SK_OUT8(IoC, ASF_YEC_PATTERN_ENA1+(port*0x80), TmpVal8); ++ ++ // enable Wake Up Frame Unit ++ SK_IN16(IoC, ASF_YEC_PATTERN_CTRL1+(port*0x80), &TmpVal16); ++ TmpVal16 &= ~0x03; // delete bit 0 and 1 ++ TmpVal16 |= 0x02; // set bit 1 ++ SK_OUT16(IoC, ASF_YEC_PATTERN_CTRL1+(port*0x80), TmpVal16); ++ break; ++ default: ++ break; ++ } ++ ++ return; ++} ++ ++/***************************************************************************** ++* ++* AsfWritePatternRam ++* ++* Description: write to pattern ram ++* ++* Notes: none ++* ++* Context: none ++* ++* Returns: 1: SUCCESS ++* 0: YLCI_ERROR ++* ++*/ ++ ++SK_I8 AsfWritePatternRam( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U8 Port, /* for future use */ ++SK_U8 PatternId1, /* 0..6 */ ++SK_U8 PatternId2, /* 0..6 */ ++SK_U8 Length1, /* 1..128 bytes */ ++SK_U8 Length2, /* 1..128 bytes */ ++SK_U8 *pMask1, ++SK_U8 *pPattern1, ++SK_U8 *pMask2, ++SK_U8 *pPattern2) ++ ++{ ++ SK_U8 i, j; ++ SK_I8 RetVal; ++ SK_U32 idx; ++ SK_U32 PattRamCluster[ASF_YEC_PATTRAM_CLUSTER_WORDS]; ++ SK_U8 PattSrcByte1[2]; // 2 pattern bytes to read/write in one cluster ++ SK_U8 PattSrcByte2[2]; // 2 pattern bytes to read/write in one cluster ++ SK_U32 TmpVal32; ++ SK_U32 mask; ++ ++ RetVal = 1; // success ++ ++ // pattern size up to 128 bytes, pattern id can be 0...6 ++ if ( (Length1 <= SK_POW_PATTERN_LENGTH) && (PatternId1 < SK_NUM_WOL_PATTERN) ) { ++ ++ for (i = 0; (i < ASF_YEC_PATTRAM_CLUSTER_SIZE) && (RetVal == 1); i++) { ++ // pattern ram is organized into cluster (i is cluster index) ++ // _after_ writing a whole cluster (= 128bit), the pattern will be written into ram! ++ ++ // read a cluster ++ for (j=0; j < ASF_YEC_PATTRAM_CLUSTER_WORDS; j++) { ++ PattRamCluster[j] = 0; ++ } ++ // read source pattern 1 ++ for (j=0; j < 2; j++) { ++ // we have 2 pattern bytes to read/write for one cluster ++ // i is cluster index ++ // j is byte index ++ idx = 2*i+j; ++ if ( idx < Length1 ) { ++ // we can read from our pattern pointer ++ PattSrcByte1[j] = pPattern1[idx]; ++ ++ // read from our enable mask pointer ++ TmpVal32 = pMask1[idx/8]; ++ mask = 0x01 << (idx % 8); ++ ++ if ( (TmpVal32 & mask) != 0 ) { ++ // enable byte ++ PattRamCluster[j*2+1] |= (BIT_24 << PatternId1); ++ } ++ else { ++ // disable byte ++ PattRamCluster[j*2+1] &= ~(BIT_24 << PatternId1); ++ } ++ } ++ else { ++ // fill up with zeros ++ PattSrcByte1[j] = 0; ++ // disable byte ++ PattRamCluster[j*2+1] &= ~(BIT_24 << PatternId1); ++ } ++ } ++ // read source pattern 2 ++ for (j=0; j < 2; j++) { ++ // we have 2 pattern bytes to read/write for one cluster ++ // i is cluster index ++ // j is byte index ++ idx = 2*i+j; ++ if ( idx < Length2 ) { ++ // we can read from our pattern pointer ++ PattSrcByte2[j] = pPattern2[idx]; ++ ++ // read from our enable mask pointer ++ TmpVal32 = pMask2[idx/8]; ++ mask = 0x01 << (idx % 8); ++ ++ if ( (TmpVal32 & mask) != 0 ) { ++ // enable byte ++ PattRamCluster[j*2+1] |= (BIT_24 << PatternId2); ++ } ++ else { ++ // disable byte ++ PattRamCluster[j*2+1] &= ~(BIT_24 << PatternId2); ++ } ++ } ++ else { ++ // fill up with zeros ++ PattSrcByte2[j] = 0; ++ // disable byte ++ PattRamCluster[j*2+1] &= ~(BIT_24 << PatternId2); ++ } ++ } ++ // set our pattern into PattRamCluster[] ++ if (PatternId1 >= 4) { ++ // upper words are interesting here ++ idx = 1; ++ } ++ else { ++ // lower words are interesting here ++ idx = 0; ++ } ++ // first byte ++ mask = 0x000000ff; ++ j = PatternId1 % 4; ++ PattRamCluster[idx] &= ~(mask << 8 * j); // delete byte in word ++ mask = PattSrcByte1[0]; ++ PattRamCluster[idx] |= (mask << 8 * j); // write pattern byte ++ // second byte ++ mask = 0x000000ff; ++ PattRamCluster[idx+2] &= ~(mask << 8 * j); // delete byte in word ++ mask = PattSrcByte1[1]; ++ PattRamCluster[idx+2] |= (mask << 8 * j); // write pattern byte ++ ++ // set our pattern into PattRamCluster[] ++ if (PatternId2 >= 4) { ++ // upper words are interesting here ++ idx = 1; ++ } ++ else { ++ // lower words are interesting here ++ idx = 0; ++ } ++ // first byte ++ mask = 0x000000ff; ++ j = PatternId2 % 4; ++ PattRamCluster[idx] &= ~(mask << 8 * j); // delete byte in word ++ mask = PattSrcByte2[0]; ++ PattRamCluster[idx] |= (mask << 8 * j); // write pattern byte ++ // second byte ++ mask = 0x000000ff; ++ PattRamCluster[idx+2] &= ~(mask << 8 * j); // delete byte in word ++ mask = PattSrcByte2[1]; ++ PattRamCluster[idx+2] |= (mask << 8 * j); // write pattern byte ++ ++ // write a cluster ++ // after writing the last cluster word, the hardware will trigger writing all cluster words ++ for (j=0; j < ASF_YEC_PATTRAM_CLUSTER_WORDS; j++) { ++ idx = ASF_YEC_PATTRAM_CLUSTER_WORDS*ASF_YEC_PATTRAM_CLUSTER_BYTES*i + ASF_YEC_PATTRAM_CLUSTER_BYTES*j; ++ if( Port == 0 ) { ++ SK_OUT32( IoC, WOL_PATT_RAM_1+idx, PattRamCluster[j] ); ++ } ++ else { ++ SK_OUT32( IoC, WOL_PATT_RAM_2+idx, PattRamCluster[j] ); ++ } ++ } ++ } ++ } ++ else { ++ RetVal = 0; // error ++ } ++ ++ return(RetVal); ++} ++ ++SK_I8 YlciEnablePattern ( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U8 port, ++SK_U8 pattno ) ++{ ++ SK_U8 val8; ++ ++ if (port > 1) { ++ return (1); ++ } ++ ++ // set ASF match enable register (incomming packets will redirect to ASF queue) ++ SK_IN8(IoC, ASF_YEC_PATTERN_MATCHENA1+(port*0x80), &val8); ++ val8 |= (0x01 << pattno); ++ SK_OUT8(IoC, ASF_YEC_PATTERN_MATCHENA1+(port*0x80), val8); ++ ++ // enable pattern pattno ++ SK_IN8(IoC, ASF_YEC_PATTERN_ENA1+(port*0x80), &val8); ++ val8 |= (0x01 << pattno); ++ SK_OUT8(IoC, ASF_YEC_PATTERN_ENA1+(port*0x80), val8); ++ ++ return ( 1 ); ++} ++ ++SK_I8 YlciDisablePattern ( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U8 port, ++SK_U8 pattno ) ++{ ++ SK_U8 val8; ++ ++ // set ASF match enable register (incomming packets will redirect to ASF queue) ++ SK_IN8(IoC, ASF_YEC_PATTERN_MATCHENA1+(port*0x80), &val8); ++ val8 &= ~(0x01 << pattno); ++ SK_OUT8(IoC, ASF_YEC_PATTERN_MATCHENA1+(port*0x80), val8); ++ ++ // enable pattern pattno ++ SK_IN8(IoC, ASF_YEC_PATTERN_ENA1+(port*0x80), &val8); ++ val8 &= ~(0x01 << pattno); ++ SK_OUT8(IoC, ASF_YEC_PATTERN_ENA1+(port*0x80), val8); ++ ++ return ( 1 ); ++} ++ ++#if (0) ++ ++/***************************************************************************** ++* ++* SkAsfAcpi ++* ++* Description: Searches for the Root System Description Pointer "RSD PTR" ++* within the range of 0xE0000 .. 0xFFFFF (ACPI Spec 5.2.4.1). ++* The "RSD PTR" is the entry point of the ACPI data base. It ++* contains pointer to the "RSDT" (32bit) and "XSDT" (64bit) ++* tables, which in turn contain lists of pointers that are ++* pointing to ACPI sub tables e.g. "ASF!" . ++* ++* Notes: none ++* ++* Context: none ++* ++* Returns: 1: OK ++* 0: UNDEFINED ++* <0: Error Codes ++* ++*/ ++SK_I8 SkAsfAcpi( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U8 *pImage ) { ++ HANDLE SectionHandle; ++ NTSTATUS NtRet; ++ unsigned char *pU8; ++ PVOID BaseAddress; ++ ULONG CommitSize; ++ ULONG i; ++ LARGE_INTEGER MaxSize; ++ LARGE_INTEGER SectOffset; ++ SIZE_T ViewSize; ++ SK_U32 RsdtAddr; ++ SK_U64 XsdtAddr; ++ SK_I8 AcpiState; ++ SK_I8 RetVal; ++ UNICODE_STRING SectionName; ++ OBJECT_ATTRIBUTES ObjAttrs; ++ ++ WCHAR const SectionNameConst[] = L"\\Device\\PhysicalMemory"; ++ ++ RsdtAddr = 0; ++ AcpiState = ASF_ACPI_STATE_OK; ++ ++ // Initialize object attributes ++ SectionName.Buffer = (PWSTR)&SectionNameConst[0]; ++ SectionName.Length = wcslen(SectionNameConst) * sizeof(WCHAR); ++ SectionName.MaximumLength = SectionName.Length + sizeof(WCHAR); ++ ++#if NDIS_VERSION > 50 ++ // WinXP ++ InitializeObjectAttributes( ++ &ObjAttrs, ++ &SectionName, ++ (OBJ_KERNEL_HANDLE | OBJ_FORCE_ACCESS_CHECK), ++ (HANDLE)NULL, ++ (PSECURITY_DESCRIPTOR)NULL ++ ); ++#else ++ // Win2k ++ InitializeObjectAttributes( ++ &ObjAttrs, ++ &SectionName, ++ (OBJ_KERNEL_HANDLE), ++ (HANDLE)NULL, ++ (PSECURITY_DESCRIPTOR)NULL ++ ); ++#endif ++ ++ // Get a SectionHandle to the "\\Device\\PhysicalMemory" section ++ NtRet = ZwOpenSection( &SectionHandle, // OUT PHANDLE SectionHandle ++ SECTION_MAP_READ, // IN ACCESS_MASK DesiredAccess, ++ &ObjAttrs ); // IN POBJECT_ATTRIBUTES ObjectAttributes ++ ++ if( NtRet == STATUS_SUCCESS ) { ++ BaseAddress = NULL; ++ SectOffset.QuadPart = 0xe0000; ++ CommitSize = 0x1ffff; ++ ViewSize = 0x1ffff; ++ NtRet = ZwMapViewOfSection( SectionHandle, // IN HANDLE SectionHandle ++ NtCurrentProcess(), // IN HANDLE ProcessHandle ++ &BaseAddress, // IN OUT PVOID *BaseAddress ++ 0L, // IN ULONG ZeroBits ++ CommitSize, // IN ULONG CommitSize, ++ &SectOffset, // IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, ++ &ViewSize, // IN OUT PSIZE_T ViewSize, ++ ViewShare, // IN SECTION_INHERIT InheritDisposition, ++ 0, // IN ULONG AllocationType, ++ PAGE_READONLY // IN ULONG Protect ++ ); ++ if( NtRet == STATUS_SUCCESS ) { ++ // Update ASF! table ++ // Search for the "RSD PTR" signature ++ pU8 = ((unsigned char *) BaseAddress); ++ for( i=0; i<(0x1ffff-7); i++ ) { ++ if( (*(pU8 + 0 ) == 'R') && (*(pU8 + 1 ) == 'S') && (*(pU8 + 2 ) == 'D') && (*(pU8 + 3 ) == ' ') && ++ (*(pU8 + 4 ) == 'P') && (*(pU8 + 5 ) == 'T') && (*(pU8 + 6 ) == 'R') ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfAcpi -> RSD PTR found at 0x%x (phys)\n", 0xe0000+i )); ++ // Get Address of the Root System Description Table "RSDT" ++ RsdtAddr = *( (SK_U32 *)(pU8 + 16) ); ++ if( RsdtAddr != 0 ) { ++ // 32bit platform ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfAcpi -> RSDT (0x%x)\n", RsdtAddr)); ++ RetVal = SkAsfAcpiRsdt( pAC, IoC, pImage, SectionHandle, RsdtAddr ); ++ if( RetVal < ASF_ACPI_STATE_UNDEFINED ) ++ AcpiState = RetVal; ++ } ++ else { ++ // 64bit platform ++ XsdtAddr = *( (SK_U64 *)(pU8 + 24) ); ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfAcpi -> XSDT (0x%x)\n", XsdtAddr )); ++ RetVal = SkAsfAcpiXsdt( pAC, IoC, pImage, SectionHandle, XsdtAddr ); ++ if( RetVal < ASF_ACPI_STATE_UNDEFINED ) ++ AcpiState = RetVal; ++ } ++ break; ++ } ++ else ++ pU8++; ++ } ++ if( i >= (0x1ffff-7) ) { ++ AcpiState = ASF_ACPI_STATE_ERROR_NO_RSDPTR; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfAcpi -> *** Error: no RSD PTR found\n")); ++ } ++ // Update GUID ++ // Search for the "_UUID_" signature ++ pU8 = ((unsigned char *) BaseAddress); ++ for( i=0; i<(0x1ffff-7); i++ ) { ++ if( (*(pU8 + 0 ) == '_') && (*(pU8 + 1 ) == 'U') && (*(pU8 + 2 ) == 'U') && (*(pU8 + 3 ) == 'I') && ++ (*(pU8 + 4 ) == 'D') && (*(pU8 + 5 ) == '_') ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfAcpi -> _UUID_ found at 0x%x (phys)\n", 0xe0000+i )); ++// RetVal = SkAsfPatchGuid( pAC, IoC, pImage, (pU8+6) ); ++ RetVal = SkAsfPatchGuid( pAC, IoC, pImage, (pU8+9) ); // pw Bug Fix ++ if( RetVal < ASF_ACPI_STATE_UNDEFINED ) ++ AcpiState = RetVal; ++ break; ++ } ++ else ++ pU8++; ++ } ++ if( i >= (0x1ffff-7) ) { ++ AcpiState = ASF_ACPI_STATE_ERROR_NO_RSDPTR; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfAcpi -> *** Error: no _UUID_ found\n")); ++ } ++ ++ ZwUnmapViewOfSection( NtCurrentProcess(), BaseAddress ); ++ } // if( NtRet == STATUS_SUCCESS ) { ++ ZwClose( SectionHandle ); ++ } ++ ++ return( AcpiState ); ++} ++#endif ++ ++#if (0) ++ ++/***************************************************************************** ++* ++* SkAsfAcpiRsdt ++* ++* Description: Searches in the pointer list of the RSDT table for the "ASF!" ++* table pointer. ++* ++* Notes: none ++* ++* Context: none ++* ++* Returns: 1: OK ++* 0: UNDEFINED ++* <0: Error Codes ++* ++*/ ++SK_I8 SkAsfAcpiRsdt( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U8 *pImage, ++HANDLE SectionHandle, ++SK_U32 PhysAddr ) { ++ SK_I8 RetVal; ++ NTSTATUS NtRet; ++ unsigned char *pU8; ++ PVOID BaseAddress; ++ ULONG CommitSize; ++ ULONG i; ++ LARGE_INTEGER MaxSize; ++ LARGE_INTEGER SectOffset; ++ SIZE_T ViewSize; ++ ++ SK_U32 Length; ++ SK_U32 NumTables; ++ SK_U32 TableAddr; ++ SK_U8 CheckSum; ++ SK_U8 Rev; ++ ++ RetVal = ASF_ACPI_STATE_UNDEFINED; ++ ++ // Try to map a view to the "RSDT" table ++ BaseAddress = NULL; ++ SectOffset.QuadPart = PhysAddr; // will be roundet down to the next allocation boundery ++ CommitSize = PAGE_SIZE*2; ++ ViewSize = PAGE_SIZE*2; ++ NtRet = ZwMapViewOfSection( SectionHandle, // IN HANDLE SectionHandle ++ NtCurrentProcess(), // IN HANDLE ProcessHandle ++ &BaseAddress, // IN OUT PVOID *BaseAddress ++ 0L, // IN ULONG ZeroBits ++ CommitSize, // IN ULONG CommitSize, ++ &SectOffset, // IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, ++ &ViewSize, // IN OUT PSIZE_T ViewSize, ++ ViewShare, // IN SECTION_INHERIT InheritDisposition, ++ 0, // IN ULONG AllocationType, ++ PAGE_READONLY // IN ULONG Protect ++ ); ++ if( NtRet == STATUS_SUCCESS ) { ++ pU8 = ((unsigned char *) BaseAddress); ++ // search for "RSDT" signature, because BaseAddress is roundet down to the ++ // next allocation boundary (PAGE_SIZE ??) ++ for( i=0; i= TABLE_HEADER_LENGTH)) { ++ NumTables = (Length - TABLE_HEADER_LENGTH) / 4; ++ // SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("SkAsfAcpiRsdt -> %d tables in the list\n", NumTables)); ++ pU8 += TABLE_HEADER_LENGTH; ++ // check all list entries (phys. addr) for a valid "ASF!" table ++ for( i=0; i ASF ++ RetVal = SkAsfPatchAsfTable( pAC, IoC, pImage, pU8, Length ); ++ } ++ else ++ RetVal = ASF_ACPI_STATE_ERROR_ASF_HEADER; ++ } // if( i < PAGE_SIZE ) { ++ else ++ RetVal = ASF_ACPI_STATE_ERROR_ASF; ++ } ++ } ++ else { // No Simulation File, take REAL ASF! Table ++ // Try to map a view to the "ASF" table ++ BaseAddress = NULL; ++ SectOffset.QuadPart = PhysAddr; ++ CommitSize = PAGE_SIZE*2; ++ ViewSize = PAGE_SIZE*2; ++ NtRet = ZwMapViewOfSection( SectionHandle, // IN HANDLE SectionHandle ++ NtCurrentProcess(), // IN HANDLE ProcessHandle ++ &BaseAddress, // IN OUT PVOID *BaseAddress ++ 0L, // IN ULONG ZeroBits ++ CommitSize, // IN ULONG CommitSize, ++ &SectOffset, // IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, ++ &ViewSize, // IN OUT PSIZE_T ViewSize, ++ ViewShare, // IN SECTION_INHERIT InheritDisposition, ++ 0, // IN ULONG AllocationType, ++ PAGE_READONLY // IN ULONG Protect ++ ); ++ if( NtRet == STATUS_SUCCESS ) { ++ pU8 = ((unsigned char *) BaseAddress); ++ // search for "ASF!" signature, because BaseAddress is roundet down to the ++ // next allocation boundary (PAGE_SIZE ??) ++ for( i=0; i ASF! table found at 0x%x (phys)\n", PhysAddr )); ++ Length = *( (SK_U32 *) (pU8 + 4) ); ++ Rev = *( pU8 + 8); ++ CheckSum = 0; ++ for( i=0; i ASF ++ RetVal = SkAsfPatchAsfTable( pAC, IoC, pImage, pU8, Length ); ++ } ++ else ++ RetVal = ASF_ACPI_STATE_ERROR_ASF_HEADER; ++ } // if( i < PAGE_SIZE ) { ++ else ++ RetVal = ASF_ACPI_STATE_ERROR_ASF; ++ ++ ZwUnmapViewOfSection( NtCurrentProcess(), BaseAddress ); ++ } ++ else ++ RetVal = ASF_ACPI_STATE_ERROR_ASF; ++ ++ ZwUnmapViewOfSection( NtCurrentProcess(), BaseAddress ); ++ } ++ ++ return( RetVal ); ++} ++#endif ++ ++#if (0) ++/***************************************************************************** ++* ++* SkAsfPatchAsfTable ++* ++* Description: Ovverides the table in the fw image with the current ++* BIOS - ASF! - table. ++* ++* Notes: none ++* ++* Context: none ++* ++* Returns: 1: OK ++* 0: UNDEFINED ++* <0: Error Codes ++* ++*/ ++SK_I8 SkAsfPatchAsfTable( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U8 *pImage, ++SK_U8 *pAsfTable, ++SK_U32 TableLength ) { ++ ++ SK_I8 RetVal; ++ SK_U32 i,j; ++ SK_U8 *pAcpiAsf; ++ SK_U8 FwImageCsOk; ++ SK_U32 FwImageCs; ++ SK_U32 FwCs; ++ SK_U32 *pTmp32; ++ ++ RetVal = ASF_ACPI_STATE_OK; ++ ++ // calculate CS of the FW image ++ pTmp32 = (SK_U32 *) pImage; ++ for( i=0, FwCs=0; i O.K. ++ pAcpiAsf = (SK_U8 *) (pImage + ASF_FLASH_OFFS_ACPI); ++ // write new "ASF!" - table to the FW image file ++ for( i=0; i O.K. ++ else ++ RetVal = ASF_ACPI_STATE_ERROR_FILE_CS; ++ ++ return( RetVal); ++} ++#endif ++ ++#if (0) ++/***************************************************************************** ++* ++* SkAsfPatchGuid ++* ++* Description: Ovverides the GUID in the fw image with the current ++* SMBios UUID. ++* ++* Notes: none ++* ++* Context: none ++* ++* Returns: 1: OK ++* 0: UNDEFINED ++* <0: Error Codes ++* ++*/ ++SK_I8 SkAsfPatchGuid( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U8 *pImage, ++SK_U8 *pGuid ) { ++ SK_I8 RetVal; ++ SK_U32 i; ++ SK_U8 *pAcpiAsf; ++ SK_U8 FwImageCsOk; ++ SK_U32 FwImageCs; ++ SK_U32 FwCs; ++ SK_U32 *pTmp32; ++ ++ RetVal = ASF_ACPI_STATE_OK; ++ ++ // calculate CS of the FW image ++ pTmp32 = (SK_U32 *) pImage; ++ for( i=0, FwCs=0; i O.K. ++ pAcpiAsf = (SK_U8 *) (pImage + ASF_FLASH_OFFS_GUID); ++ // write new GUID table to the FW image file ++ for( i=0; i<16; i++ ) { ++ *(pAcpiAsf+i) = *(pGuid+i); ++ } ++ // calculate new FW image checksum ++ pTmp32 = (SK_U32 *) pImage; ++ for( i=0, FwCs=0; i O.K. ++ else ++ RetVal = ASF_ACPI_STATE_ERROR_FILE_CS; ++ ++ return( RetVal); ++} ++#endif ++ ++#if (0) ++/***************************************************************************** ++* ++* SkAsfExamineAsfTable ++* ++* Description: Ovverides the dynamic parts of the ASF! table in order to ++* avoid frequently flash writes caused by changing data. ++* ++* Notes: none ++* ++* Context: none ++* ++* Returns: 1: OK ++* 0: UNDEFINED ++* <0: Error Codes ++* ++*/ ++void SkAsfExamineAsfTable( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U8 *pAsf, ++SK_U32 TableLength ) { ++ SK_U8 *pTmp, *pRmcp, *x; ++ SK_U8 Type; ++ SK_U8 LastRecord; ++ SK_U8 Cs; ++ SK_U16 Length; ++ SK_U16 i,j; ++ ++ // copy the ASF table to our asf-mib structure ++ // and print the asf table to debug output ++ pAC->AsfData.Mib.Acpi.length = TableLength; ++ for( i=0; iAsfData.Mib.Acpi.buffer[i] = *(pAsf+i); ++ } ++ if( i % 16 ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" %02x", *(pAsf+i))); ++ } ++ else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n %02x", *(pAsf+i))); ++ } ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n")); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\nASF! Table:\n")); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" L:%d Rev:%d Cs:0x%x\n", *((SK_U32 *)(pAsf+4)), *(pAsf+8),*(pAsf+9) )); ++ pTmp = pAsf+36; // offset to the 1st information record ++ do { ++ Type = (*pTmp) & 0x7f; ++ LastRecord = (*pTmp) & 0x80; ++ Length = *((SK_U16 *) (pTmp+2)); ++ switch( Type ) { ++ case ASF_RECORD_INFO: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" ASF_INFO L:%d\n", *((SK_U16 *)(pTmp+2)) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" MinWd %d MinWait:%d\n", *(pTmp+4),*(pTmp+5) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" SystemId: %02x\n", *((SK_U16 *)(pTmp+6)) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" ManufactId: %02x %02x %02x %02x Flags:0x%x\n", ++ *(pTmp+8),*(pTmp+9),*(pTmp+10),*(pTmp+11),*(pTmp+12) )); ++ pTmp += Length; ++ break; ++ case ASF_RECORD_ALRT: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" ASF_ALRT L:%d\n", *((SK_U16 *)(pTmp+4)) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" As:0x%x DAs:0x%x\n", *(pTmp+4),*(pTmp+5) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" NumAlrt:%d L:%d\n", *(pTmp+6),*(pTmp+7) )); ++ x = pTmp+8; ++ for( i=0; i<*(pTmp+6); i++ ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Ev%d",i)); ++ for( j=0; j<12; j++ ) ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" %02x", *(x++) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n")); ++ } ++ pTmp += Length; ++ break; ++ case ASF_RECORD_RCTL: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" ASF_RCTL L:%d\n", *((SK_U16 *)(pTmp+2)) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" NumCtrl:%d L:%d\n", *(pTmp+4),*(pTmp+5) )); ++ x = pTmp+6; ++ for( i=0; i<*(pTmp+4); i++ ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Ctrl%d",i)); ++ for( j=0; j<4; j++ ) ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" %02x", *(x++) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n")); ++ } ++ pTmp += Length; ++ break; ++ case ASF_RECORD_RMCP: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" ASF_RMCP L:%d\n", *((SK_U16 *)(pTmp+2)) )); ++ pRmcp = pTmp+4; ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" ")); ++ for( i=0; i<19; i++ ) ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" %02x", *(pRmcp+i) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n")); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" RemCtrlCap:")); ++ for( i=0; i<7; i++ ) ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" %02x", *(pRmcp+i) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n")); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" BootOptionCompletionCode: %02x\n", *(pRmcp+7))); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" IANA EnterpriseId: %02x %02x %02x %02x\n", ++ *(pRmcp+8),*(pRmcp+9), *(pRmcp+10), *(pRmcp+11) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" SpecialCommand: %02x\n", *(pRmcp+12))); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" SpecialCommandPar: %02x %02x\n", *(pRmcp+13), *(pRmcp+14))); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" BootOptions: %02x %02x\n", *(pRmcp+15), *(pRmcp+16))); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" OEM Parameter: %02x %02x\n", *(pRmcp+17), *(pRmcp+18))); ++ pRmcp += 7; // skip Remote Control Capabilities ++ // if cpu is running, provide RMCP data to firmware ++ if( pAC->AsfData.CpuAlive ) ++ SkAsfSendRmcpData( pAC, IoC, pRmcp, 12 ); ++ for( i=0; i<12; i++ ) ++ *(pRmcp++) = 0; // erase dynamic part of the record ++ pTmp += Length; ++ break; ++ case ASF_RECORD_ADDR: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" ASF_ADDR L:%d SEEPROM Adr:0x%x NumAddr:%d\n", ++ *((SK_U16 *)(pTmp+2)), *(pTmp+4), *(pTmp+5) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" Addr:")); ++ for( i=0; i<*(pTmp+5); i++ ) ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" %02x", *(pTmp+6+i) )); ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,("\n")); ++ pTmp += Length; ++ break; ++ default: ++ SK_DBG_MSG(pAC, SK_DBGMOD_ASF, SK_DBGCAT_CTRL,(" UNKNOWN Type:0x%x L:%d\n", *pTmp, *((SK_U16 *)(pTmp+2)) )); ++ LastRecord = 1; ++ break; ++ } ++ if( LastRecord ) ++ break; ++ } while ( (SK_U32)(pTmp-pAsf) < TableLength ); ++ ++ // calculate new checksum ++ *(pAsf+9) = 0; // delete old Cs ++ for( Cs=0, i=0; i // for string operations ++ ++ ++SK_I8 AsfMac2Asci( SK_U8 *buf, SK_U32 *len, SK_U8 *mac ) { ++ SK_I8 RetCode; ++// SK_U8 i, x; ++ SK_U8 i; ++ ++ RetCode = 1; ++ *len = 0; ++ for( i=0; i<6; i++ ) { ++ AsfInt2Hex( &buf[*len], 2, (SK_U32) mac[i] ); ++ (*len)+=2; ++ if( i < 5 ) ++ buf[(*len)++] = '-'; ++ } ++ return( RetCode ); ++} ++ ++SK_I8 AsfAsci2Mac( SK_U8 *buf, SK_U32 len, SK_U8 *mac ) { ++ SK_I8 RetCode; ++ SK_U8 i, ind; ++ ++ RetCode = 1; ++ ++ ind = 0; ++ for( i=0; i<6; i++ ) { ++ AsfHex2U8( &buf[ind], &mac[i] ); ++ ind+=2; ++ if( (buf[ind] != '-') && (buf[ind] != ':') && ( i < 5) ) { ++ RetCode = 0; ++ break; ++ } ++ ind++; ++ } ++ ++ return( RetCode ); ++} ++ ++SK_I8 AsfIp2Asci( SK_U8 *buf, SK_U32 *len, SK_U8 *ip ) { ++ SK_I8 RetCode; ++ SK_U8 i, x; ++ ++ RetCode = 1; ++ *len = 0; ++ for( i=0; i<4; i++ ) { ++ x = ip[i] / 100; /* H */ ++ if( x > 0 ) ++ buf[(*len)++] = '0' + x; ++ x = (ip[i] % 100) / 10; /* Z */ ++ if( (x > 0) || (ip[i] > 99)) ++ buf[(*len)++] = '0' + x; ++ x = ip[i] % 10; /* E */ ++ buf[(*len)++] = '0' + x; ++ if( i < 3 ) ++ buf[(*len)++] = '.'; ++ } ++ return( RetCode ); ++} ++ ++SK_I8 AsfAsci2Ip( SK_U8 *buf, SK_U32 len, SK_U8 *ip ) { ++ SK_I8 RetCode; ++ SK_U8 TmpBuf [3]; ++ SK_U8 i,j, ind, bind; ++ ++ RetCode = 1; ++ ++ bind = 0; ++ ind = 0; ++ for ( i=0; i= '0') && (buf[size-1-i] <= '9') ) ++ *val |= ((buf[size-1-i]-'0') << (i*4)); ++ ++ if( (buf[size-1-i] >= 'A') && (buf[size-1-i] <= 'F') ) ++ *val |= ((buf[size-1-i]-'A'+10) << (i*4)); ++ ++ if( (buf[size-1-i] >= 'a') && (buf[size-1-i] <= 'f') ) ++ *val |= ((buf[size-1-i]-'a'+10) << (i*4)); ++ } ++ return( 1 ); ++} ++ ++SK_I8 AsfInt2Hex( SK_U8 *buf, SK_U8 size, SK_U32 val ) { ++ SK_U8 i; ++ SK_U8 x; ++ ++ if( size > 4 ) ++ return( 0 ); ++ ++ for( i=0; i>(i*4))&0x000f; ++ if( (x >= 0) && (x <= 9) ) ++ buf[size-1-i] = x + '0'; ++ if( (x >= 0xa) && (x <= 0xf) ) ++ buf[size-1-i] = x - 0xa + 'A'; ++ } ++ return( 1 ); ++} ++ ++SK_I8 AsfDec2Int( SK_U8 *buf, SK_U8 size, SK_U32 *val ) { ++ SK_U8 i; ++ ++ *val = 0; ++ ++ if( size > 4 ) ++ return( 0 ); ++ ++ for( i=0; i= '0') && (buf[size-1-i] <= '9') ) ++ *val |= ((buf[size-1-i]-'0') << (i+8)); ++ } ++ return( 1 ); ++} ++ ++ ++#ifdef __cplusplus ++} ++#endif /* __cplusplus */ ++ +diff -ruN linux/drivers/net/sk98lin/skge.c linux-new/drivers/net/sk98lin/skge.c +--- linux/drivers/net/sk98lin/skge.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skge.c 2007-01-24 14:03:43.000000000 +0100 +@@ -1,32 +1,26 @@ + /****************************************************************************** + * +- * Name: skge.c +- * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ +- * Purpose: The main driver source module ++ * Name: skge.c ++ * Project: GEnesis, PCI Gigabit Ethernet Adapter ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: The main driver source module + * + ******************************************************************************/ + + /****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2005 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) ++ * Author: Mirko Lindner (mlindner@syskonnect.de) ++ * Ralph Roesler (rroesler@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 +@@ -38,86 +32,55 @@ + + /****************************************************************************** + * +- * 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: +- * +- * +- * +- * "h/skdrv1st.h" +- * +- * +- * +- * +- * +- * +- * +- * +- * +- * +- * +- * +- * +- * +- * those three depending on kernel version used: +- * +- * +- * +- * +- * +- * "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/skrlmt.h" ++ * All source files in this sk98lin directory except of the sk98lin ++ * Linux specific files ++ * ++ * - skdim.c ++ * - skethtool.c ++ * - skge.c ++ * - skproc.c ++ * - sky2.c ++ * - Makefile ++ * - h/skdrv1st.h ++ * - h/skdrv2nd.h ++ * - h/sktypes.h ++ * - h/skversion.h ++ * ++ * are part of SysKonnect's common modules for the SK-9xxx adapters. ++ * ++ * Those common module files which are not Linux specific are used to ++ * build drivers on different OS' (e.g. Windows, MAC OS) so that those ++ * drivers are based on the same set of files ++ * ++ * At a first glance, this seems to complicate things unnescessarily on ++ * Linux, but please do not try to 'clean up' them without VERY good ++ * reasons, because this will make it more difficult to keep the sk98lin ++ * driver for Linux in synchronisation with the other drivers running on ++ * other operating systems. + * + ******************************************************************************/ + + #include "h/skversion.h" + +-#include + #include +-#include + #include +-#include +-#include +-#include +-#include ++#include ++ ++#ifdef CONFIG_PROC_FS ++#include ++#endif + + #include "h/skdrv1st.h" + #include "h/skdrv2nd.h" ++#include "h/skpcidevid.h" ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) ++#include ++#endif ++ ++#define ENABLE_FUTURE_ETH + + /******************************************************************************* + * +@@ -128,62 +91,15 @@ + /* 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 ++#define CLEAR_AND_START_RX(Port) SK_OUT8(pAC->IoBase, RxQueueAddr[(Port)]+Q_CSR, CSR_START | CSR_IRQ_CL_F) ++#define START_RX(Port) SK_OUT8(pAC->IoBase, RxQueueAddr[(Port)]+Q_CSR, CSR_START) ++#define CLEAR_TX_IRQ(Port,Prio) SK_OUT8(pAC->IoBase, TxQueueAddr[(Port)][(Prio)]+Q_CSR, CSR_IRQ_CL_F) + + + /******************************************************************************* +@@ -192,14 +108,31 @@ + * + ******************************************************************************/ + ++static int __devinit sk98lin_init_device(struct pci_dev *pdev, const struct pci_device_id *ent); ++static void sk98lin_remove_device(struct pci_dev *pdev); ++#ifdef CONFIG_PM ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) ++static int sk98lin_suspend(struct pci_dev *pdev, pm_message_t state); ++#else ++static int sk98lin_suspend(struct pci_dev *pdev, SK_U32 state); ++#endif ++static int sk98lin_resume(struct pci_dev *pdev); ++static void SkEnableWOMagicPacket(SK_AC *pAC, SK_IOC IoC, SK_MAC_ADDR MacAddr); ++#endif ++#ifdef Y2_RECOVERY ++static void SkGeHandleKernelTimer(unsigned long ptr); ++void SkGeCheckTimer(DEV_NET *pNet); ++static SK_BOOL CheckRXCounters(DEV_NET *pNet); ++static void CheckRxPath(DEV_NET *pNet); ++#endif + 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); +-static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id); ++static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, 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); +@@ -208,128 +141,1131 @@ + 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*); ++#ifdef CONFIG_SK98LIN_NAPI ++static int SkGePoll(struct net_device *dev, int *budget); ++static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL, int*, int); ++#else + static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL); +-static void ClearAndStartRx(SK_AC*, int); +-static void ClearTxIrq(SK_AC*, int, int); ++#endif ++#ifdef SK_POLL_CONTROLLER ++static void SkGeNetPoll(struct SK_NET_DEVICE *dev); ++#endif + 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 void SkLocalEventQueue( SK_AC *pAC, ++ SK_U32 Class, ++ SK_U32 Event, ++ SK_U32 Param1, ++ SK_U32 Param2, ++ SK_BOOL Flag); ++extern void SkLocalEventQueue64( SK_AC *pAC, ++ SK_U32 Class, ++ SK_U32 Event, ++ SK_U64 Param, ++ SK_BOOL Flag); ++ ++static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*); + + /******************************************************************************* + * + * Extern Function Prototypes + * + ******************************************************************************/ ++ ++extern SK_BOOL SkY2AllocateResources(SK_AC *pAC); ++extern void SkY2FreeResources(SK_AC *pAC); ++extern void SkY2AllocateRxBuffers(SK_AC *pAC,SK_IOC IoC,int Port); ++extern void SkY2FreeRxBuffers(SK_AC *pAC,SK_IOC IoC,int Port); ++extern void SkY2FreeTxBuffers(SK_AC *pAC,SK_IOC IoC,int Port); ++extern SkIsrRetVar SkY2Isr(int irq,void *dev_id,struct pt_regs *ptregs); ++extern int SkY2Xmit(struct sk_buff *skb,struct SK_NET_DEVICE *dev); ++extern void SkY2PortStop(SK_AC *pAC,SK_IOC IoC,int Port,int Dir,int RstMode); ++extern void SkY2PortStart(SK_AC *pAC,SK_IOC IoC,int Port); ++extern int SkY2RlmtSend(SK_AC *pAC,int PortNr,struct sk_buff *pMessage); ++extern void SkY2RestartStatusUnit(SK_AC *pAC); ++extern void FillReceiveTableYukon2(SK_AC *pAC,SK_IOC IoC,int Port); ++#ifdef CONFIG_SK98LIN_NAPI ++extern int SkY2Poll(struct net_device *dev, int *budget); ++#endif ++ + 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 ++#ifndef ENABLE_FUTURE_ETH ++extern int SkEthIoctl(struct net_device *netdev, struct ifreq *ifr); ++#else ++/* Ethtool functions */ ++extern int SkGeGetSettings(struct net_device *dev, struct ethtool_cmd *ecmd); ++extern void SkGeGetDrvInfo(struct net_device *dev, struct ethtool_drvinfo *ecmd); ++extern void SkGeGetWolSettings(struct net_device *dev, struct ethtool_wolinfo *ecmd); ++extern void SkGeGetPauseParam(struct net_device *dev, struct ethtool_pauseparam *ecmd); ++extern int SkGeGetCoalesce(struct net_device *dev, struct ethtool_coalesce *ecmd); ++extern SK_U32 SkGeGetRxCsum(struct net_device *dev); ++extern void SkGeGetStrings(struct net_device *dev, u32 stringset, u8 *strings); ++extern int SkGeGetStatsLen(struct net_device *dev); ++extern void SkGeGetEthStats(struct net_device *dev, struct ethtool_stats *stats, u64 *data); ++extern int SkGeSetSettings(struct net_device *dev, struct ethtool_cmd *ecmd); ++extern int SkGeSetWolSettings(struct net_device *dev, struct ethtool_wolinfo *ewol); ++extern int SkGeSetPauseParam(struct net_device *dev, struct ethtool_pauseparam *ecmd); ++extern int SkGeSetCoalesce(struct net_device *dev, struct ethtool_coalesce *ecmd); ++extern int SkGeSetSG(struct net_device *dev, u32 data); ++extern int SkGeSetTxCsum(struct net_device *dev, u32 data); ++extern int SkGeSetRxCsum(struct net_device *dev, u32 data); ++extern int SkGePhysId(struct net_device *dev, u32 data); ++#endif ++ ++#ifdef NETIF_F_TSO ++extern int SkGeSetTSO(struct net_device *netdev, u32 data); ++#endif ++ ++#ifdef CONFIG_PROC_FS ++static const char SK_Root_Dir_entry[] = "sk98lin"; ++static struct proc_dir_entry *pSkRootDir; ++extern struct file_operations sk_proc_fops; ++#endif ++ ++#ifdef DEBUG ++static void DumpMsg(struct sk_buff*, char*); ++static void DumpData(char*, int); ++static void DumpLong(char*, int); ++#endif ++ ++/* global variables *********************************************************/ ++static const char *BootString = BOOT_STRING; ++struct SK_NET_DEVICE *SkGeRootDev = NULL; ++static SK_BOOL DoPrintInterfaceChange = SK_TRUE; ++ ++/* local variables **********************************************************/ ++static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}}; ++static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480}; ++static int sk98lin_max_boards_found = 0; ++static int is_closed = 0; ++ ++#ifdef CONFIG_PROC_FS ++static struct proc_dir_entry *pSkRootDir; ++#endif ++ ++ ++ ++#ifdef ENABLE_FUTURE_ETH ++static struct ethtool_ops sk98lin_ethtool_ops = { ++ .get_sg = ethtool_op_get_sg, ++ .get_link = ethtool_op_get_link, ++ .get_tx_csum = ethtool_op_get_tx_csum, ++ .get_tx_csum = ethtool_op_get_tx_csum, ++/* .get_perm_addr = ethtool_op_get_perm_addr, */ ++ .get_settings = SkGeGetSettings, ++ .get_drvinfo = SkGeGetDrvInfo, ++ .get_wol = SkGeGetWolSettings, ++ .get_pauseparam = SkGeGetPauseParam, ++ .get_coalesce = SkGeGetCoalesce, ++ .get_rx_csum = SkGeGetRxCsum, ++ .get_strings = SkGeGetStrings, ++ .get_stats_count = SkGeGetStatsLen, ++ .get_ethtool_stats = SkGeGetEthStats, ++ ++ .set_settings = SkGeSetSettings, ++ .set_wol = SkGeSetWolSettings, ++ .set_pauseparam = SkGeSetPauseParam, ++ .set_coalesce = SkGeSetCoalesce, ++ .set_sg = SkGeSetSG, ++ .set_tx_csum = SkGeSetTxCsum, ++ .set_rx_csum = SkGeSetRxCsum, ++ ++ .phys_id = SkGePhysId, ++ ++#ifdef NETIF_F_TSO ++ .get_tso = ethtool_op_get_tso, ++ .set_tso = SkGeSetTSO, ++#endif ++ ++/* .get_regs_len = */ ++/* .get_regs = */ ++/* .get_msglevel = */ ++/* .nway_reset = */ ++/* .get_ringparam = */ ++/* .set_msglevel = */ ++/* .set_ringparam = */ ++}; ++#endif ++ ++MODULE_DEVICE_TABLE(pci, sk98lin_pci_tbl); ++ ++static struct pci_driver sk98lin_driver = { ++ .name = DRIVER_FILE_NAME, ++ .id_table = sk98lin_pci_tbl, ++ .probe = sk98lin_init_device, ++ .remove = __devexit_p(sk98lin_remove_device), ++#ifdef CONFIG_PM ++ .suspend = sk98lin_suspend, ++ .resume = sk98lin_resume ++#endif ++}; ++ ++ ++/***************************************************************************** ++ * ++ * sk98lin_init_device - initialize the adapter ++ * ++ * Description: ++ * This function initializes the adapter. Resources for ++ * the adapter are allocated and the adapter is brought into Init 1 ++ * state. ++ * ++ * Returns: ++ * 0, if everything is ok ++ * !=0, on error ++ */ ++static int __devinit sk98lin_init_device(struct pci_dev *pdev, ++ const struct pci_device_id *ent) ++ ++{ ++ static SK_BOOL sk98lin_boot_string = SK_FALSE; ++ static SK_BOOL sk98lin_proc_entry = SK_FALSE; ++ static int sk98lin_boards_found = 0; ++ SK_AC *pAC; ++ DEV_NET *pNet = NULL; ++ struct SK_NET_DEVICE *dev = NULL; ++ int retval; ++#ifdef CONFIG_PROC_FS ++#endif ++ int pci_using_dac; ++ ++ retval = pci_enable_device(pdev); ++ if (retval) { ++ printk(KERN_ERR "Cannot enable PCI device, " ++ "aborting.\n"); ++ return retval; ++ } ++ ++ dev = NULL; ++ pNet = NULL; ++ ++ /* INSERT * We have to find the power-management capabilities */ ++ /* Find power-management capability. */ ++ ++ pci_using_dac = 0; /* Set 32 bit DMA per default */ ++ /* Configure DMA attributes. */ ++ retval = pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL); ++ if (!retval) { ++ pci_using_dac = 1; ++ } else { ++ retval = pci_set_dma_mask(pdev, (u64) 0xffffffff); ++ if (retval) { ++ printk(KERN_ERR "No usable DMA configuration, " ++ "aborting.\n"); ++ return retval; ++ } ++ } ++ ++ ++ if ((dev = alloc_etherdev(sizeof(DEV_NET))) == NULL) { ++ printk(KERN_ERR "Unable to allocate etherdev " ++ "structure!\n"); ++ return -ENODEV; ++ } ++ ++ pNet = dev->priv; ++ pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); ++ if (pNet->pAC == NULL){ ++ free_netdev(dev); ++ printk(KERN_ERR "Unable to allocate adapter " ++ "structure!\n"); ++ return -ENODEV; ++ } ++ ++ /* Print message */ ++ if (!sk98lin_boot_string) { ++ /* set display flag to TRUE so that */ ++ /* we only display this string ONCE */ ++ sk98lin_boot_string = SK_TRUE; ++ printk("%s\n", BootString); ++ } ++ ++ memset(pNet->pAC, 0, sizeof(SK_AC)); ++ pAC = pNet->pAC; ++ pAC->PciDev = pdev; ++ pAC->PciDevId = pdev->device; ++ pAC->dev[0] = dev; ++ pAC->dev[1] = dev; ++ sprintf(pAC->Name, "SysKonnect SK-98xx"); ++ pAC->CheckQueue = SK_FALSE; ++ pAC->InterfaceUp[0] = 0; ++ pAC->InterfaceUp[1] = 0; ++ dev->irq = pdev->irq; ++ retval = SkGeInitPCI(pAC); ++ if (retval) { ++ printk("SKGE: PCI setup failed: %i\n", retval); ++ free_netdev(dev); ++ return -ENODEV; ++ } ++ ++ SET_MODULE_OWNER(dev); ++#ifdef ENABLE_FUTURE_ETH ++ SET_ETHTOOL_OPS(dev, &sk98lin_ethtool_ops); ++#endif ++ ++ dev->open = &SkGeOpen; ++ dev->stop = &SkGeClose; ++ dev->get_stats = &SkGeStats; ++ dev->set_multicast_list = &SkGeSetRxMode; ++ dev->set_mac_address = &SkGeSetMacAddr; ++ dev->do_ioctl = &SkGeIoctl; ++ dev->change_mtu = &SkGeChangeMtu; ++ dev->flags &= ~IFF_RUNNING; ++#ifdef SK_POLL_CONTROLLER ++ dev->poll_controller = SkGeNetPoll; ++#endif ++ SET_NETDEV_DEV(dev, &pdev->dev); ++ ++ pAC->Index = sk98lin_boards_found; ++ ++ if (SkGeBoardInit(dev, pAC)) { ++ free_netdev(dev); ++ return -ENODEV; ++ } else { ++ ProductStr(pAC); ++ } ++ ++ if (pci_using_dac) ++ dev->features |= NETIF_F_HIGHDMA; ++ ++ /* shifter to later moment in time... */ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ dev->hard_start_xmit = &SkY2Xmit; ++#ifdef CONFIG_SK98LIN_NAPI ++ dev->poll = &SkY2Poll; ++ dev->weight = 64; ++#endif ++ } else { ++ dev->hard_start_xmit = &SkGeXmit; ++#ifdef CONFIG_SK98LIN_NAPI ++ dev->poll = &SkGePoll; ++ dev->weight = 64; ++#endif ++ } ++ ++#ifdef NETIF_F_TSO ++#ifdef USE_SK_TSO_FEATURE ++ if (CHIP_ID_YUKON_2(pAC)) { ++ dev->features |= NETIF_F_TSO; ++ } ++#endif ++#endif ++#ifdef CONFIG_SK98LIN_ZEROCOPY ++ if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) ++ dev->features |= NETIF_F_SG; ++#endif ++#ifdef USE_SK_TX_CHECKSUM ++ if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) ++ dev->features |= NETIF_F_IP_CSUM; ++#endif ++#ifdef USE_SK_RX_CHECKSUM ++ pAC->RxPort[0].UseRxCsum = SK_TRUE; ++ if (pAC->GIni.GIMacsFound == 2 ) { ++ pAC->RxPort[1].UseRxCsum = SK_TRUE; ++ } ++#endif ++ ++ /* Save the hardware revision */ ++ pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + ++ (pAC->GIni.GIPciHwRev & 0x0F); ++ ++ /* Set driver globals */ ++ pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME; ++ pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE; ++ ++ SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA)); ++ SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), ++ sizeof(SK_PNMI_STRUCT_DATA)); ++ ++ /* Register net device */ ++ retval = register_netdev(dev); ++ if (retval) { ++ printk(KERN_ERR "SKGE: Could not register device.\n"); ++ FreeResources(dev); ++ free_netdev(dev); ++ return retval; ++ } ++ ++ /* Save initial device name */ ++ strcpy(pNet->InitialDevName, dev->name); ++ ++ /* Set network to off */ ++ netif_stop_queue(dev); ++ netif_carrier_off(dev); ++ ++ /* Print adapter specific string from vpd and config settings */ ++ printk("%s: %s\n", pNet->InitialDevName, pAC->DeviceStr); ++ printk(" PrefPort:%c RlmtMode:%s\n", ++ 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber, ++ (pAC->RlmtMode==0) ? "Check Link State" : ++ ((pAC->RlmtMode==1) ? "Check Link State" : ++ ((pAC->RlmtMode==3) ? "Check Local Port" : ++ ((pAC->RlmtMode==7) ? "Check Segmentation" : ++ ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error"))))); ++ ++ SkGeYellowLED(pAC, pAC->IoBase, 1); ++ ++ memcpy((caddr_t) &dev->dev_addr, ++ (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6); ++ ++ /* First adapter... Create proc and print message */ ++#ifdef CONFIG_PROC_FS ++ if (!sk98lin_proc_entry) { ++ sk98lin_proc_entry = SK_TRUE; ++ SK_MEMCPY(&SK_Root_Dir_entry, BootString, ++ sizeof(SK_Root_Dir_entry) - 1); ++ ++ /*Create proc (directory)*/ ++ if(!pSkRootDir) { ++ pSkRootDir = proc_mkdir(SK_Root_Dir_entry, proc_net); ++ if (!pSkRootDir) { ++ printk(KERN_WARNING "%s: Unable to create /proc/net/%s", ++ dev->name, SK_Root_Dir_entry); ++ } else { ++ pSkRootDir->owner = THIS_MODULE; ++ } ++ } ++ } ++ ++ /* Create proc file */ ++ /* No further proc file creation here */ ++ ++#endif ++ ++ pNet->PortNr = 0; ++ pNet->NetNr = 0; ++ ++ sk98lin_boards_found++; ++ pci_set_drvdata(pdev, dev); ++ ++ /* More then one port found */ ++ if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { ++ if ((dev = alloc_etherdev(sizeof(DEV_NET))) == 0) { ++ printk(KERN_ERR "Unable to allocate etherdev " ++ "structure!\n"); ++ return -ENODEV; ++ } ++ ++ pAC->dev[1] = dev; ++ pNet = dev->priv; ++ pNet->PortNr = 1; ++ pNet->NetNr = 1; ++ pNet->pAC = pAC; ++ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ dev->hard_start_xmit = &SkY2Xmit; ++#ifdef CONFIG_SK98LIN_NAPI ++ dev->poll = &SkY2Poll; ++ dev->weight = 64; ++#endif ++ } else { ++ dev->hard_start_xmit = &SkGeXmit; ++#ifdef CONFIG_SK98LIN_NAPI ++ dev->poll = &SkGePoll; ++ dev->weight = 64; ++#endif ++ } ++ ++#ifdef ENABLE_FUTURE_ETH ++ SET_ETHTOOL_OPS(dev, &sk98lin_ethtool_ops); ++#endif ++ ++ dev->open = &SkGeOpen; ++ dev->stop = &SkGeClose; ++ dev->get_stats = &SkGeStats; ++ dev->set_multicast_list = &SkGeSetRxMode; ++ dev->set_mac_address = &SkGeSetMacAddr; ++ dev->do_ioctl = &SkGeIoctl; ++ dev->change_mtu = &SkGeChangeMtu; ++ dev->flags &= ~IFF_RUNNING; ++#ifdef SK_POLL_CONTROLLER ++ dev->poll_controller = SkGeNetPoll; ++#endif ++ ++#ifdef NETIF_F_TSO ++#ifdef USE_SK_TSO_FEATURE ++ if ((CHIP_ID_YUKON_2(pAC)) && ++ (pAC->GIni.GIChipId != CHIP_ID_YUKON_EC_U)) { ++ dev->features |= NETIF_F_TSO; ++ } ++#endif ++#endif ++#ifdef CONFIG_SK98LIN_ZEROCOPY ++ /* Don't handle if Genesis chipset */ ++ if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) ++ dev->features |= NETIF_F_SG; ++#endif ++#ifdef USE_SK_TX_CHECKSUM ++ /* Don't handle if Genesis chipset */ ++ if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) ++ dev->features |= NETIF_F_IP_CSUM; ++#endif ++ ++ if (register_netdev(dev)) { ++ printk(KERN_ERR "SKGE: Could not register device.\n"); ++ free_netdev(dev); ++ pAC->dev[1] = pAC->dev[0]; ++ } else { ++ ++ /* Save initial device name */ ++ strcpy(pNet->InitialDevName, dev->name); ++ ++ /* Set network to off */ ++ netif_stop_queue(dev); ++ netif_carrier_off(dev); ++ ++ ++#ifdef CONFIG_PROC_FS ++ /* No further proc file creation here */ ++#endif ++ ++ memcpy((caddr_t) &dev->dev_addr, ++ (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6); ++ ++ printk("%s: %s\n", pNet->InitialDevName, pAC->DeviceStr); ++ printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); ++ } ++ } ++ ++ pAC->Index = sk98lin_boards_found; ++ sk98lin_max_boards_found = sk98lin_boards_found; ++ return 0; ++} ++ ++ ++ ++/***************************************************************************** ++ * ++ * SkGeInitPCI - Init the PCI resources ++ * ++ * Description: ++ * This function initialize the PCI resources and IO ++ * ++ * Returns: N/A ++ * ++ */ ++static 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, DRIVER_FILE_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 = (char*)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; ++} ++ ++#ifdef CONFIG_PROC_FS ++/***************************************************************************** ++ * ++ * SkGeHandleProcfsTimer - Handle the procfs timer requests ++ * ++ * Description: ++ * Checks, if the device's name changed. If this is the case ++ * it deletes the old profs entry and creates a new one with ++ * the new name. ++ * ++ * Returns: N/A ++ * ++ */ ++static void SkGeHandleProcfsTimer(unsigned long ptr) ++{ ++ DEV_NET *pNet = (DEV_NET*) ptr; ++ struct proc_dir_entry *pProcFile; ++ ++ /* ++ * If the current name and the last saved name of the device differ ++ * we need to update our procfs entry. ++ */ ++ if ( (pSkRootDir) && ++ (strcmp(pNet->CurrentName, pNet->pAC->dev[pNet->NetNr]->name) != 0) ) { ++ ++ if (pNet->pAC->InterfaceUp[pNet->NetNr] == 1) ++ remove_proc_entry(pNet->CurrentName, pSkRootDir); ++ ++ /* ++ * InterfaceUp only holds 1 if both the network interface is up and ++ * the corresponding procfs entry is done. Otherwise it is set to 0. ++ */ ++ pNet->pAC->InterfaceUp[pNet->NetNr] = 0; ++ ++ pProcFile = create_proc_entry(pNet->pAC->dev[pNet->NetNr]->name, S_IRUGO, pSkRootDir); ++ pProcFile->proc_fops = &sk_proc_fops; ++ pProcFile->data = pNet->pAC->dev[pNet->NetNr]; ++ ++ /* ++ * Remember, interface dev nr pNet->NetNr is up and procfs entry is created. ++ */ ++ pNet->pAC->InterfaceUp[pNet->NetNr] = 1; ++ ++ strcpy(pNet->CurrentName, pNet->pAC->dev[pNet->NetNr]->name); ++ } ++ ++ /* ++ * Restart Procfs Timer ++ */ ++ pNet->ProcfsTimer.expires = jiffies + HZ*5; /* 5 secs */ ++ add_timer(&pNet->ProcfsTimer); ++} ++#endif ++ ++#ifdef Y2_RECOVERY ++/***************************************************************************** ++ * ++ * SkGeHandleKernelTimer - Handle the kernel timer requests ++ * ++ * Description: ++ * If the requested time interval for the timer has elapsed, ++ * this function checks the link state. ++ * ++ * Returns: N/A ++ * ++ */ ++static void SkGeHandleKernelTimer( ++unsigned long ptr) /* holds the pointer to adapter control context */ ++{ ++ DEV_NET *pNet = (DEV_NET*) ptr; ++ SkGeCheckTimer(pNet); ++} ++ ++/***************************************************************************** ++ * ++ * sk98lin_check_timer - Resume the the card ++ * ++ * Description: ++ * This function checks the kernel timer ++ * ++ * Returns: N/A ++ * ++ */ ++void SkGeCheckTimer( ++DEV_NET *pNet) /* holds the pointer to adapter control context */ ++{ ++ SK_AC *pAC = pNet->pAC; ++ SK_BOOL StartTimer = SK_TRUE; ++ SK_U32 StatSpeed, StatDuplex, NewTimerInterval; ++ ++#ifdef SK_EXTREME ++ if (HW_IS_EXT_LE_FORMAT(pAC)) { ++ /* Disable checks for Yukon Extreme */ ++ return; ++ } ++#endif ++ ++ StatSpeed = pAC->GIni.GP[pNet->NetNr].PLinkSpeedUsed; ++ if (StatSpeed == SK_LSPEED_STAT_10MBPS) { ++ StatDuplex = pAC->GIni.GP[pNet->NetNr].PLinkModeStatus; ++ if ((StatDuplex == SK_LMODE_STAT_AUTOHALF) || ++ (StatDuplex == SK_LMODE_STAT_HALF)) { ++ NewTimerInterval = (HZ*2); ++ } else { ++ NewTimerInterval = (HZ); ++ } ++ } else if (StatSpeed == SK_LSPEED_STAT_100MBPS) { ++ NewTimerInterval = (HZ/2); ++ } else if (StatSpeed == SK_LSPEED_STAT_1000MBPS) { ++ NewTimerInterval = (HZ/4); ++ } else { ++ NewTimerInterval = (HZ*2); ++ } ++ ++ if (pNet->InRecover) { ++ pNet->KernelTimer.expires = jiffies + NewTimerInterval; ++ add_timer(&pNet->KernelTimer); ++ ++ return; ++ } ++ if (pNet->TimerExpired) ++ return; ++ pNet->TimerExpired = SK_TRUE; ++ ++#define TXPORT pAC->TxPort[pNet->PortNr][TX_PRIO_LOW] ++#define RXPORT pAC->RxPort[pNet->PortNr] ++ ++ if ( (CHIP_ID_YUKON_2(pAC)) && ++ (netif_running(pAC->dev[pNet->PortNr]))) { ++ ++#ifdef Y2_RX_CHECK ++ if (HW_FEATURE(pAC, HWF_WA_DEV_4167)) { ++ /* Checks the RX path */ ++ CheckRxPath(pNet); ++ } ++#endif ++ ++ /* Check the transmitter */ ++ if (!(IS_Q_EMPTY(&TXPORT.TxAQ_working))) { ++ if (TXPORT.LastDone != TXPORT.TxALET.Done) { ++ TXPORT.LastDone = TXPORT.TxALET.Done; ++ pNet->TransmitTimeoutTimer = 0; ++ } else { ++ pNet->TransmitTimeoutTimer++; ++ if (pNet->TransmitTimeoutTimer >= 10) { ++ pNet->TransmitTimeoutTimer = 0; ++#ifdef CHECK_TRANSMIT_TIMEOUT ++ StartTimer = SK_FALSE; ++ SkLocalEventQueue(pAC, SKGE_DRV, ++ SK_DRV_RECOVER,pNet->PortNr,-1,SK_FALSE); ++#endif ++ } ++ } ++ } ++ ++#ifdef CHECK_TRANSMIT_TIMEOUT ++// if (!timer_pending(&pNet->KernelTimer)) { ++ pNet->KernelTimer.expires = jiffies + NewTimerInterval; ++ add_timer(&pNet->KernelTimer); ++ pNet->TimerExpired = SK_FALSE; ++// } ++#endif ++ } ++} ++ ++ ++/***************************************************************************** ++* ++* CheckRXCounters - Checks the the statistics for RX path hang ++* ++* Description: ++* This function is called periodical by a timer. ++* ++* Notes: ++* ++* Function Parameters: ++* ++* Returns: ++* Traffic status ++* ++*/ ++static SK_BOOL CheckRXCounters( ++DEV_NET *pNet) /* holds the pointer to adapter control context */ ++{ ++ SK_AC *pAC = pNet->pAC; ++ SK_BOOL bStatus = SK_FALSE; ++ ++ /* Variable used to store the MAC RX FIFO RP, RPLev*/ ++ SK_U32 MACFifoRP = 0; ++ SK_U32 MACFifoRLev = 0; ++ ++ /* Variable used to store the PCI RX FIFO RP, RPLev*/ ++ SK_U32 RXFifoRP = 0; ++ SK_U8 RXFifoRLev = 0; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("==> CheckRXCounters()\n")); ++ ++ /*Check if statistic counters hangs*/ ++ if (pNet->LastJiffies == pAC->dev[pNet->PortNr]->last_rx) { ++ /* Now read the values of read pointer/level from MAC RX FIFO again */ ++ SK_IN32(pAC->IoBase, MR_ADDR(pNet->PortNr, RX_GMF_RP), &MACFifoRP); ++ SK_IN32(pAC->IoBase, MR_ADDR(pNet->PortNr, RX_GMF_RLEV), &MACFifoRLev); ++ ++ /* Now read the values of read pointer/level from RX FIFO again */ ++ SK_IN8(pAC->IoBase, Q_ADDR(pAC->GIni.GP[pNet->PortNr].PRxQOff, Q_RX_RP), &RXFifoRP); ++ SK_IN8(pAC->IoBase, Q_ADDR(pAC->GIni.GP[pNet->PortNr].PRxQOff, Q_RX_RL), &RXFifoRLev); ++ ++ /* Check if the MAC RX hang */ ++ if ((MACFifoRP == pNet->PreviousMACFifoRP) && ++ (MACFifoRLev != 0) && ++ (MACFifoRLev >= pNet->PreviousMACFifoRLev)){ ++ bStatus = SK_TRUE; ++ } ++ ++ /* Check if the PCI RX hang */ ++ if ((RXFifoRP == pNet->PreviousRXFifoRP) && ++ (RXFifoRLev != 0) && ++ (RXFifoRLev >= pNet->PreviousRXFifoRLev)){ ++ /*Set the flag to indicate that the RX FIFO hangs*/ ++ bStatus = SK_TRUE; ++ } ++ } ++ ++ /* Store now the values of counters for next check */ ++ pNet->LastJiffies = pAC->dev[pNet->PortNr]->last_rx; ++ ++ /* Store the values of read pointer/level from MAC RX FIFO for next test */ ++ pNet->PreviousMACFifoRP = MACFifoRP; ++ pNet->PreviousMACFifoRLev = MACFifoRLev; ++ ++ /* Store the values of read pointer/level from RX FIFO for next test */ ++ pNet->PreviousRXFifoRP = RXFifoRP; ++ pNet->PreviousRXFifoRLev = RXFifoRLev; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("<== CheckRXCounters()\n")); ++ ++ return bStatus; ++} ++ ++/***************************************************************************** ++* ++* CheckRxPath - Checks if the RX path ++* ++* Description: ++* This function is called periodical by a timer. ++* ++* Notes: ++* ++* Function Parameters: ++* ++* Returns: ++* None. ++* ++*/ ++static void CheckRxPath( ++DEV_NET *pNet) /* holds the pointer to adapter control context */ ++{ ++ unsigned long Flags; /* for the spin locks */ ++ /* Initialize the pAC structure.*/ ++ SK_AC *pAC = pNet->pAC; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("==> CheckRxPath()\n")); ++ ++ /*If the statistics are not changed then could be an RX problem */ ++ if (CheckRXCounters(pNet)){ ++ /* ++ * First we try the simple solution by resetting the Level Timer ++ */ ++ ++ /* Stop Level Timer of Status BMU */ ++ SK_OUT8(pAC->IoBase, STAT_LEV_TIMER_CTRL, TIM_STOP); ++ ++ /* Start Level Timer of Status BMU */ ++ SK_OUT8(pAC->IoBase, STAT_LEV_TIMER_CTRL, TIM_START); ++ ++ if (!CheckRXCounters(pNet)) { ++ return; ++ } ++ ++ spin_lock_irqsave(&pAC->SlowPathLock, Flags); ++ SkLocalEventQueue(pAC, SKGE_DRV, ++ SK_DRV_RECOVER,pNet->PortNr,-1,SK_TRUE); ++ ++ /* Reset the fifo counters */ ++ pNet->PreviousMACFifoRP = 0; ++ pNet->PreviousMACFifoRLev = 0; ++ pNet->PreviousRXFifoRP = 0; ++ pNet->PreviousRXFifoRLev = 0; ++ ++ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("<== CheckRxPath()\n")); ++} ++ + +-/* global variables *********************************************************/ +-static SK_BOOL DoPrintInterfaceChange = SK_TRUE; +-extern const 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}; ++#endif + ++ ++#ifdef CONFIG_PM + /***************************************************************************** + * +- * SkPciWriteCfgDWord - write a 32 bit value to pci config space ++ * sk98lin_resume - Resume the the card + * + * Description: +- * This routine writes a 32 bit value to the pci configuration +- * space. ++ * This function resumes the card into the D0 state + * +- * Returns: +- * 0 - indicate everything worked ok. +- * != 0 - error indication ++ * Returns: N/A ++ * + */ +-static inline int SkPciWriteCfgDWord( +-SK_AC *pAC, /* Adapter Control structure pointer */ +-int PciAddr, /* PCI register address */ +-SK_U32 Val) /* pointer to store the read value */ ++static int sk98lin_resume( ++struct pci_dev *pdev) /* the device that is to resume */ + { +- pci_write_config_dword(pAC->PciDev, PciAddr, Val); +- return(0); +-} /* SkPciWriteCfgDWord */ ++ struct net_device *dev = pci_get_drvdata(pdev); ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ SK_U16 PmCtlSts; ++ ++ /* Set the power state to D0 */ ++ pci_set_power_state(pdev, 0); ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) ++ pci_restore_state(pdev); ++#else ++ pci_restore_state(pdev, pAC->PciState); ++#endif ++ ++ pci_enable_device(pdev); ++ pci_set_master(pdev); ++ ++ pci_enable_wake(pdev, 3, 0); ++ pci_enable_wake(pdev, 4, 0); ++ ++ SK_OUT8(pAC->IoBase, RX_GMF_CTRL_T, (SK_U8)GMF_RST_CLR); ++ ++ /* Set the adapter power state to D0 */ ++ SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); ++ PmCtlSts &= ~(PCI_PM_STATE_D3); /* reset all DState bits */ ++ PmCtlSts |= PCI_PM_STATE_D0; ++ SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PmCtlSts); ++ ++ /* Reinit the adapter and start the port again */ ++ pAC->BoardLevel = SK_INIT_DATA; ++ SkDrvLeaveDiagMode(pAC); ++ ++ if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) || ++ (CHIP_ID_YUKON_2(pAC)) ) { ++ pAC->StatusLETable.Done = 0; ++ pAC->StatusLETable.Put = 0; ++ pAC->StatusLETable.HwPut = 0; ++ SkGeY2InitStatBmu(pAC, pAC->IoBase, &pAC->StatusLETable); ++ } + ++ return 0; ++} ++ + /***************************************************************************** + * +- * SkGeInitPCI - Init the PCI resources ++ * sk98lin_suspend - Suspend the card + * + * Description: +- * This function initialize the PCI resources and IO ++ * This function suspends the card into a defined state ++ * ++ * Returns: N/A ++ * ++ */ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) ++static int sk98lin_suspend( ++struct pci_dev *pdev, /* pointer to the device that is to suspend */ ++pm_message_t state) /* what power state is desired by Linux? */ ++#else ++static int sk98lin_suspend( ++struct pci_dev *pdev, /* pointer to the device that is to suspend */ ++SK_U32 state) /* what power state is desired by Linux? */ ++#endif ++{ ++ struct net_device *dev = pci_get_drvdata(pdev); ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ SK_U16 PciPMControlStatus; ++ SK_U16 PciPMCapabilities; ++ SK_MAC_ADDR MacAddr; ++ int i; ++ ++ /* GEnesis and first yukon revs do not support power management */ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { ++ if (pAC->GIni.GIChipRev == 0) { ++ return 0; /* power management not supported */ ++ } ++ } ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { ++ return 0; /* not supported for this chipset */ ++ } ++ ++ if (pAC->WolInfo.ConfiguredWolOptions == 0) { ++ return 0; /* WOL possible, but disabled via ethtool */ ++ } ++ ++ if(netif_running(dev)) { ++ netif_stop_queue(dev); /* stop device if running */ ++ } ++ ++ /* read the PM control/status register from the PCI config space */ ++ SK_IN16(pAC->IoBase, PCI_C(pAC, PCI_PM_CTL_STS), &PciPMControlStatus); ++ ++ /* read the power management capabilities from the config space */ ++ SK_IN16(pAC->IoBase, PCI_C(pAC, PCI_PM_CAP_REG), &PciPMCapabilities); ++ ++ /* Enable WakeUp with Magic Packet - get MAC address from adapter */ ++ for (i = 0; i < SK_MAC_ADDR_LEN; i++) { ++ /* virtual address: will be used for data */ ++ SK_IN8(pAC->IoBase, (B2_MAC_1 + i), &MacAddr.a[i]); ++ } ++ ++ SkDrvEnterDiagMode(pAC); ++ SkEnableWOMagicPacket(pAC, pAC->IoBase, MacAddr); ++ ++ pci_enable_wake(pdev, 3, 1); ++ pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) ++ pci_save_state(pdev); ++#else ++ pci_save_state(pdev, pAC->PciState); ++#endif ++ pci_disable_device(pdev); // NEW ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) ++ pci_set_power_state(pdev, pci_choose_state(pdev, state)); /* set the state */ ++#else ++ pci_set_power_state(pdev, state); /* set the state */ ++#endif ++ ++ return 0; ++} ++ ++ ++/****************************************************************************** ++ * ++ * SkEnableWOMagicPacket - Enable Wake on Magic Packet on the adapter ++ * ++ * Context: ++ * init, pageable ++ * the adapter should be de-initialized before calling this function + * + * Returns: +- * 0 - indicate everything worked ok. +- * != 0 - error indication ++ * nothing + */ +-static __devinit int SkGeInitPCI(SK_AC *pAC) +-{ +- struct SK_NET_DEVICE *dev = pAC->dev[0]; +- struct pci_dev *pdev = pAC->PciDev; +- int retval; + +- dev->mem_start = pci_resource_start (pdev, 0); +- pci_set_master(pdev); ++static void SkEnableWOMagicPacket( ++SK_AC *pAC, /* Adapter Control Context */ ++SK_IOC IoC, /* I/O control context */ ++SK_MAC_ADDR MacAddr) /* MacAddr expected in magic packet */ ++{ ++ SK_U16 Word; ++ SK_U32 DWord; ++ int i; ++ int HwPortIndex; ++ int Port = 0; ++ ++ /* use Port 0 as long as we do not have any dual port cards which support WOL */ ++ HwPortIndex = 0; ++ DWord = 0; + +- retval = pci_request_regions(pdev, "sk98lin"); +- if (retval) +- goto out; ++ SK_OUT16(IoC, 0x0004, 0x0002); /* clear S/W Reset */ ++ SK_OUT16(IoC, 0x0f10, 0x0002); /* clear Link Reset */ + +-#ifdef SK_BIG_ENDIAN + /* +- * On big endian machines, we use the adapter's aibility of +- * reading the descriptors as big endian. ++ * PHY Configuration: ++ * Autonegotioation is enalbed, advertise 10 HD, 10 FD, ++ * 100 HD, and 100 FD. + */ +- { +- SK_U32 our2; +- SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2); +- our2 |= PCI_REV_DESC; +- SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2); ++ if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) || ++ (pAC->GIni.GIChipId == CHIP_ID_YUKON) || ++ (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) || ++ (CHIP_ID_YUKON_2(pAC)) ) { ++ ++ SK_OUT8(IoC, 0x0007, 0xa9); /* enable VAUX */ ++ ++ /* WA code for COMA mode */ ++ /* Only for yukon plus based chipsets rev A3 */ ++ if (pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { ++ SK_IN32(IoC, B2_GP_IO, &DWord); ++ DWord |= GP_DIR_9; /* set to output */ ++ DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ ++ SK_OUT32(IoC, B2_GP_IO, DWord); /* clear PHY reset */ ++ } ++ ++ if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) || ++ (pAC->GIni.GIChipId == CHIP_ID_YUKON)) { ++ SK_OUT32(IoC, 0x0f04, 0x01f04001); /* set PHY reset */ ++ SK_OUT32(IoC, 0x0f04, 0x01f04002); /* clear PHY reset */ ++ } else { ++ SK_OUT8(IoC, 0x0f04, 0x02); /* clear PHY reset */ ++ } ++ ++ SK_OUT8(IoC, 0x0f00, 0x02); /* clear MAC reset */ ++ SkGmPhyWrite(pAC, IoC, Port, 4, 0x01e1); /* advertise 10/100 HD/FD */ ++ SkGmPhyWrite(pAC, IoC, Port, 9, 0x0000); /* do not advertise 1000 HD/FD */ ++ SkGmPhyWrite(pAC, IoC, Port, 00, 0xB300); /* 100 MBit, disable Autoneg */ ++ } else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) { ++ SK_OUT8(IoC, 0x0007, 0xa9); /* enable VAUX */ ++ SK_OUT8(IoC, 0x0f04, 0x02); /* clear PHY reset */ ++ SK_OUT8(IoC, 0x0f00, 0x02); /* clear MAC reset */ ++ SkGmPhyWrite(pAC, IoC, Port, 16, 0x0130); /* Enable Automatic Crossover */ ++ SkGmPhyWrite(pAC, IoC, Port, 00, 0xB300); /* 100 MBit, disable Autoneg */ + } +-#endif ++ + + /* +- * Remap the regs into kernel space. ++ * MAC Configuration: ++ * Set the MAC to 100 HD and enable the auto update features ++ * for Speed, Flow Control and Duplex Mode. ++ * If autonegotiation completes successfully the ++ * MAC takes the link parameters from the PHY. ++ * If the link partner doesn't support autonegotiation ++ * the MAC can receive magic packets if the link partner ++ * uses 100 HD. + */ +- pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000); +- if (!pAC->IoBase) { +- retval = -EIO; +- goto out_release; ++ SK_OUT16(IoC, 0x2804, 0x3832); ++ ++ ++ /* ++ * Set Up Magic Packet parameters ++ */ ++ for (i = 0; i < 6; i+=2) { /* set up magic packet MAC address */ ++ SK_IN16(IoC, 0x100 + i, &Word); ++ SK_OUT16(IoC, 0xf24 + i, Word); + } + +- return 0; ++ SK_OUT16(IoC, 0x0f20, 0x0208); /* enable PME on magic packet */ ++ /* and on wake up frame */ + +- out_release: +- pci_release_regions(pdev); +- out: +- return retval; +-} ++ /* ++ * Set up PME generation ++ */ ++ /* set PME legacy mode */ ++ /* Only for PCI express based chipsets */ ++ if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) || ++ (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) || ++ (CHIP_ID_YUKON_2(pAC))) { ++ SkPciReadCfgDWord(pAC, 0x40, &DWord); ++ DWord |= 0x8000; ++ SkPciWriteCfgDWord(pAC, 0x40, DWord); ++ } ++ ++ SK_OUT8(IoC, RX_GMF_CTRL_T, (SK_U8)GMF_RST_SET); ++ ++ /* clear PME status and switch adapter to DState */ ++ SkPciReadCfgWord(pAC, 0x4c, &Word); ++ Word |= 0x103; ++ SkPciWriteCfgWord(pAC, 0x4c, Word); ++} /* SkEnableWOMagicPacket */ ++#endif + + + /***************************************************************************** +@@ -349,20 +1285,24 @@ + 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); ++ if (dev->priv) { ++ pNet = (DEV_NET*) dev->priv; ++ 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 (CHIP_ID_YUKON_2(pAC)) { ++ SkY2FreeResources(pAC); ++ } else { ++ BoardFreeMem(pAC); ++ } + } + + } /* FreeResources */ +@@ -371,6 +1311,8 @@ + MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver"); + MODULE_LICENSE("GPL"); + ++MODULE_VERSION(DRV_VERSION); ++ + #ifdef LINK_SPEED_A + static char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED; + #else +@@ -452,9 +1394,11 @@ + 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]; + ++static char *LowLatency[SK_MAX_CARD_PARAM]; ++static char *BroadcastPrio[SK_MAX_CARD_PARAM]; ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) + module_param_array(Speed_A, charp, NULL, 0); + module_param_array(Speed_B, charp, NULL, 0); + module_param_array(AutoNeg_A, charp, NULL, 0); +@@ -471,9 +1415,129 @@ + /* 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); ++module_param_array(LowLatency, charp, NULL, 0); ++module_param_array(BroadcastPrio, charp, NULL, 0); ++#else ++MODULE_PARM(Speed_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(Speed_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(AutoNeg_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(AutoNeg_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(DupCap_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(DupCap_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(Role_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(Role_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(ConType, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(PrefPort, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(RlmtMode, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(IntsPerSec, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i"); ++MODULE_PARM(Moderation, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(ModerationMask, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(LowLatency, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++MODULE_PARM(BroadcastPrio, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); ++#endif ++ ++ ++/***************************************************************************** ++ * ++ * sk98lin_remove_device - device deinit function ++ * ++ * Description: ++ * Disable adapter if it is still running, free resources, ++ * free device struct. ++ * ++ * Returns: N/A ++ */ ++ ++static void sk98lin_remove_device(struct pci_dev *pdev) ++{ ++DEV_NET *pNet; ++SK_AC *pAC; ++struct SK_NET_DEVICE *next; ++unsigned long Flags; ++struct net_device *dev = pci_get_drvdata(pdev); ++ ++ ++ /* Device not available. Return. */ ++ if (!dev) ++ return; ++ ++ pNet = (DEV_NET*) dev->priv; ++ pAC = pNet->pAC; ++ next = pAC->Next; ++ ++#ifndef SK_ASF ++ netif_stop_queue(dev); ++#endif ++ SkGeYellowLED(pAC, pAC->IoBase, 0); ++ ++ if(pAC->BoardLevel == SK_INIT_RUN) { ++ /* board is still alive */ ++ spin_lock_irqsave(&pAC->SlowPathLock, Flags); ++#ifndef SK_ASF ++ SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, ++ 0, -1, SK_FALSE); ++ SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, ++ 1, -1, SK_TRUE); ++#endif ++ ++ /* disable interrupts */ ++ SK_OUT32(pAC->IoBase, B0_IMSK, 0); ++#ifdef SK_ASF ++ SkAsfDeInit(pAC, pAC->IoBase); ++#endif ++ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); ++ pAC->BoardLevel = SK_INIT_DATA; ++ /* We do NOT check here, if IRQ was pending, of course*/ ++ } ++ ++ if(pAC->BoardLevel == SK_INIT_IO) { ++ /* board is still alive */ ++ SkGeDeInit(pAC, pAC->IoBase); ++ pAC->BoardLevel = SK_INIT_DATA; ++ } ++ ++ if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){ ++ unregister_netdev(pAC->dev[1]); ++ free_netdev(pAC->dev[1]); ++ } ++ ++ FreeResources(dev); ++ ++#ifdef CONFIG_PROC_FS ++ /* Remove the sk98lin procfs device entries */ ++ if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){ ++ if (pAC->InterfaceUp[1] == 1) { ++ remove_proc_entry(pAC->dev[1]->name, pSkRootDir); ++ } ++ } ++ if (pAC->InterfaceUp[0] == 1) { ++ remove_proc_entry(pAC->dev[0]->name, pSkRootDir); ++ } ++#endif ++ ++ dev->get_stats = NULL; ++ /* ++ * otherwise unregister_netdev calls get_stats with ++ * invalid IO ... :-( ++ */ ++ unregister_netdev(dev); ++ free_netdev(dev); ++ kfree(pAC); ++ sk98lin_max_boards_found--; ++ ++#ifdef CONFIG_PROC_FS ++ /* Remove all Proc entries if last device */ ++ if (sk98lin_max_boards_found == 0) { ++ /* clear proc-dir */ ++ remove_proc_entry(pSkRootDir->name, proc_net); ++ } ++#endif ++ ++} ++ + + /***************************************************************************** + * +@@ -491,11 +1555,11 @@ + static int __devinit 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; ++unsigned long Flags; /* for the spin locks */ + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, + ("IoBase: %08lX\n", (unsigned long)pAC->IoBase)); +@@ -511,21 +1575,30 @@ + 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); ++ spin_lock_init(&pAC->InitLock); /* Init lock */ ++ spin_lock_init(&pAC->SlowPathLock); ++ spin_lock_init(&pAC->TxQueueLock); /* for Yukon2 chipsets */ ++ spin_lock_init(&pAC->SetPutIndexLock); /* for Yukon2 chipsets */ + + /* level 0 init common modules here */ +- ++ ++#ifdef SK_ASF ++ spin_lock(&pAC->SlowPathLock); ++#endif ++#ifndef SK_ASF + spin_lock_irqsave(&pAC->SlowPathLock, Flags); ++#endif + /* Does a RESET on board ...*/ + if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) { + printk("HWInit (0) failed.\n"); ++#ifdef SK_ASF ++ spin_unlock(&pAC->SlowPathLock); ++#endif ++#ifndef SK_ASF + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); +- return -EIO; ++#endif ++ return(-EAGAIN); + } + SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA); + SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA); +@@ -533,21 +1606,27 @@ + SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA); + SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA); + SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA); ++#ifdef SK_ASF ++ SkAsfInit(pAC, pAC->IoBase, SK_INIT_DATA); ++#endif + + pAC->BoardLevel = SK_INIT_DATA; +- pAC->RxBufSize = ETH_BUF_SIZE; ++ pAC->RxPort[0].RxBufSize = ETH_BUF_SIZE; ++ pAC->RxPort[1].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"); ++#ifdef SK_ASF ++ spin_unlock(&pAC->SlowPathLock); ++#endif ++#ifndef SK_ASF + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); +- return -EIO; ++#endif ++ return(-EAGAIN); + } + SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO); + SkEventInit(pAC, pAC->IoBase, SK_INIT_IO); +@@ -555,46 +1634,101 @@ + SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO); + SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO); + SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO); ++#ifdef SK_ASF ++ SkAsfInit(pAC, pAC->IoBase, SK_INIT_IO); ++#endif ++#ifdef Y2_RECOVERY ++ /* mark entries invalid */ ++ pAC->LastPort = 3; ++ pAC->LastOpc = 0xFF; ++#endif + + /* Set chipset type support */ +- pAC->ChipsetType = 0; + if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) || +- (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) { +- pAC->ChipsetType = 1; ++ (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) || ++ (pAC->GIni.GIChipId == CHIP_ID_YUKON_LP)) { ++ pAC->ChipsetType = 1; /* Yukon chipset (descriptor logic) */ ++ } else if (CHIP_ID_YUKON_2(pAC)) { ++ pAC->ChipsetType = 2; /* Yukon2 chipset (list logic) */ ++ } else { ++ pAC->ChipsetType = 0; /* Genesis chipset (descriptor logic) */ ++ } ++ ++ /* wake on lan support */ ++ pAC->WolInfo.SupportedWolOptions = 0; ++#if defined (ETHTOOL_GWOL) && defined (ETHTOOL_SWOL) ++ if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) { ++ pAC->WolInfo.SupportedWolOptions = WAKE_MAGIC; ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { ++ if (pAC->GIni.GIChipRev == 0) { ++ pAC->WolInfo.SupportedWolOptions = 0; ++ } ++ } + } ++#endif ++ pAC->WolInfo.ConfiguredWolOptions = pAC->WolInfo.SupportedWolOptions; + + GetConfiguration(pAC); + if (pAC->RlmtNets == 2) { +- pAC->GIni.GIPortUsage = SK_MUL_LINK; ++ pAC->GIni.GP[0].PPortUsage = SK_MUL_LINK; ++ pAC->GIni.GP[1].PPortUsage = SK_MUL_LINK; + } + + pAC->BoardLevel = SK_INIT_IO; ++#ifdef SK_ASF ++ spin_unlock(&pAC->SlowPathLock); ++#endif ++#ifndef SK_ASF + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); ++#endif + +- if (pAC->GIni.GIMacsFound == 2) { +- Ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev); +- } else if (pAC->GIni.GIMacsFound == 1) { +- Ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, +- "sk98lin", dev); +- } else { +- printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n", +- pAC->GIni.GIMacsFound); +- return -EIO; ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ if (pAC->GIni.GIMacsFound == 2) { ++ Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, dev->name, dev); ++ } else if (pAC->GIni.GIMacsFound == 1) { ++ Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, dev->name, dev); ++ } else { ++ printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n", ++ pAC->GIni.GIMacsFound); ++ return -EAGAIN; ++ } ++ } ++ else { ++ Ret = request_irq(dev->irq, SkY2Isr, SA_SHIRQ, dev->name, dev); + } + + if (Ret) { + printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n", +- dev->irq); +- return Ret; ++ 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 -ENOMEM; ++ /* ++ ** Alloc descriptor/LETable memory for this board (both RxD/TxD) ++ */ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ if (!SkY2AllocateResources(pAC)) { ++ printk("No memory for Yukon2 settings\n"); ++ return(-EAGAIN); ++ } ++ } else { ++ if(!BoardAllocMem(pAC)) { ++ printk("No memory for descriptor rings.\n"); ++ return(-EAGAIN); ++ } + } + ++#ifdef SK_USE_CSUM ++ SkCsSetReceiveFlags(pAC, ++ SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP, ++ &pAC->CsOfs1, &pAC->CsOfs2, 0); ++ pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1; ++#endif ++ ++ /* ++ ** Function BoardInitMem() for Yukon dependent settings... ++ */ + BoardInitMem(pAC); + /* tschilling: New common function with minimum size check. */ + DualNet = SK_FALSE; +@@ -606,11 +1740,22 @@ + pAC, + pAC->ActivePort, + DualNet)) { +- BoardFreeMem(pAC); ++ if (CHIP_ID_YUKON_2(pAC)) { ++ SkY2FreeResources(pAC); ++ } else { ++ BoardFreeMem(pAC); ++ } ++ + printk("sk98lin: SkGeInitAssignRamToQueues failed.\n"); +- return -EIO; ++ return(-EAGAIN); + } + ++ /* ++ * Register the device here ++ */ ++ pAC->Next = SkGeRootDev; ++ SkGeRootDev = dev; ++ + return (0); + } /* SkGeBoardInit */ + +@@ -629,7 +1774,8 @@ + * SK_TRUE, if all memory could be allocated + * SK_FALSE, if not + */ +-static __devinit SK_BOOL BoardAllocMem(SK_AC *pAC) ++static SK_BOOL BoardAllocMem( ++SK_AC *pAC) + { + caddr_t pDescrMem; /* pointer to descriptor memory area */ + size_t AllocLength; /* length of complete descriptor area */ +@@ -699,16 +1845,20 @@ + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, + ("BoardFreeMem\n")); ++ ++ if (pAC->pDescrMem) { ++ + #if (BITS_PER_LONG == 32) +- AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8; ++ 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; ++ AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound ++ + RX_RING_SIZE + 8; + #endif + +- pci_free_consistent(pAC->PciDev, AllocLength, ++ pci_free_consistent(pAC->PciDev, AllocLength, + pAC->pDescrMem, pAC->pDescrMemDMA); +- pAC->pDescrMem = NULL; ++ pAC->pDescrMem = NULL; ++ } + } /* BoardFreeMem */ + + +@@ -717,12 +1867,13 @@ + * BoardInitMem - initiate the descriptor rings + * + * Description: +- * This function sets the descriptor rings up in memory. ++ * This function sets the descriptor rings or LETables up in memory. + * The adapter is initialized with the descriptor start addresses. + * + * Returns: N/A + */ +-static __devinit void BoardInitMem(SK_AC *pAC) ++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*/ +@@ -731,34 +1882,37 @@ + 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; ++ if (!pAC->GIni.GIYukon2) { ++ 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; iGIni.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); ++ for (i=0; iGIni.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, ++ &pAC->TxPort[i][0].TxdRingPrevFree, ++ 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, ++ &pAC->RxPort[i].RxdRingFree, ++ SK_FALSE); ++ } + } + } /* BoardInitMem */ + +- + /***************************************************************************** + * + * SetupRing - create one descriptor ring +@@ -778,6 +1932,7 @@ + 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 */ ++int *pRingPrevFree, /* address where the # of free descr. goes */ + SK_BOOL IsTx) /* flag: is this a tx ring */ + { + int i; /* loop counter */ +@@ -810,7 +1965,7 @@ + /* set the pointers right */ + pDescr->VNextRxd = VNextDescr & 0xffffffffULL; + pDescr->pNextRxd = pNextDescr; +- if (!IsTx) pDescr->TcpSumStarts = ETH_HLEN << 16 | ETH_HLEN; ++ pDescr->TcpSumStarts = pAC->CsOfs; + + /* advance one step */ + pPrevDescr = pDescr; +@@ -820,11 +1975,12 @@ + } + pPrevDescr->pNextRxd = (RXD*) pMemArea; + pPrevDescr->VNextRxd = VMemArea; +- pDescr = (RXD*) pMemArea; +- *ppRingHead = (RXD*) pMemArea; +- *ppRingTail = *ppRingHead; +- *ppRingPrev = pPrevDescr; +- *pRingFree = DescrNum; ++ pDescr = (RXD*) pMemArea; ++ *ppRingHead = (RXD*) pMemArea; ++ *ppRingTail = *ppRingHead; ++ *ppRingPrev = pPrevDescr; ++ *pRingFree = DescrNum; ++ *pRingPrevFree = DescrNum; + } /* SetupRing */ + + +@@ -882,24 +2038,42 @@ + * Returns: N/A + * + */ +-static SkIsrRetVar SkGeIsr(int irq, void *dev_id) ++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); ++ pNet = (DEV_NET*) dev->priv; + pAC = pNet->pAC; + + /* + * Check and process if its our interrupt + */ + SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc); +- if (IntSrc == 0) { ++ if ((IntSrc == 0) && (!pNet->NetConsoleMode)) { + return SkIsrRetNone; + } + ++#ifdef CONFIG_SK98LIN_NAPI ++ if (netif_rx_schedule_prep(dev)) { ++ pAC->GIni.GIValIrqMask &= ~(NAPI_DRV_IRQS); ++ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); ++ __netif_rx_schedule(dev); ++ } ++ ++#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ ++ if (IntSrc & IS_XA1_F) { ++ CLEAR_TX_IRQ(0, TX_PRIO_LOW); ++ } ++ if (IntSrc & IS_XA2_F) { ++ CLEAR_TX_IRQ(1, TX_PRIO_LOW); ++ } ++#endif ++ ++ ++#else + while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) { + #if 0 /* software irq currently not used */ + if (IntSrc & IS_IRQ_SW) { +@@ -913,6 +2087,7 @@ + SK_DBGCAT_DRV_INT_SRC, + ("EOF RX1 IRQ\n")); + ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); ++ CLEAR_AND_START_RX(0); + SK_PNMI_CNT_RX_INTR(pAC, 0); + } + if (IntSrc & IS_R2_F) { +@@ -920,6 +2095,7 @@ + SK_DBGCAT_DRV_INT_SRC, + ("EOF RX2 IRQ\n")); + ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE); ++ CLEAR_AND_START_RX(1); + SK_PNMI_CNT_RX_INTR(pAC, 1); + } + #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ +@@ -927,6 +2103,7 @@ + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_INT_SRC, + ("EOF AS TX1 IRQ\n")); ++ CLEAR_TX_IRQ(0, TX_PRIO_LOW); + SK_PNMI_CNT_TX_INTR(pAC, 0); + spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); + FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); +@@ -936,6 +2113,7 @@ + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_INT_SRC, + ("EOF AS TX2 IRQ\n")); ++ CLEAR_TX_IRQ(1, TX_PRIO_LOW); + SK_PNMI_CNT_TX_INTR(pAC, 1); + spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); + FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]); +@@ -946,38 +2124,42 @@ + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_INT_SRC, + ("EOF SY TX1 IRQ\n")); ++ CLEAR_TX_IRQ(0, TX_PRIO_HIGH); + 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")); ++ CLEAR_TX_IRQ(1, TX_PRIO_HIGH); + 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) */ ++#endif ++ ++#ifndef CONFIG_SK98LIN_NAPI ++ /* Handle interrupts */ ++ 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); ++ ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); ++ START_RX(0); ++ 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); ++ ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE); ++ START_RX(1); ++#endif + + IntSrc &= pAC->GIni.GIValIrqMask; + if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) { +@@ -990,19 +2172,9 @@ + + SkEventDispatcher(pAC, pAC->IoBase); + spin_unlock(&pAC->SlowPathLock); ++ START_RX(0); ++ START_RX(1); + } +- /* +- * 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; +@@ -1014,7 +2186,8 @@ + /* IRQ is processed - Enable IRQs again*/ + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); + +- return SkIsrRetHandled; ++ return SkIsrRetHandled; ++ + } /* SkGeIsr */ + + +@@ -1031,24 +2204,40 @@ + * Returns: N/A + * + */ +-static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id) ++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); ++ pNet = (DEV_NET*) dev->priv; + pAC = pNet->pAC; + + /* + * Check and process if its our interrupt + */ + SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc); +- if (IntSrc == 0) { ++ if ((IntSrc == 0) && (!pNet->NetConsoleMode)) { + return SkIsrRetNone; ++ + } + ++#ifdef CONFIG_SK98LIN_NAPI ++ if (netif_rx_schedule_prep(dev)) { ++ CLEAR_AND_START_RX(0); ++ CLEAR_TX_IRQ(0, TX_PRIO_LOW); ++ pAC->GIni.GIValIrqMask &= ~(NAPI_DRV_IRQS); ++ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); ++ __netif_rx_schedule(dev); ++ } ++ ++#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ ++ if (IntSrc & IS_XA1_F) { ++ CLEAR_TX_IRQ(0, TX_PRIO_LOW); ++ } ++#endif ++#else + while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) { + #if 0 /* software irq currently not used */ + if (IntSrc & IS_IRQ_SW) { +@@ -1062,6 +2251,7 @@ + SK_DBGCAT_DRV_INT_SRC, + ("EOF RX1 IRQ\n")); + ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); ++ CLEAR_AND_START_RX(0); + SK_PNMI_CNT_RX_INTR(pAC, 0); + } + #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ +@@ -1069,6 +2259,7 @@ + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_INT_SRC, + ("EOF AS TX1 IRQ\n")); ++ CLEAR_TX_IRQ(0, TX_PRIO_LOW); + SK_PNMI_CNT_TX_INTR(pAC, 0); + spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); + FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); +@@ -1079,25 +2270,27 @@ + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_INT_SRC, + ("EOF SY TX1 IRQ\n")); ++ CLEAR_TX_IRQ(0, TX_PRIO_HIGH); + 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) */ ++#endif + ++#ifndef CONFIG_SK98LIN_NAPI ++ 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); ++ ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); ++ START_RX(0); ++#endif ++ + IntSrc &= pAC->GIni.GIValIrqMask; + if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, +@@ -1109,43 +2302,15 @@ + + SkEventDispatcher(pAC, pAC->IoBase); + spin_unlock(&pAC->SlowPathLock); ++ START_RX(0); + } +- /* +- * 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 */ ++ return SkIsrRetHandled; + +-#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); +- enable_irq(dev->irq); +-} +-#endif ++} /* SkGeIsrOnePort */ + + /**************************************************************************** + * +@@ -1164,27 +2329,36 @@ + * != 0 on error + */ + static int SkGeOpen( +-struct SK_NET_DEVICE *dev) ++struct SK_NET_DEVICE *dev) /* the device that is to be opened */ + { +- DEV_NET *pNet; +- SK_AC *pAC; +- unsigned long Flags; /* for spin lock */ +- int i; +- SK_EVPARA EvPara; /* an event parameter union */ ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ unsigned long Flags; /* for the spin locks */ ++ int CurrMac; /* loop ctr for ports */ ++ unsigned long InitFlags; ++ SK_U32 StatSpeed, StatDuplex, NewTimerInterval; ++ ++ struct proc_dir_entry *pProcFile; + +- 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 ++#ifdef SK_ASF ++ spin_lock(&pAC->InitLock); ++#endif ++#ifndef SK_ASF ++ spin_lock_irqsave(&pAC->InitLock, InitFlags); ++#endif ++ + if (pAC->DiagModeActive == DIAG_ACTIVE) { + if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { + return (-1); /* still in use by diag; deny actions */ + } + } +-#endif ++ ++ if (!try_module_get(THIS_MODULE)) { ++ return (-1); /* increase of usage count not possible */ ++ } + + /* Set blink mode */ + if ((pAC->PciDev->vendor == 0x1186) || (pAC->PciDev->vendor == 0x11ab )) +@@ -1193,6 +2367,7 @@ + if (pAC->BoardLevel == SK_INIT_DATA) { + /* level 1 init common modules here */ + if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { ++ module_put(THIS_MODULE); /* decrease usage count */ + printk("%s: HWInit (1) failed.\n", pAC->dev[pNet->PortNr]->name); + return (-1); + } +@@ -1202,12 +2377,21 @@ + SkAddrInit (pAC, pAC->IoBase, SK_INIT_IO); + SkRlmtInit (pAC, pAC->IoBase, SK_INIT_IO); + SkTimerInit (pAC, pAC->IoBase, SK_INIT_IO); ++#ifdef SK_ASF ++ SkAsfInit (pAC, pAC->IoBase, SK_INIT_IO); ++#endif + pAC->BoardLevel = SK_INIT_IO; ++#ifdef Y2_RECOVERY ++ /* mark entries invalid */ ++ pAC->LastPort = 3; ++ pAC->LastOpc = 0xFF; ++#endif + } + + if (pAC->BoardLevel != SK_INIT_RUN) { + /* tschilling: Level 2 init modules here, check return value. */ + if (SkGeInit(pAC, pAC->IoBase, SK_INIT_RUN) != 0) { ++ module_put(THIS_MODULE); /* decrease usage count */ + printk("%s: HWInit (2) failed.\n", pAC->dev[pNet->PortNr]->name); + return (-1); + } +@@ -1217,47 +2401,139 @@ + SkAddrInit (pAC, pAC->IoBase, SK_INIT_RUN); + SkRlmtInit (pAC, pAC->IoBase, SK_INIT_RUN); + SkTimerInit (pAC, pAC->IoBase, SK_INIT_RUN); ++#ifdef SK_ASF ++ SkAsfInit (pAC, pAC->IoBase, SK_INIT_RUN); ++#endif + pAC->BoardLevel = SK_INIT_RUN; + } + +- for (i=0; iGIni.GIMacsFound; i++) { +- /* Enable transmit descriptor polling. */ +- SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); +- FillRxRing(pAC, &pAC->RxPort[i]); ++ for (CurrMac=0; CurrMacGIni.GIMacsFound; CurrMac++) { ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ /* Enable transmit descriptor polling. */ ++ SkGePollTxD(pAC, pAC->IoBase, CurrMac, SK_TRUE); ++ FillRxRing(pAC, &pAC->RxPort[CurrMac]); ++ SkMacRxTxEnable(pAC, pAC->IoBase, pNet->PortNr); ++ } + } +- SkGeYellowLED(pAC, pAC->IoBase, 1); + +- StartDrvCleanupTimer(pAC); ++ SkGeYellowLED(pAC, pAC->IoBase, 1); + 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); ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ /* ++ ** Has been setup already at SkGeInit(SK_INIT_IO), ++ ** but additional masking added for Genesis & Yukon ++ ** chipsets -> modify it... ++ */ ++ pAC->GIni.GIValIrqMask &= IRQ_MASK; ++#ifndef USE_TX_COMPLETE ++ pAC->GIni.GIValIrqMask &= ~(TX_COMPL_IRQS); ++#endif ++ } + + 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); ++ SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, ++ pAC->RlmtNets, -1, SK_FALSE); ++ SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE, ++ pAC->RlmtMode, 0, SK_FALSE); + } + +- EvPara.Para32[0] = pNet->NetNr; +- EvPara.Para32[1] = -1; +- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); +- SkEventDispatcher(pAC, pAC->IoBase); ++ SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, ++ pNet->NetNr, -1, SK_TRUE); + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + ++#ifdef Y2_RECOVERY ++ pNet->TimerExpired = SK_FALSE; ++ pNet->InRecover = SK_FALSE; ++ pNet->NetConsoleMode = SK_FALSE; ++ ++ StatSpeed = pAC->GIni.GP[pNet->NetNr].PLinkSpeedUsed; ++ if (StatSpeed == SK_LSPEED_STAT_10MBPS) { ++ StatDuplex = pAC->GIni.GP[pNet->NetNr].PLinkModeStatus; ++ if ((StatDuplex == SK_LMODE_STAT_AUTOHALF) || ++ (StatDuplex == SK_LMODE_STAT_HALF)) { ++ NewTimerInterval = (HZ*2); ++ } else { ++ NewTimerInterval = (HZ); ++ } ++ } else if (StatSpeed == SK_LSPEED_STAT_100MBPS) { ++ NewTimerInterval = (HZ/2); ++ } else if (StatSpeed == SK_LSPEED_STAT_1000MBPS) { ++ NewTimerInterval = (HZ/4); ++ } else { ++ NewTimerInterval = (HZ*2); ++ } ++ ++ /* Initialize the kernel timer */ ++ init_timer(&pNet->KernelTimer); ++ pNet->KernelTimer.function = SkGeHandleKernelTimer; ++ pNet->KernelTimer.data = (unsigned long) pNet; ++ pNet->KernelTimer.expires = jiffies + NewTimerInterval; ++ add_timer(&pNet->KernelTimer); ++#endif ++#ifdef SK_ASF ++ /* Set OS Present Flag in ASF Status and Command Register */ ++ SK_IN32( pAC->IoBase, REG_ASF_STATUS_CMD, &TmpVal32 ); ++ TmpVal32 |= BIT_4; ++ SK_OUT32( pAC->IoBase, REG_ASF_STATUS_CMD, TmpVal32 ); ++ ++ YlciDisablePattern(pAC, pAC->IoBase, 0, 5); // Disable ARP pattern, OS is now responsible for ARP handling ++ ++ if (pAC->AsfData.DualMode == SK_GEASF_Y2_DUALPORT) { ++ YlciDisablePattern(pAC, pAC->IoBase, 1, 5); // Disable ARP pattern, OS is now responsible for ARP handling ++ } ++ ++ if (is_closed) { ++ Para.Para32[0] = pAC->ActivePort; ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para); ++ } ++#endif ++ ++ /* enable Interrupts */ ++ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); ++ SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK); ++ + pAC->MaxPorts++; + ++ /* Set state to open */ ++ is_closed = 0; ++ ++ /* Initialize the procfs timer */ ++ init_timer(&pNet->ProcfsTimer); ++ pNet->ProcfsTimer.function = SkGeHandleProcfsTimer; ++ pNet->ProcfsTimer.data = (unsigned long) pNet; ++ pNet->ProcfsTimer.expires = jiffies + HZ*5; /* initially 5 secs */ ++ add_timer(&pNet->ProcfsTimer); ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) { ++ SK_OUT8(pAC->IoBase, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | ++ PC_VAUX_OFF | PC_VCC_ON)); ++ } ++ ++#ifdef SK_ASF ++ spin_unlock(&pAC->InitLock); ++#endif ++#ifndef SK_ASF ++ spin_unlock_irqrestore(&pAC->InitLock, InitFlags); ++#endif ++ ++#ifdef CONFIG_PROC_FS ++ if ( (!pAC->InterfaceUp[pNet->NetNr]) && ++ (pSkRootDir) ) { ++ pProcFile = create_proc_entry(pAC->dev[pNet->NetNr]->name, S_IRUGO, pSkRootDir); ++ pProcFile->proc_fops = &sk_proc_fops; ++ pProcFile->data = dev; ++ ++ /* ++ * Remember, interface dev nr pNet->NetNr is up ++ */ ++ pAC->InterfaceUp[pNet->NetNr] = 1; ++ ++ strcpy(pNet->CurrentName, pNet->pAC->dev[pNet->NetNr]->name); ++ } ++#endif + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, + ("SkGeOpen suceeded\n")); +@@ -1278,32 +2554,44 @@ + * error code - on error + */ + static int SkGeClose( +-struct SK_NET_DEVICE *dev) ++struct SK_NET_DEVICE *dev) /* the device that is to be closed */ + { +- DEV_NET *pNet; +- DEV_NET *newPtrNet; +- SK_AC *pAC; +- +- unsigned long Flags; /* for spin lock */ +- int i; +- int PortIdx; +- SK_EVPARA EvPara; +- ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ DEV_NET *newPtrNet; ++ unsigned long Flags; /* for the spin locks */ ++ unsigned long InitFlags; /* for the spin locks */ ++ int CurrMac; /* loop ctr for the current MAC */ ++ int PortIdx; ++#ifdef CONFIG_SK98LIN_NAPI ++ int WorkToDo = 1; /* min(*budget, dev->quota); */ ++ int WorkDone = 0; ++#endif + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, + ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC)); ++ spin_lock_irqsave(&pAC->InitLock, InitFlags); ++#ifdef SK_ASF ++ SkAsfDeInit(pAC, pAC->IoBase); ++#endif + +- pNet = netdev_priv(dev); +- pAC = pNet->pAC; ++#ifdef CONFIG_PROC_FS ++ del_timer(&pNet->ProcfsTimer); ++#endif ++ ++#ifdef Y2_RECOVERY ++ pNet->InRecover = SK_TRUE; ++ del_timer(&pNet->KernelTimer); ++#endif + +-#ifdef SK_DIAG_SUPPORT + if (pAC->DiagModeActive == DIAG_ACTIVE) { + if (pAC->DiagFlowCtrl == SK_FALSE) { ++ module_put(THIS_MODULE); + /* + ** 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]); ++ newPtrNet = (DEV_NET *) pAC->dev[0]->priv; + if (newPtrNet == pNet) { + pAC->WasIfUp[0] = SK_FALSE; + } else { +@@ -1314,17 +2602,19 @@ + pAC->DiagFlowCtrl = SK_FALSE; + } + } +-#endif + ++#ifdef SK_ASF ++ netif_stop_queue(dev); ++ netif_carrier_off(dev); ++#else + netif_stop_queue(dev); ++#endif + + if (pAC->RlmtNets == 1) + PortIdx = pAC->ActivePort; + else + PortIdx = pNet->NetNr; + +- StopDrvCleanupTimer(pAC); +- + /* + * Clear multicast table, promiscuous mode .... + */ +@@ -1336,46 +2626,142 @@ + 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); ++#ifndef SK_ASF ++ SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, ++ pNet->NetNr, -1, SK_TRUE); + /* stop the hardware */ +- SkGeDeInit(pAC, pAC->IoBase); +- pAC->BoardLevel = SK_INIT_DATA; ++ SK_OUT32(pAC->IoBase, B0_IMSK, 0); ++#endif ++ ++ if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 1)) { ++ /* RLMT check link state mode */ ++ for (CurrMac=0; CurrMacGIni.GIMacsFound; CurrMac++) { ++ if (CHIP_ID_YUKON_2(pAC)) { ++#ifdef SK_ASF ++ SkY2PortStop( pAC, ++ pAC->IoBase, ++ CurrMac, ++ SK_STOP_RX, ++ SK_HARD_RST); ++ SkY2PortStop( pAC, ++ pAC->IoBase, ++ CurrMac, ++ SK_STOP_TX, ++ SK_HARD_RST); ++#else ++ SkY2PortStop( pAC, ++ pAC->IoBase, ++ CurrMac, ++ SK_STOP_ALL, ++ SK_HARD_RST); ++#endif ++ } else { ++ SkGeStopPort( pAC, ++ pAC->IoBase, ++ CurrMac, ++ SK_STOP_ALL, ++ SK_HARD_RST); ++ } ++ } /* for */ ++ } else { ++ /* Single link or single port */ ++ if (CHIP_ID_YUKON_2(pAC)) { ++#ifdef SK_ASF ++ SkY2PortStop( pAC, ++ pAC->IoBase, ++ PortIdx, ++ SK_STOP_RX, ++ SK_HARD_RST); ++ SkY2PortStop( pAC, ++ pAC->IoBase, ++ PortIdx, ++ SK_STOP_TX, ++ SK_HARD_RST); ++#else ++ SkY2PortStop( pAC, ++ pAC->IoBase, ++ PortIdx, ++ SK_STOP_ALL, ++ SK_HARD_RST); ++#endif ++ } else { ++ SkGeStopPort( pAC, ++ pAC->IoBase, ++ PortIdx, ++ SK_STOP_ALL, ++ SK_HARD_RST); ++ } ++ } + 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); ++#ifdef SK_ASF ++ SkY2PortStop(pAC, pAC->IoBase, pNet->PortNr, ++ SK_STOP_RX, SK_HARD_RST); ++ SkY2PortStop(pAC, pAC->IoBase, pNet->PortNr, ++ SK_STOP_TX, SK_HARD_RST); ++#else ++ SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, ++ pNet->NetNr, -1, SK_FALSE); ++ SkLocalEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET, ++ pNet->NetNr, -1, SK_TRUE); ++#endif + 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); ++ if (CHIP_ID_YUKON_2(pAC)) { ++ SkY2PortStop(pAC, pAC->IoBase, pNet->PortNr, ++ SK_STOP_ALL, SK_HARD_RST); ++ } ++ else { ++ 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; iGIni.GIMacsFound; i++) { +- ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); +- ClearRxRing(pAC, &pAC->RxPort[i]); +- ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]); ++ for (CurrMac=0; CurrMacGIni.GIMacsFound; CurrMac++) { ++ if (!CHIP_ID_YUKON_2(pAC)) { ++#ifdef CONFIG_SK98LIN_NAPI ++ WorkToDo = 1; ++ ReceiveIrq(pAC,&pAC->RxPort[CurrMac], ++ SK_TRUE,&WorkDone,WorkToDo); ++#else ++ ReceiveIrq(pAC,&pAC->RxPort[CurrMac],SK_TRUE); ++#endif ++ ClearRxRing(pAC, &pAC->RxPort[CurrMac]); ++ ClearTxRing(pAC, &pAC->TxPort[CurrMac][TX_PRIO_LOW]); ++ } else { ++ SkY2FreeRxBuffers(pAC, pAC->IoBase, CurrMac); ++ SkY2FreeTxBuffers(pAC, pAC->IoBase, CurrMac); ++ } + } + } 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]); ++ if (!CHIP_ID_YUKON_2(pAC)) { ++#ifdef CONFIG_SK98LIN_NAPI ++ WorkToDo = 1; ++ ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE, &WorkDone, WorkToDo); ++#else ++ ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE); ++#endif ++ ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]); ++ ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]); ++ } ++ else { ++ SkY2FreeRxBuffers(pAC, pAC->IoBase, pNet->PortNr); ++ SkY2FreeTxBuffers(pAC, pAC->IoBase, pNet->PortNr); ++ } ++ } ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) { ++ SK_OUT8(pAC->IoBase, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | ++ PC_VAUX_ON | PC_VCC_OFF)); + } + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, +@@ -1386,6 +2772,13 @@ + sizeof(SK_PNMI_STRUCT_DATA)); + + pAC->MaxPorts--; ++ module_put(THIS_MODULE); ++ ++#ifdef Y2_RECOVERY ++ pNet->InRecover = SK_FALSE; ++#endif ++ is_closed = 1; ++ spin_unlock_irqrestore(&pAC->InitLock, InitFlags); + + return (0); + } /* SkGeClose */ +@@ -1412,7 +2805,7 @@ + SK_AC *pAC; + int Rc; /* return code of XmitFrame */ + +- pNet = netdev_priv(dev); ++ pNet = (DEV_NET*) dev->priv; + pAC = pNet->pAC; + + if ((!skb_shinfo(skb)->nr_frags) || +@@ -1458,6 +2851,96 @@ + return (0); + } /* SkGeXmit */ + ++#ifdef CONFIG_SK98LIN_NAPI ++/***************************************************************************** ++ * ++ * SkGePoll - NAPI Rx polling callback for GEnesis and Yukon chipsets ++ * ++ * Description: ++ * Called by the Linux system in case NAPI polling is activated ++ * ++ * Returns: ++ * The number of work data still to be handled ++ */ ++static int SkGePoll(struct net_device *dev, int *budget) ++{ ++ SK_AC *pAC = ((DEV_NET*)(dev->priv))->pAC; /* pointer to adapter context */ ++ int WorkToDo = min(*budget, dev->quota); ++ int WorkDone = 0; ++ unsigned long Flags; ++ ++ ++ if (pAC->dev[0] != pAC->dev[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); ++ ++ ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE, &WorkDone, WorkToDo); ++ CLEAR_AND_START_RX(1); ++ } ++ 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); ++ ++ ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE, &WorkDone, WorkToDo); ++ CLEAR_AND_START_RX(0); ++ ++ *budget -= WorkDone; ++ dev->quota -= WorkDone; ++ ++ if(WorkDone < WorkToDo) { ++ spin_lock_irqsave(&pAC->SlowPathLock, Flags); ++ netif_rx_complete(dev); ++ pAC->GIni.GIValIrqMask |= (NAPI_DRV_IRQS); ++#ifndef USE_TX_COMPLETE ++ pAC->GIni.GIValIrqMask &= ~(TX_COMPL_IRQS); ++#endif ++ /* enable interrupts again */ ++ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); ++ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); ++ } ++ return (WorkDone >= WorkToDo); ++} /* SkGePoll */ ++#endif ++ ++#ifdef SK_POLL_CONTROLLER ++/***************************************************************************** ++ * ++ * SkGeNetPoll - Polling "interrupt" ++ * ++ * Description: ++ * Polling 'interrupt' - used by things like netconsole and netdump ++ * to send skbs without having to re-enable interrupts. ++ * It's not called while the interrupt routine is executing. ++ */ ++static void SkGeNetPoll( ++struct SK_NET_DEVICE *dev) ++{ ++DEV_NET *pNet; ++SK_AC *pAC; ++ ++ pNet = (DEV_NET*) dev->priv; ++ pAC = pNet->pAC; ++ pNet->NetConsoleMode = SK_TRUE; ++ ++ /* Prevent any reconfiguration while handling ++ the 'interrupt' */ ++ SK_OUT32(pAC->IoBase, B0_IMSK, 0); ++ ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ /* Handle the GENESIS Isr */ ++ if (pAC->GIni.GIMacsFound == 2) ++ SkGeIsr(dev->irq, dev, NULL); ++ else ++ SkGeIsrOnePort(dev->irq, dev, NULL); ++ } else { ++ /* Handle the Yukon2 Isr */ ++ SkY2Isr(dev->irq, dev, NULL); ++ } ++ ++} ++#endif ++ + + /***************************************************************************** + * +@@ -1482,7 +2965,7 @@ + * < 0 - on failure: other problems ( -> return failure to upper layers) + */ + static int XmitFrame( +-SK_AC *pAC, /* pointer to adapter context */ ++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 */ + { +@@ -1490,17 +2973,22 @@ + 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); ++ if ((pTxPort->TxdRingPrevFree - pTxPort->TxdRingFree) > 6) { ++ FreeTxDescriptors(pAC, pTxPort); ++ pTxPort->TxdRingPrevFree = pTxPort->TxdRingFree; ++ } + #endif + if (pTxPort->TxdRingFree == 0) { + /* +- ** no enough free descriptors in ring at the moment. ++ ** not enough free descriptors in ring at the moment. + ** Maybe free'ing some old one help? + */ + FreeTxDescriptors(pAC, pTxPort); +@@ -1527,7 +3015,11 @@ + ** This is to resolve faulty padding by the HW with 0xaa bytes. + */ + if (BytesSend < C_LEN_ETHERNET_MINSIZE) { ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) ++ if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) { ++#else + if (skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) { ++#endif + spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); + return 0; + } +@@ -1561,11 +3053,13 @@ + pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); + pTxd->pMBuf = pMessage; + ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) + if (pMessage->ip_summed == CHECKSUM_PARTIAL) { +- u16 hdrlen = skb_transport_offset(pMessage); +- u16 offset = hdrlen + pMessage->csum_offset; +- +- if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) && ++#else ++ if (pMessage->ip_summed == CHECKSUM_HW) { ++#endif ++ 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; +@@ -1573,9 +3067,14 @@ + pTxd->TBControl = BMU_UDP_CHECK; + } + +- pTxd->TcpSumOfs = 0; +- pTxd->TcpSumSt = hdrlen; +- pTxd->TcpSumWr = offset; ++ 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 | +@@ -1583,7 +3082,7 @@ + BMU_IRQ_EOF | + #endif + pMessage->len; +- } else { ++ } else { + pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK | + BMU_SW | BMU_EOF | + #ifdef USE_TX_COMPLETE +@@ -1638,10 +3137,11 @@ + TXD *pTxdLst; + int CurrFrag; + int BytesSend; ++ int IpHeaderLength; ++ int Protocol; + skb_frag_t *sk_frag; + SK_U64 PhysAddr; + unsigned long Flags; +- SK_U32 Control; + + spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); + #ifndef USE_TX_COMPLETE +@@ -1664,6 +3164,7 @@ + pTxdFst = pTxd; + pTxdLst = pTxd; + BytesSend = 0; ++ Protocol = 0; + + /* + ** Map the first fragment (header) into the DMA-space +@@ -1680,32 +3181,37 @@ + /* + ** Does the HW need to evaluate checksum for TCP or UDP packets? + */ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) + if (pMessage->ip_summed == CHECKSUM_PARTIAL) { +- u16 hdrlen = skb_transport_offset(pMessage); +- u16 offset = hdrlen + pMessage->csum_offset; +- +- Control = BMU_STFWD; +- ++#else ++ if (pMessage->ip_summed == CHECKSUM_HW) { ++#endif ++ 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) + */ +- if ((ipip_hdr(pMessage)->protocol == IPPROTO_UDP) && ++ 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)) { +- Control |= BMU_TCP_CHECK; ++ pTxd->TBControl |= BMU_TCP_CHECK; + } else { +- Control |= BMU_UDP_CHECK; ++ pTxd->TBControl |= BMU_UDP_CHECK; + } + +- pTxd->TcpSumOfs = 0; +- pTxd->TcpSumSt = hdrlen; +- pTxd->TcpSumWr = offset; +- } else +- Control = BMU_CHECK | BMU_SW; +- +- pTxd->TBControl = BMU_STF | Control | skb_headlen(pMessage); ++ 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--; +@@ -1729,18 +3235,44 @@ + pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); + pTxd->pMBuf = pMessage; + +- pTxd->TBControl = Control | BMU_OWN | sk_frag->size; ++ /* ++ ** Does the HW need to evaluate checksum for TCP or UDP packets? ++ */ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) ++ if (pMessage->ip_summed == CHECKSUM_PARTIAL) { ++#else ++ if (pMessage->ip_summed == CHECKSUM_HW) { ++#endif ++ 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; ++ pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF | sk_frag->size; + #else +- pTxd->TBControl |= BMU_EOF; ++ 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; +@@ -1894,7 +3426,7 @@ + SK_U16 Length; /* data fragment length */ + SK_U64 PhysAddr; /* physical address of a rx buffer */ + +- pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC); ++ pMsgBlock = alloc_skb(pRxPort->RxBufSize, GFP_ATOMIC); + if (pMsgBlock == NULL) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_ENTRY, +@@ -1908,12 +3440,12 @@ + pRxd = pRxPort->pRxdRingTail; + pRxPort->pRxdRingTail = pRxd->pNextRxd; + pRxPort->RxdRingFree--; +- Length = pAC->RxBufSize; ++ Length = pRxPort->RxBufSize; + PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, + virt_to_page(pMsgBlock->data), + ((unsigned long) pMsgBlock->data & + ~PAGE_MASK), +- pAC->RxBufSize - 2, ++ pRxPort->RxBufSize - 2, + PCI_DMA_FROMDEVICE); + + pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); +@@ -1953,7 +3485,7 @@ + pRxd = pRxPort->pRxdRingTail; + pRxPort->pRxdRingTail = pRxd->pNextRxd; + pRxPort->RxdRingFree--; +- Length = pAC->RxBufSize; ++ Length = pRxPort->RxBufSize; + + pRxd->VDataLow = PhysLow; + pRxd->VDataHigh = PhysHigh; +@@ -1978,28 +3510,40 @@ + * 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 */ +-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; +-SK_U64 PhysAddr; ++#ifdef CONFIG_SK98LIN_NAPI ++SK_AC *pAC, /* pointer to adapter context */ ++RX_PORT *pRxPort, /* pointer to receive port struct */ ++SK_BOOL SlowPathLock, /* indicates if SlowPathLock is needed */ ++int *WorkDone, ++int WorkToDo) ++#else ++SK_AC *pAC, /* pointer to adapter context */ ++RX_PORT *pRxPort, /* pointer to receive port struct */ ++SK_BOOL SlowPathLock) /* indicates if SlowPathLock is needed */ ++#endif ++{ ++ RXD *pRxd; /* pointer to receive descriptors */ ++ struct sk_buff *pMsg; /* pointer to message holding frame */ ++ struct sk_buff *pNewMsg; /* pointer to new message for frame copy */ ++ SK_MBUF *pRlmtMbuf; /* ptr to buffer for giving frame to RLMT */ ++ SK_EVPARA EvPara; /* an event parameter union */ ++ SK_U32 Control; /* control field of descriptor */ ++ unsigned long Flags; /* for spin lock handling */ ++ int PortIndex = pRxPort->PortIndex; ++ int FrameLength; /* total length of received frame */ ++ int IpFrameLength; /* IP length of the received frame */ ++ unsigned int Offset; ++ unsigned int NumBytes; ++ unsigned int RlmtNotifier; ++ SK_BOOL IsBc; /* we received a broadcast packet */ ++ SK_BOOL IsMc; /* we received a multicast packet */ ++ SK_BOOL IsBadFrame; /* the frame received is bad! */ ++ 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 */ +@@ -2021,6 +3565,13 @@ + + Control = pRxd->RBControl; + ++#ifdef CONFIG_SK98LIN_NAPI ++ if (*WorkDone >= WorkToDo) { ++ break; ++ } ++ (*WorkDone)++; ++#endif ++ + /* check if this descriptor is ready */ + if ((Control & BMU_OWN) != 0) { + /* this descriptor is not yet ready */ +@@ -2029,11 +3580,10 @@ + FillRxRing(pAC, pRxPort); + return; + } +- pAC->DynIrqModInfo.NbrProcessedDescr++; + + /* get length of frame and check it */ + FrameLength = Control & BMU_BBC; +- if (FrameLength > pAC->RxBufSize) { ++ if (FrameLength > pRxPort->RxBufSize) { + goto rx_failed; + } + +@@ -2048,8 +3598,8 @@ + FrameStat = pRxd->FrameStat; + + /* check for frame length mismatch */ +-#define XMR_FS_LEN_SHIFT 18 +-#define GMR_FS_LEN_SHIFT 16 ++#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, +@@ -2059,8 +3609,7 @@ + (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT))); + goto rx_failed; + } +- } +- else { ++ } else { + if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS, +@@ -2093,9 +3642,6 @@ + /* 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, +@@ -2103,6 +3649,20 @@ + "Control: %x\nRxStat: %x\n", + Control, FrameStat)); + ++ PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; ++ PhysAddr |= (SK_U64) pRxd->VDataLow; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ++ pci_dma_sync_single(pAC->PciDev, ++ (dma_addr_t) PhysAddr, ++ FrameLength, ++ PCI_DMA_FROMDEVICE); ++#else ++ pci_dma_sync_single_for_cpu(pAC->PciDev, ++ (dma_addr_t) PhysAddr, ++ FrameLength, ++ PCI_DMA_FROMDEVICE); ++#endif + ReQueueRxBuffer(pAC, pRxPort, pMsg, + pRxd->VDataHigh, pRxd->VDataLow); + +@@ -2122,95 +3682,112 @@ + 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); +- skb_copy_to_linear_data(pNewMsg, pMsg, FrameLength); +- ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ++ pci_dma_sync_single(pAC->PciDev, ++ (dma_addr_t) PhysAddr, ++ FrameLength, ++ PCI_DMA_FROMDEVICE); ++#else + pci_dma_sync_single_for_device(pAC->PciDev, +- (dma_addr_t) PhysAddr, +- FrameLength, +- PCI_DMA_FROMDEVICE); ++ (dma_addr_t) PhysAddr, ++ FrameLength, ++ PCI_DMA_FROMDEVICE); ++#endif ++ ++ eth_copy_and_sum(pNewMsg, pMsg->data, ++ FrameLength, 0); + ReQueueRxBuffer(pAC, pRxPort, pMsg, + pRxd->VDataHigh, pRxd->VDataLow); + + pMsg = pNewMsg; + +- } +- else { ++ } 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, ++ pRxPort->RxBufSize - 2, + PCI_DMA_FROMDEVICE); ++ skb_put(pMsg, FrameLength); /* set message len */ ++ pMsg->ip_summed = CHECKSUM_NONE; /* initial default */ + +- /* set length in message */ +- skb_put(pMsg, FrameLength); +- } /* frame > SK_COPY_TRESHOLD */ +- +-#ifdef USE_SK_RX_CHECKSUM +- pMsg->csum = pRxd->TcpSums & 0xffff; +- pMsg->ip_summed = CHECKSUM_COMPLETE; ++ if (pRxPort->UseRxCsum) { ++ Type = ntohs(*((short*)&pMsg->data[12])); ++ if (Type == 0x800) { ++ IpFrameLength = (int) ntohs((unsigned short) ++ ((unsigned short *) pMsg->data)[8]); ++ if ((FrameLength - IpFrameLength) == 0xe) { ++ Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff); ++ Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff); ++ if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) && ++ (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) || ++ (pAC->ChipsetType)) { ++ Result = SkCsGetReceiveInfo(pAC, &pMsg->data[14], ++ Csum1, Csum2, 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)) { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) ++ pMsg->ip_summed = CHECKSUM_COMPLETE; ++ pMsg->csum = Csum1 & 0xffff; + #else +- pMsg->ip_summed = CHECKSUM_NONE; ++ pMsg->ip_summed = CHECKSUM_UNNECESSARY; + #endif +- ++ } 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 */ ++ } /* pRxPort->UseRxCsum */ ++ } /* 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 ++ RlmtNotifier = SK_RLMT_RX_PROTOCOL; + SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength, +- IsBc, &Offset, &NumBytes); ++ 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); ++ SK_RLMT_LOOKAHEAD(pAC,PortIndex,&pMsg->data[Offset], ++ IsBc,IsMc,&RlmtNotifier); + } +- if (ForRlmt == SK_RLMT_RX_PROTOCOL) { +- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W")); ++ if (RlmtNotifier == 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 */ ++ if ((PortIndex == pAC->ActivePort)||(pAC->RlmtNets == 2)) { + 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->protocol = eth_type_trans(pMsg, +- pAC->dev[pRxPort->PortIndex]); +- netif_rx(pMsg); +- pAC->dev[pRxPort->PortIndex]->last_rx = jiffies; +- } +- else { +- /* drop frame */ ++ SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,FrameLength,PortIndex); ++ pMsg->dev = pAC->dev[PortIndex]; ++ pMsg->protocol = eth_type_trans(pMsg,pAC->dev[PortIndex]); ++ netif_rx(pMsg); /* frame for upper layer */ ++ pAC->dev[PortIndex]->last_rx = jiffies; ++ } else { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, +- SK_DBGCAT_DRV_RX_PROGRESS, +- ("D")); +- DEV_KFREE_SKB(pMsg); ++ SK_DBGCAT_DRV_RX_PROGRESS,("D")); ++ DEV_KFREE_SKB(pMsg); /* drop frame */ + } +- +- } /* if not for rlmt */ +- else { +- /* packet for rlmt */ ++ } else { /* packet for RLMT stack */ + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, +- SK_DBGCAT_DRV_RX_PROGRESS, ("R")); ++ SK_DBGCAT_DRV_RX_PROGRESS,("R")); + pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC, + pAC->IoBase, FrameLength); + if (pRlmtMbuf != NULL) { +@@ -2238,31 +3815,26 @@ + } + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, +- SK_DBGCAT_DRV_RX_PROGRESS, +- ("Q")); ++ 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->protocol = eth_type_trans(pMsg, +- pAC->dev[pRxPort->PortIndex]); ++ if ((pAC->dev[PortIndex]->flags & (IFF_PROMISC | IFF_ALLMULTI)) || ++ (RlmtNotifier & SK_RLMT_RX_PROTOCOL)) { ++ pMsg->dev = pAC->dev[PortIndex]; ++ pMsg->protocol = eth_type_trans(pMsg,pAC->dev[PortIndex]); ++#ifdef CONFIG_SK98LIN_NAPI ++ netif_receive_skb(pMsg); ++#else + netif_rx(pMsg); +- pAC->dev[pRxPort->PortIndex]->last_rx = jiffies; +- } +- else { ++#endif ++ pAC->dev[PortIndex]->last_rx = jiffies; ++ } else { + DEV_KFREE_SKB(pMsg); + } +- +- } /* if packet for rlmt */ ++ } /* if packet for RLMT stack */ + } /* 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: +@@ -2276,7 +3848,7 @@ + PhysAddr |= (SK_U64) pRxd->VDataLow; + pci_unmap_page(pAC->PciDev, + PhysAddr, +- pAC->RxBufSize - 2, ++ pRxPort->RxBufSize - 2, + PCI_DMA_FROMDEVICE); + DEV_KFREE_SKB_IRQ(pRxd->pMBuf); + pRxd->pMBuf = NULL; +@@ -2286,49 +3858,6 @@ + + } /* 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 +@@ -2359,7 +3888,7 @@ + PhysAddr |= (SK_U64) pRxd->VDataLow; + pci_unmap_page(pAC->PciDev, + PhysAddr, +- pAC->RxBufSize - 2, ++ pRxPort->RxBufSize - 2, + PCI_DMA_FROMDEVICE); + DEV_KFREE_SKB(pRxd->pMBuf); + pRxd->pMBuf = NULL; +@@ -2417,31 +3946,32 @@ + static int SkGeSetMacAddr(struct SK_NET_DEVICE *dev, void *p) + { + +-DEV_NET *pNet = netdev_priv(dev); ++DEV_NET *pNet = (DEV_NET*) dev->priv; + SK_AC *pAC = pNet->pAC; ++int Ret; + + 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, ++ Ret = SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr, + (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS); + else +- SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort, ++ Ret = SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort, + (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS); +- +- + + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); ++ ++ if (Ret != SK_ADDR_OVERRIDE_SUCCESS) ++ return -EBUSY; ++ + return 0; + } /* SkGeSetMacAddr */ + +@@ -2474,7 +4004,7 @@ + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, + ("SkGeSetRxMode starts now... ")); + +- pNet = netdev_priv(dev); ++ pNet = (DEV_NET*) dev->priv; + pAC = pNet->pAC; + if (pAC->RlmtNets == 1) + PortIdx = pAC->ActivePort; +@@ -2523,6 +4053,45 @@ + + /***************************************************************************** + * ++ * SkSetMtuBufferSize - set the MTU buffer to another value ++ * ++ * Description: ++ * This function sets the new buffers and is called whenever the MTU ++ * size is changed ++ * ++ * Returns: ++ * N/A ++ */ ++ ++static void SkSetMtuBufferSize( ++SK_AC *pAC, /* pointer to adapter context */ ++int PortNr, /* Port number */ ++int Mtu) /* pointer to tx prt struct */ ++{ ++ pAC->RxPort[PortNr].RxBufSize = Mtu + 32; ++ ++ /* RxBufSize must be a multiple of 8 */ ++ while (pAC->RxPort[PortNr].RxBufSize % 8) { ++ pAC->RxPort[PortNr].RxBufSize = ++ pAC->RxPort[PortNr].RxBufSize + 1; ++ } ++ ++ if (Mtu > 1500) { ++ pAC->GIni.GP[PortNr].PPortUsage = SK_JUMBO_LINK; ++ } else { ++ if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { ++ pAC->GIni.GP[PortNr].PPortUsage = SK_MUL_LINK; ++ } else { ++ pAC->GIni.GP[PortNr].PPortUsage = SK_RED_LINK; ++ } ++ } ++ ++ return; ++} ++ ++ ++/***************************************************************************** ++ * + * SkGeChangeMtu - set the MTU to another value + * + * Description: +@@ -2536,28 +4105,32 @@ + */ + static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu) + { +-DEV_NET *pNet; +-struct net_device *pOtherDev; +-SK_AC *pAC; +-unsigned long Flags; +-int i; +-SK_EVPARA EvPara; ++DEV_NET *pNet; ++SK_AC *pAC; ++unsigned long Flags; ++#ifdef CONFIG_SK98LIN_NAPI ++int WorkToDo = 1; // min(*budget, dev->quota); ++int WorkDone = 0; ++#endif + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, + ("SkGeChangeMtu starts now...\n")); + +- pNet = netdev_priv(dev); ++ pNet = (DEV_NET*) dev->priv; + pAC = pNet->pAC; + ++ /* MTU size outside the spec */ + if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) { + return -EINVAL; + } + +- if(pAC->BoardLevel != SK_INIT_RUN) { ++ /* MTU > 1500 on yukon FE not allowed */ ++ if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) ++ && (NewMtu > 1500)){ + return -EINVAL; + } + +-#ifdef SK_DIAG_SUPPORT ++ /* Diag access active */ + if (pAC->DiagModeActive == DIAG_ACTIVE) { + if (pAC->DiagFlowCtrl == SK_FALSE) { + return -1; /* still in use, deny any actions of MTU */ +@@ -2565,201 +4138,84 @@ + pAC->DiagFlowCtrl = SK_FALSE; + } + } +-#endif +- +- pOtherDev = pAC->dev[1 - pNet->NetNr]; + +- if ( netif_running(pOtherDev) && (pOtherDev->mtu > 1500) +- && (NewMtu <= 1500)) +- return 0; +- +- pAC->RxBufSize = NewMtu + 32; ++ /* TSO on Yukon Ultra and MTU > 1500 not supported */ ++#ifdef NETIF_F_TSO ++ if (CHIP_ID_YUKON_2(pAC)) { ++ if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) && (NewMtu > SK_JUMBO_MTU)) { ++ dev->features &= NETIF_F_TSO; ++ } else { ++ dev->features |= NETIF_F_TSO; ++ } ++ } ++#endif + dev->mtu = NewMtu; ++ SkSetMtuBufferSize(pAC, pNet->PortNr, NewMtu); + +- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, +- ("New MTU: %d\n", NewMtu)); ++ if(!netif_running(dev)) { ++ /* Preset MTU size if device not ready/running */ ++ return 0; ++ } + +- /* +- ** Prevent any reconfiguration while changing the MTU +- ** by disabling any interrupts +- */ ++ /* 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; iGIni.GIMacsFound; i++) { +- spin_lock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock); +- netif_stop_queue(pAC->dev[i]); ++ /* Notify RLMT that the port has to be stopped */ ++ netif_stop_queue(dev); ++ SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, ++ pNet->PortNr, -1, SK_TRUE); ++ spin_lock(&pAC->TxPort[pNet->PortNr][TX_PRIO_LOW].TxDesRingLock); + +- } + +- /* +- ** 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; iGIni.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); +- } +- } +- } ++ /* Change RxFillLimit to 1 */ ++ if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { ++ pAC->RxPort[pNet->PortNr].RxFillLimit = 1; + } else { +- /* +- ** Use the normal amount of rx buffers +- */ +- for (i=0; iGIni.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); +- } +- } +- } ++ pAC->RxPort[1 - pNet->PortNr].RxFillLimit = 1; ++ pAC->RxPort[pNet->PortNr].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; ++ /* clear and reinit the rx rings here, because of new MTU size */ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ SkY2PortStop(pAC, pAC->IoBase, pNet->PortNr, SK_STOP_ALL, SK_SOFT_RST); ++ SkY2AllocateRxBuffers(pAC, pAC->IoBase, pNet->PortNr); ++ SkY2PortStart(pAC, pAC->IoBase, pNet->PortNr); + } else { +- if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { +- pAC->GIni.GIPortUsage = SK_MUL_LINK; +- } else { +- pAC->GIni.GIPortUsage = SK_RED_LINK; +- } +- } ++// SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr, SK_STOP_ALL, SK_SOFT_RST); ++#ifdef CONFIG_SK98LIN_NAPI ++ WorkToDo = 1; ++ ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE, &WorkDone, WorkToDo); ++#else ++ ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE); ++#endif ++ ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]); ++ FillRxRing(pAC, &pAC->RxPort[pNet->PortNr]); + +- 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); ++ /* Enable transmit descriptor polling */ ++ SkGePollTxD(pAC, pAC->IoBase, pNet->PortNr, SK_TRUE); ++ FillRxRing(pAC, &pAC->RxPort[pNet->PortNr]); ++ } + +- /* +- ** clear and reinit the rx rings here +- */ +- for (i=0; iGIni.GIMacsFound; i++) { +- ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); +- ClearRxRing(pAC, &pAC->RxPort[i]); +- FillRxRing(pAC, &pAC->RxPort[i]); ++ netif_start_queue(pAC->dev[pNet->PortNr]); + +- /* +- ** Enable transmit descriptor polling +- */ +- SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); +- FillRxRing(pAC, &pAC->RxPort[i]); +- }; ++ spin_unlock(&pAC->TxPort[pNet->PortNr][TX_PRIO_LOW].TxDesRingLock); + +- 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); +- } ++ /* Notify RLMT about the changing and restarting one (or more) ports */ ++ SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, ++ pNet->PortNr, -1, SK_TRUE); + +- /* +- ** Enable Interrupts again +- */ ++ /* 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 (netif_running(pOtherDev)) { +- DEV_NET *pOtherNet = netdev_priv(pOtherDev); +- 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; ++ return 0; + +-} /* SkGeChangeMtu */ ++} + + + /***************************************************************************** +@@ -2775,125 +4231,67 @@ + */ + 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; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ unsigned long LateCollisions, ExcessiveCollisions, RxTooLong; ++ unsigned long Flags; /* for spin lock */ ++ SK_U32 MaxNumOidEntries, Oid, Len; ++ char Buf[8]; ++ struct { ++ SK_U32 Oid; ++ unsigned long *pVar; ++ } Vars[] = { ++ { OID_SKGE_STAT_TX_LATE_COL, &LateCollisions }, ++ { OID_SKGE_STAT_TX_EXCESS_COL, &ExcessiveCollisions }, ++ { OID_SKGE_STAT_RX_TOO_LONG, &RxTooLong }, ++ { OID_SKGE_STAT_RX, &pAC->stats.rx_packets }, ++ { OID_SKGE_STAT_TX, &pAC->stats.tx_packets }, ++ { OID_SKGE_STAT_RX_OCTETS, &pAC->stats.rx_bytes }, ++ { OID_SKGE_STAT_TX_OCTETS, &pAC->stats.tx_bytes }, ++ { OID_SKGE_RX_NO_BUF_CTS, &pAC->stats.rx_dropped }, ++ { OID_SKGE_TX_NO_BUF_CTS, &pAC->stats.tx_dropped }, ++ { OID_SKGE_STAT_RX_MULTICAST, &pAC->stats.multicast }, ++ { OID_SKGE_STAT_RX_RUNT, &pAC->stats.rx_length_errors }, ++ { OID_SKGE_STAT_RX_FCS, &pAC->stats.rx_crc_errors }, ++ { OID_SKGE_STAT_RX_FRAMING, &pAC->stats.rx_frame_errors }, ++ { OID_SKGE_STAT_RX_OVERFLOW, &pAC->stats.rx_over_errors }, ++ { OID_SKGE_STAT_RX_MISSED, &pAC->stats.rx_missed_errors }, ++ { OID_SKGE_STAT_TX_CARRIER, &pAC->stats.tx_carrier_errors }, ++ { OID_SKGE_STAT_TX_UNDERRUN, &pAC->stats.tx_fifo_errors }, ++ }; ++ ++ if ((pAC->DiagModeActive == DIAG_NOTACTIVE) && ++ (pAC->BoardLevel == SK_INIT_RUN)) { ++ memset(&pAC->stats, 0x00, sizeof(pAC->stats)); /* clean first */ ++ spin_lock_irqsave(&pAC->SlowPathLock, Flags); + +-#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 ++ MaxNumOidEntries = sizeof(Vars) / sizeof(Vars[0]); ++ for (Oid = 0; Oid < MaxNumOidEntries; Oid++) { ++ if (SkPnmiGetVar(pAC,pAC->IoBase, Vars[Oid].Oid, ++ &Buf, &Len, 1, pNet->NetNr) != SK_PNMI_ERR_OK) { ++ memset(Buf, 0x00, sizeof(Buf)); ++ } ++ *Vars[Oid].pVar = (unsigned long) (*((SK_U64 *) Buf)); ++ } ++ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + +- pPnmiStat = &pPnmiStruct->Stat[0]; +- pPnmiConf = &pPnmiStruct->Conf[0]; ++ pAC->stats.collisions = LateCollisions + ExcessiveCollisions; ++ pAC->stats.tx_errors = pAC->stats.tx_carrier_errors + ++ pAC->stats.tx_fifo_errors; ++ pAC->stats.rx_errors = pAC->stats.rx_length_errors + ++ pAC->stats.rx_crc_errors + ++ pAC->stats.rx_frame_errors + ++ pAC->stats.rx_over_errors + ++ pAC->stats.rx_missed_errors; + +- 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 (dev->mtu <= 1500) { +- pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF; +- } else { +- pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts - +- pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF); ++ if (dev->mtu > 1500) { ++ pAC->stats.rx_errors = pAC->stats.rx_errors - RxTooLong; ++ } + } + +- +- 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 */ + +-/* +- * Basic MII register access +- */ +-static int SkGeMiiIoctl(struct net_device *dev, +- struct mii_ioctl_data *data, int cmd) +-{ +- DEV_NET *pNet = netdev_priv(dev); +- SK_AC *pAC = pNet->pAC; +- SK_IOC IoC = pAC->IoBase; +- int Port = pNet->PortNr; +- SK_GEPORT *pPrt = &pAC->GIni.GP[Port]; +- unsigned long Flags; +- int err = 0; +- int reg = data->reg_num & 0x1f; +- SK_U16 val = data->val_in; +- +- if (!netif_running(dev)) +- return -ENODEV; /* Phy still in reset */ +- +- spin_lock_irqsave(&pAC->SlowPathLock, Flags); +- switch(cmd) { +- case SIOCGMIIPHY: +- data->phy_id = pPrt->PhyAddr; +- +- /* fallthru */ +- case SIOCGMIIREG: +- if (pAC->GIni.GIGenesis) +- SkXmPhyRead(pAC, IoC, Port, reg, &val); +- else +- SkGmPhyRead(pAC, IoC, Port, reg, &val); +- +- data->val_out = val; +- break; +- +- case SIOCSMIIREG: +- if (!capable(CAP_NET_ADMIN)) +- err = -EPERM; +- +- else if (pAC->GIni.GIGenesis) +- SkXmPhyWrite(pAC, IoC, Port, reg, val); +- else +- SkGmPhyWrite(pAC, IoC, Port, reg, val); +- break; +- default: +- err = -EOPNOTSUPP; +- } +- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); +- return err; +-} +- +- + /***************************************************************************** + * + * SkGeIoctl - IO-control function +@@ -2901,41 +4299,43 @@ + * 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 (useful for SysKonnect-internal tools). ++ * 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); ++static int SkGeIoctl( ++struct SK_NET_DEVICE *dev, /* the device the IOCTL is to be performed on */ ++struct ifreq *rq, /* additional request structure containing data */ ++int cmd) /* requested IOCTL command number */ ++{ ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ struct pci_dev *pdev = NULL; ++ void *pMemBuf; ++ SK_GE_IOCTL Ioctl; ++ unsigned long Flags; /* for spin lock */ ++ unsigned int Err = 0; ++ unsigned int Length = 0; ++ int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32); ++ int Size = 0; ++ int Ret = 0; + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, + ("SkGeIoctl starts now...\n")); + +- pNet = netdev_priv(dev); +- pAC = pNet->pAC; +- +- if (cmd == SIOCGMIIPHY || cmd == SIOCSMIIREG || cmd == SIOCGMIIREG) +- return SkGeMiiIoctl(dev, if_mii(rq), cmd); +- + if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) { + return -EFAULT; + } + + switch(cmd) { +- case SK_IOCTL_SETMIB: +- case SK_IOCTL_PRESETMIB: ++#ifndef ENABLE_FUTURE_ETH ++ case SIOCETHTOOL: ++ return SkEthIoctl(dev, rq ); ++#endif ++ case SK_IOCTL_SETMIB: /* FALL THRU */ ++ case SK_IOCTL_PRESETMIB: /* FALL THRU (if capable!) */ + if (!capable(CAP_NET_ADMIN)) return -EPERM; + case SK_IOCTL_GETMIB: + if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData, +@@ -2962,6 +4362,7 @@ + if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) { + return -ENOMEM; + } ++ spin_lock_irqsave(&pAC->SlowPathLock, Flags); + if(copy_from_user(pMemBuf, Ioctl.pData, Length)) { + Err = -EFAULT; + goto fault_gen; +@@ -2980,10 +4381,10 @@ + goto fault_gen; + } + fault_gen: ++ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + kfree(pMemBuf); /* cleanup everything */ + break; +-#ifdef SK_DIAG_SUPPORT +- case SK_IOCTL_DIAG: ++ case SK_IOCTL_DIAG: + if (!capable(CAP_NET_ADMIN)) return -EPERM; + if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) { + Length = Ioctl.Len; +@@ -3020,7 +4421,6 @@ + fault_diag: + kfree(pMemBuf); /* cleanup everything */ + break; +-#endif + default: + Err = -EOPNOTSUPP; + } +@@ -3052,12 +4452,12 @@ + unsigned int Size, /* length of ioctl data */ + int mode) /* flag for set/preset */ + { +-unsigned long Flags; /* for spin lock */ +-SK_AC *pAC; ++ SK_AC *pAC = pNet->pAC; ++ unsigned long Flags; /* for spin lock */ + + 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) { +@@ -3100,17 +4500,18 @@ + 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; ++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 */ ++int IrqModMaskOffset = 6; /* all ints moderated=default */ ++ ++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: +@@ -3128,6 +4529,15 @@ + {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF }, + {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} }; + ++SK_U32 IrqModMask[7][2] = ++ { { IRQ_MASK_RX_ONLY , Y2_DRIVER_IRQS }, ++ { IRQ_MASK_TX_ONLY , Y2_DRIVER_IRQS }, ++ { IRQ_MASK_SP_ONLY , Y2_SPECIAL_IRQS }, ++ { IRQ_MASK_SP_RX , Y2_IRQ_MASK }, ++ { IRQ_MASK_TX_RX , Y2_DRIVER_IRQS }, ++ { IRQ_MASK_SP_TX , Y2_IRQ_MASK }, ++ { IRQ_MASK_RX_TX_SP, Y2_IRQ_MASK } }; ++ + #define DC_BOTH 0 + #define DC_FULL 1 + #define DC_HALF 2 +@@ -3160,6 +4570,7 @@ + ** ConType DupCap AutoNeg FlowCtrl Role Speed + ** ------- ------ ------- -------- ---------- ----- + ** Auto Both On SymOrRem Auto Auto ++ ** 1000FD Full Off None 1000 + ** 100FD Full Off None 100 + ** 100HD Half Off None 100 + ** 10FD Full Off None 10 +@@ -3167,66 +4578,86 @@ + ** + ** This ConType parameter is used for all ports of the adapter! + */ +- if ( (ConType != NULL) && ++ 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"); +- } ++ /* 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]); ++ ++ ConType[pAC->Index] = "Auto"; ++ } ++ ++ if ((pAC->ChipsetType) && ++ (pAC->GIni.GICopperType != SK_TRUE) && ++ (strcmp(ConType[pAC->Index],"") != 0) && ++ (strcmp(ConType[pAC->Index],"1000FD") != 0)) { ++ /* Set the speed parameter back */ ++ printk("sk98lin: Illegal value \"%s\" " ++ "for ConType." ++ " Using Auto.\n", ++ ConType[pAC->Index]); ++ IsConTypeDefined = SK_FALSE; ++ ConType[pAC->Index] = "Auto"; ++ } + +- if (strcmp(ConType[pAC->Index],"")==0) { ++ if (strcmp(ConType[pAC->Index],"")==0) { + IsConTypeDefined = SK_FALSE; /* No ConType defined */ +- } else if (strcmp(ConType[pAC->Index],"Auto")==0) { ++ } 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) { ++ } else if (strcmp(ConType[pAC->Index],"1000FD")==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_1000MBPS; ++ } ++ } 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) { ++ } 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) { ++ } 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) { ++ } 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 { ++ } else { + printk("sk98lin: Illegal value \"%s\" for ConType\n", + ConType[pAC->Index]); + IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */ + } +- } else { ++ } else { + IsConTypeDefined = SK_FALSE; /* No ConType defined */ + } + +@@ -3245,14 +4676,30 @@ + } 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; ++ if ((pAC->PciDev->vendor == 0x11ab ) && ++ (pAC->PciDev->device == 0x4350)) { ++ LinkSpeed = SK_LSPEED_100MBPS; ++ printk("sk98lin: Illegal value \"%s\" for Speed_A.\n" ++ "Gigabit speed not possible with this chip revision!", ++ Speed_A[pAC->Index]); ++ } else { ++ 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; ++ if ((pAC->PciDev->vendor == 0x11ab ) && ++ (pAC->PciDev->device == 0x4350)) { ++ /* Gigabit speed not supported ++ * Swith to speed 100 ++ */ ++ LinkSpeed = SK_LSPEED_100MBPS; ++ } else { ++ IsLinkSpeedDefined = SK_FALSE; ++ } + } + + /* +@@ -3347,9 +4794,6 @@ + } + + 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; + } + +@@ -3377,7 +4821,7 @@ + FlowCtrl = SK_FLOW_MODE_NONE; + } else { + printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n", +- FlowCtrl_A[pAC->Index]); ++ FlowCtrl_A[pAC->Index]); + IsFlowCtrlDefined = SK_FALSE; + } + } else { +@@ -3469,7 +4913,7 @@ + ** Decide whether to set new config value if somethig valid has + ** been received. + */ +- if (IsLinkSpeedDefined) { ++ if (IsLinkSpeedDefined) { + pAC->GIni.GP[1].PLinkSpeed = LinkSpeed; + } + +@@ -3545,9 +4989,6 @@ + } + + 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; + } + +@@ -3660,11 +5101,15 @@ + } + + pAC->RlmtNets = 1; ++ pAC->RlmtMode = 0; + + if (RlmtMode != NULL && pAC->IndexIndex] != NULL) { + if (strcmp(RlmtMode[pAC->Index], "") == 0) { +- pAC->RlmtMode = 0; ++ if (pAC->GIni.GIMacsFound == 2) { ++ pAC->RlmtMode = SK_RLMT_CHECK_LINK; ++ pAC->RlmtNets = 2; ++ } + } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) { + pAC->RlmtMode = SK_RLMT_CHECK_LINK; + } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) { +@@ -3685,12 +5130,46 @@ + pAC->RlmtMode = 0; + } + } else { +- pAC->RlmtMode = 0; ++ if (pAC->GIni.GIMacsFound == 2) { ++ pAC->RlmtMode = SK_RLMT_CHECK_LINK; ++ pAC->RlmtNets = 2; ++ } + } +- ++ ++#ifdef SK_YUKON2 ++ /* ++ ** use dualnet config per default ++ * ++ pAC->RlmtMode = SK_RLMT_CHECK_LINK; ++ pAC->RlmtNets = 2; ++ */ ++#endif ++ ++ ++ /* ++ ** Check the LowLatance parameters ++ */ ++ pAC->LowLatency = SK_FALSE; ++ if (LowLatency[pAC->Index] != NULL) { ++ if (strcmp(LowLatency[pAC->Index], "On") == 0) { ++ pAC->LowLatency = SK_TRUE; ++ } ++ } ++ ++ /* ++ ** Check the BroadcastPrio parameters ++ */ ++ pAC->Rlmt.Net[0].ChgBcPrio = SK_FALSE; ++ if (BroadcastPrio[pAC->Index] != NULL) { ++ if (strcmp(BroadcastPrio[pAC->Index], "On") == 0) { ++ pAC->Rlmt.Net[0].ChgBcPrio = SK_TRUE; ++ } ++ } ++ + /* + ** Check the interrupt moderation parameters + */ ++ pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; + if (Moderation[pAC->Index] != NULL) { + if (strcmp(Moderation[pAC->Index], "") == 0) { + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; +@@ -3704,70 +5183,49 @@ + 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; ++/* Set interrupt moderation if wished */ ++#ifdef CONFIG_SK98LIN_STATINT ++ pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC; ++#endif + } + + if (ModerationMask[pAC->Index] != NULL) { + if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) { +- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; ++ IrqModMaskOffset = 0; + } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) { +- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY; ++ IrqModMaskOffset = 1; + } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) { +- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY; ++ IrqModMaskOffset = 2; + } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) { +- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; ++ IrqModMaskOffset = 3; + } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) { +- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; ++ IrqModMaskOffset = 3; + } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) { +- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; ++ IrqModMaskOffset = 4; + } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) { +- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; ++ IrqModMaskOffset = 4; + } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) { +- pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; ++ IrqModMaskOffset = 5; + } 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; ++ IrqModMaskOffset = 5; ++ } else { /* some rubbish stated */ ++ // IrqModMaskOffset = 6; ->has been initialized ++ // already at the begin of this function... + } +- } else { /* operator has stated nothing */ +- pAC->DynIrqModInfo.AutoSizing = SK_FALSE; ++ } ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ pAC->DynIrqModInfo.MaskIrqModeration = IrqModMask[IrqModMaskOffset][0]; ++ } else { ++ pAC->DynIrqModInfo.MaskIrqModeration = IrqModMask[IrqModMaskOffset][1]; + } + ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; ++ } else { ++ pAC->DynIrqModInfo.MaxModIntsPerSec = C_Y2_INTS_PER_SEC_DEFAULT; ++ } + if (IntsPerSec[pAC->Index] != 0) { + if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) || + (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) { +@@ -3776,28 +5234,25 @@ + 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; ++ pAC->DynIrqModInfo.MaxModIntsPerSec); + } 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.MaxModIntsPerSec / 5); + + pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit = + pAC->DynIrqModInfo.MaxModIntsPerSec - +- (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); +- +- pAC->DynIrqModInfo.PrevTimeVal = jiffies; /* initial value */ ++ (pAC->DynIrqModInfo.MaxModIntsPerSec / 5); + ++ pAC->DynIrqModInfo.DynIrqModSampleInterval = ++ SK_DRV_MODERATION_TIMER_LENGTH; + + } /* GetConfiguration */ + +@@ -3812,62 +5267,22 @@ + * + * Returns: N/A + */ +-static inline int ProductStr( +- SK_AC *pAC, /* pointer to adapter context */ +- char *DeviceStr, /* result string */ +- int StrLen /* length of the string */ +-) ++static void ProductStr(SK_AC *pAC) + { +-char Keyword[] = VPD_NAME; /* vpd productname identifier */ +-int ReturnCode; /* return code from vpd_read */ +-unsigned long Flags; ++ char Default[] = "Generic Marvell Yukon chipset Ethernet device"; ++ char Key[] = VPD_NAME; /* VPD productname key */ ++ int StrLen = 80; /* stringlen */ ++ unsigned long Flags; + + spin_lock_irqsave(&pAC->SlowPathLock, Flags); +- ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, DeviceStr, &StrLen); ++ if (VpdRead(pAC, pAC->IoBase, Key, pAC->DeviceStr, &StrLen)) { ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR, ++ ("Error reading VPD data: %d\n", ReturnCode)); ++ strcpy(pAC->DeviceStr, Default); ++ } + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); +- +- return ReturnCode; + } /* 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 *********************************************/ + /****************************************************************************/ +@@ -3956,7 +5371,9 @@ + SK_U64 SkOsGetTime(SK_AC *pAC) + { + SK_U64 PrivateJiffies; ++ + SkOsGetTimeCurrent(pAC, &PrivateJiffies); ++ + return PrivateJiffies; + } /* SkOsGetTime */ + +@@ -4029,6 +5446,28 @@ + + /***************************************************************************** + * ++ * 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: +@@ -4089,29 +5528,27 @@ + * + */ + 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; ++SK_AC *pAC, /* pointer to adapter context */ ++SK_IOC IoC, /* IO control 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 */ ++ SK_BOOL DualNet; ++ SK_U32 Reason; ++ unsigned long Flags; ++ unsigned long InitFlags; ++ int FromPort; /* the port from which we switch away */ ++ int ToPort; /* the port we switch to */ ++ int Stat; ++ DEV_NET *pNet = NULL; ++#ifdef CONFIG_SK98LIN_NAPI ++ int WorkToDo = 1; /* min(*budget, dev->quota); */ ++ int WorkDone = 0; ++#endif + + 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, +@@ -4121,210 +5558,303 @@ + } else { + printk("%s: Port B failed.\n", pAC->dev[1]->name); + } +- /* cgoos */ + break; +- case SK_DRV_PORT_RESET: /* SK_U32 PortIdx */ +- /* action list 4 */ ++ case SK_DRV_PORT_RESET: + 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); ++ SkLocalEventQueue64(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET, ++ FromPort, SK_FALSE); + spin_lock_irqsave( + &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, + Flags); +- +- SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST); +- netif_carrier_off(pAC->dev[Param.Para32[0]]); ++ if (CHIP_ID_YUKON_2(pAC)) { ++ SkY2PortStop(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST); ++ } else { ++ 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]); ++ if (!CHIP_ID_YUKON_2(pAC)) { ++#ifdef CONFIG_SK98LIN_NAPI ++ WorkToDo = 1; ++ ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE, &WorkDone, WorkToDo); ++#else ++ ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); ++#endif ++ 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); ++ ++#ifdef USE_TIST_FOR_RESET ++ if (!HW_IS_EXT_LE_FORMAT(pAC) && pAC->GIni.GIYukon2) { ++#ifdef Y2_RECOVERY ++ /* for Yukon II we want to have tist enabled all the time */ ++ if (!SK_ADAPTER_WAITING_FOR_TIST(pAC)) { ++ Y2_ENABLE_TIST(pAC->IoBase); ++ } ++#else ++ /* make sure that we do not accept any status LEs from now on */ ++ if (SK_ADAPTER_WAITING_FOR_TIST(pAC)) { ++#endif ++ /* port already waiting for tist */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, ++ ("Port %c is now waiting for specific Tist\n", ++ 'A' + FromPort)); ++ SK_SET_WAIT_BIT_FOR_PORT( ++ pAC, ++ SK_PSTATE_WAITING_FOR_SPECIFIC_TIST, ++ FromPort); ++ /* get current timestamp */ ++ Y2_GET_TIST_LOW_VAL(pAC->IoBase, &pAC->MinTistLo); ++ pAC->MinTistHi = pAC->GIni.GITimeStampCnt; ++#ifndef Y2_RECOVERY + } else { +- printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name); ++ /* nobody is waiting yet */ ++ SK_SET_WAIT_BIT_FOR_PORT( ++ pAC, ++ SK_PSTATE_WAITING_FOR_ANY_TIST, ++ FromPort); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, ++ ("Port %c is now waiting for any Tist (0x%X)\n", ++ 'A' + FromPort, pAC->AdapterResetState)); ++ /* start tist */ ++ Y2_ENABLE_TIST(pAC-IoBase); ++ } ++#endif ++ } ++#endif ++ ++#ifdef Y2_LE_CHECK ++ /* mark entries invalid */ ++ pAC->LastPort = 3; ++ pAC->LastOpc = 0xFF; ++#endif ++ if (CHIP_ID_YUKON_2(pAC)) { ++ SkY2PortStart(pAC, IoC, FromPort); ++ } else { ++ /* 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); ++ CLEAR_AND_START_RX(FromPort); + } +- 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 */ +- { struct net_device *dev = pAC->dev[Param.Para32[0]]; +- /* action list 5 */ ++ case SK_DRV_NET_UP: ++ spin_lock_irqsave(&pAC->InitLock, InitFlags); + 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); +- ++ ("NET UP EVENT, Port: %d ", FromPort)); ++ SkAddrMcUpdate(pAC,IoC, FromPort); /* Mac update */ + if (DoPrintInterfaceChange) { +- printk("%s: network connection up using" +- " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]); ++ printk("%s: network connection up using port %c\n", ++ pAC->dev[FromPort]->name, 'A'+FromPort); + +- /* 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"); +- } ++ /* 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"); ++ } + +- 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"); ++ if ((Stat == SK_LMODE_STAT_AUTOHALF) || ++ (Stat == SK_LMODE_STAT_HALF)) { ++ printk(" duplex mode: half\n"); ++ } else { ++ printk(" duplex mode: full\n"); + } +- else if (Stat == SK_MS_STAT_SLAVE ) { +- printk(" role: slave\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"); + } +- else { +- printk(" role: ???\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", ++ /* Display 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", ++ } 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"); ++ } else { ++ printk(" irq moderation: disabled\n"); ++ } ++ ++#ifdef NETIF_F_TSO ++ if (CHIP_ID_YUKON_2(pAC)) { ++ if (pAC->dev[FromPort]->features & NETIF_F_TSO) { ++ printk(" tcp offload: enabled\n"); ++ } else { ++ printk(" tcp offload: disabled\n"); ++ } ++ } ++#endif + ++ if (pAC->dev[FromPort]->features & NETIF_F_SG) { ++ printk(" scatter-gather: enabled\n"); ++ } else { ++ printk(" scatter-gather: disabled\n"); ++ } ++ ++ if (pAC->dev[FromPort]->features & NETIF_F_IP_CSUM) { ++ printk(" tx-checksum: enabled\n"); ++ } else { ++ printk(" tx-checksum: disabled\n"); ++ } + +- printk(" scatter-gather: %s\n", +- (dev->features & NETIF_F_SG) ? "enabled" : "disabled"); +- printk(" tx-checksum: %s\n", +- (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled"); +- printk(" rx-checksum: %s\n", +- pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled"); ++ if (pAC->RxPort[FromPort].UseRxCsum) { ++ printk(" rx-checksum: enabled\n"); ++ } else { ++ printk(" rx-checksum: disabled\n"); ++ } ++#ifdef CONFIG_SK98LIN_NAPI ++ printk(" rx-polling: enabled\n"); ++#endif ++ if (pAC->LowLatency) { ++ printk(" low latency: enabled\n"); ++ } + ++ if (pAC->Rlmt.Net[0].ChgBcPrio) { ++ printk(" broadcast prio: enabled\n"); ++ } ++#ifdef SK_ASF ++ printk(" IPMI: enabled\n"); ++#endif + } else { +- DoPrintInterfaceChange = SK_TRUE; +- } ++ 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); ++ if ((FromPort != pAC->ActivePort)&&(pAC->RlmtNets == 1)) { ++ SkLocalEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN, ++ pAC->ActivePort, FromPort, SK_FALSE); + } + + /* Inform the world that link protocol is up. */ +- netif_carrier_on(dev); ++ netif_wake_queue(pAC->dev[FromPort]); ++ netif_carrier_on(pAC->dev[FromPort]); ++ pAC->dev[FromPort]->flags |= IFF_RUNNING; ++ spin_unlock_irqrestore(&pAC->InitLock, InitFlags); + break; +- } +- case SK_DRV_NET_DOWN: /* SK_U32 Reason */ +- /* action list 7 */ ++ case SK_DRV_NET_DOWN: ++ Reason = Param.Para32[0]; ++ FromPort = Param.Para32[1]; + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, + ("NET DOWN EVENT ")); ++ ++ /* Stop queue and carrier */ ++ netif_stop_queue(pAC->dev[FromPort]); ++ netif_carrier_off(pAC->dev[FromPort]); ++ ++ /* Print link change */ + if (DoPrintInterfaceChange) { +- printk("%s: network connection down\n", +- pAC->dev[Param.Para32[1]]->name); ++ if (pAC->dev[FromPort]->flags & IFF_RUNNING) { ++ printk("%s: network connection down\n", ++ pAC->dev[FromPort]->name); ++ } + } else { + DoPrintInterfaceChange = SK_TRUE; + } +- netif_carrier_off(pAC->dev[Param.Para32[1]]); ++ pAC->dev[FromPort]->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 */ ++ case SK_DRV_SWITCH_HARD: /* FALL THRU */ ++ case SK_DRV_SWITCH_SOFT: /* FALL THRU */ ++ case SK_DRV_SWITCH_INTERN: + FromPort = Param.Para32[0]; +- ToPort = Param.Para32[1]; ++ ToPort = Param.Para32[1]; ++ printk("%s: switching from port %c to port %c\n", ++ pAC->dev[0]->name, 'A'+FromPort, 'A'+ToPort); + 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); ++ SkLocalEventQueue64(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET, ++ FromPort, SK_FALSE); ++ SkLocalEventQueue64(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET, ++ ToPort, SK_FALSE); + 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); ++ if (CHIP_ID_YUKON_2(pAC)) { ++ SkY2PortStop(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST); ++ SkY2PortStop(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST); ++ } ++ else { ++ 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]); ++ if (!CHIP_ID_YUKON_2(pAC)) { ++#ifdef CONFIG_SK98LIN_NAPI ++ WorkToDo = 1; ++ ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE, &WorkDone, WorkToDo); ++ ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE, &WorkDone, WorkToDo); ++#else ++ ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */ ++ ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */ ++#endif ++ 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) { +@@ -4342,74 +5872,316 @@ + 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 (!CHIP_ID_YUKON_2(pAC)) { ++ /* 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); ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ if (Event == SK_DRV_SWITCH_SOFT) { ++ SkMacRxTxEnable(pAC, IoC, FromPort); ++ } ++ SkMacRxTxEnable(pAC, IoC, ToPort); + } +- 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); ++ ++#ifdef USE_TIST_FOR_RESET ++ if (!HW_IS_EXT_LE_FORMAT(pAC) && pAC->GIni.GIYukon2) { ++ /* make sure that we do not accept any status LEs from now on */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, ++ ("both Ports now waiting for specific Tist\n")); ++ SK_SET_WAIT_BIT_FOR_PORT( ++ pAC, ++ SK_PSTATE_WAITING_FOR_ANY_TIST, ++ 0); ++ SK_SET_WAIT_BIT_FOR_PORT( ++ pAC, ++ SK_PSTATE_WAITING_FOR_ANY_TIST, ++ 1); ++ ++ /* start tist */ ++ Y2_ENABLE_TIST(pAC->IoBase); ++ } ++#endif ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ PortReInitBmu(pAC, FromPort); ++ PortReInitBmu(pAC, ToPort); ++ SkGePollTxD(pAC, IoC, FromPort, SK_TRUE); ++ SkGePollTxD(pAC, IoC, ToPort, SK_TRUE); ++ CLEAR_AND_START_RX(FromPort); ++ CLEAR_AND_START_RX(ToPort); ++ } else { ++ SkY2PortStart(pAC, IoC, FromPort); ++ SkY2PortStart(pAC, IoC, ToPort); ++#ifdef SK_YUKON2 ++ /* in yukon-II always port 0 has to be started first */ ++ // SkY2PortStart(pAC, IoC, 0); ++ // SkY2PortStart(pAC, IoC, 1); ++#endif ++ } + 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 ")); ++ 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); ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW], ++ pMsg) < 0) { ++ DEV_KFREE_SKB_ANY(pMsg); ++ } ++ } else { ++ if (SkY2RlmtSend(pAC, pRlmtMbuf->PortIdx, 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 +- */ ++ /* check what IRQs are to be moderated */ + 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; ++ case SK_DRV_ADAP_FAIL: ++#if (!defined (Y2_RECOVERY) && !defined (Y2_LE_CHECK)) ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, ++ ("ADAPTER FAIL EVENT\n")); ++ printk("%s: Adapter failed.\n", pAC->dev[0]->name); ++ SK_OUT32(pAC->IoBase, B0_IMSK, 0); /* disable interrupts */ ++ break; ++#endif ++ ++#if (defined (Y2_RECOVERY) || defined (Y2_LE_CHECK)) ++ case SK_DRV_RECOVER: ++ spin_lock_irqsave(&pAC->InitLock, InitFlags); ++ pNet = (DEV_NET *) pAC->dev[Param.Para32[0]]->priv; ++ ++ /* Recover already in progress */ ++ if (pNet->InRecover) { ++ break; ++ } ++ ++ netif_stop_queue(pAC->dev[Param.Para32[0]]); /* stop device if running */ ++ pNet->InRecover = SK_TRUE; ++ ++ FromPort = Param.Para32[0]; ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, ++ ("PORT RESET EVENT, Port: %d ", FromPort)); ++ ++ /* Disable interrupts */ ++ SK_OUT32(pAC->IoBase, B0_IMSK, 0); ++ SK_OUT32(pAC->IoBase, B0_HWE_IMSK, 0); ++ ++ SkLocalEventQueue64(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET, ++ FromPort, SK_FALSE); ++ spin_lock_irqsave( ++ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, ++ Flags); ++ if (CHIP_ID_YUKON_2(pAC)) { ++ SkY2PortStop(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST); ++ } else { ++ SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST); ++ } ++ pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING; ++ spin_unlock_irqrestore( ++ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, ++ Flags); ++ ++ if (!CHIP_ID_YUKON_2(pAC)) { ++#ifdef CONFIG_SK98LIN_NAPI ++ WorkToDo = 1; ++ ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE, &WorkDone, WorkToDo); ++#else ++ ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); ++#endif ++ ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); ++ } ++ spin_lock_irqsave( ++ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, ++ Flags); ++ ++#ifdef USE_TIST_FOR_RESET ++ if (!HW_IS_EXT_LE_FORMAT(pAC) && pAC->GIni.GIYukon2) { ++#if 0 ++ /* make sure that we do not accept any status LEs from now on */ ++ Y2_ENABLE_TIST(pAC->IoBase); ++ ++ /* get current timestamp */ ++ Y2_GET_TIST_LOW_VAL(pAC->IoBase, &pAC->MinTistLo); ++ pAC->MinTistHi = pAC->GIni.GITimeStampCnt; ++ ++ SK_SET_WAIT_BIT_FOR_PORT( ++ pAC, ++ SK_PSTATE_WAITING_FOR_SPECIFIC_TIST, ++ FromPort); ++#endif ++ SK_SET_WAIT_BIT_FOR_PORT( ++ pAC, ++ SK_PSTATE_WAITING_FOR_ANY_TIST, ++ FromPort); ++ ++ /* start tist */ ++ Y2_ENABLE_TIST(pAC->IoBase); ++ } ++#endif ++ ++ /* Restart Receive BMU on Yukon-2 */ ++ if (HW_FEATURE(pAC, HWF_WA_DEV_4167)) { ++ SkYuk2RestartRxBmu(pAC, IoC, FromPort); ++ } ++ ++#ifdef Y2_LE_CHECK ++ /* mark entries invalid */ ++ pAC->LastPort = 3; ++ pAC->LastOpc = 0xFF; ++#endif ++ ++#endif ++ /* Restart ports but do not initialize PHY. */ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ SkY2PortStart(pAC, IoC, FromPort); ++ } else { ++ /* 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); ++ CLEAR_AND_START_RX(FromPort); ++ } ++ spin_unlock_irqrestore( ++ &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, ++ Flags); ++ ++ /* Map any waiting RX buffers to HW */ ++ FillReceiveTableYukon2(pAC, pAC->IoBase, FromPort); ++ ++ pNet->InRecover = SK_FALSE; ++ /* enable Interrupts */ ++ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); ++ SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK); ++ netif_wake_queue(pAC->dev[FromPort]); ++ spin_unlock_irqrestore(&pAC->InitLock, InitFlags); ++ break; + default: + break; + } +- SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, +- ("END EVENT ")); +- +- return (0); +-} /* SkDrvEvent */ ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, ++ ("END EVENT ")); ++ ++ return (0); ++} /* SkDrvEvent */ ++ ++ ++/****************************************************************************** ++ * ++ * SkLocalEventQueue() - add event to queue ++ * ++ * Description: ++ * This function adds an event to the event queue and run the ++ * SkEventDispatcher. At least Init Level 1 is required to queue events, ++ * but will be scheduled add Init Level 2. ++ * ++ * returns: ++ * nothing ++ */ ++void SkLocalEventQueue( ++SK_AC *pAC, /* Adapters context */ ++SK_U32 Class, /* Event Class */ ++SK_U32 Event, /* Event to be queued */ ++SK_U32 Param1, /* Event parameter 1 */ ++SK_U32 Param2, /* Event parameter 2 */ ++SK_BOOL Dispatcher) /* Dispatcher flag: ++ * TRUE == Call SkEventDispatcher ++ * FALSE == Don't execute SkEventDispatcher ++ */ ++{ ++ SK_EVPARA EvPara; ++ EvPara.Para32[0] = Param1; ++ EvPara.Para32[1] = Param2; ++ ++ ++ if (Class == SKGE_PNMI) { ++ SkPnmiEvent( pAC, ++ pAC->IoBase, ++ Event, ++ EvPara); ++ } else { ++ SkEventQueue( pAC, ++ Class, ++ Event, ++ EvPara); ++ } ++ ++ /* Run the dispatcher */ ++ if (Dispatcher) { ++ SkEventDispatcher(pAC, pAC->IoBase); ++ } ++ ++} ++ ++/****************************************************************************** ++ * ++ * SkLocalEventQueue64() - add event to queue (64bit version) ++ * ++ * Description: ++ * This function adds an event to the event queue and run the ++ * SkEventDispatcher. At least Init Level 1 is required to queue events, ++ * but will be scheduled add Init Level 2. ++ * ++ * returns: ++ * nothing ++ */ ++void SkLocalEventQueue64( ++SK_AC *pAC, /* Adapters context */ ++SK_U32 Class, /* Event Class */ ++SK_U32 Event, /* Event to be queued */ ++SK_U64 Param, /* Event parameter */ ++SK_BOOL Dispatcher) /* Dispatcher flag: ++ * TRUE == Call SkEventDispatcher ++ * FALSE == Don't execute SkEventDispatcher ++ */ ++{ ++ SK_EVPARA EvPara; ++ EvPara.Para64 = Param; ++ ++ ++ if (Class == SKGE_PNMI) { ++ SkPnmiEvent( pAC, ++ pAC->IoBase, ++ Event, ++ EvPara); ++ } else { ++ SkEventQueue( pAC, ++ Class, ++ Event, ++ EvPara); ++ } ++ ++ /* Run the dispatcher */ ++ if (Dispatcher) { ++ SkEventDispatcher(pAC, pAC->IoBase); ++ } ++ ++} + + + /***************************************************************************** +@@ -4454,14 +6226,22 @@ + case SK_ERRCL_COMM: + strcpy(ClassStr, "Communication error"); + break; ++ case SK_ERRCL_INFO: ++ strcpy(ClassStr, "Information"); ++ break; + } +- printk(KERN_INFO "%s: -- ERROR --\n Class: %s\n" +- " Nr: 0x%x\n Msg: %s\n", pAC->dev[0]->name, +- ClassStr, ErrNum, pErrorMsg); + +-} /* SkErrorLog */ ++ if (ErrClass == SK_ERRCL_INFO) { ++ printk(KERN_INFO "%s: -- INFORMATION --\n" ++ " Msg: %s\n", pAC->dev[0]->name, ++ pErrorMsg); ++ } else { ++ printk(KERN_INFO "%s: -- ERROR --\n Class: %s\n" ++ " Nr: 0x%x\n Msg: %s\n", pAC->dev[0]->name, ++ ClassStr, ErrNum, pErrorMsg); ++ } + +-#ifdef SK_DIAG_SUPPORT ++} /* SkErrorLog */ + + /***************************************************************************** + * +@@ -4477,8 +6257,11 @@ + int SkDrvEnterDiagMode( + SK_AC *pAc) /* pointer to adapter context */ + { +- DEV_NET *pNet = netdev_priv(pAc->dev[0]); +- SK_AC *pAC = pNet->pAC; ++ SK_AC *pAC = NULL; ++ DEV_NET *pNet = NULL; ++ ++ pNet = (DEV_NET *) pAc->dev[0]->priv; ++ pAC = pNet->pAC; + + SK_MEMCPY(&(pAc->PnmiBackup), &(pAc->PnmiStruct), + sizeof(SK_PNMI_STRUCT_DATA)); +@@ -4493,8 +6276,9 @@ + } else { + pAC->WasIfUp[0] = SK_FALSE; + } +- if (pNet != netdev_priv(pAC->dev[1])) { +- pNet = netdev_priv(pAC->dev[1]); ++ ++ if (pNet != (DEV_NET *) pAc->dev[1]->priv) { ++ pNet = (DEV_NET *) pAc->dev[1]->priv; + if (netif_running(pAC->dev[1])) { + pAC->WasIfUp[1] = SK_TRUE; + pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ +@@ -4527,16 +6311,16 @@ + sizeof(SK_PNMI_STRUCT_DATA)); + pAc->DiagModeActive = DIAG_NOTACTIVE; + pAc->Pnmi.DiagAttached = SK_DIAG_IDLE; +- if (pAc->WasIfUp[0] == SK_TRUE) { +- pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ ++ if (pAc->WasIfUp[0] == SK_TRUE) { ++ pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ + DoPrintInterfaceChange = SK_FALSE; +- SkDrvInitAdapter(pAc, 0); /* first device */ +- } +- if (pAc->WasIfUp[1] == SK_TRUE) { +- pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ ++ SkDrvInitAdapter(pAc, 0); /* first device */ ++ } ++ if (pAc->WasIfUp[1] == SK_TRUE) { ++ pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ + DoPrintInterfaceChange = SK_FALSE; +- SkDrvInitAdapter(pAc, 1); /* second device */ +- } ++ SkDrvInitAdapter(pAc, 1); /* second device */ ++ } + return(0); + } + +@@ -4616,11 +6400,20 @@ + + dev = pAC->dev[devNbr]; + +- /* On Linux 2.6 the network driver does NOT mess with reference +- ** counts. The driver MUST be able to be unloaded at any time +- ** due to the possibility of hotplug. ++ /* ++ ** Function SkGeClose() uses MOD_DEC_USE_COUNT (2.2/2.4) ++ ** or module_put() (2.6) to decrease the number of users for ++ ** a device, but if a device is to be put under control of ++ ** the DIAG, that count is OK already and does not need to ++ ** be adapted! Hence the opposite MOD_INC_USE_COUNT or ++ ** try_module_get() needs to be used again to correct that. + */ ++ if (!try_module_get(THIS_MODULE)) { ++ return (-1); ++ } ++ + if (SkGeClose(dev) != 0) { ++ module_put(THIS_MODULE); + return (-1); + } + return (0); +@@ -4649,6 +6442,17 @@ + + if (SkGeOpen(dev) != 0) { + return (-1); ++ } else { ++ /* ++ ** Function SkGeOpen() uses MOD_INC_USE_COUNT (2.2/2.4) ++ ** or try_module_get() (2.6) to increase the number of ++ ** users for a device, but if a device was just under ++ ** control of the DIAG, that count is OK already and ++ ** does not need to be adapted! Hence the opposite ++ ** MOD_DEC_USE_COUNT or module_put() needs to be used ++ ** again to correct that. ++ */ ++ module_put(THIS_MODULE); + } + + /* +@@ -4661,14 +6465,25 @@ + + } /* SkDrvInitAdapter */ + +-#endif ++static int __init sk98lin_init(void) ++{ ++ return pci_module_init(&sk98lin_driver); ++} ++ ++static void __exit sk98lin_cleanup(void) ++{ ++ pci_unregister_driver(&sk98lin_driver); ++} ++ ++module_init(sk98lin_init); ++module_exit(sk98lin_cleanup); ++ + + #ifdef DEBUG + /****************************************************************************/ + /* "debug only" section *****************************************************/ + /****************************************************************************/ + +- + /***************************************************************************** + * + * DumpMsg - print a frame +@@ -4679,9 +6494,11 @@ + * Returns: N/A + * + */ +-static void DumpMsg(struct sk_buff *skb, char *str) ++static void DumpMsg( ++struct sk_buff *skb, /* linux' socket buffer */ ++char *str) /* additional msg string */ + { +- int msglen; ++ int msglen = (skb->len > 64) ? 64 : skb->len; + + if (skb == NULL) { + printk("DumpMsg(): NULL-Message\n"); +@@ -4693,19 +6510,14 @@ + return; + } + +- msglen = skb->len; +- if (msglen > 64) +- msglen = 64; +- +- printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len); +- ++ printk("DumpMsg: PhysPage: %p\n", ++ page_address(virt_to_page(skb->data))); ++ printk("--- Begin of message from %s , len %d (from %d) ----\n", ++ str, msglen, skb->len); + DumpData((char *)skb->data, msglen); +- + printk("------- End of message ---------\n"); + } /* DumpMsg */ + +- +- + /***************************************************************************** + * + * DumpData - print a data area +@@ -4717,23 +6529,22 @@ + * Returns: N/A + * + */ +-static void DumpData(char *p, int size) +-{ +-register int i; +-int haddr, addr; +-char hex_buffer[180]; +-char asc_buffer[180]; +-char HEXCHAR[] = "0123456789ABCDEF"; +- +- addr = 0; +- haddr = 0; +- hex_buffer[0] = 0; +- asc_buffer[0] = 0; ++static void DumpData( ++char *p, /* pointer to area containing the data */ ++int size) /* the size of that data area in bytes */ ++{ ++ register int i; ++ int haddr = 0, addr = 0; ++ char hex_buffer[180] = { '\0' }; ++ char asc_buffer[180] = { '\0' }; ++ char HEXCHAR[] = "0123456789ABCDEF"; ++ + for (i=0; i < size; ) { +- if (*p >= '0' && *p <='z') ++ if (*p >= '0' && *p <='z') { + asc_buffer[addr] = *p; +- else ++ } else { + asc_buffer[addr] = '.'; ++ } + addr++; + asc_buffer[addr] = 0; + hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4]; +@@ -4759,27 +6570,24 @@ + * DumpLong - print a data area as long values + * + * Description: +- * This function prints a area of data to the system logfile/to the ++ * This function prints a long variable to the system logfile/to the + * console. + * + * Returns: N/A + * + */ +-static void DumpLong(char *pc, int size) +-{ +-register int i; +-int haddr, addr; +-char hex_buffer[180]; +-char asc_buffer[180]; +-char HEXCHAR[] = "0123456789ABCDEF"; +-long *p; +-int l; +- +- addr = 0; +- haddr = 0; +- hex_buffer[0] = 0; +- asc_buffer[0] = 0; +- p = (long*) pc; ++static void DumpLong( ++char *pc, /* location of the variable to print */ ++int size) /* how large is the variable? */ ++{ ++ register int i; ++ int haddr = 0, addr = 0; ++ char hex_buffer[180] = { '\0' }; ++ char asc_buffer[180] = { '\0' }; ++ char HEXCHAR[] = "0123456789ABCDEF"; ++ long *p = (long*) pc; ++ int l; ++ + for (i=0; i < size; ) { + l = (long) *p; + hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf]; +@@ -4813,399 +6621,9 @@ + + #endif + +-static int __devinit skge_probe_one(struct pci_dev *pdev, +- const struct pci_device_id *ent) +-{ +- SK_AC *pAC; +- DEV_NET *pNet = NULL; +- struct net_device *dev = NULL; +- static int boards_found = 0; +- int error = -ENODEV; +- int using_dac = 0; +- char DeviceStr[80]; +- +- if (pci_enable_device(pdev)) +- goto out; +- +- /* Configure DMA attributes. */ +- if (sizeof(dma_addr_t) > sizeof(u32) && +- !(error = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) { +- using_dac = 1; +- error = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); +- if (error < 0) { +- printk(KERN_ERR "sk98lin %s unable to obtain 64 bit DMA " +- "for consistent allocations\n", pci_name(pdev)); +- goto out_disable_device; +- } +- } else { +- error = pci_set_dma_mask(pdev, DMA_32BIT_MASK); +- if (error) { +- printk(KERN_ERR "sk98lin %s no usable DMA configuration\n", +- pci_name(pdev)); +- goto out_disable_device; +- } +- } +- +- error = -ENOMEM; +- dev = alloc_etherdev(sizeof(DEV_NET)); +- if (!dev) { +- printk(KERN_ERR "sk98lin: unable to allocate etherdev " +- "structure!\n"); +- goto out_disable_device; +- } +- +- pNet = netdev_priv(dev); +- pNet->pAC = kzalloc(sizeof(SK_AC), GFP_KERNEL); +- if (!pNet->pAC) { +- printk(KERN_ERR "sk98lin: unable to allocate adapter " +- "structure!\n"); +- goto out_free_netdev; +- } +- +- pAC = pNet->pAC; +- pAC->PciDev = pdev; +- +- pAC->dev[0] = dev; +- pAC->dev[1] = dev; +- pAC->CheckQueue = SK_FALSE; +- +- dev->irq = pdev->irq; +- +- error = SkGeInitPCI(pAC); +- if (error) { +- printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error); +- goto out_free_netdev; +- } +- +- SET_MODULE_OWNER(dev); +- dev->open = &SkGeOpen; +- dev->stop = &SkGeClose; +- dev->hard_start_xmit = &SkGeXmit; +- dev->get_stats = &SkGeStats; +- dev->set_multicast_list = &SkGeSetRxMode; +- dev->set_mac_address = &SkGeSetMacAddr; +- dev->do_ioctl = &SkGeIoctl; +- dev->change_mtu = &SkGeChangeMtu; +-#ifdef CONFIG_NET_POLL_CONTROLLER +- dev->poll_controller = &SkGePollController; +-#endif +- SET_NETDEV_DEV(dev, &pdev->dev); +- SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps); +- +- /* Use only if yukon hardware */ +- if (pAC->ChipsetType) { +-#ifdef USE_SK_TX_CHECKSUM +- dev->features |= NETIF_F_IP_CSUM; +-#endif +-#ifdef SK_ZEROCOPY +- dev->features |= NETIF_F_SG; +-#endif +-#ifdef USE_SK_RX_CHECKSUM +- pAC->RxPort[0].RxCsum = 1; +-#endif +- } +- +- if (using_dac) +- dev->features |= NETIF_F_HIGHDMA; +- +- pAC->Index = boards_found++; +- +- error = SkGeBoardInit(dev, pAC); +- if (error) +- goto out_free_netdev; +- +- /* Read Adapter name from VPD */ +- if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) { +- error = -EIO; +- printk(KERN_ERR "sk98lin: Could not read VPD data.\n"); +- goto out_free_resources; +- } +- +- /* Register net device */ +- error = register_netdev(dev); +- if (error) { +- printk(KERN_ERR "sk98lin: Could not register device.\n"); +- goto out_free_resources; +- } +- +- /* Print adapter specific string from vpd */ +- printk("%s: %s\n", dev->name, DeviceStr); +- +- /* Print configuration settings */ +- printk(" PrefPort:%c RlmtMode:%s\n", +- 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber, +- (pAC->RlmtMode==0) ? "Check Link State" : +- ((pAC->RlmtMode==1) ? "Check Link State" : +- ((pAC->RlmtMode==3) ? "Check Local Port" : +- ((pAC->RlmtMode==7) ? "Check Segmentation" : +- ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error"))))); +- +- SkGeYellowLED(pAC, pAC->IoBase, 1); +- +- memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6); +- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); +- +- pNet->PortNr = 0; +- pNet->NetNr = 0; +- +- boards_found++; +- +- pci_set_drvdata(pdev, dev); +- +- /* More then one port found */ +- if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { +- dev = alloc_etherdev(sizeof(DEV_NET)); +- if (!dev) { +- printk(KERN_ERR "sk98lin: unable to allocate etherdev " +- "structure!\n"); +- goto single_port; +- } +- +- pNet = netdev_priv(dev); +- pNet->PortNr = 1; +- pNet->NetNr = 1; +- pNet->pAC = pAC; +- +- dev->open = &SkGeOpen; +- dev->stop = &SkGeClose; +- dev->hard_start_xmit = &SkGeXmit; +- dev->get_stats = &SkGeStats; +- dev->set_multicast_list = &SkGeSetRxMode; +- dev->set_mac_address = &SkGeSetMacAddr; +- dev->do_ioctl = &SkGeIoctl; +- dev->change_mtu = &SkGeChangeMtu; +- SET_NETDEV_DEV(dev, &pdev->dev); +- SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps); +- +- if (pAC->ChipsetType) { +-#ifdef USE_SK_TX_CHECKSUM +- dev->features |= NETIF_F_IP_CSUM; +-#endif +-#ifdef SK_ZEROCOPY +- dev->features |= NETIF_F_SG; +-#endif +-#ifdef USE_SK_RX_CHECKSUM +- pAC->RxPort[1].RxCsum = 1; +-#endif +- } +- +- if (using_dac) +- dev->features |= NETIF_F_HIGHDMA; +- +- error = register_netdev(dev); +- if (error) { +- printk(KERN_ERR "sk98lin: Could not register device" +- " for second port. (%d)\n", error); +- free_netdev(dev); +- goto single_port; +- } +- +- pAC->dev[1] = dev; +- memcpy(&dev->dev_addr, +- &pAC->Addr.Net[1].CurrentMacAddress, 6); +- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); +- +- printk("%s: %s\n", dev->name, DeviceStr); +- printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); +- } +- +-single_port: +- +- /* Save the hardware revision */ +- pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + +- (pAC->GIni.GIPciHwRev & 0x0F); +- +- /* Set driver globals */ +- pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME; +- pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE; +- +- memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA)); +- memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA)); +- +- return 0; +- +- out_free_resources: +- FreeResources(dev); +- out_free_netdev: +- free_netdev(dev); +- out_disable_device: +- pci_disable_device(pdev); +- out: +- return error; +-} +- +-static void __devexit skge_remove_one(struct pci_dev *pdev) +-{ +- struct net_device *dev = pci_get_drvdata(pdev); +- DEV_NET *pNet = netdev_priv(dev); +- SK_AC *pAC = pNet->pAC; +- struct net_device *otherdev = pAC->dev[1]; +- +- unregister_netdev(dev); +- +- SkGeYellowLED(pAC, pAC->IoBase, 0); +- +- if (pAC->BoardLevel == SK_INIT_RUN) { +- SK_EVPARA EvPara; +- unsigned long Flags; +- +- /* board is still alive */ +- spin_lock_irqsave(&pAC->SlowPathLock, Flags); +- EvPara.Para32[0] = 0; +- EvPara.Para32[1] = -1; +- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); +- EvPara.Para32[0] = 1; +- EvPara.Para32[1] = -1; +- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); +- SkEventDispatcher(pAC, pAC->IoBase); +- /* disable interrupts */ +- SK_OUT32(pAC->IoBase, B0_IMSK, 0); +- SkGeDeInit(pAC, pAC->IoBase); +- spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); +- pAC->BoardLevel = SK_INIT_DATA; +- /* We do NOT check here, if IRQ was pending, of course*/ +- } +- +- if (pAC->BoardLevel == SK_INIT_IO) { +- /* board is still alive */ +- SkGeDeInit(pAC, pAC->IoBase); +- pAC->BoardLevel = SK_INIT_DATA; +- } +- +- FreeResources(dev); +- free_netdev(dev); +- if (otherdev != dev) +- free_netdev(otherdev); +- kfree(pAC); +-} +- +-#ifdef CONFIG_PM +-static int skge_suspend(struct pci_dev *pdev, pm_message_t state) +-{ +- struct net_device *dev = pci_get_drvdata(pdev); +- DEV_NET *pNet = netdev_priv(dev); +- SK_AC *pAC = pNet->pAC; +- struct net_device *otherdev = pAC->dev[1]; +- +- if (netif_running(dev)) { +- netif_carrier_off(dev); +- DoPrintInterfaceChange = SK_FALSE; +- SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */ +- netif_device_detach(dev); +- } +- if (otherdev != dev) { +- if (netif_running(otherdev)) { +- netif_carrier_off(otherdev); +- DoPrintInterfaceChange = SK_FALSE; +- SkDrvDeInitAdapter(pAC, 1); /* performs SkGeClose */ +- netif_device_detach(otherdev); +- } +- } +- +- pci_save_state(pdev); +- pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); +- if (pAC->AllocFlag & SK_ALLOC_IRQ) { +- free_irq(dev->irq, dev); +- } +- pci_disable_device(pdev); +- pci_set_power_state(pdev, pci_choose_state(pdev, state)); +- +- return 0; +-} +- +-static int skge_resume(struct pci_dev *pdev) +-{ +- struct net_device *dev = pci_get_drvdata(pdev); +- DEV_NET *pNet = netdev_priv(dev); +- SK_AC *pAC = pNet->pAC; +- struct net_device *otherdev = pAC->dev[1]; +- int ret; +- +- pci_set_power_state(pdev, PCI_D0); +- pci_restore_state(pdev); +- ret = pci_enable_device(pdev); +- if (ret) { +- printk(KERN_WARNING "sk98lin: unable to enable device %s " +- "in resume\n", dev->name); +- goto err_out; +- } +- pci_set_master(pdev); +- if (pAC->GIni.GIMacsFound == 2) +- ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, "sk98lin", dev); +- else +- ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, "sk98lin", dev); +- if (ret) { +- printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq); +- ret = -EBUSY; +- goto err_out_disable_pdev; +- } +- +- netif_device_attach(dev); +- if (netif_running(dev)) { +- DoPrintInterfaceChange = SK_FALSE; +- SkDrvInitAdapter(pAC, 0); /* first device */ +- } +- if (otherdev != dev) { +- netif_device_attach(otherdev); +- if (netif_running(otherdev)) { +- DoPrintInterfaceChange = SK_FALSE; +- SkDrvInitAdapter(pAC, 1); /* second device */ +- } +- } +- +- return 0; +- +-err_out_disable_pdev: +- pci_disable_device(pdev); +-err_out: +- pAC->AllocFlag &= ~SK_ALLOC_IRQ; +- dev->irq = 0; +- return ret; +-} +-#else +-#define skge_suspend NULL +-#define skge_resume NULL +-#endif +- +-static struct pci_device_id skge_pci_tbl[] = { +- { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +- { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +- { PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +- { PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +-/* DLink card does not have valid VPD so this driver gags +- * { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +- */ +- { PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +- { PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +- { PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +- { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, }, +- { PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, +- { 0 } +-}; +- +-MODULE_DEVICE_TABLE(pci, skge_pci_tbl); +- +-static struct pci_driver skge_driver = { +- .name = "sk98lin", +- .id_table = skge_pci_tbl, +- .probe = skge_probe_one, +- .remove = __devexit_p(skge_remove_one), +- .suspend = skge_suspend, +- .resume = skge_resume, +-}; +- +-static int __init skge_init(void) +-{ +- printk(KERN_NOTICE "sk98lin: driver has been replaced by the skge driver" +- " and is scheduled for removal\n"); +- +- return pci_register_driver(&skge_driver); +-} +- +-static void __exit skge_exit(void) +-{ +- pci_unregister_driver(&skge_driver); +-} ++/******************************************************************************* ++ * ++ * End of file ++ * ++ ******************************************************************************/ + +-module_init(skge_init); +-module_exit(skge_exit); +diff -ruN linux/drivers/net/sk98lin/skgehwt.c linux-new/drivers/net/sk98lin/skgehwt.c +--- linux/drivers/net/sk98lin/skgehwt.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skgehwt.c 2007-01-24 14:03:40.000000000 +0100 +@@ -2,16 +2,17 @@ + * + * Name: skgehwt.c + * Project: Gigabit Ethernet Adapters, Event Scheduler Module +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Hardware Timer + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2004 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 +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -27,7 +29,7 @@ + */ + #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) + static const char SysKonnectFileId[] = +- "@(#) $Id$ (C) Marvell."; ++ "@(#) $Id$ (C) Marvell."; + #endif + + #include "h/skdrv1st.h" /* Driver Specific Definitions */ +@@ -44,10 +46,10 @@ + /* + * Prototypes of local functions. + */ +-#define SK_HWT_MAX (65000) ++#define SK_HWT_MAX 65000UL * 160 /* ca. 10 sec. */ + + /* correction factor */ +-#define SK_HWT_FAC (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100) ++#define SK_HWT_FAC (10 * (SK_U32)pAC->GIni.GIHstClkFact / 16) + + /* + * Initialize hardware timer. +@@ -73,29 +75,21 @@ + void SkHwtStart( + SK_AC *pAC, /* Adapters context */ + SK_IOC Ioc, /* IoContext */ +-SK_U32 Time) /* Time in units of 16us to load the timer with. */ ++SK_U32 Time) /* Time in usec to load the timer */ + { +- SK_U32 Cnt; +- + if (Time > SK_HWT_MAX) + Time = SK_HWT_MAX; + + pAC->Hwt.TStart = Time; + pAC->Hwt.TStop = 0L; + +- Cnt = Time; +- +- /* +- * if time < 16 us +- * time = 16 us +- */ +- if (!Cnt) { +- Cnt++; ++ if (!Time) { ++ Time = 1L; + } + +- SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC); +- +- SK_OUT16(Ioc, B2_TI_CTRL, TIM_START); /* Start timer. */ ++ SK_OUT32(Ioc, B2_TI_INI, Time * SK_HWT_FAC); ++ ++ SK_OUT16(Ioc, B2_TI_CTRL, TIM_START); /* Start timer */ + + pAC->Hwt.TActive = SK_TRUE; + } +@@ -109,13 +103,12 @@ + SK_IOC Ioc) /* IoContext */ + { + SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP); +- ++ + SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ); + + pAC->Hwt.TActive = SK_FALSE; + } + +- + /* + * Stop hardware timer and read time elapsed since last start. + * +@@ -129,6 +122,9 @@ + { + SK_U32 TRead; + SK_U32 IStatus; ++ SK_U32 TimerInt; ++ ++ TimerInt = CHIP_ID_YUKON_2(pAC) ? Y2_IS_TIMINT : IS_TIMINT; + + if (pAC->Hwt.TActive) { + +@@ -139,15 +135,15 @@ + + SK_IN32(Ioc, B0_ISRC, &IStatus); + +- /* Check if timer expired (or wraped around) */ +- if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) { +- ++ /* Check if timer expired (or wrapped around) */ ++ if ((TRead > pAC->Hwt.TStart) || ((IStatus & TimerInt) != 0)) { ++ + SkHwtStop(pAC, Ioc); +- ++ + pAC->Hwt.TStop = pAC->Hwt.TStart; + } + else { +- ++ + pAC->Hwt.TStop = pAC->Hwt.TStart - TRead; + } + } +@@ -162,9 +158,9 @@ + SK_IOC Ioc) /* IoContext */ + { + SkHwtStop(pAC, Ioc); +- ++ + pAC->Hwt.TStop = pAC->Hwt.TStart; +- ++ + SkTimerDone(pAC, Ioc); + } + +diff -ruN linux/drivers/net/sk98lin/skgeinit.c linux-new/drivers/net/sk98lin/skgeinit.c +--- linux/drivers/net/sk98lin/skgeinit.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skgeinit.c 2007-01-24 13:58:33.000000000 +0100 +@@ -2,23 +2,24 @@ + * + * Name: skgeinit.c + * Project: Gigabit Ethernet Adapters, Common Modules +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Contains functions to initialize the adapter + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2006 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. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -31,7 +32,7 @@ + + #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) + static const char SysKonnectFileId[] = +- "@(#) $Id$ (C) Marvell."; ++ "@(#) $Id$ (C) Marvell."; + #endif + + struct s_QOffTab { +@@ -39,6 +40,7 @@ + int XsQOff; /* Sync Tx Queue Address Offset */ + int XaQOff; /* Async Tx Queue Address Offset */ + }; ++ + static struct s_QOffTab QOffTab[] = { + {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2} + }; +@@ -57,6 +59,126 @@ + #endif + }; + ++#ifndef SK_SLIM ++/****************************************************************************** ++ * ++ * SkGePortVlan() - Enable / Disable VLAN support ++ * ++ * Description: ++ * Enable or disable the VLAN support of the selected port. ++ * The new configuration is *not* saved over any SkGeStopPort() and ++ * SkGeInitPort() calls. ++ * Currently this function is only supported on Yukon-2/EC adapters. ++ * ++ * Returns: ++ * nothing ++ */ ++void SkGePortVlan( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port number */ ++SK_BOOL Enable) /* Flag */ ++{ ++ SK_U32 RxCtrl; ++ SK_U32 TxCtrl; ++ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ if (Enable) { ++ RxCtrl = RX_VLAN_STRIP_ON; ++ TxCtrl = TX_VLAN_TAG_ON; ++ } ++ else { ++ RxCtrl = RX_VLAN_STRIP_OFF; ++ TxCtrl = TX_VLAN_TAG_OFF; ++ } ++ ++ SK_OUT32(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), RxCtrl); ++ ++ SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TxCtrl); ++ } ++} /* SkGePortVlan */ ++ ++ ++/****************************************************************************** ++ * ++ * SkGeRxRss() - Enable / Disable RSS Hash Calculation ++ * ++ * Description: ++ * Enable or disable the RSS hash calculation of the selected port. ++ * The new configuration is *not* saved over any SkGeStopPort() and ++ * SkGeInitPort() calls. ++ * Currently this function is only supported on Yukon-2/EC adapters. ++ * ++ * Returns: ++ * nothing ++ */ ++void SkGeRxRss( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port number */ ++SK_BOOL Enable) /* Flag */ ++{ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR), ++ Enable ? BMU_ENA_RX_RSS_HASH : BMU_DIS_RX_RSS_HASH); ++ } ++} /* SkGeRxRss */ ++ ++ ++/****************************************************************************** ++ * ++ * SkGeRxCsum() - Enable / Disable Receive Checksum ++ * ++ * Description: ++ * Enable or disable the checksum of the selected port. ++ * The new configuration is *not* saved over any SkGeStopPort() and ++ * SkGeInitPort() calls. ++ * Currently this function is only supported on Yukon-2/EC adapters. ++ * ++ * Returns: ++ * nothing ++ */ ++void SkGeRxCsum( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port number */ ++SK_BOOL Enable) /* Flag */ ++{ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR), ++ Enable ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); ++ } ++} /* SkGeRxCsum */ ++#endif /* !SK_SLIM */ ++ ++/****************************************************************************** ++ * ++ * SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring ++ * ++ * Description: ++ * Enable or disable the descriptor polling of the receive descriptor ++ * ring (RxD) for port 'Port'. ++ * The new configuration is *not* saved over any SkGeStopPort() and ++ * SkGeInitPort() calls. ++ * ++ * Returns: ++ * nothing ++ */ ++void SkGePollRxD( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (MAC_1 + n) */ ++SK_BOOL PollRxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */ ++{ ++ SK_GEPORT *pPrt; ++ ++ pPrt = &pAC->GIni.GP[Port]; ++ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (SK_U32)((PollRxD) ? ++ CSR_ENA_POL : CSR_DIS_POL)); ++} /* SkGePollRxD */ ++ ++ + /****************************************************************************** + * + * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings +@@ -71,8 +193,8 @@ + * nothing + */ + void SkGePollTxD( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + SK_BOOL PollTxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */ + { +@@ -86,13 +208,13 @@ + if (pPrt->PXSQSize != 0) { + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord); + } +- ++ + if (pPrt->PXAQSize != 0) { + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord); + } + } /* SkGePollTxD */ + +- ++#ifndef SK_SLIM + /****************************************************************************** + * + * SkGeYellowLED() - Switch the yellow LED on or off. +@@ -107,20 +229,30 @@ + * nothing + */ + void SkGeYellowLED( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int State) /* yellow LED state, 0 = OFF, 0 != ON */ + { ++ int LedReg; ++ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ /* different mapping on Yukon-2 */ ++ LedReg = B0_CTST + 1; ++ } ++ else { ++ LedReg = B0_LED; ++ } ++ + if (State == 0) { +- /* Switch yellow LED OFF */ +- SK_OUT8(IoC, B0_LED, LED_STAT_OFF); ++ /* Switch state LED OFF */ ++ SK_OUT8(IoC, LedReg, LED_STAT_OFF); + } + else { +- /* Switch yellow LED ON */ +- SK_OUT8(IoC, B0_LED, LED_STAT_ON); ++ /* Switch state LED ON */ ++ SK_OUT8(IoC, LedReg, LED_STAT_ON); + } + } /* SkGeYellowLED */ +- ++#endif /* !SK_SLIM */ + + #if (!defined(SK_SLIM) || defined(GENESIS)) + /****************************************************************************** +@@ -141,8 +273,8 @@ + * nothing + */ + void SkGeXmitLED( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Led, /* offset to the LED Init Value register */ + int Mode) /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */ + { +@@ -167,18 +299,17 @@ + */ + SK_OUT32(IoC, Led + XMIT_LED_CNT, 0); + SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF); +- break; + } +- ++ + /* +- * 1000BT: The Transmit LED is driven by the PHY. ++ * 1000BT: the Transmit LED is driven by the PHY. + * But the default LED configuration is used for + * Level One and Broadcom PHYs. +- * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.) +- * (In this case it has to be added here. But we will see. XXX) ++ * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set. ++ * In this case it has to be added here.) + */ + } /* SkGeXmitLED */ +-#endif /* !SK_SLIM || GENESIS */ ++#endif /* !SK_SLIM || GENESIS */ + + + /****************************************************************************** +@@ -199,7 +330,7 @@ + * 1: configuration error + */ + static int DoCalcAddr( +-SK_AC *pAC, /* adapter context */ ++SK_AC *pAC, /* Adapter Context */ + SK_GEPORT SK_FAR *pPrt, /* port index */ + int QuSize, /* size of the queue to configure in kB */ + SK_U32 SK_FAR *StartVal, /* start value for address calculation */ +@@ -236,12 +367,35 @@ + + /****************************************************************************** + * ++ * SkGeRoundQueueSize() - Round the given queue size to the adpaters QZ units ++ * ++ * Description: ++ * This function rounds the given queue size in kBs to adapter specific ++ * queue size units (Genesis and Yukon: 8 kB, Yukon-2/EC: 1 kB). ++ * ++ * Returns: ++ * the rounded queue size in kB ++ */ ++static int SkGeRoundQueueSize( ++SK_AC *pAC, /* Adapter Context */ ++int QueueSizeKB) /* Queue size in kB */ ++{ ++ int QueueSizeSteps; ++ ++ QueueSizeSteps = (CHIP_ID_YUKON_2(pAC)) ? QZ_STEP_Y2 : QZ_STEP; ++ ++ return((QueueSizeKB + QueueSizeSteps - 1) & ~(QueueSizeSteps - 1)); ++} /* SkGeRoundQueueSize */ ++ ++ ++/****************************************************************************** ++ * + * SkGeInitAssignRamToQueues() - allocate default queue sizes + * + * Description: + * This function assigns the memory to the different queues and ports. + * When DualNet is set to SK_TRUE all ports get the same amount of memory. +- * Otherwise the first port gets most of the memory and all the ++ * Otherwise the first port gets most of the memory and all the + * other ports just the required minimum. + * This function can only be called when pAC->GIni.GIRamSize and + * pAC->GIni.GIMacsFound have been initialized, usually this happens +@@ -254,102 +408,146 @@ + */ + + int SkGeInitAssignRamToQueues( +-SK_AC *pAC, /* Adapter context */ ++SK_AC *pAC, /* Adapter Context */ + int ActivePort, /* Active Port in RLMT mode */ +-SK_BOOL DualNet) /* adapter context */ ++SK_BOOL DualNet) /* Dual Net active */ + { + int i; + int UsedKilobytes; /* memory already assigned */ + int ActivePortKilobytes; /* memory available for active port */ +- SK_GEPORT *pGePort; +- +- UsedKilobytes = 0; ++ int MinQueueSize; /* min. memory for queues */ ++ int TotalRamSize; /* total memory for queues */ ++ SK_BOOL DualPortYukon2; ++ SK_GEPORT *pPrt; + + if (ActivePort >= pAC->GIni.GIMacsFound) { ++ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n", + ActivePort)); + return(1); + } +- if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) + +- ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) { ++ ++ DualPortYukon2 = (CHIP_ID_YUKON_2(pAC) && pAC->GIni.GIMacsFound == 2); ++ ++ TotalRamSize = pAC->GIni.GIRamSize; ++ ++ if (DualPortYukon2) { ++ TotalRamSize *= 2; ++ } ++ ++ MinQueueSize = SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE; ++ ++ if (MinQueueSize > pAC->GIni.GIRamSize) { ++ MinQueueSize = pAC->GIni.GIRamSize; ++ } ++ ++ if ((pAC->GIni.GIMacsFound * MinQueueSize + ++ RAM_QUOTA_SYNC * SK_MIN_TXQ_SIZE) > TotalRamSize) { ++ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n", +- pAC->GIni.GIRamSize)); ++ TotalRamSize)); + return(2); + } + + if (DualNet) { + /* every port gets the same amount of memory */ +- ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound; ++ ActivePortKilobytes = TotalRamSize / pAC->GIni.GIMacsFound; ++ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + +- pGePort = &pAC->GIni.GP[i]; +- ++ pPrt = &pAC->GIni.GP[i]; ++ ++ if (DualPortYukon2) { ++ ActivePortKilobytes = pAC->GIni.GIRamSize; ++ } + /* take away the minimum memory for active queues */ +- ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE); ++ ActivePortKilobytes -= MinQueueSize; + + /* receive queue gets the minimum + 80% of the rest */ +- pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB(( +- ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100)) ++ pPrt->PRxQSize = SkGeRoundQueueSize(pAC, ++ (int)((long)ActivePortKilobytes * RAM_QUOTA_RX) / 100) + + SK_MIN_RXQ_SIZE; + +- ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE); ++ ActivePortKilobytes -= (pPrt->PRxQSize - SK_MIN_RXQ_SIZE); + + /* synchronous transmit queue */ +- pGePort->PXSQSize = 0; ++ pPrt->PXSQSize = 0; + + /* asynchronous transmit queue */ +- pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes + +- SK_MIN_TXQ_SIZE); ++ pPrt->PXAQSize = SkGeRoundQueueSize(pAC, ++ ActivePortKilobytes + SK_MIN_TXQ_SIZE); + } + } +- else { +- /* Rlmt Mode or single link adapter */ ++ else { /* RLMT Mode or single link adapter */ ++ ++ UsedKilobytes = 0; + +- /* Set standby queue size defaults for all standby ports */ ++ /* set standby queue size defaults for all standby ports */ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + + if (i != ActivePort) { +- pGePort = &pAC->GIni.GP[i]; ++ pPrt = &pAC->GIni.GP[i]; + +- pGePort->PRxQSize = SK_MIN_RXQ_SIZE; +- pGePort->PXAQSize = SK_MIN_TXQ_SIZE; +- pGePort->PXSQSize = 0; ++ if (DualPortYukon2) { ++ pPrt->PRxQSize = SkGeRoundQueueSize(pAC, ++ (int)((long)(pAC->GIni.GIRamSize - MinQueueSize) * ++ RAM_QUOTA_RX) / 100) + SK_MIN_RXQ_SIZE; ++ ++ pPrt->PXAQSize = pAC->GIni.GIRamSize - pPrt->PRxQSize; ++ } ++ else { ++ pPrt->PRxQSize = SK_MIN_RXQ_SIZE; ++ pPrt->PXAQSize = SK_MIN_TXQ_SIZE; ++ } ++ pPrt->PXSQSize = 0; + + /* Count used RAM */ +- UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize; ++ UsedKilobytes += pPrt->PRxQSize + pPrt->PXAQSize; + } + } + /* what's left? */ +- ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes; ++ ActivePortKilobytes = TotalRamSize - UsedKilobytes; + + /* assign it to the active port */ + /* first take away the minimum memory */ +- ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE); +- pGePort = &pAC->GIni.GP[ActivePort]; ++ ActivePortKilobytes -= MinQueueSize; ++ pPrt = &pAC->GIni.GP[ActivePort]; ++ ++ /* receive queue gets 80% of the rest */ ++ pPrt->PRxQSize = SkGeRoundQueueSize(pAC, ++ (int)((long)ActivePortKilobytes * RAM_QUOTA_RX) / 100); + +- /* receive queue get's the minimum + 80% of the rest */ +- pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes * +- (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE; ++ ActivePortKilobytes -= pPrt->PRxQSize; + +- ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE); ++ /* add the minimum memory for Rx queue */ ++ pPrt->PRxQSize += MinQueueSize/2; + + /* synchronous transmit queue */ +- pGePort->PXSQSize = 0; ++ pPrt->PXSQSize = 0; + +- /* asynchronous transmit queue */ +- pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) + +- SK_MIN_TXQ_SIZE; ++ /* asynchronous transmit queue gets 20% of the rest */ ++ pPrt->PXAQSize = SkGeRoundQueueSize(pAC, ActivePortKilobytes) + ++ /* add the minimum memory for Tx queue */ ++ MinQueueSize/2; + } +-#ifdef VCPU +- VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n", +- pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize); +-#endif /* VCPU */ ++ ++#ifdef DEBUG ++ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { ++ ++ pPrt = &pAC->GIni.GP[i]; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("Port %d: RxQSize=%u, TxAQSize=%u, TxSQSize=%u\n", ++ i, pPrt->PRxQSize, pPrt->PXAQSize, pPrt->PXSQSize)); ++ } ++#endif /* DEBUG */ + + return(0); + } /* SkGeInitAssignRamToQueues */ + ++ + /****************************************************************************** + * + * SkGeCheckQSize() - Checks the Adapters Queue Size Configuration +@@ -360,12 +558,12 @@ + * used ports. + * This requirements must be fullfilled to have a valid configuration: + * - The size of all queues must not exceed GIRamSize. +- * - The queue sizes must be specified in units of 8 kB. ++ * - The queue sizes must be specified in units of 8 kB (Genesis & Yukon). + * - The size of Rx queues of available ports must not be +- * smaller than 16 kB. ++ * smaller than 16 kB (Genesis & Yukon) resp. 10 kB (Yukon-2). + * - The size of at least one Tx queue (synch. or asynch.) +- * of available ports must not be smaller than 16 kB +- * when Jumbo Frames are used. ++ * of available ports must not be smaller than 16 kB (Genesis & Yukon), ++ * resp. 10 kB (Yukon-2) when Jumbo Frames are used. + * - The RAM start and end addresses must not be changed + * for ports which are already initialized. + * Furthermore SkGeCheckQSize() defines the Start and End Addresses +@@ -376,7 +574,7 @@ + * 1: Queue Size Configuration invalid + */ + static int SkGeCheckQSize( +-SK_AC *pAC, /* adapter context */ ++SK_AC *pAC, /* Adapter Context */ + int Port) /* port index */ + { + SK_GEPORT *pPrt; +@@ -386,55 +584,68 @@ + SK_U32 StartAddr; + #ifndef SK_SLIM + int UsedMem; /* total memory used (max. found ports) */ +-#endif ++#endif + + Rtv = 0; +- ++ + #ifndef SK_SLIM + + UsedMem = 0; ++ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + pPrt = &pAC->GIni.GP[i]; + +- if ((pPrt->PRxQSize & QZ_UNITS) != 0 || +- (pPrt->PXSQSize & QZ_UNITS) != 0 || +- (pPrt->PXAQSize & QZ_UNITS) != 0) { ++ if (CHIP_ID_YUKON_2(pAC)) { ++ UsedMem = 0; ++ } ++ else if (((pPrt->PRxQSize & QZ_UNITS) != 0 || ++ (pPrt->PXSQSize & QZ_UNITS) != 0 || ++ (pPrt->PXAQSize & QZ_UNITS) != 0)) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); + return(1); + } + +- if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) { ++#ifndef SK_DIAG ++ if (i == Port && pAC->GIni.GIRamSize > SK_MIN_RXQ_SIZE && ++ pPrt->PRxQSize < SK_MIN_RXQ_SIZE) { + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG); + return(1); + } +- ++ + /* + * the size of at least one Tx queue (synch. or asynch.) has to be > 0. + * if Jumbo Frames are used, this size has to be >= 16 kB. + */ + if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) || +- (pAC->GIni.GIPortUsage == SK_JUMBO_LINK && +- ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) || ++ (pPrt->PPortUsage == SK_JUMBO_LINK && ++ ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) || + (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) { + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG); + return(1); + } +- ++#endif /* !SK_DIAG */ ++ + UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize; ++ ++ if (UsedMem > pAC->GIni.GIRamSize) { ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); ++ return(1); ++ } + } +- +- if (UsedMem > pAC->GIni.GIRamSize) { +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); +- return(1); +- } +-#endif /* !SK_SLIM */ ++ ++#endif /* !SK_SLIM */ + + /* Now start address calculation */ + StartAddr = pAC->GIni.GIRamOffs; + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { ++ + pPrt = &pAC->GIni.GP[i]; + ++ if (CHIP_ID_YUKON_2(pAC)) { ++ StartAddr = 0; ++ } ++ + /* Calculate/Check values for the receive queue */ + Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr, + &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd); +@@ -474,8 +685,8 @@ + * nothing + */ + static void SkGeInitMacArb( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC) /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ + { + /* release local reset */ + SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR); +@@ -514,8 +725,8 @@ + * nothing + */ + static void SkGeInitPktArb( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC) /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ + { + /* release local reset */ + SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR); +@@ -531,7 +742,8 @@ + * NOTE: the packet arbiter timeout interrupt is needed for + * half duplex hangup workaround + */ +- if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) { ++ if (pAC->GIni.GP[MAC_1].PPortUsage != SK_JUMBO_LINK && ++ pAC->GIni.GP[MAC_2].PPortUsage != SK_JUMBO_LINK) { + if (pAC->GIni.GIMacsFound == 1) { + SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1); + } +@@ -554,14 +766,11 @@ + * nothing + */ + static void SkGeInitMacFifo( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_U16 Word; +-#ifdef VCPU +- SK_U32 DWord; +-#endif /* VCPU */ + /* + * For each FIFO: + * - release local reset +@@ -569,63 +778,105 @@ + * - setup defaults for the control register + * - enable the FIFO + */ +- ++ + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +- /* Configure Rx MAC FIFO */ ++ /* configure Rx MAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR); + SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF); + SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD); +- +- /* Configure Tx MAC FIFO */ ++ ++ /* configure Tx MAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR); + SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); + SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD); +- +- /* Enable frame flushing if jumbo frames used */ +- if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { ++ ++ /* enable frame flushing if jumbo frames used */ ++ if (pAC->GIni.GP[Port].PPortUsage == SK_JUMBO_LINK) { + SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH); + } + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { +- /* set Rx GMAC FIFO Flush Mask */ +- SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK); +- ++ + Word = (SK_U16)GMF_RX_CTRL_DEF; + +- /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */ +- if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) { ++ /* disable Rx GMAC FIFO Flush for YUKON-Plus */ ++ if (pAC->GIni.GIYukonLite) { + + Word &= ~GMF_RX_F_FL_ON; + } +- +- /* Configure Rx MAC FIFO */ ++ ++ /* configure Rx GMAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word); +- +- /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */ +- SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); +- +- /* Configure Tx MAC FIFO */ ++ ++ Word = RX_FF_FL_DEF_MSK; ++ ++#ifndef SK_DIAG ++ if (HW_FEATURE(pAC, HWF_WA_DEV_4115)) { ++ /* ++ * Flushing must be enabled (needed for ASF see dev. #4.29), ++ * but the flushing mask should be disabled (see dev. #4.115) ++ */ ++ Word = 0; ++ } ++#endif /* !SK_DIAG */ ++ ++ /* set Rx GMAC FIFO Flush Mask (after clearing reset) */ ++ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), Word); ++ ++ /* default: 0x0a -> 56 bytes on Yukon-1 and 64 bytes on Yukon-2 */ ++ Word = (SK_U16)RX_GMF_FL_THR_DEF; ++ ++ if (CHIP_ID_YUKON_2(pAC) && pAC->GIni.GIAsfEnabled) { ++ /* WA for dev. #4.30 & 4.89 (reduce to 0x08 -> 48 bytes) */ ++ Word -= 2; ++ } ++ else { ++ /* ++ * because Pause Packet Truncation in GMAC is not working ++ * we have to increase the Flush Threshold to 64 bytes ++ * in order to flush pause packets in Rx FIFO on Yukon-1 ++ */ ++ Word++; ++ } ++ ++ /* set Rx GMAC FIFO Flush Threshold (after clearing reset) */ ++ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), Word); ++ ++ /* configure Tx GMAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); + SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF); +- +-#ifdef VCPU +- SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord); +- SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord); +-#endif /* VCPU */ +- +- /* set Tx GMAC FIFO Almost Empty Threshold */ +-/* SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */ ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_EX) { ++ /* set Rx Pause Threshold */ ++ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_LP_THR), (SK_U16)SK_ECU_LLPP); ++ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_UP_THR), (SK_U16)SK_ECU_ULPP); ++ ++ if (pAC->GIni.GP[Port].PPortUsage == SK_JUMBO_LINK) { ++ /* set Tx GMAC FIFO Almost Empty Threshold */ ++ SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), ++ (SK_ECU_JUMBO_WM << 16) | (SK_U16)SK_ECU_AE_THR); ++ /* disable Store & Forward mode for TX */ ++ SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TX_STFW_DIS); ++ } ++#ifdef TEST_ONLY ++ else { ++ /* enable Store & Forward mode for TX */ ++ SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TX_STFW_ENA); ++ } ++#endif /* TEST_ONLY */ ++ } + } + #endif /* YUKON */ + + } /* SkGeInitMacFifo */ + +-#ifdef SK_LNK_SYNC_CNT ++#ifdef SK_LNK_SYNC_CNT + /****************************************************************************** + * + * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting +@@ -646,8 +897,8 @@ + * nothing + */ + void SkGeLoadLnkSyncCnt( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + SK_U32 CntVal) /* Counter value */ + { +@@ -657,7 +908,7 @@ + SK_BOOL IrqPend; + + /* stop counter */ +- SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP); ++ SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_STOP); + + /* + * ASIC problem: +@@ -670,6 +921,7 @@ + IrqPend = SK_FALSE; + SK_IN32(IoC, B0_ISRC, &ISrc); + SK_IN32(IoC, B0_IMSK, &OrgIMsk); ++ + if (Port == MAC_1) { + NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1; + if ((ISrc & IS_LNK_SYNC_M1) != 0) { +@@ -682,6 +934,7 @@ + IrqPend = SK_TRUE; + } + } ++ + if (!IrqPend) { + SK_OUT32(IoC, B0_IMSK, NewIMsk); + } +@@ -690,15 +943,17 @@ + SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal); + + /* start counter */ +- SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START); ++ SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_START); + + if (!IrqPend) { +- /* clear the unexpected IRQ, and restore the interrupt mask */ +- SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ); ++ /* clear the unexpected IRQ */ ++ SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_CLR_IRQ); ++ ++ /* restore the interrupt mask */ + SK_OUT32(IoC, B0_IMSK, OrgIMsk); + } + } /* SkGeLoadLnkSyncCnt*/ +-#endif /* SK_LNK_SYNC_CNT */ ++#endif /* SK_LNK_SYNC_CNT */ + + #if defined(SK_DIAG) || defined(SK_CFG_SYNC) + /****************************************************************************** +@@ -730,8 +985,8 @@ + * synchronous queue is configured + */ + int SkGeCfgSync( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + SK_U32 IntTime, /* Interval Timer Value in units of 8ns */ + SK_U32 LimCount, /* Number of bytes to transfer during IntTime */ +@@ -749,16 +1004,16 @@ + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); + return(1); + } +- ++ + if (pAC->GIni.GP[Port].PXSQSize == 0) { + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG); + return(2); + } +- ++ + /* calculate register values */ + IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100; + LimCount = LimCount / 8; +- ++ + if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) { + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); + return(1); +@@ -776,13 +1031,13 @@ + */ + SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), + TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); +- ++ + SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime); + SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount); +- ++ + SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), + (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC))); +- ++ + if (IntTime != 0 || LimCount != 0) { + SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC); + } +@@ -803,10 +1058,10 @@ + * Returns: + * nothing + */ +-static void DoInitRamQueue( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ +-int QuIoOffs, /* Queue IO Address Offset */ ++void DoInitRamQueue( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int QuIoOffs, /* Queue I/O Address Offset */ + SK_U32 QuStartAddr, /* Queue Start Address */ + SK_U32 QuEndAddr, /* Queue End Address */ + int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */ +@@ -839,8 +1094,7 @@ + + /* continue with SK_RX_BRAM_Q */ + case SK_RX_BRAM_Q: +- /* write threshold for Rx Queue */ +- ++ /* write threshold for Rx Queue (Pause packets) */ + SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal); + SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal); + +@@ -854,7 +1108,8 @@ + * or YUKON is used ((GMAC Tx FIFO is only 1 kB) + * we NEED Store & Forward of the RAM buffer. + */ +- if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK || ++ if (pAC->GIni.GP[MAC_1].PPortUsage == SK_JUMBO_LINK || ++ pAC->GIni.GP[MAC_2].PPortUsage == SK_JUMBO_LINK || + pAC->GIni.GIYukon) { + /* enable Store & Forward Mode for the Tx Side */ + SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD); +@@ -883,17 +1138,21 @@ + * nothing + */ + static void SkGeInitRamBufs( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; + int RxQType; + ++ if (!HW_IS_RAM_IF_AVAIL(pAC)) { ++ return; ++ } ++ + pPrt = &pAC->GIni.GP[Port]; + +- if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) { +- RxQType = SK_RX_SRAM_Q; /* small Rx Queue */ ++ if (pPrt->PRxQSize <= SK_MIN_RXQ_SIZE) { ++ RxQType = SK_RX_SRAM_Q; /* small Rx Queue */ + } + else { + RxQType = SK_RX_BRAM_Q; /* big Rx Queue */ +@@ -901,10 +1160,10 @@ + + DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart, + pPrt->PRxQRamEnd, RxQType); +- ++ + DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart, + pPrt->PXsQRamEnd, SK_TX_RAM_Q); +- ++ + DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart, + pPrt->PXaQRamEnd, SK_TX_RAM_Q); + +@@ -924,27 +1183,42 @@ + * Returns: + * nothing + */ +-static void SkGeInitRamIface( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC) /* IO context */ ++void SkGeInitRamIface( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ + { +- /* release local reset */ +- SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR); ++ int i; ++ int RamBuffers; + +- /* configure timeout values */ +- SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53); +- SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53); +- SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53); +- SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53); +- SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53); +- SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53); +- SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53); +- SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53); +- SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53); +- SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53); +- SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53); +- SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53); ++ if (!HW_IS_RAM_IF_AVAIL(pAC)) { ++ return; ++ } ++ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ RamBuffers = pAC->GIni.GIMacsFound; ++ } ++ else { ++ RamBuffers = 1; ++ } ++ ++ for (i = 0; i < RamBuffers; i++) { ++ /* release local reset */ ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_CTRL), (SK_U8)RI_RST_CLR); + ++ /* configure timeout values */ ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53); ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53); ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53); ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53); ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53); ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53); ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53); ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53); ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53); ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53); ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53); ++ SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53); ++ } + } /* SkGeInitRamIface */ + + +@@ -959,41 +1233,99 @@ + * nothing + */ + static void SkGeInitBmu( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; +- SK_U32 RxWm; +- SK_U32 TxWm; ++ SK_U16 RxWm; ++ SK_U16 TxWm; + + pPrt = &pAC->GIni.GP[Port]; + + RxWm = SK_BMU_RX_WM; + TxWm = SK_BMU_TX_WM; +- +- if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) { +- /* for better performance */ +- RxWm /= 2; +- TxWm /= 2; +- } + +- /* Rx Queue: Release all local resets and set the watermark */ +- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET); +- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm); ++ if (CHIP_ID_YUKON_2(pAC)) { + +- /* +- * Tx Queue: Release all local resets if the queue is used ! +- * set watermark +- */ +- if (pPrt->PXSQSize != 0) { +- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET); +- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm); ++ if (pAC->GIni.GIPciBus == SK_PEX_BUS) { ++ /* for better performance set it to 128 */ ++ RxWm = SK_BMU_RX_WM_PEX; ++ } ++ ++ /* Rx Queue: Release all local resets and set the watermark */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_CLR_RESET); ++ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_OPER_INIT); ++ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_FIFO_OP_ON); ++ ++ SK_OUT16(IoC, Q_ADDR(pPrt->PRxQOff, Q_WM), RxWm); ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U && ++ (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_A1 || ++ pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_B0)) { ++ /* MAC Rx RAM Read is controlled by hardware */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), F_M_RX_RAM_DIS); ++ } ++ ++ /* ++ * Tx Queue: Release all local resets if the queue is used ! ++ * set watermark ++ */ ++ if (pPrt->PXSQSize != 0 && HW_SYNC_TX_SUPPORTED(pAC)) { ++ /* Yukon-EC doesn't have a synchronous Tx queue */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_CLR_RESET); ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_OPER_INIT); ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_FIFO_OP_ON); ++ ++ SK_OUT16(IoC, Q_ADDR(pPrt->PXsQOff, Q_WM), TxWm); ++ } ++ ++ if (pPrt->PXAQSize != 0) { ++ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_CLR_RESET); ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_OPER_INIT); ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_FIFO_OP_ON); ++ ++#if (!defined(SK_SLIM) && !defined(SK_DIAG)) ++ if (HW_FEATURE(pAC, HWF_TX_IP_ID_INCR_ON)) { ++ /* Enable Tx IP ID Increment */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_TX_IPIDINCR_ON); ++ } ++#endif /* !SK_SLIM && !SK_DIAG */ ++ ++ SK_OUT16(IoC, Q_ADDR(pPrt->PXaQOff, Q_WM), TxWm); ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U && ++ pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_A0) { ++ /* fix for Yukon-EC Ultra: set BMU FIFO level */ ++ SK_OUT16(IoC, Q_ADDR(pPrt->PXaQOff, Q_AL), SK_ECU_TXFF_LEV); ++ } ++ } + } +- +- if (pPrt->PXAQSize != 0) { +- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET); +- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm); ++ else { ++ if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) { ++ /* for better performance */ ++ RxWm /= 2; ++ TxWm /= 2; ++ } ++ ++ /* Rx Queue: Release all local resets and set the watermark */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET); ++ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm); ++ ++ /* ++ * Tx Queue: Release all local resets if the queue is used ! ++ * set watermark ++ */ ++ if (pPrt->PXSQSize != 0) { ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET); ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm); ++ } ++ ++ if (pPrt->PXAQSize != 0) { ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET); ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm); ++ } + } + /* + * Do NOT enable the descriptor poll timers here, because +@@ -1017,20 +1349,29 @@ + */ + static SK_U32 TestStopBit( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* IO Context */ +-int QuIoOffs) /* Queue IO Address Offset */ ++SK_IOC IoC, /* I/O Context */ ++int QuIoOffs) /* Queue I/O Address Offset */ + { + SK_U32 QuCsr; /* CSR contents */ + + SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); +- +- if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) { +- /* Stop Descriptor overridden by start command */ +- SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP); + +- SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); ++ if (CHIP_ID_YUKON_2(pAC)) { ++ if ((QuCsr & (BMU_STOP | BMU_IDLE)) == 0) { ++ /* Stop Descriptor overridden by start command */ ++ SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), BMU_STOP); ++ ++ SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); ++ } ++ } ++ else { ++ if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) { ++ /* Stop Descriptor overridden by start command */ ++ SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP); ++ ++ SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); ++ } + } +- + return(QuCsr); + } /* TestStopBit */ + +@@ -1054,8 +1395,8 @@ + * has to be stopped once before. + * SK_STOP_ALL SK_STOP_TX + SK_STOP_RX + * +- * RstMode = SK_SOFT_RST Resets the MAC. The PHY is still alive. +- * SK_HARD_RST Resets the MAC and the PHY. ++ * RstMode = SK_SOFT_RST Resets the MAC, the PHY is still alive. ++ * SK_HARD_RST Resets the MAC and the PHY. + * + * Example: + * 1) A Link Down event was signaled for a port. Therefore the activity +@@ -1114,56 +1455,86 @@ + * SWITCH_PORT. + */ + void SkGeStopPort( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* I/O context */ +-int Port, /* port to stop (MAC_1 + n) */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port to stop (MAC_1 + n) */ + int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */ + int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */ + { +-#ifndef SK_DIAG +- SK_EVPARA Para; +-#endif /* !SK_DIAG */ + SK_GEPORT *pPrt; +- SK_U32 DWord; ++ SK_U32 RxCsr; + SK_U32 XsCsr; + SK_U32 XaCsr; + SK_U64 ToutStart; ++ SK_U32 CsrStart; ++ SK_U32 CsrStop; ++ SK_U32 CsrIdle; ++ SK_U32 CsrTest; ++ SK_U8 rsl; /* FIFO read shadow level */ ++ SK_U8 rl; /* FIFO read level */ + int i; + int ToutCnt; + + pPrt = &pAC->GIni.GP[Port]; + ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("SkGeStopPort: Port %d, Dir %d, RstMode %d\n", ++ Port, Dir, RstMode)); ++ ++ /* set the proper values of Q_CSR register layout depending on the chip */ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ CsrStart = BMU_START; ++ CsrStop = BMU_STOP; ++ CsrIdle = BMU_IDLE; ++ CsrTest = BMU_IDLE; ++ } ++ else { ++ CsrStart = CSR_START; ++ CsrStop = CSR_STOP; ++ CsrIdle = CSR_SV_IDLE; ++ CsrTest = CSR_SV_IDLE | CSR_STOP; ++ } ++ + if ((Dir & SK_STOP_TX) != 0) { +- /* disable receiver and transmitter */ +- SkMacRxTxDisable(pAC, IoC, Port); +- ++ ++ if (!pAC->GIni.GIAsfEnabled) { ++ /* disable receiver and transmitter */ ++ SkMacRxTxDisable(pAC, IoC, Port); ++ } ++ + /* stop both transmit queues */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CsrStop); ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CsrStop); + /* + * If the BMU is in the reset state CSR_STOP will terminate + * immediately. + */ +- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP); +- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP); + + ToutStart = SkOsGetTime(pAC); + ToutCnt = 0; + do { +- /* +- * Clear packet arbiter timeout to make sure +- * this loop will terminate. +- */ +- SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? +- PA_CLR_TO_TX1 : PA_CLR_TO_TX2)); +- +- /* +- * If the transfer stucks at the MAC the STOP command will not +- * terminate if we don't flush the XMAC's transmit FIFO ! +- */ +- SkMacFlushTxFifo(pAC, IoC, Port); ++#ifdef GENESIS ++ if (pAC->GIni.GIGenesis) { ++ /* clear Tx packet arbiter timeout IRQ */ ++ SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? ++ PA_CLR_TO_TX1 : PA_CLR_TO_TX2)); ++ /* ++ * If the transfer stucks at the XMAC the STOP command will not ++ * terminate if we don't flush the XMAC's transmit FIFO ! ++ */ ++ SkMacFlushTxFifo(pAC, IoC, Port); ++ } ++#endif /* GENESIS */ + +- XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff); + XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff); + ++ if (HW_SYNC_TX_SUPPORTED(pAC)) { ++ XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff); ++ } ++ else { ++ XsCsr = XaCsr; ++ } ++ + if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) { + /* + * Timeout of 1/18 second reached. +@@ -1171,67 +1542,115 @@ + */ + ToutCnt++; + if (ToutCnt > 1) { +- /* Might be a problem when the driver event handler +- * calls StopPort again. XXX. ++ /* ++ * If BMU stop doesn't terminate, we assume that ++ * we have a stable state and can reset the BMU, ++ * the Prefetch Unit, and RAM buffer now. + */ +- +- /* Fatal Error, Loop aborted */ +- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018, +- SKERR_HWI_E018MSG); +-#ifndef SK_DIAG +- Para.Para64 = Port; +- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); +-#endif /* !SK_DIAG */ +- return; ++ break; /* ===> leave do/while loop here */ + } + /* +- * Cache incoherency workaround: Assume a start command ++ * Cache incoherency workaround: assume a start command + * has been lost while sending the frame. + */ + ToutStart = SkOsGetTime(pAC); + +- if ((XsCsr & CSR_STOP) != 0) { +- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START); ++ if ((XsCsr & CsrStop) != 0) { ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CsrStart); + } +- if ((XaCsr & CSR_STOP) != 0) { +- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START); ++ ++ if ((XaCsr & CsrStop) != 0) { ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CsrStart); + } +- } + ++ /* ++ * After the previous operations the X(s|a)Csr does no ++ * longer contain the proper values ++ */ ++ XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff); ++ ++ if (HW_SYNC_TX_SUPPORTED(pAC)) { ++ XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff); ++ } ++ else { ++ XsCsr = XaCsr; ++ } ++ } + /* + * Because of the ASIC problem report entry from 21.08.1998 it is + * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set. ++ * (valid for GENESIS only) + */ +- } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE || +- (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); ++ } while (((XsCsr & CsrTest) != CsrIdle || ++ (XaCsr & CsrTest) != CsrIdle)); ++ ++ if (pAC->GIni.GIAsfEnabled) { + +- /* Reset the MAC depending on the RstMode */ +- if (RstMode == SK_SOFT_RST) { +- SkMacSoftRst(pAC, IoC, Port); ++ pPrt->PState = (RstMode == SK_SOFT_RST) ? SK_PRT_STOP : ++ SK_PRT_RESET; + } + else { +- SkMacHardRst(pAC, IoC, Port); ++ /* Reset the MAC depending on the RstMode */ ++ if (RstMode == SK_SOFT_RST) { ++ ++ SkMacSoftRst(pAC, IoC, Port); ++ } ++ else { ++#ifdef SK_DIAG ++ if (HW_FEATURE(pAC, HWF_WA_DEV_472) && Port == MAC_1 && ++ pAC->GIni.GP[MAC_2].PState == SK_PRT_RUN) { ++ ++ pAC->GIni.GP[MAC_1].PState = SK_PRT_RESET; ++ ++ /* set GPHY Control reset */ ++ SK_OUT8(IoC, MR_ADDR(MAC_1, GPHY_CTRL), (SK_U8)GPC_RST_SET); ++ } ++ else { ++ ++ SkMacHardRst(pAC, IoC, Port); ++ } ++#else /* !SK_DIAG */ ++ SkMacHardRst(pAC, IoC, Port); ++#endif /* !SK_DIAG */ ++ } + } +- +- /* Disable Force Sync bit and Enable Alloc bit */ ++ ++ /* disable Force Sync bit and Enable Alloc bit */ + SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), + TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); +- ++ + /* Stop Interval Timer and Limit Counter of Tx Arbiter */ + SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L); + SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L); + + /* Perform a local reset of the port's Tx path */ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ /* Reset the PCI FIFO of the async Tx queue */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), ++ BMU_RST_SET | BMU_FIFO_RST); ++ ++ /* Reset the PCI FIFO of the sync Tx queue */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), ++ BMU_RST_SET | BMU_FIFO_RST); ++ ++ /* Reset the Tx prefetch units */ ++ SK_OUT32(IoC, Y2_PREF_Q_ADDR(pPrt->PXaQOff, PREF_UNIT_CTRL_REG), ++ PREF_UNIT_RST_SET); ++ SK_OUT32(IoC, Y2_PREF_Q_ADDR(pPrt->PXsQOff, PREF_UNIT_CTRL_REG), ++ PREF_UNIT_RST_SET); ++ } ++ else { ++ /* Reset the PCI FIFO of the async Tx queue */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET); ++ /* Reset the PCI FIFO of the sync Tx queue */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET); ++ } + +- /* Reset the PCI FIFO of the async Tx queue */ +- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET); +- /* Reset the PCI FIFO of the sync Tx queue */ +- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET); + /* Reset the RAM Buffer async Tx queue */ + SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET); + /* Reset the RAM Buffer sync Tx queue */ + SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET); +- ++ + /* Reset Tx MAC FIFO */ + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +@@ -1243,74 +1662,131 @@ + SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { +- /* Reset TX MAC FIFO */ +- SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); ++ /* do the reset only if ASF is not enabled */ ++ if (!pAC->GIni.GIAsfEnabled) { ++ /* Reset Tx MAC FIFO */ ++ SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); ++ } ++ ++ /* set Pause Off */ ++ SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_PAUSE_OFF); + } + #endif /* YUKON */ + } + + if ((Dir & SK_STOP_RX) != 0) { +- /* +- * The RX Stop Command will not terminate if no buffers +- * are queued in the RxD ring. But it will always reach +- * the Idle state. Therefore we can use this feature to +- * stop the transfer of received packets. +- */ +- /* stop the port's receive queue */ +- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP); +- +- i = 100; +- do { ++ ++ if (CHIP_ID_YUKON_2(pAC)) { + /* +- * Clear packet arbiter timeout to make sure +- * this loop will terminate ++ * The RX Stop command will not work for Yukon-2 if the BMU does not ++ * reach the end of packet and since we can't make sure that we have ++ * incoming data, we must reset the BMU while it is not during a DMA ++ * transfer. Since it is possible that the RX path is still active, ++ * the RX RAM buffer will be stopped first, so any possible incoming ++ * data will not trigger a DMA. After the RAM buffer is stopped, the ++ * BMU is polled until any DMA in progress is ended and only then it ++ * will be reset. + */ +- SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? +- PA_CLR_TO_RX1 : PA_CLR_TO_RX2)); + +- DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff); ++ /* disable the RAM Buffer receive queue */ ++ SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_DIS_OP_MD); + +- /* timeout if i==0 (bug fix for #10748) */ +- if (--i == 0) { +- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024, +- SKERR_HWI_E024MSG); +- break; ++ i = 0xffff; ++ while (--i) { ++ SK_IN8(IoC, RB_ADDR(pPrt->PRxQOff, Q_RX_RSL), &rsl); ++ SK_IN8(IoC, RB_ADDR(pPrt->PRxQOff, Q_RX_RL), &rl); ++ ++ if (rsl == rl) { ++ break; ++ } + } ++ ++ /* ++ * If the Rx side is blocked, the above loop cannot terminate. ++ * But, if there was any traffic it should be terminated, now. ++ * However, stop the Rx BMU and the Prefetch Unit ! ++ */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), ++ BMU_RST_SET | BMU_FIFO_RST); ++ /* reset the Rx prefetch unit */ ++ SK_OUT32(IoC, Y2_PREF_Q_ADDR(pPrt->PRxQOff, PREF_UNIT_CTRL_REG), ++ PREF_UNIT_RST_SET); ++ } ++ else { + /* +- * because of the ASIC problem report entry from 21.08.98 +- * it is required to wait until CSR_STOP is reset and +- * CSR_SV_IDLE is set. ++ * The RX Stop Command will not terminate if no buffers ++ * are queued in the RxD ring. But it will always reach ++ * the Idle state. Therefore we can use this feature to ++ * stop the transfer of received packets. + */ +- } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); ++ /* stop the port's receive queue */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CsrStop); ++ ++ i = 100; ++ do { ++#ifdef GENESIS ++ if (pAC->GIni.GIGenesis) { ++ /* clear Rx packet arbiter timeout IRQ */ ++ SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? ++ PA_CLR_TO_RX1 : PA_CLR_TO_RX2)); ++ } ++#endif /* GENESIS */ ++ ++ RxCsr = TestStopBit(pAC, IoC, pPrt->PRxQOff); + +- /* The path data transfer activity is fully stopped now */ ++ /* timeout if i==0 (bug fix for #10748) */ ++ if (--i == 0) { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024, ++ SKERR_HWI_E024MSG); ++ break; ++ } ++ /* ++ * Because of the ASIC problem report entry from 21.08.1998 it is ++ * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set. ++ * (valid for GENESIS only) ++ */ ++ } while ((RxCsr & CsrTest) != CsrIdle); ++ /* The path data transfer activity is fully stopped now */ + +- /* Perform a local reset of the port's Rx path */ ++ /* Perform a local reset of the port's Rx path */ ++ /* Reset the PCI FIFO of the Rx queue */ ++ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET); ++ } + +- /* Reset the PCI FIFO of the Rx queue */ +- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET); + /* Reset the RAM Buffer receive queue */ + SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET); + +- /* Reset Rx MAC FIFO */ + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +- ++ /* Reset Rx MAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET); + + /* switch Rx LED off, stop the LED counter */ + SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON +- if (pAC->GIni.GIYukon) { ++ if (pAC->GIni.GIYukon && !pAC->GIni.GIAsfEnabled) { + /* Reset Rx MAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); + } ++ ++#ifndef NDIS_MINIPORT_DRIVER /* temp. ifndef, remove after PM module rework*/ ++ /* WA for Dev. #4.169 */ ++ if ((pAC->GIni.GIChipId == CHIP_ID_YUKON || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) && ++ RstMode == SK_HARD_RST) { ++ /* set Link Control reset */ ++ SK_OUT8(IoC, MR_ADDR(Port, GMAC_LINK_CTRL), (SK_U8)GMLC_RST_SET); ++ ++ /* clear Link Control reset */ ++ SK_OUT8(IoC, MR_ADDR(Port, GMAC_LINK_CTRL), (SK_U8)GMLC_RST_CLR); ++ } ++#endif /* !NDIS_MINIPORT */ + #endif /* YUKON */ + } + } /* SkGeStopPort */ +@@ -1327,8 +1803,8 @@ + * nothing + */ + static void SkGeInit0( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC) /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ + { + int i; + SK_GEPORT *pPrt; +@@ -1337,6 +1813,7 @@ + pPrt = &pAC->GIni.GP[i]; + + pPrt->PState = SK_PRT_RESET; ++ pPrt->PPortUsage = SK_RED_LINK; + pPrt->PRxQOff = QOffTab[i].RxQOff; + pPrt->PXsQOff = QOffTab[i].XsQOff; + pPrt->PXaQOff = QOffTab[i].XaQOff; +@@ -1363,24 +1840,250 @@ + pPrt->PMSMode = (SK_U8)SK_MS_MODE_AUTO; + pPrt->PMSStatus = (SK_U8)SK_MS_STAT_UNSET; + pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN; ++ pPrt->PEnDetMode = SK_FALSE; + pPrt->PAutoNegFail = SK_FALSE; + pPrt->PHWLinkUp = SK_FALSE; +- pPrt->PLinkBroken = SK_TRUE; /* See WA code */ ++ pPrt->PLinkBroken = SK_TRUE; /* See WA code */ + pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE; + pPrt->PMacColThres = TX_COL_DEF; + pPrt->PMacJamLen = TX_JAM_LEN_DEF; +- pPrt->PMacJamIpgVal = TX_JAM_IPG_DEF; ++ pPrt->PMacJamIpgVal = TX_JAM_IPG_DEF; + pPrt->PMacJamIpgData = TX_IPG_JAM_DEF; ++ pPrt->PMacBackOffLim = TX_BOF_LIM_DEF; ++ pPrt->PMacDataBlind = DATA_BLIND_DEF; + pPrt->PMacIpgData = IPG_DATA_DEF; + pPrt->PMacLimit4 = SK_FALSE; + } + +- pAC->GIni.GIPortUsage = SK_RED_LINK; + pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value; +- pAC->GIni.GIValIrqMask = IS_ALL_MSK; ++ pAC->GIni.GIChipCap = 0; ++ pAC->GIni.GIExtLeFormat = SK_FALSE; ++ pAC->GIni.GIJumTcpSegSup = SK_FALSE; ++ pAC->GIni.GIGotoD3Cold = SK_FALSE; ++ pAC->GIni.GIVMainAvail = SK_TRUE; ++ ++ for (i = 0; i < 4; i++) { ++ pAC->GIni.HwF.Features[i]= 0x00000000; ++ pAC->GIni.HwF.OnMask[i] = 0x00000000; ++ pAC->GIni.HwF.OffMask[i] = 0x00000000; ++ } + + } /* SkGeInit0*/ + ++#ifdef SK_PCI_RESET ++/****************************************************************************** ++ * ++ * SkGePciReset() - Reset PCI interface ++ * ++ * Description: ++ * o Read PCI configuration. ++ * o Change power state to 3. ++ * o Change power state to 0. ++ * o Restore PCI configuration. ++ * ++ * Returns: ++ * 0: Success. ++ * 1: Power state could not be changed to 3. ++ */ ++static int SkGePciReset( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ ++{ ++ int i; ++ SK_U16 PmCtlSts; ++ SK_U32 Bp1; ++ SK_U32 Bp2; ++ SK_U16 PciCmd; ++ SK_U8 Cls; ++ SK_U8 Lat; ++ SK_U8 ConfigSpace[PCI_CFG_SIZE]; ++ ++ /* ++ * Note: Switching to D3 state is like a software reset. ++ * Switching from D3 to D0 is a hardware reset. ++ * We have to save and restore the configuration space. ++ */ ++ for (i = 0; i < PCI_CFG_SIZE; i++) { ++ SkPciReadCfgDWord(pAC, i*4, &ConfigSpace[i]); ++ } ++ ++ /* We know the RAM Interface Arbiter is enabled. */ ++ SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3); ++ ++ SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); ++ ++ if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) { ++ return(1); ++ } ++ ++ /* Return to D0 state. */ ++ SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D0); ++ ++ /* Check for D0 state. */ ++ SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); ++ ++ if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) { ++ return(1); ++ } ++ ++ /* Check PCI Config Registers. */ ++ SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd); ++ SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls); ++ SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1); ++ ++ /* ++ * Compute the location in PCI config space of BAR2 ++ * relativ to the location of BAR1 ++ */ ++ if ((Bp1 & PCI_MEM_TYP_MSK) == PCI_MEM64BIT) { ++ /* BAR1 is 64 bits wide */ ++ i = 8; ++ } ++ else { ++ i = 4; ++ } ++ ++ SkPciReadCfgDWord(pAC, PCI_BASE_1ST + i, &Bp2); ++ SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat); ++ ++ if (PciCmd != 0 || Cls != 0 || (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1 || ++ Lat != 0) { ++ return(1); ++ } ++ ++ /* Restore PCI Config Space. */ ++ for (i = 0; i < PCI_CFG_SIZE; i++) { ++ SkPciWriteCfgDWord(pAC, i*4, ConfigSpace[i]); ++ } ++ ++ return(0); ++} /* SkGePciReset */ ++#endif /* SK_PCI_RESET */ ++ ++ ++#ifndef SK_SLIM ++/****************************************************************************** ++ * ++ * SkGeSetUpSupFeatures() - Collect Feature List for HW_FEATURE Macro ++ * ++ * Description: ++ * This function collects the available features and required ++ * deviation services of the Adapter and provides these ++ * information in the GIHwF struct. This information is used as ++ * default value and may be overritten by the driver using the ++ * SET_HW_FEATURE_MASK() macro in its Init0 phase. ++ * ++ * Notice: ++ * Using the On and Off mask: Never switch on the same bit in both ++ * masks simultaneously. However, if doing the Off mask will win. ++ * ++ * Returns: ++ * nothing ++ */ ++static void SkGeSetUpSupFeatures( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ ++{ ++ int i; ++ SK_U16 Word; ++ ++ switch (pAC->GIni.GIChipId) { ++ case CHIP_ID_YUKON_EC: ++ pAC->GIni.GIJumTcpSegSup = SK_TRUE; ++ ++ if (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_A1) { ++ /* A0/A1 */ ++ pAC->GIni.HwF.Features[HW_DEV_LIST] = ++ HWF_WA_DEV_42 | HWF_WA_DEV_46 | HWF_WA_DEV_43_418 | ++ HWF_WA_DEV_420 | HWF_WA_DEV_423 | HWF_WA_DEV_424 | ++ HWF_WA_DEV_425 | HWF_WA_DEV_427 | HWF_WA_DEV_428 | ++ HWF_WA_DEV_483 | HWF_WA_DEV_4109 | ++ HWF_WA_DEV_4152 | HWF_WA_DEV_4167; ++ } ++ else { ++ /* A2/A3 */ ++ pAC->GIni.HwF.Features[HW_DEV_LIST] = ++ HWF_WA_DEV_424 | HWF_WA_DEV_425 | HWF_WA_DEV_427 | ++ HWF_WA_DEV_428 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 | ++ HWF_WA_DEV_4152 | HWF_WA_DEV_4167; ++ } ++ break; ++ case CHIP_ID_YUKON_FE: ++ pAC->GIni.HwF.Features[HW_DEV_LIST] = ++ HWF_WA_DEV_427 | HWF_WA_DEV_4109 | ++ HWF_WA_DEV_4152 | HWF_WA_DEV_4167; ++ break; ++ case CHIP_ID_YUKON_XL: ++ pAC->GIni.GIJumTcpSegSup = SK_TRUE; ++ ++ switch (pAC->GIni.GIChipRev) { ++ case CHIP_REV_YU_XL_A0: /* still needed for Diag */ ++ pAC->GIni.HwF.Features[HW_DEV_LIST] = ++ HWF_WA_DEV_427 | HWF_WA_DEV_463 | HWF_WA_DEV_472 | ++ HWF_WA_DEV_479 | HWF_WA_DEV_483 | HWF_WA_DEV_4115 | ++ HWF_WA_DEV_4152 | HWF_WA_DEV_4167; ++ break; ++ ++ case CHIP_REV_YU_XL_A1: ++ pAC->GIni.HwF.Features[HW_DEV_LIST] = ++ HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 | ++ HWF_WA_DEV_4115 | HWF_WA_DEV_4152 | HWF_WA_DEV_4167; ++ break; ++ ++ case CHIP_REV_YU_XL_A2: ++ pAC->GIni.HwF.Features[HW_DEV_LIST] = ++ HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 | ++ HWF_WA_DEV_4115 | HWF_WA_DEV_4167; ++ break; ++ ++ case CHIP_REV_YU_XL_A3: ++ pAC->GIni.HwF.Features[HW_DEV_LIST] = ++ HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 | ++ HWF_WA_DEV_4115; ++ break; ++ } ++ break; ++ case CHIP_ID_YUKON_EC_U: ++ if (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_A0) { ++ pAC->GIni.HwF.Features[HW_DEV_LIST] = ++ HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 | ++ HWF_WA_DEV_4217; ++ } ++ else if (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_A1) { ++ pAC->GIni.HwF.Features[HW_DEV_LIST] = ++ HWF_WA_DEV_427 | HWF_WA_DEV_4109 | HWF_WA_DEV_4185 | ++ HWF_WA_DEV_4217; ++ ++ /* check for Rev. A1 */ ++ SK_IN16(IoC, Q_ADDR(Q_XA1, Q_WM), &Word); ++ ++ if (Word == 0) { ++ pAC->GIni.HwF.Features[HW_DEV_LIST] |= ++ HWF_WA_DEV_4185CS | HWF_WA_DEV_4200; ++ } ++ } ++ else if (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_B0) { ++ pAC->GIni.HwF.Features[HW_DEV_LIST] = ++ HWF_WA_DEV_427 | HWF_WA_DEV_4109 | HWF_WA_DEV_4185 | ++ HWF_WA_DEV_4217; ++ } ++ break; ++ case CHIP_ID_YUKON_EX: ++ if (pAC->GIni.GIChipRev == CHIP_REV_YU_EX_A0) { ++ pAC->GIni.HwF.Features[HW_DEV_LIST] = ++ HWF_WA_DEV_4217 | HWF_WA_DEV_LIM_IPV6_RSS | HWF_WA_DEV_53; ++ } ++ break; ++ } ++ ++ for (i = 0; i < 4; i++) { ++ pAC->GIni.HwF.Features[i] = ++ (pAC->GIni.HwF.Features[i] | pAC->GIni.HwF.OnMask[i]) & ++ ~pAC->GIni.HwF.OffMask[i]; ++ } ++} /* SkGeSetUpSupFeatures */ ++#endif /* !SK_SLIM */ ++ + + /****************************************************************************** + * +@@ -1404,76 +2107,286 @@ + * 6: HW self test failed + */ + static int SkGeInit1( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC) /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ + { + SK_U8 Byte; + SK_U16 Word; +- SK_U16 CtrlStat; ++ SK_U32 CtrlStat; ++ SK_U32 VauxAvail; + SK_U32 DWord; ++ SK_U32 Our1; ++ SK_U32 PowerDownBit; ++ SK_BOOL FiberType; ++ SK_GEPORT *pPrt; ++ int LedCfg; + int RetVal; +- int i; ++ int i, j; + + RetVal = 0; + +- /* save CLK_RUN bits (YUKON-Lite) */ +- SK_IN16(IoC, B0_CTST, &CtrlStat); ++#ifdef SK_SLIM ++ SkPciWriteCfgDWord(IoC, PCI_OUR_REG_3, 0x00000000); ++#else /* !SK_SLIM */ ++ /* read Chip Identification Number */ ++ SK_IN8(IoC, B2_CHIP_ID, &Byte); ++ pAC->GIni.GIChipId = Byte; + +- /* do the SW-reset */ +- SK_OUT8(IoC, B0_CTST, CS_RST_SET); ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EX || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) { ++ /* Enable all clocks: otherwise the device will hang */ ++ /* Do not use PCI_C here */ ++ SK_OUT32(IoC, (Y2_CFG_SPC + PCI_OUR_REG_3), 0x00000000); ++ } ++#endif /* !SK_SLIM */ ++ ++ /* save CLK_RUN & ASF_ENABLE bits (YUKON-Lite, YUKON-EC) */ ++ SK_IN32(IoC, B0_CTST, &CtrlStat); ++ ++#ifdef SK_PCI_RESET ++ (void)SkGePciReset(pAC, IoC); ++#endif /* SK_PCI_RESET */ + + /* release the SW-reset */ ++ /* Important: SW-reset has to be cleared here, to ensure ++ * the CHIP_ID can be read I/O-mapped based, too - ++ * remember the RAP register can only be written if SW-reset is cleared. ++ */ + SK_OUT8(IoC, B0_CTST, CS_RST_CLR); + ++ /* read Chip Identification Number; needed in case of SK_SLIM */ ++ SK_IN8(IoC, B2_CHIP_ID, &Byte); ++ pAC->GIni.GIChipId = Byte; ++ pAC->GIni.GIAsfEnabled = SK_FALSE; ++ ++ /* ASF support only for Yukon-2 */ ++ if ((pAC->GIni.GIChipId >= CHIP_ID_YUKON_XL) && ++ (pAC->GIni.GIChipId <= CHIP_ID_YUKON_EC)) { ++#ifdef SK_ASF ++ if ((CtrlStat & Y2_ASF_ENABLE) != 0) { ++ /* do the SW-reset only if ASF is not enabled */ ++ pAC->GIni.GIAsfEnabled = SK_TRUE; ++ } ++#else /* !SK_ASF */ ++ ++ /* put ASF system in reset state */ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EX) { ++ /* Do not touch bit 5..3 */ ++ SK_IN16(IoC, HCU_CCSR, &Word); ++ ++ pAC->GIni.GIAsfRunning = ++ ((Word & HCU_CCSR_UC_STATE_MSK) == HCU_CCSR_ASF_RUNNING); ++ ++ Word &= ~(HCU_CCSR_AHB_RST | HCU_CCSR_CPU_RST_MODE | ++ HCU_CCSR_UC_STATE_MSK); ++ ++ SK_OUT16(IoC, HCU_CCSR, Word); ++ } ++ else { /* Yukon-EC / Yukon-2 */ ++ SK_IN8(IoC, B28_Y2_ASF_STAT_CMD, &Byte); ++ ++ pAC->GIni.GIAsfRunning = Byte & Y2_ASF_RUNNING; ++ ++ SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, (SK_U8)Y2_ASF_RESET); ++ } ++ ++ /* disable ASF Unit */ ++ SK_OUT16(IoC, B0_CTST, Y2_ASF_DISABLE); ++#endif /* !SK_ASF */ ++ } ++ ++ if (!pAC->GIni.GIAsfEnabled) { ++ /* Yukon-2: required for Diag and Power Management */ ++ /* set the SW-reset */ ++ SK_OUT8(IoC, B0_CTST, CS_RST_SET); ++ ++ /* release the SW-reset */ ++ SK_OUT8(IoC, B0_CTST, CS_RST_CLR); ++ } ++ ++ /* enable Config Write */ ++ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); ++ + /* reset all error bits in the PCI STATUS register */ + /* + * Note: PCI Cfg cycles cannot be used, because they are not + * available on some platforms after 'boot time'. + */ +- SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); +- +- SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); +- SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); +- SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); ++ SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word); ++ ++ SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), Word | (SK_U16)PCI_ERRBITS); + + /* release Master Reset */ + SK_OUT8(IoC, B0_CTST, CS_MRST_CLR); + + #ifdef CLK_RUN + CtrlStat |= CS_CLK_RUN_ENA; +-#endif /* CLK_RUN */ + + /* restore CLK_RUN bits */ + SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat & + (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA))); ++#endif /* CLK_RUN */ ++ ++ if ((pAC->GIni.GIChipId >= CHIP_ID_YUKON_XL) && ++ (pAC->GIni.GIChipId <= CHIP_ID_YUKON_FE)) { ++ ++ pAC->GIni.GIYukon2 = SK_TRUE; ++ pAC->GIni.GIValIrqMask = Y2_IS_ALL_MSK; ++ pAC->GIni.GIValHwIrqMask = Y2_HWE_ALL_MSK; ++ ++ VauxAvail = Y2_VAUX_AVAIL; ++ ++ /* check if VMAIN is available */ ++ if ((CtrlStat & Y2_VMAIN_AVAIL) == 0) { ++ pAC->GIni.GIVMainAvail = SK_FALSE; ++ } ++ ++ SK_IN32(IoC, PCI_C(pAC, PCI_OUR_STATUS), &DWord); ++ ++ if ((DWord & PCI_OS_PCI_X) != 0) { ++#ifndef SK_SLIM ++ /* this is a PCI / PCI-X bus */ ++ if ((DWord & PCI_OS_PCIX) != 0) { ++ /* this is a PCI-X bus */ ++ pAC->GIni.GIPciBus = SK_PCIX_BUS; ++ ++ /* PCI-X is always 64-bit wide */ ++ pAC->GIni.GIPciSlot64 = SK_TRUE; ++ ++ pAC->GIni.GIPciMode = (SK_U8)(PCI_OS_SPEED(DWord)); ++ } ++ else { ++ /* this is a conventional PCI bus */ ++ pAC->GIni.GIPciBus = SK_PCI_BUS; ++ ++ SK_IN16(IoC, PCI_C(pAC, PCI_OUR_REG_2), &Word); ++ ++ /* check if 64-bit width is used */ ++ pAC->GIni.GIPciSlot64 = (SK_BOOL) ++ (((DWord & PCI_OS_PCI64B) != 0) && ++ ((Word & PCI_USEDATA64) != 0)); ++ ++ /* check if 66 MHz PCI Clock is active */ ++ pAC->GIni.GIPciClock66 = (SK_BOOL)((DWord & PCI_OS_PCI66M) != 0); ++ } ++#endif /* !SK_SLIM */ ++ } ++ else { ++ /* this is a PEX bus */ ++ pAC->GIni.GIPciBus = SK_PEX_BUS; ++ ++ /* clear any PEX errors */ ++ SK_OUT32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), 0xffffffffUL); ++ ++ SK_IN32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), &DWord); ++ ++ if ((DWord & PEX_RX_OV) != 0) { ++ /* Dev #4.205 occured */ ++ pAC->GIni.GIValHwIrqMask &= ~Y2_IS_PCI_EXP; ++ pAC->GIni.GIValIrqMask &= ~Y2_IS_HW_ERR; ++ } ++ ++ SK_IN16(IoC, PCI_C(pAC, PEX_LNK_STAT), &Word); ++ ++ pAC->GIni.GIPexWidth = (SK_U8)((Word & PEX_LS_LINK_WI_MSK) >> 4); ++ } ++ /* ++ * Yukon-2 chips family has a different way of providing ++ * the number of MACs available ++ */ ++ pAC->GIni.GIMacsFound = 1; ++ ++ /* get HW Resources */ ++ SK_IN8(IoC, B2_Y2_HW_RES, &Byte); ++ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ /* ++ * OEM config value is overwritten and should not ++ * be used for Yukon-2 ++ */ ++ pAC->GIni.GILedBlinkCtrl |= SK_ACT_LED_BLINK; ++ ++#ifndef SK_SLIM ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_EX) { ++ /* LED Configuration is stored in GPIO */ ++ SK_IN8(IoC, B2_GP_IO, &Byte); ++ } ++#endif /* !SK_SLIM */ ++ ++ if ((LedCfg = CFG_LED_MODE(Byte)) == CFG_LED_DUAL_ACT_LNK) { ++ ++ pAC->GIni.GILedBlinkCtrl |= SK_DUAL_LED_ACT_LNK; ++ } ++ else if (LedCfg == CFG_LED_LINK_MUX_P60) { ++ /* LED pin 60 used differently */ ++ pAC->GIni.GILedBlinkCtrl |= SK_LED_LINK_MUX_P60; ++ } ++ } ++ ++ /* save HW Resources / Application Information */ ++ pAC->GIni.GIHwResInfo = Byte; ++ ++ if ((Byte & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) { ++ ++ SK_IN8(IoC, B2_Y2_CLK_GATE, &Byte); ++ ++ if (!(Byte & Y2_STATUS_LNK2_INAC)) { ++ /* Link 2 activ */ ++ pAC->GIni.GIMacsFound++; ++ } ++ } ++ ++#ifdef VCPU ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) { ++ /* temporary WA for reported number of links */ ++ pAC->GIni.GIMacsFound = 2; ++ } ++#endif /* VCPU */ ++ ++ /* read Chip Revision */ ++ SK_IN8(IoC, B2_MAC_CFG, &Byte); ++ ++ pAC->GIni.GIChipCap = Byte & 0x0f; ++ } ++ else { ++ pAC->GIni.GIYukon2 = SK_FALSE; ++ pAC->GIni.GIValIrqMask = IS_ALL_MSK; ++ pAC->GIni.GIValHwIrqMask = 0; /* not activated */ ++ ++ VauxAvail = CS_VAUX_AVAIL; ++ ++ /* read number of MACs and Chip Revision */ ++ SK_IN8(IoC, B2_MAC_CFG, &Byte); ++ ++ pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2; ++ } + +- /* read Chip Identification Number */ +- SK_IN8(IoC, B2_CHIP_ID, &Byte); +- pAC->GIni.GIChipId = Byte; +- +- /* read number of MACs */ +- SK_IN8(IoC, B2_MAC_CFG, &Byte); +- pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2; +- + /* get Chip Revision Number */ + pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4); + +- /* get diff. PCI parameters */ +- SK_IN16(IoC, B0_CTST, &CtrlStat); +- ++#ifndef SK_DIAG ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL && ++ pAC->GIni.GIChipRev == CHIP_REV_YU_XL_A0) { ++ /* Yukon-2 Chip Rev. A0 */ ++ return(6); ++ } ++#endif /* !SK_DIAG */ ++ + /* read the adapters RAM size */ + SK_IN8(IoC, B2_E_0, &Byte); +- ++ + pAC->GIni.GIGenesis = SK_FALSE; + pAC->GIni.GIYukon = SK_FALSE; + pAC->GIni.GIYukonLite = SK_FALSE; ++ pAC->GIni.GIVauxAvail = SK_FALSE; + + #ifdef GENESIS + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + + pAC->GIni.GIGenesis = SK_TRUE; + +- if (Byte == (SK_U8)3) { ++ if (Byte == (SK_U8)3) { + /* special case: 4 x 64k x 36, offset = 0x80000 */ + pAC->GIni.GIRamSize = 1024; + pAC->GIni.GIRamOffs = (SK_U32)512 * 1024; +@@ -1482,196 +2395,382 @@ + pAC->GIni.GIRamSize = (int)Byte * 512; + pAC->GIni.GIRamOffs = 0; + } +- /* all GE adapters work with 53.125 MHz host clock */ ++ /* all GENESIS adapters work with 53.125 MHz host clock */ + pAC->GIni.GIHstClkFact = SK_FACT_53; +- ++ + /* set Descr. Poll Timer Init Value to 250 ms */ + pAC->GIni.GIPollTimerVal = + SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100; + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) { +- ++ + pAC->GIni.GIYukon = SK_TRUE; +- ++ + pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4; +- ++ ++#ifndef SK_SLIM + pAC->GIni.GIRamOffs = 0; +- +- /* WA for chip Rev. A */ ++ ++ /* WA for Yukon chip Rev. A0 */ + pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON && + pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0; +- ++ + /* get PM Capabilities of PCI config space */ +- SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word); ++ SK_IN16(IoC, PCI_C(pAC, PCI_PM_CAP_REG), &Word); + + /* check if VAUX is available */ +- if (((CtrlStat & CS_VAUX_AVAIL) != 0) && ++ if (((CtrlStat & VauxAvail) != 0) && + /* check also if PME from D3cold is set */ + ((Word & PCI_PME_D3C_SUP) != 0)) { + /* set entry in GE init struct */ + pAC->GIni.GIVauxAvail = SK_TRUE; + } +- +- if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) { +- /* this is Rev. A1 */ +- pAC->GIni.GIYukonLite = SK_TRUE; ++#endif /* !SK_SLIM */ ++ ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) { ++ /* this is Rev. A1 */ ++ pAC->GIni.GIYukonLite = SK_TRUE; ++ } ++#ifndef SK_SLIM ++ else { ++ /* save Flash-Address Register */ ++ SK_IN32(IoC, B2_FAR, &DWord); ++ ++ /* test Flash-Address Register */ ++ SK_OUT8(IoC, B2_FAR + 3, 0xff); ++ SK_IN8(IoC, B2_FAR + 3, &Byte); ++ ++ if (Byte != 0) { ++ /* this is Rev. A0 */ ++ pAC->GIni.GIYukonLite = SK_TRUE; ++ ++ /* restore Flash-Address Register */ ++ SK_OUT32(IoC, B2_FAR, DWord); ++ } ++ } ++#endif /* !SK_SLIM */ + } + else { +- /* save Flash-Address Register */ +- SK_IN32(IoC, B2_FAR, &DWord); ++ /* Check for CLS = 0 (dev. #4.55) */ ++ if (pAC->GIni.GIPciBus != SK_PEX_BUS) { ++ /* PCI and PCI-X */ ++ SK_IN8(IoC, PCI_C(pAC, PCI_CACHE_LSZ), &Byte); ++ ++ if (Byte == 0) { ++ /* set CLS to 2 if configured to 0 */ ++ SK_OUT8(IoC, PCI_C(pAC, PCI_CACHE_LSZ), 2); ++ } ++ ++ if (pAC->GIni.GIPciBus == SK_PCIX_BUS) { ++ /* set Cache Line Size opt. */ ++ SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord); ++ DWord |= PCI_CLS_OPT; ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord); ++ } ++ } ++ } + +- /* test Flash-Address Register */ +- SK_OUT8(IoC, B2_FAR + 3, 0xff); +- SK_IN8(IoC, B2_FAR + 3, &Byte); ++ /* GeCommon also used in ASF firmware: VMain may not be available */ ++ if (pAC->GIni.GIVMainAvail) { ++ /* switch power to VCC (WA for VAUX problem) */ ++ SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | ++ PC_VAUX_OFF | PC_VCC_ON)); ++ } ++ ++ Byte = 0; ++ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ switch (pAC->GIni.GIChipId) { ++ /* PEX adapters work with different host clock */ ++ case CHIP_ID_YUKON_EC: ++ case CHIP_ID_YUKON_EC_U: ++ case CHIP_ID_YUKON_EX: /* to be checked */ ++ /* Yukon-EC works with 125 MHz host clock */ ++ pAC->GIni.GIHstClkFact = SK_FACT_125; ++ break; ++ case CHIP_ID_YUKON_FE: ++ /* Yukon-FE works with 100 MHz host clock */ ++ pAC->GIni.GIHstClkFact = SK_FACT_100; ++ break; ++ case CHIP_ID_YUKON_XL: ++ /* all Yukon-2 adapters work with 156 MHz host clock */ ++ pAC->GIni.GIHstClkFact = 2 * SK_FACT_78; ++ ++ if (pAC->GIni.GIChipRev > CHIP_REV_YU_XL_A1) { ++ /* enable bits are inverted */ ++ Byte = (SK_U8)(Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | ++ Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS | ++ Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS); ++ } ++ break; ++ default: ++ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E006, ++ SKERR_HWI_E006MSG); ++ } + +- if (Byte != 0) { +- /* this is Rev. A0 */ +- pAC->GIni.GIYukonLite = SK_TRUE; ++ pAC->GIni.GIPollTimerVal = ++ SK_DPOLL_DEF_Y2 * (SK_U32)pAC->GIni.GIHstClkFact / 100; + +- /* restore Flash-Address Register */ +- SK_OUT32(IoC, B2_FAR, DWord); ++ /* set power down bit */ ++ PowerDownBit = PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD; ++ ++ /* disable Core Clock Division, set Clock Select to 0 (Yukon-2) */ ++ SK_OUT32(IoC, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS); ++ ++ /* enable MAC/PHY, PCI and Core Clock for both Links */ ++ SK_OUT8(IoC, B2_Y2_CLK_GATE, Byte); ++ } ++ else { ++ /* YUKON adapters work with 78 MHz host clock */ ++ pAC->GIni.GIHstClkFact = SK_FACT_78; ++ ++ pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */ ++ ++ /* read the Interrupt source */ ++ SK_IN32(IoC, B0_ISRC, &DWord); ++ ++ if ((DWord & IS_HW_ERR) != 0) { ++ /* read the HW Error Interrupt source */ ++ SK_IN32(IoC, B0_HWE_ISRC, &DWord); ++ ++ if ((DWord & IS_IRQ_SENSOR) != 0) { ++ /* disable HW Error IRQ */ ++ pAC->GIni.GIValIrqMask &= ~IS_HW_ERR; ++ } ++ } ++ /* set power down bit */ ++ PowerDownBit = PCI_PHY_COMA; ++ } ++ ++ SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &Our1); ++ ++ Our1 &= ~PowerDownBit; ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL && ++ pAC->GIni.GIChipRev > CHIP_REV_YU_XL_A1) { ++ /* deassert Low Power for 1st PHY */ ++ Our1 |= PCI_Y2_PHY1_COMA; ++ ++ if (pAC->GIni.GIMacsFound > 1) { ++ /* deassert Low Power for 2nd PHY */ ++ Our1 |= PCI_Y2_PHY2_COMA; + } + } ++ else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_EX) { ++ /* enable HW WOL */ ++ SK_OUT16(IoC, B0_CTST, (SK_U16)Y2_HW_WOL_ON); ++ ++ /* enable all clocks; OUR_REG_3 is set at the top of the function */ ++ SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_4), &DWord); ++ ++ DWord &= P_ASPM_CONTROL_MSK; ++ /* set all bits to 0 except bits 15..12 */ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_4), DWord); ++ ++ /* set to default value */ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5), 0); ++ } ++ ++ /* release PHY from PowerDown/COMA Mode */ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), Our1); + +- /* switch power to VCC (WA for VAUX problem) */ +- SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | +- PC_VAUX_OFF | PC_VCC_ON)); ++ if (!pAC->GIni.GIAsfEnabled) { + +- /* read the Interrupt source */ +- SK_IN32(IoC, B0_ISRC, &DWord); +- +- if ((DWord & IS_HW_ERR) != 0) { +- /* read the HW Error Interrupt source */ +- SK_IN32(IoC, B0_HWE_ISRC, &DWord); +- +- if ((DWord & IS_IRQ_SENSOR) != 0) { +- /* disable HW Error IRQ */ +- pAC->GIni.GIValIrqMask &= ~IS_HW_ERR; +- } +- } +- +- for (i = 0; i < pAC->GIni.GIMacsFound; i++) { +- /* set GMAC Link Control reset */ +- SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET); ++ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { ++ /* set Link Control reset */ ++ SK_OUT8(IoC, MR_ADDR(i, GMAC_LINK_CTRL), (SK_U8)GMLC_RST_SET); + +- /* clear GMAC Link Control reset */ +- SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR); ++ /* clear Link Control reset */ ++ SK_OUT8(IoC, MR_ADDR(i, GMAC_LINK_CTRL), (SK_U8)GMLC_RST_CLR); ++ } + } +- /* all YU chips work with 78.125 MHz host clock */ +- pAC->GIni.GIHstClkFact = SK_FACT_78; +- +- pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */ + } + #endif /* YUKON */ + +- /* check if 64-bit PCI Slot is present */ +- pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0); +- +- /* check if 66 MHz PCI Clock is active */ +- pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0); ++ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); ++ ++#ifndef SK_SLIM ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ /* this is a conventional PCI bus */ ++ pAC->GIni.GIPciBus = SK_PCI_BUS; ++ ++ /* check if 64-bit PCI Slot is present */ ++ pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0); ++ ++ /* check if 66 MHz PCI Clock is active */ ++ pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0); ++ } + + /* read PCI HW Revision Id. */ +- SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte); ++ SK_IN8(IoC, PCI_C(pAC, PCI_REV_ID), &Byte); + pAC->GIni.GIPciHwRev = Byte; + ++ /* read connector type */ ++ SK_IN8(IoC, B2_CONN_TYP, &pAC->GIni.GIConTyp); ++#endif /* !SK_SLIM */ ++ + /* read the PMD type */ + SK_IN8(IoC, B2_PMD_TYP, &Byte); +- pAC->GIni.GICopperType = (SK_U8)(Byte == 'T'); + +- /* read the PHY type */ ++ pAC->GIni.GIPmdTyp = Byte; ++ ++ FiberType = (Byte == 'L' || Byte == 'S' || Byte == 'P'); ++ ++ pAC->GIni.GICopperType = (SK_BOOL)(Byte == 'T' || Byte == '1' || ++ (pAC->GIni.GIYukon2 && !FiberType)); ++ ++ /* read the PHY type (Yukon and Genesis) */ + SK_IN8(IoC, B2_E_1, &Byte); + + Byte &= 0x0f; /* the PHY type is stored in the lower nibble */ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { +- ++ ++ pPrt = &pAC->GIni.GP[i]; ++ ++ /* get the MAC addresses */ ++ for (j = 0; j < 3; j++) { ++ SK_IN16(IoC, B2_MAC_1 + i * 8 + j * 2, &pPrt->PMacAddr[j]); ++ } ++ + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { + switch (Byte) { + case SK_PHY_XMAC: +- pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC; ++ pPrt->PhyAddr = PHY_ADDR_XMAC; + break; + case SK_PHY_BCOM: +- pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM; +- pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO | ++ pPrt->PhyAddr = PHY_ADDR_BCOM; ++ pPrt->PMSCap = (SK_U8)(SK_MS_CAP_AUTO | + SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE); + break; + #ifdef OTHER_PHY + case SK_PHY_LONE: +- pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE; ++ pPrt->PhyAddr = PHY_ADDR_LONE; + break; + case SK_PHY_NAT: +- pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT; ++ pPrt->PhyAddr = PHY_ADDR_NAT; + break; + #endif /* OTHER_PHY */ + default: + /* ERROR: unexpected PHY type detected */ + RetVal = 5; +- break; + } + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { +- +- if (Byte < (SK_U8)SK_PHY_MARV_COPPER) { ++ ++ if (((Byte < (SK_U8)SK_PHY_MARV_COPPER) || pAC->GIni.GIYukon2) && ++ !FiberType) { + /* if this field is not initialized */ + Byte = (SK_U8)SK_PHY_MARV_COPPER; +- ++ + pAC->GIni.GICopperType = SK_TRUE; + } +- +- pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV; +- ++ ++ pPrt->PhyAddr = PHY_ADDR_MARV; ++ + if (pAC->GIni.GICopperType) { + +- pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO | +- SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS | +- SK_LSPEED_CAP_1000MBPS); +- +- pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO; +- +- pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO | ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE || ++ (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC && ++ pAC->GIni.GIChipCap == 2)) { ++ ++ pPrt->PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_100MBPS | ++ SK_LSPEED_CAP_10MBPS); ++ ++ pAC->GIni.GIRamSize = 4; ++ } ++ else { ++ pPrt->PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_1000MBPS | ++ SK_LSPEED_CAP_100MBPS | SK_LSPEED_CAP_10MBPS | ++ SK_LSPEED_CAP_AUTO); ++ } ++ ++ pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_AUTO; ++ ++ pPrt->PMSCap = (SK_U8)(SK_MS_CAP_AUTO | + SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE); + } + else { + Byte = (SK_U8)SK_PHY_MARV_FIBER; + } + } ++ ++ /* clear TWSI IRQ */ ++ SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); ++ + #endif /* YUKON */ +- +- pAC->GIni.GP[i].PhyType = (int)Byte; +- ++ ++ pPrt->PhyType = (int)Byte; ++ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, +- ("PHY type: %d PHY addr: %04x\n", Byte, +- pAC->GIni.GP[i].PhyAddr)); ++ ("PHY type: %d PHY addr: %04x\n", ++ Byte, pPrt->PhyAddr)); + } +- ++ + /* get MAC Type & set function pointers dependent on */ + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +- ++ ++ pAC->GIni.GINumOfPattern = 0; + pAC->GIni.GIMacType = SK_MAC_XMAC; + + pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats; + pAC->GIni.GIFunc.pFnMacStatistic = SkXmMacStatistic; + pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter; + pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus; ++#ifdef SK_DIAG ++ pAC->GIni.GIFunc.pFnMacPhyRead = SkXmPhyRead; ++ pAC->GIni.GIFunc.pFnMacPhyWrite = SkXmPhyWrite; ++#else /* SK_DIAG */ ++ pAC->GIni.GIFunc.pSkGeSirqIsr = SkGeYuSirqIsr; ++#endif /* !SK_DIAG */ + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { +- ++ ++ pAC->GIni.GINumOfPattern = 7; ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EX) { ++ ++ pAC->GIni.GIExtLeFormat = SK_TRUE; ++ pAC->GIni.GINumOfPattern += 2; ++ ++ /* Bypass MACSec unit */ ++ SK_OUT32(IoC, MAC_CTRL, MAC_CTRL_BYP_MACSECRX_ON | ++ MAC_CTRL_BYP_MACSECTX_ON | MAC_CTRL_BYP_RETR_ON); ++ } ++ ++#ifndef SK_SLIM + pAC->GIni.GIMacType = SK_MAC_GMAC; + + pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats; + pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic; + pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter; + pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus; ++#endif /* !SK_SLIM */ ++ ++#ifdef SK_DIAG ++ pAC->GIni.GIFunc.pFnMacPhyRead = SkGmPhyRead; ++ pAC->GIni.GIFunc.pFnMacPhyWrite = SkGmPhyWrite; ++#else /* SK_DIAG */ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ pAC->GIni.GIFunc.pSkGeSirqIsr = SkYuk2SirqIsr; ++ } ++ else { ++ pAC->GIni.GIFunc.pSkGeSirqIsr = SkGeYuSirqIsr; ++ } ++#endif /* !SK_DIAG */ + + #ifdef SPECIAL_HANDLING + if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { +@@ -1684,7 +2783,13 @@ + #endif + } + #endif /* YUKON */ +- ++ ++#ifndef SK_SLIM ++ ++ SkGeSetUpSupFeatures(pAC, IoC); ++ ++#endif /* !SK_SLIM */ ++ + return(RetVal); + } /* SkGeInit1 */ + +@@ -1705,9 +2810,15 @@ + * nothing + */ + static void SkGeInit2( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC) /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ + { ++#ifdef YUKON ++ SK_U16 Word; ++#if (!defined(SK_SLIM) && !defined(SK_DIAG)) ++ SK_EVPARA Para; ++#endif /* !SK_SLIM && !SK_DIAG */ ++#endif /* YUKON */ + #ifdef GENESIS + SK_U32 DWord; + #endif /* GENESIS */ +@@ -1720,7 +2831,9 @@ + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG); + } ++ + SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal); ++ + SK_OUT8(IoC, B28_DPT_CTRL, DPT_START); + } + +@@ -1730,6 +2843,7 @@ + DWord = SK_BLK_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100; + + SK_OUT32(IoC, B2_BSC_INI, DWord); ++ + SK_OUT8(IoC, B2_BSC_CTRL, BSC_START); + + /* +@@ -1741,13 +2855,13 @@ + SkGeInitPktArb(pAC, IoC); + } + #endif /* GENESIS */ +- +-#ifdef YUKON ++ ++#ifdef xSK_DIAG + if (pAC->GIni.GIYukon) { + /* start Time Stamp Timer */ + SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START); + } +-#endif /* YUKON */ ++#endif /* SK_DIAG */ + + /* enable the Tx Arbiters */ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { +@@ -1757,8 +2871,66 @@ + /* enable the RAM Interface Arbiter */ + SkGeInitRamIface(pAC, IoC); + ++#ifdef YUKON ++ if (CHIP_ID_YUKON_2(pAC)) { ++ ++ if (pAC->GIni.GIPciBus == SK_PEX_BUS) { ++ ++ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); ++ ++ /* get Max. Read Request Size */ ++ SK_IN16(IoC, PCI_C(pAC, PEX_DEV_CTRL), &Word); ++ ++ /* check for HW-default value of 512 bytes */ ++ if ((Word & PEX_DC_MAX_RRS_MSK) == PEX_DC_MAX_RD_RQ_SIZE(2)) { ++ /* change Max. Read Request Size to 2048 bytes */ ++ Word &= ~PEX_DC_MAX_RRS_MSK; ++ Word |= PEX_DC_MAX_RD_RQ_SIZE(4); ++ ++ SK_OUT16(IoC, PCI_C(pAC, PEX_DEV_CTRL), Word); ++ } ++ ++#ifdef REPLAY_TIMER ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) { ++ /* PEX Ack Reply Timeout to 40 us */ ++ SK_OUT16(IoC, PCI_C(pAC, PEX_ACK_RPLY_TOX1), 0x2710); ++ } ++#endif ++ ++ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); ++ ++#if (!defined(SK_SLIM) && !defined(SK_DIAG)) ++ SK_IN16(IoC, PCI_C(pAC, PEX_LNK_CAP), &Word); ++ ++ Word = (Word & PEX_CAP_MAX_WI_MSK) >> 4; ++ ++ /* compare PEX Negotiated Link Width against max. capabil */ ++ if (pAC->GIni.GIPexWidth != (SK_U8)Word) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("PEX negotiated Link width is: %d, exp.: %d\n", ++ pAC->GIni.GIPexWidth, Word)); ++ ++#ifndef NDIS_MINIPORT_DRIVER ++ SK_ERR_LOG(pAC, SK_ERRCL_INFO, SKERR_HWI_E026, ++ SKERR_HWI_E026MSG); ++#endif ++ Para.Para64 = 0; ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PEX_LINK_WIDTH, Para); ++ } ++#endif /* !SK_SLIM && !SK_DIAG */ ++ } ++ ++ /* ++ * Writing the HW Error Mask Reg. will not generate an IRQ ++ * as long as the B0_IMSK is not set by the driver. ++ */ ++ SK_OUT32(IoC, B0_HWE_IMSK, pAC->GIni.GIValHwIrqMask); ++ } ++#endif /* YUKON */ + } /* SkGeInit2 */ + ++ + /****************************************************************************** + * + * SkGeInit() - Initialize the GE Adapter with the specified level. +@@ -1780,23 +2952,23 @@ + * if Number of MACs > SK_MAX_MACS + * + * After returning from Level 0 the adapter +- * may be accessed with IO operations. ++ * may be accessed with I/O operations. + * + * Level 2: start the Blink Source Counter + * + * Returns: + * 0: success +- * 1: Number of MACs exceeds SK_MAX_MACS (after level 1) ++ * 1: Number of MACs exceeds SK_MAX_MACS (after level 1) + * 2: Adapter not present or not accessible + * 3: Illegal initialization level +- * 4: Initialization Level 1 Call missing ++ * 4: Initialization level 1 call missing + * 5: Unexpected PHY type detected + * 6: HW self test failed + */ + int SkGeInit( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ +-int Level) /* initialization level */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Level) /* Initialization Level */ + { + int RetVal; /* return value */ + SK_U32 DWord; +@@ -1811,7 +2983,7 @@ + SkGeInit0(pAC, IoC); + pAC->GIni.GILevel = SK_INIT_DATA; + break; +- ++ + case SK_INIT_IO: + /* Initialization Level 1 */ + RetVal = SkGeInit1(pAC, IoC); +@@ -1823,22 +2995,26 @@ + SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL); + SK_IN32(IoC, B2_IRQM_INI, &DWord); + SK_OUT32(IoC, B2_IRQM_INI, 0L); +- ++ + if (DWord != SK_TEST_VAL) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("Error accessing IRQM register, 0x%08lX\n", DWord)); + RetVal = 2; + break; + } + ++#ifdef DEBUG + /* check if the number of GIMacsFound matches SK_MAX_MACS */ + if (pAC->GIni.GIMacsFound > SK_MAX_MACS) { + RetVal = 1; + break; + } ++#endif /* DEBUG */ + + /* Level 1 successfully passed */ + pAC->GIni.GILevel = SK_INIT_IO; + break; +- ++ + case SK_INIT_RUN: + /* Initialization Level 2 */ + if (pAC->GIni.GILevel != SK_INIT_IO) { +@@ -1848,12 +3024,13 @@ + RetVal = 4; + break; + } ++ + SkGeInit2(pAC, IoC); + + /* Level 2 successfully passed */ + pAC->GIni.GILevel = SK_INIT_RUN; + break; +- ++ + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG); + RetVal = 3; +@@ -1876,46 +3053,116 @@ + * nothing + */ + void SkGeDeInit( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC) /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ + { + int i; + SK_U16 Word; + ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("SkGeDeInit: PState %d\n",pAC->GIni.GP[0].PState)); ++ + #if (!defined(SK_SLIM) && !defined(VCPU)) + /* ensure I2C is ready */ + SkI2cWaitIrq(pAC, IoC); +-#endif ++#endif + +- /* stop all current transfer activity */ +- for (i = 0; i < pAC->GIni.GIMacsFound; i++) { +- if (pAC->GIni.GP[i].PState != SK_PRT_STOP && +- pAC->GIni.GP[i].PState != SK_PRT_RESET) { ++#ifdef SK_PHY_LP_MODE_DEEP_SLEEP ++ /* ++ * for power saving purposes within mobile environments ++ * we set the PHY to coma mode. ++ */ + +- SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST); ++ if (CHIP_ID_YUKON_2(pAC) && !pAC->GIni.GIAsfEnabled ++#ifdef XXX ++ || (pAC->GIni.GIYukonLite && pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) ++#endif /* XXX */ ++ ) { ++ ++ /* flag for SkGmEnterLowPowerMode() that the call was from here */ ++ pAC->GIni.GILevel = SK_INIT_IO; ++ ++ /* for all ports switch PHY to coma mode */ ++ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { ++ ++ /* Reset Rx MAC FIFO */ ++ SK_OUT8(IoC, MR_ADDR(i, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); ++ ++ (void)SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP); ++ } ++ } ++ else if (pAC->GIni.GIYukonLite) { ++ /* switch PHY to IEEE Power Down mode */ ++ (void)SkGmEnterLowPowerMode(pAC, IoC, 0, PHY_PM_IEEE_POWER_DOWN); ++ ++ if (pAC->GIni.GIVauxAvail) { ++ /* switch power to VAUX */ ++ SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | ++ PC_VAUX_ON | PC_VCC_OFF)); ++ } ++ } ++#else /* !SK_PHY_LP_MODE_DEEP_SLEEP */ ++ ++ if (!pAC->GIni.GIAsfEnabled) { ++ /* stop all current transfer activity */ ++ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { ++ if (pAC->GIni.GP[i].PState != SK_PRT_STOP && ++ pAC->GIni.GP[i].PState != SK_PRT_RESET) { ++ ++ SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST); ++ } + } + } + +- /* Reset all bits in the PCI STATUS register */ ++ /* reset all bits in the PCI STATUS register */ + /* + * Note: PCI Cfg cycles cannot be used, because they are not + * available on some platforms after 'boot time'. + */ +- SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); +- ++ SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word); ++ + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); +- SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); ++ ++ SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), Word | (SK_U16)PCI_ERRBITS); ++ + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + +- /* do the reset, all LEDs are switched off now */ +- SK_OUT8(IoC, B0_CTST, CS_RST_SET); +- ++ if (!pAC->GIni.GIAsfEnabled) { ++ /* set the SW-reset */ ++ SK_OUT8(IoC, B0_CTST, CS_RST_SET); ++ } ++#endif /* !SK_PHY_LP_MODE_DEEP_SLEEP */ ++ + pAC->GIni.GILevel = SK_INIT_DATA; + } /* SkGeDeInit */ + + + /****************************************************************************** + * ++ * SkGeByPassMacSec() - Startup initialization for MAC Security unit ++ * ++ * Description: ++ * Set the MAC security unit into a state to bypass all data. ++ * ++ * Returns: ++ * nothing ++ */ ++static void SkGeByPassMacSec( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port) /* Port to configure */ ++{ ++ if (HW_IS_EXT_LE_FORMAT(pAC)) { ++ /* Bypass all MacSec frames */ ++ SK_OUT32(IoC, MR_ADDR(Port, MAC_CTRL), ++ MAC_CTRL_BYP_MACSECRX_ON | ++ MAC_CTRL_BYP_MACSECTX_ON | ++ MAC_CTRL_BYP_RETR_ON); ++ } ++} ++ ++/****************************************************************************** ++ * + * SkGeInitPort() Initialize the specified port. + * + * Description: +@@ -1943,8 +3190,8 @@ + * 2: The port has to be stopped before it can be initialized again. + */ + int SkGeInitPort( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port to configure */ + { + SK_GEPORT *pPrt; +@@ -1955,8 +3202,8 @@ + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG); + return(1); + } +- +- if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) { ++ ++ if (pPrt->PState >= SK_PRT_INIT) { + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG); + return(2); + } +@@ -1967,35 +3214,35 @@ + if (pAC->GIni.GIGenesis) { + /* initialize Rx, Tx and Link LED */ + /* +- * If 1000BT Phy needs LED initialization than swap ++ * If 1000BT PHY needs LED initialization than swap + * LED and XMAC initialization order + */ + SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA); + SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA); + /* The Link LED is initialized by RLMT or Diagnostics itself */ +- ++ + SkXmInitMac(pAC, IoC, Port); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { + + SkGmInitMac(pAC, IoC, Port); + } + #endif /* YUKON */ +- ++ + /* do NOT initialize the Link Sync Counter */ + + SkGeInitMacFifo(pAC, IoC, Port); +- ++ + SkGeInitRamBufs(pAC, IoC, Port); +- ++ + if (pPrt->PXSQSize != 0) { + /* enable Force Sync bit if synchronous queue available */ + SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC); + } +- ++ + SkGeInitBmu(pAC, IoC, Port); + + /* mark port as initialized */ +@@ -2003,3 +3250,280 @@ + + return(0); + } /* SkGeInitPort */ ++ ++ ++#if (defined(YUK2) && !defined(SK_SLIM)) ++/****************************************************************************** ++ * ++ * SkGeRamWrite() - Writes One quadword to RAM ++ * ++ * Returns: ++ * 0 ++ */ ++static void SkGeRamWrite( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++SK_U32 Addr, /* Address to be written to (in quadwords) */ ++SK_U32 LowDword, /* Lower Dword to be written */ ++SK_U32 HighDword, /* Upper Dword to be written */ ++int Port) /* Select RAM buffer (Yukon-2 has 2 RAM buffers) */ ++{ ++ SK_OUT32(IoC, SELECT_RAM_BUFFER(Port, B3_RAM_ADDR), Addr); ++ ++ /* Write Access is initiated by writing the upper Dword */ ++ SK_OUT32(IoC, SELECT_RAM_BUFFER(Port, B3_RAM_DATA_LO), LowDword); ++ ++ SK_OUT32(IoC, SELECT_RAM_BUFFER(Port, B3_RAM_DATA_HI), HighDword); ++} ++ ++/****************************************************************************** ++ * ++ * SkYuk2RestartRxBmu() - Restart Receive BMU on Yukon-2 ++ * ++ * return: ++ * 0 o.k. ++ * 1 timeout ++ */ ++int SkYuk2RestartRxBmu( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port) /* Port Index (MAC_1 + n) */ ++{ ++ SK_U16 Word; ++ SK_U16 MacCtrl; ++ SK_U16 MacCtrlSave; ++ SK_U16 RxCtrl; ++ SK_U16 FlushMask; ++ SK_U16 FlushTrsh; ++ SK_U32 RamAdr; ++ SK_U32 StartTime; ++ SK_U32 CurrTime; ++ SK_U32 Delta; ++ SK_U32 TimeOut; ++ SK_BOOL TimeStampDisabled; ++ SK_GEPORT *pPrt; /* GIni Port struct pointer */ ++ SK_U16 WordBuffer[4]; /* Buffer to handle MAC address */ ++ int i; ++ int Rtv; ++ ++ Rtv = 0; ++ ++ /* read the MAC Interrupt source register */ ++ SK_IN16(IoC, MR_ADDR(Port, GMAC_IRQ_SRC), &Word); ++ ++ /* check if a packet was received by the MAC */ ++ if ((Word & GM_IS_RX_COMPL) == 0) { ++ /* workaround not necessary */ ++ return(0); ++ } ++ ++ pPrt = &pAC->GIni.GP[Port]; ++ ++ /* ++ 1. save Rx MAC FIFO Flush Mask and Rx MAC FIFO Flush Threshold ++ 2. save MAC Rx Control Register ++ 3. re-initialize MAC Rx FIFO, Rx RAM Buffer Queue, PCI Rx FIFO, ++ Rx BMU and Rx Prefetch Unit of the link. ++ 4. set Rx MAC FIFO Flush Mask to 0xffff ++ set Rx MAC FIFO Flush Threshold to a high value, e.g. 0x20 ++ 5. set MAC to loopback mode and switch MAC back to Rx/Tx enable ++ 6. clear Rx/Tx Frame Complete IRQ in Rx/T MAC FIFO Control Register ++ 7. send one packet with a size of 64bytes (size below flush threshold) ++ from TXA RAM Buffer Queue to set the rx_sop flop: ++ - set TxAQ Write Pointer to (packet size in qwords + 2) ++ - set TxAQ Level to (packet size in qwords + 2) ++ - write Internal Status Word 1 and 2 to TxAQ RAM Buffer Queue QWord 0,1 ++ according to figure 61 on page 330 of Yukon-2 Spec. ++ - write MAC header with Destination Address = own MAC address to ++ TxAQ RAM Buffer Queue QWords 2 and 3 ++ - set TxAQ Packet Counter to 1 -> packet is transmitted immediately ++ 8. poll MAC IRQ Source Register for IRQ Rx/Tx Frame Complete ++ 9. restore MAC Rx Control Register ++ 10. restore Rx MAC FIFO Flush Mask and Rx MAC FIFO Flush Threshold ++ 11. set MAC back to GMII mode ++ */ ++ ++ /* save MAC General Purpose Control */ ++ GM_IN16(IoC, Port, GM_GP_CTRL, &MacCtrlSave); ++ ++ /* save Rx MAC FIFO Flush Mask */ ++ SK_IN16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), &FlushMask); ++ ++ /* save Rx MAC FIFO Flush Threshold */ ++ SK_IN16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), &FlushTrsh); ++ ++ /* save MAC Rx Control Register */ ++ GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("SkYuk2RestartRxBmu: Port %d, RxCtrl=0x%04X\n", ++ Port, RxCtrl)); ++ ++ /* configure the MAC FIFOs */ ++ SkGeInitMacFifo(pAC, IoC, Port); ++ ++ SkGeInitRamBufs(pAC, IoC, Port); ++ ++ SkGeInitBmu(pAC, IoC, Port); ++ ++ SK_IN8(IoC, GMAC_TI_ST_CTRL, &Word); ++ ++ TimeStampDisabled = (Word & GMT_ST_START) == 0; ++ ++ if (TimeStampDisabled) { ++ /* start Time Stamp Timer */ ++ SkMacTimeStamp(pAC, IoC, Port, SK_TRUE); ++ } ++ ++ /* configure Rx MAC FIFO */ ++ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), GMF_RX_CTRL_DEF); ++ ++ /* set Rx MAC FIFO Flush Mask */ ++ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), 0xffff); ++ ++ /* set Rx MAC FIFO Flush Threshold */ ++ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), 0x20); ++ ++ /* set to promiscuous mode */ ++ Word = RxCtrl & ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); ++ ++ /* set MAC Rx Control Register */ ++ GM_OUT16(IoC, Port, GM_RX_CTRL, Word); ++ ++ MacCtrl = MacCtrlSave | GM_GPCR_LOOP_ENA | GM_GPCR_FL_PASS | ++ GM_GPCR_DUP_FULL | GM_GPCR_AU_ALL_DIS; ++ ++ /* enable MAC Loopback Mode */ ++ GM_OUT16(IoC, Port, GM_GP_CTRL, MacCtrl); ++ ++ /* enable MAC Rx/Tx */ ++ GM_OUT16(IoC, Port, GM_GP_CTRL, MacCtrl | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); ++ ++ /* clear MAC IRQ Rx Frame Complete */ ++ SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FC); ++ ++ /* clear MAC IRQ Tx Frame Complete */ ++ SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FC); ++ ++/* get current value of timestamp timer */ ++ SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime); ++ ++ /* check for half-duplex */ ++ if ((MacCtrlSave & GM_GPCR_DUP_FULL) == 0) { ++ /* set delay to 20 ms */ ++ TimeOut = HW_MS_TO_TICKS(pAC, 20); ++ ++ do { ++ /* dummy read */ ++ GM_IN16(IoC, Port, GM_GP_STAT, &Word); ++ ++ /* get current value of timestamp timer */ ++ SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); ++ ++ if (CurrTime >= StartTime) { ++ Delta = CurrTime - StartTime; ++ } ++ else { ++ Delta = CurrTime + ~StartTime + 1; ++ } ++ ++ } while (Delta < TimeOut); ++ } ++ ++ /* send one packet with a size of 64bytes from RAM buffer*/ ++ ++ RamAdr = pPrt->PXaQRamStart / 8; ++ ++ SK_OUT32(IoC, RB_ADDR(pPrt->PXaQOff, RB_WP), RamAdr + 10); ++ ++ SK_OUT32(IoC, RB_ADDR(pPrt->PXaQOff, RB_LEV), 10); ++ ++ /* write 1st status quad word (packet end address in RAM, packet length */ ++ SkGeRamWrite(pAC, IoC, RamAdr, (RamAdr + 9) << 16, 64, Port); ++ ++ /* write 2nd status quad word */ ++ SkGeRamWrite(pAC, IoC, RamAdr + 1, 0, 0, Port); ++ ++ for (i = 0; i < 3; i++) { ++ /* set MAC Destination Address */ ++ WordBuffer[i] = pPrt->PMacAddr[i]; ++ } ++ ++ WordBuffer[3] = WordBuffer[0]; ++ ++ /* write DA to MAC header */ ++ SkGeRamWrite(pAC, IoC, RamAdr + 2, (SK_U32)(*(SK_U32 *)&WordBuffer[0]), ++ (SK_U32)(*(SK_U32 *)&WordBuffer[2]), Port); ++ ++ WordBuffer[0] = WordBuffer[1]; ++ WordBuffer[1] = WordBuffer[2]; ++ WordBuffer[2] = 0x3200; /* len / type field (big endian) */ ++ WordBuffer[3] = 0; ++ ++ /* write SA and type field to MAC header */ ++ SkGeRamWrite(pAC, IoC, RamAdr + 3, (SK_U32)(*(SK_U32 *)&WordBuffer[0]), ++ (SK_U32)(*(SK_U32 *)&WordBuffer[2]), Port); ++ ++ SkGeRamWrite(pAC, IoC, RamAdr + 4, 0x4c56524d, /* "MRVL" */ ++ 0x00464d2d, Port); /* "-MF" */ ++ ++ for (i = 0; i < 5; i++) { ++ /* fill packet with zeroes */ ++ SkGeRamWrite(pAC, IoC, RamAdr + 5 + i, 0, 0, Port); ++ } ++ ++ SK_OUT32(IoC, RB_ADDR(pPrt->PXaQOff, RB_PC), 1); ++ ++ /* get current value of timestamp timer */ ++ SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime); ++ ++ /* set timeout to 10 ms */ ++ TimeOut = HW_MS_TO_TICKS(pAC, 10); ++ ++ do { ++ /* get current value of timestamp timer */ ++ SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); ++ ++ if (CurrTime >= StartTime) { ++ Delta = CurrTime - StartTime; ++ } ++ else { ++ Delta = CurrTime + ~StartTime + 1; ++ } ++ ++ if (Delta > TimeOut) { ++ Rtv = 1; ++ break; ++ } ++ ++ /* read the MAC Interrupt source register */ ++ SK_IN16(IoC, MR_ADDR(Port, GMAC_IRQ_SRC), &Word); ++ ++ } while ((Word & (GM_IS_TX_COMPL | GM_IS_RX_COMPL)) != ++ (GM_IS_TX_COMPL | GM_IS_RX_COMPL)); ++ ++ /* clear MAC IRQ Rx Frame Complete */ ++ SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FC); ++ ++ if (TimeStampDisabled) { ++ /* stop Time Stamp Timer */ ++ SkMacTimeStamp(pAC, IoC, Port, SK_TRUE); ++ } ++ ++ /* restore MAC General Purpose Control */ ++ GM_OUT16(IoC, Port, GM_GP_CTRL, MacCtrlSave); ++ ++ /* restore MAC Rx Control Register */ ++ GM_OUT16(IoC, Port, GM_RX_CTRL, RxCtrl); ++ ++ /* restore Rx MAC FIFO Flush Mask */ ++ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), FlushMask); ++ ++ /* restore Rx MAC FIFO Flush Threshold */ ++ SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), FlushTrsh); ++ ++ return(Rtv); ++ ++} /* SkYuk2RestartRxBmu */ ++#endif /* YUK2 && !SK_SLIM */ ++ +diff -ruN linux/drivers/net/sk98lin/skgemib.c linux-new/drivers/net/sk98lin/skgemib.c +--- linux/drivers/net/sk98lin/skgemib.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skgemib.c 2007-01-24 14:03:40.000000000 +0100 +@@ -1,17 +1,18 @@ + /***************************************************************************** + * + * Name: skgemib.c +- * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ ++ * Project: Gigabit Ethernet Adapters, PNMI-Module ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Private Network Management Interface Management Database + * + ****************************************************************************/ + + /****************************************************************************** + * +- * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * LICENSE: ++ * (C)Copyright 1998-2002 SysKonnect. ++ * (C)Copyright 2002-2007 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 +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -80,6 +82,12 @@ + unsigned int TableIndex, SK_U32 NetIndex); + #endif /* SK_DIAG_SUPPORT */ + ++#ifdef SK_ASF ++PNMI_STATIC int Asf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, ++ char *pBuf, unsigned int *pLen, SK_U32 Instance, ++ unsigned int TableIndex, SK_U32 NetIndex); ++#endif /* SK_ASF */ ++ + + /* defines *******************************************************************/ + #define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0])) +@@ -251,6 +259,183 @@ + 0, + SK_PNMI_RW, DiagActions, 0}, + #endif /* SK_DIAG_SUPPORT */ ++#ifdef SK_ASF ++ {OID_SKGE_ASF, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_STORE_CONFIG, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_ENA, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_RETRANS, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_RETRANS_INT, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_HB_ENA, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_HB_INT, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_WD_ENA, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_WD_TIME, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_IP_SOURCE, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_MAC_SOURCE, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_IP_DEST, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_MAC_DEST, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_COMMUNITY_NAME, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_RSP_ENA, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_RETRANS_COUNT_MIN, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_RETRANS_COUNT_MAX, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_RETRANS_INT_MIN, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_RETRANS_INT_MAX, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_HB_INT_MIN, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_HB_INT_MAX, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_WD_TIME_MIN, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_WD_TIME_MAX, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_HB_CAP, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_WD_TIMER_RES, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_GUID, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_KEY_OP, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_KEY_ADM, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_KEY_GEN, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_CAP, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_PAR_1, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_OVERALL_OID, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RW, Asf, 0}, ++ {OID_SKGE_ASF_FWVER_OID, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RO, Asf, 0}, ++ {OID_SKGE_ASF_ACPI_OID, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RO, Asf, 0}, ++ {OID_SKGE_ASF_SMBUS_OID, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RO, Asf, 0}, ++#endif /* SK_ASF */ + {OID_SKGE_MDB_VERSION, + 1, + 0, +@@ -871,6 +1056,13 @@ + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType), + SK_PNMI_RO, MacPrivateConf, 0}, ++#ifdef SK_PHY_LP_MODE ++ {OID_SKGE_PHY_LP_MODE, ++ SK_PNMI_MAC_ENTRIES, ++ sizeof(SK_PNMI_CONF), ++ SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyMode), ++ SK_PNMI_RW, MacPrivateConf, 0}, ++#endif + {OID_SKGE_LINK_CAP, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), +@@ -1066,6 +1258,11 @@ + 0, + 0, + SK_PNMI_RO, Vct, 0}, ++ {OID_SKGE_VCT_CAPABILITIES, ++ 0, ++ 0, ++ 0, ++ SK_PNMI_RO, Vct, 0}, + {OID_SKGE_BOARDLEVEL, + 0, + 0, +diff -ruN linux/drivers/net/sk98lin/skgepnmi.c linux-new/drivers/net/sk98lin/skgepnmi.c +--- linux/drivers/net/sk98lin/skgepnmi.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skgepnmi.c 2007-01-24 13:58:33.000000000 +0100 +@@ -1,17 +1,18 @@ + /***************************************************************************** + * + * Name: skgepnmi.c +- * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ ++ * Project: Gigabit Ethernet Adapters, PNMI-Module ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Private Network Management Interface + * + ****************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2007 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 +@@ -19,14 +20,14 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +- +-#ifndef _lint ++#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) + static const char SysKonnectFileId[] = +- "@(#) $Id$ (C) Marvell."; +-#endif /* !_lint */ ++ "@(#) $Id$ (C) Marvell."; ++#endif + + #include "h/skdrv1st.h" + #include "h/sktypes.h" +@@ -38,12 +39,14 @@ + #include "h/skcsum.h" + #include "h/skvpd.h" + #include "h/skgehw.h" ++#include "h/sky2le.h" + #include "h/skgeinit.h" + #include "h/skdrv2nd.h" + #include "h/skgepnm2.h" + #ifdef SK_POWER_MGMT + #include "h/skgepmgt.h" +-#endif ++#endif /* SK_POWER_MGMT */ ++ + /* defines *******************************************************************/ + + #ifndef DEBUG +@@ -53,23 +56,6 @@ + #endif /* DEBUG */ + + /* +- * Public Function prototypes +- */ +-int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level); +-int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, +- unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); +-int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, +- unsigned int *pLen, SK_U32 NetIndex); +-int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, +- unsigned int *pLen, SK_U32 NetIndex); +-int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, +- unsigned int *pLen, SK_U32 NetIndex); +-int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param); +-int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf, +- unsigned int * pLen, SK_U32 NetIndex); +- +- +-/* + * Private Function prototypes + */ + +@@ -105,9 +91,8 @@ + PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); + PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC); + PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf); +-PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf, +- unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex); + PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32); ++PNMI_STATIC void VctGetResults(SK_AC *, SK_IOC, SK_U32); + + /* + * Table to correlate OID with handler function and index to +@@ -339,7 +324,7 @@ + * SkPnmiInit - Init function of PNMI + * + * Description: +- * SK_INIT_DATA: Initialises the data structures ++ * SK_INIT_DATA: Initializes the data structures + * SK_INIT_IO: Resets the XMAC statistics, determines the device and + * connector type. + * SK_INIT_RUN: Starts a timer event for port switch per hour +@@ -349,17 +334,13 @@ + * Always 0 + */ + int SkPnmiInit( +-SK_AC *pAC, /* Pointer to adapter context */ +-SK_IOC IoC, /* IO context handle */ +-int Level) /* Initialization level */ ++SK_AC *pAC, /* Pointer to adapter context */ ++SK_IOC IoC, /* IO context handle */ ++int Level) /* Initialization level */ + { + unsigned int PortMax; /* Number of ports */ + unsigned int PortIndex; /* Current port index in loop */ +- SK_U16 Val16; /* Multiple purpose 16 bit variable */ +- SK_U8 Val8; /* Mulitple purpose 8 bit variable */ +- SK_EVPARA EventParam; /* Event struct for timer event */ +- SK_PNMI_VCT *pVctBackupData; +- ++ SK_EVPARA EventParam; /* Event struct for timer event */ + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: SkPnmiInit: Called, level=%d\n", Level)); +@@ -368,18 +349,24 @@ + + case SK_INIT_DATA: + SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi)); ++ + pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN; + pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); + pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES; ++ + for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) { + + pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE; + pAC->Pnmi.DualNetActiveFlag = SK_FALSE; ++ ++ /* Initialize DSP variables for Vct() to 0xff => Never written! */ ++ pAC->GIni.GP[PortIndex].PCableLen = 0xff; ++ pAC->Pnmi.VctBackup[PortIndex].CableLen = 0xff; + } + + #ifdef SK_PNMI_CHECK + if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) { +- ++ + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG); + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, +@@ -390,7 +377,7 @@ + + if (SK_PNMI_MAX_IDX != + (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) { +- ++ + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG); + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, +@@ -404,51 +391,36 @@ + break; + + case SK_INIT_IO: +- /* +- * Reset MAC counters +- */ ++ ++ /* Reset MAC counters. */ + PortMax = pAC->GIni.GIMacsFound; + + for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) { + + pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex); + } +- +- /* Initialize DSP variables for Vct() to 0xff => Never written! */ +- for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) { +- pAC->GIni.GP[PortIndex].PCableLen = 0xff; +- pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex]; +- pVctBackupData->PCableLen = 0xff; +- } +- +- /* +- * Get pci bus speed +- */ +- SK_IN16(IoC, B0_CTST, &Val16); +- if ((Val16 & CS_BUS_CLOCK) == 0) { + +- pAC->Pnmi.PciBusSpeed = 33; ++ /* Get PCI bus speed. */ ++ if (pAC->GIni.GIPciClock66) { ++ ++ pAC->Pnmi.PciBusSpeed = 66; + } + else { +- pAC->Pnmi.PciBusSpeed = 66; ++ pAC->Pnmi.PciBusSpeed = 33; + } + +- /* +- * Get pci bus width +- */ +- SK_IN16(IoC, B0_CTST, &Val16); +- if ((Val16 & CS_BUS_SLOT_SZ) == 0) { ++ /* Get PCI bus width. */ ++ if (pAC->GIni.GIPciSlot64) { + +- pAC->Pnmi.PciBusWidth = 32; ++ pAC->Pnmi.PciBusWidth = 64; + } + else { +- pAC->Pnmi.PciBusWidth = 64; ++ pAC->Pnmi.PciBusWidth = 32; + } + +- /* +- * Get chipset +- */ ++ /* Get chipset. */ + switch (pAC->GIni.GIChipId) { ++ + case CHIP_ID_GENESIS: + pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC; + break; +@@ -457,57 +429,51 @@ + pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON; + break; + ++ case CHIP_ID_YUKON_LITE: ++ pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_LITE; ++ break; ++ ++ case CHIP_ID_YUKON_LP: ++ pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_LP; ++ break; ++ ++ case CHIP_ID_YUKON_XL: ++ pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_XL; ++ break; ++ ++ case CHIP_ID_YUKON_EC: ++ pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_EC; ++ break; ++ ++ case CHIP_ID_YUKON_FE: ++ pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_FE; ++ break; ++ + default: + break; + } + +- /* +- * Get PMD and DeviceType +- */ +- SK_IN8(IoC, B2_PMD_TYP, &Val8); +- switch (Val8) { ++ /* Get PMD and Device Type. */ ++ switch (pAC->GIni.GIPmdTyp) { ++ + case 'S': + pAC->Pnmi.PMD = 3; +- if (pAC->GIni.GIMacsFound > 1) { +- +- pAC->Pnmi.DeviceType = 0x00020002; +- } +- else { +- pAC->Pnmi.DeviceType = 0x00020001; +- } ++ pAC->Pnmi.DeviceType = 0x00020001; + break; + + case 'L': + pAC->Pnmi.PMD = 2; +- if (pAC->GIni.GIMacsFound > 1) { +- +- pAC->Pnmi.DeviceType = 0x00020004; +- } +- else { +- pAC->Pnmi.DeviceType = 0x00020003; +- } ++ pAC->Pnmi.DeviceType = 0x00020003; + break; + + case 'C': + pAC->Pnmi.PMD = 4; +- if (pAC->GIni.GIMacsFound > 1) { +- +- pAC->Pnmi.DeviceType = 0x00020006; +- } +- else { +- pAC->Pnmi.DeviceType = 0x00020005; +- } ++ pAC->Pnmi.DeviceType = 0x00020005; + break; + + case 'T': + pAC->Pnmi.PMD = 5; +- if (pAC->GIni.GIMacsFound > 1) { +- +- pAC->Pnmi.DeviceType = 0x00020008; +- } +- else { +- pAC->Pnmi.DeviceType = 0x00020007; +- } ++ pAC->Pnmi.DeviceType = 0x00020007; + break; + + default : +@@ -516,11 +482,14 @@ + break; + } + +- /* +- * Get connector +- */ +- SK_IN8(IoC, B2_CONN_TYP, &Val8); +- switch (Val8) { ++ if (pAC->GIni.GIMacsFound > 1) { ++ ++ pAC->Pnmi.DeviceType++; ++ } ++ ++ /* Get connector type. */ ++ switch (pAC->GIni.GIConTyp) { ++ + case 'C': + pAC->Pnmi.Connector = 2; + break; +@@ -548,17 +517,17 @@ + break; + + case SK_INIT_RUN: +- /* +- * Start timer for RLMT change counter +- */ ++ ++ /* Start timer for RLMT change counter. */ + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); ++ + SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, +- 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, ++ SK_PNMI_EVT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, + EventParam); + break; + + default: +- break; /* Nothing todo */ ++ break; /* Nothing to do. */ + } + + return (0); +@@ -583,7 +552,7 @@ + * exist (e.g. port instance 3 on a two port + * adapter. + */ +-static int SkPnmiGetVar( ++int SkPnmiGetVar( + SK_AC *pAC, /* Pointer to adapter context */ + SK_IOC IoC, /* IO context handle */ + SK_U32 Id, /* Object ID that is to be processed */ +@@ -607,7 +576,7 @@ + * Description: + * Calls a general sub-function for all this stuff. The preset does + * the same as a set, but returns just before finally setting the +- * new value. This is useful to check if a set might be successfull. ++ * new value. This is usefull to check if a set might be successfull. + * If the instance -1 is passed, an array of values is supposed and + * all instances of the OID will be set. + * +@@ -625,7 +594,7 @@ + * exist (e.g. port instance 3 on a two port + * adapter. + */ +-static int SkPnmiPreSetVar( ++int SkPnmiPreSetVar( + SK_AC *pAC, /* Pointer to adapter context */ + SK_IOC IoC, /* IO context handle */ + SK_U32 Id, /* Object ID that is to be processed */ +@@ -638,7 +607,6 @@ + ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", + Id, *pLen, Instance, NetIndex)); + +- + return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen, + Instance, NetIndex)); + } +@@ -650,7 +618,7 @@ + * Description: + * Calls a general sub-function for all this stuff. The preset does + * the same as a set, but returns just before finally setting the +- * new value. This is useful to check if a set might be successfull. ++ * new value. This is usefull to check if a set might be successfull. + * If the instance -1 is passed, an array of values is supposed and + * all instances of the OID will be set. + * +@@ -720,7 +688,6 @@ + unsigned int TmpLen; + char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE]; + +- + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n", + *pLen, NetIndex)); +@@ -729,22 +696,19 @@ + + if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) { + +- SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, +- (SK_U32)(-1)); ++ SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, (SK_U32)(-1)); + } + + *pLen = SK_PNMI_STRUCT_SIZE; + return (SK_PNMI_ERR_TOO_SHORT); + } + +- /* +- * Check NetIndex +- */ ++ /* Check NetIndex. */ + if (NetIndex >= pAC->Rlmt.NumNets) { + return (SK_PNMI_ERR_UNKNOWN_NET); + } + +- /* Update statistic */ ++ /* Update statistics. */ + SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call"); + + if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) != +@@ -769,35 +733,37 @@ + return (Ret); + } + +- /* +- * Increment semaphores to indicate that an update was +- * already done +- */ ++ /* Increment semaphores to indicate that an update was already done. */ + pAC->Pnmi.MacUpdatedFlag ++; + pAC->Pnmi.RlmtUpdatedFlag ++; + pAC->Pnmi.SirqUpdatedFlag ++; + +- /* Get vpd keys for instance calculation */ +- Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen); +- if (Ret != SK_PNMI_ERR_OK) { ++ /* ++ * Get VPD keys for instance calculation. ++ * Please read comment in Vpd(). ++ */ ++ if (pAC->Pnmi.VpdKeyReadError == SK_FALSE) { ++ Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen); ++ if (Ret != SK_PNMI_ERR_OK) { + +- pAC->Pnmi.MacUpdatedFlag --; +- pAC->Pnmi.RlmtUpdatedFlag --; +- pAC->Pnmi.SirqUpdatedFlag --; ++ pAC->Pnmi.MacUpdatedFlag --; ++ pAC->Pnmi.RlmtUpdatedFlag --; ++ pAC->Pnmi.SirqUpdatedFlag --; + +- SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); +- SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); +- *pLen = SK_PNMI_MIN_STRUCT_SIZE; +- return (SK_PNMI_ERR_GENERAL); ++ SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); ++ SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); ++ *pLen = SK_PNMI_MIN_STRUCT_SIZE; ++ return (SK_PNMI_ERR_GENERAL); ++ } + } + +- /* Retrieve values */ ++ /* Retrieve values. */ + SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE); ++ + for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) { + + InstanceNo = IdTable[TableIndex].InstanceNo; +- for (InstanceCnt = 1; InstanceCnt <= InstanceNo; +- InstanceCnt ++) { ++ for (InstanceCnt = 1; InstanceCnt <= InstanceNo; InstanceCnt ++) { + + DstOffset = IdTable[TableIndex].Offset + + (InstanceCnt - 1) * +@@ -832,7 +798,7 @@ + */ + if (Ret == SK_PNMI_ERR_UNKNOWN_INST) { + +- break; ++ break; + } + + if (Ret != SK_PNMI_ERR_OK) { +@@ -866,7 +832,7 @@ + * Description: + * Calls a general sub-function for all this set stuff. The preset does + * the same as a set, but returns just before finally setting the +- * new value. This is useful to check if a set might be successfull. ++ * new value. This is usefull to check if a set might be successfull. + * The sub-function runs through the IdTable, checks which OIDs are able + * to set, and calls the handler function of the OID to perform the + * preset. The return value of the function will also be stored in +@@ -992,9 +958,8 @@ + SK_EVPARA Param) /* Event dependent parameter */ + { + unsigned int PhysPortIndex; +- unsigned int MaxNetNumber; ++ unsigned int MaxNetNumber; + int CounterIndex; +- int Ret; + SK_U16 MacStatus; + SK_U64 OverflowStatus; + SK_U64 Mask; +@@ -1008,12 +973,7 @@ + SK_U64 Delta; + SK_PNMI_ESTIMATE *pEst; + SK_U32 NetIndex; +- SK_GEPORT *pPrt; +- SK_PNMI_VCT *pVctBackupData; + SK_U32 RetCode; +- int i; +- SK_U32 CableLength; +- + + #ifdef DEBUG + if (Event != SK_PNMI_EVT_XMAC_RESET) { +@@ -1026,7 +986,7 @@ + SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call"); + + MacType = pAC->GIni.GIMacType; +- ++ + switch (Event) { + + case SK_PNMI_EVT_SIRQ_OVERFLOW: +@@ -1044,9 +1004,7 @@ + #endif /* DEBUG */ + OverflowStatus = 0; + +- /* +- * Check which source caused an overflow interrupt. +- */ ++ /* Check which source caused an overflow interrupt. */ + if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex, + MacStatus, &OverflowStatus) != 0) || + (OverflowStatus == 0)) { +@@ -1064,7 +1022,6 @@ + + Mask = (SK_U64)1 << CounterIndex; + if ((OverflowStatus & Mask) == 0) { +- + continue; + } + +@@ -1095,24 +1052,20 @@ + case SK_PNMI_HRX_OCTETLOW: + case SK_PNMI_HRX_IRLENGTH: + case SK_PNMI_HRX_RESERVED: +- +- /* +- * the following counters aren't be handled (id > 63) +- */ ++ ++ /* The following counters aren't be handled (id > 63). */ + case SK_PNMI_HTX_SYNC: + case SK_PNMI_HTX_SYNC_OCTET: + break; + + case SK_PNMI_HRX_LONGFRAMES: + if (MacType == SK_MAC_GMAC) { +- pAC->Pnmi.Port[PhysPortIndex]. +- CounterHigh[CounterIndex] ++; ++ pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] ++; + } + break; + + default: +- pAC->Pnmi.Port[PhysPortIndex]. +- CounterHigh[CounterIndex] ++; ++ pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] ++; + } + } + break; +@@ -1179,13 +1132,13 @@ + (unsigned int)Param.Para64); + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + break; +- ++ + case SK_PNMI_EVT_SEN_ERR_UPP: + #ifdef DEBUG + if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, +- ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n", ++ ("PNMI: ERR: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n", + (unsigned int)Param.Para64)); + return (0); + } +@@ -1204,16 +1157,14 @@ + case SK_PNMI_EVT_CHG_EST_TIMER: + /* + * Calculate port switch average on a per hour basis +- * Time interval for check : 28125 ms ++ * Time interval for check : 28125 ms (SK_PNMI_EVT_TIMER_CHECK) + * Number of values for average : 8 + * + * Be careful in changing these values, on change check + * - typedef of SK_PNMI_ESTIMATE (Size of EstValue + * array one less than value number) + * - Timer initialization SkTimerStart() in SkPnmiInit +- * - Delta value below must be multiplicated with +- * power of 2 +- * ++ * - Delta value below must be multiplicated with power of 2 + */ + pEst = &pAC->Pnmi.RlmtChangeEstimate; + CounterIndex = pEst->EstValueIndex + 1; +@@ -1236,7 +1187,7 @@ + Delta = NewestValue - OldestValue; + } + else { +- /* Overflow situation */ ++ /* Overflow situation. */ + Delta = (SK_U64)(0 - OldestValue) + NewestValue; + } + +@@ -1262,8 +1213,9 @@ + } + + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); ++ + SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, +- 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, ++ SK_PNMI_EVT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, + EventParam); + break; + +@@ -1307,29 +1259,25 @@ + (unsigned int)Param.Para64)); + return (0); + } +-#endif ++#endif /* DEBUG */ ++ + PhysPortIndex = (unsigned int)Param.Para64; + +- /* +- * Update XMAC statistic to get fresh values +- */ +- Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); +- if (Ret != SK_PNMI_ERR_OK) { ++ /* Update XMAC statistic to get fresh values. */ ++ if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) != ++ SK_PNMI_ERR_OK) { + + SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); + return (0); + } +- /* +- * Increment semaphore to indicate that an update was +- * already done +- */ ++ ++ /* Increment semaphore to indicate that an update was already done. */ + pAC->Pnmi.MacUpdatedFlag ++; + + for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; + CounterIndex ++) { + + if (!StatAddr[CounterIndex][MacType].GetOffset) { +- + continue; + } + +@@ -1349,7 +1297,7 @@ + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter" +- " wrong, PhysPortIndex=%d\n", PhysPortIndex)); ++ " wrong, PhysPortIndex=%d\n", PhysPortIndex)); + + return (0); + } +@@ -1362,23 +1310,24 @@ + QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex); + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + +- /* Bugfix for XMAC errata (#10620)*/ ++ /* Bugfix for XMAC errata (#10620). */ + if (MacType == SK_MAC_XMAC) { +- /* Add incremental difference to offset (#10620)*/ ++ /* Add incremental difference to offset (#10620). */ + (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, + XM_RXE_SHT_ERR, &Val32); +- ++ + Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. + CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); ++ + pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] += + Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark; + } +- ++ + /* Tell VctStatus() that a link was up meanwhile. */ + pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK; + break; + +- case SK_PNMI_EVT_RLMT_PORT_DOWN: ++ case SK_PNMI_EVT_RLMT_PORT_DOWN: + PhysPortIndex = (unsigned int)Param.Para32[0]; + + #ifdef DEBUG +@@ -1386,7 +1335,7 @@ + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter" +- " wrong, PhysPortIndex=%d\n", PhysPortIndex)); ++ " wrong, PhysPortIndex=%d\n", PhysPortIndex)); + + return (0); + } +@@ -1399,12 +1348,12 @@ + QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex); + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + +- /* Bugfix #10620 - get zero level for incremental difference */ ++ /* Bugfix #10620 - get zero level for incremental difference. */ + if (MacType == SK_MAC_XMAC) { + + (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, + XM_RXE_SHT_ERR, &Val32); +- ++ + pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark = + (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. + CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); +@@ -1431,17 +1380,13 @@ + } + #endif /* DEBUG */ + +- /* +- * For now, ignore event if NetIndex != 0. +- */ ++ /* For now, ignore event if NetIndex != 0. */ + if (Param.Para32[1] != 0) { + + return (0); + } + +- /* +- * Nothing to do if port is already inactive +- */ ++ /* Nothing to do if port is already inactive. */ + if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + + return (0); +@@ -1472,7 +1417,6 @@ + CounterIndex ++) { + + if (!StatAddr[CounterIndex][MacType].GetOffset) { +- + continue; + } + +@@ -1481,9 +1425,7 @@ + pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value; + } + +- /* +- * Set port to inactive +- */ ++ /* Set port to inactive. */ + pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE; + + pAC->Pnmi.MacUpdatedFlag --; +@@ -1509,25 +1451,19 @@ + } + #endif /* DEBUG */ + +- /* +- * For now, ignore event if NetIndex != 0. +- */ ++ /* For now, ignore event if NetIndex != 0. */ + if (Param.Para32[1] != 0) { + + return (0); + } + +- /* +- * Nothing to do if port is already active +- */ ++ /* Nothing to do if port is already inactive. */ + if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + + return (0); + } + +- /* +- * Statistic maintenance +- */ ++ /* Statistic maintenance. */ + pAC->Pnmi.RlmtChangeCts ++; + pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); + +@@ -1561,7 +1497,6 @@ + CounterIndex ++) { + + if (!StatAddr[CounterIndex][MacType].GetOffset) { +- + continue; + } + +@@ -1570,16 +1505,14 @@ + pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value; + } + +- /* Set port to active */ ++ /* Set port to active. */ + pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE; + + pAC->Pnmi.MacUpdatedFlag --; + break; + + case SK_PNMI_EVT_RLMT_SEGMENTATION: +- /* +- * Para.Para32[0] contains the NetIndex. +- */ ++ /* Para.Para32[0] contains the NetIndex. */ + + /* + * Store a trap message in the trap buffer and generate an event for +@@ -1589,78 +1522,60 @@ + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + break; + +- case SK_PNMI_EVT_RLMT_SET_NETS: ++ case SK_PNMI_EVT_RLMT_SET_NETS: + /* + * Param.Para32[0] contains the number of Nets. + * Param.Para32[1] is reserved, contains -1. + */ +- /* +- * Check number of nets +- */ ++ /* Check number of nets. */ + MaxNetNumber = pAC->GIni.GIMacsFound; +- if (((unsigned int)Param.Para32[0] < 1) +- || ((unsigned int)Param.Para32[0] > MaxNetNumber)) { ++ ++ if (((unsigned int)Param.Para32[0] < 1) || ++ ((unsigned int)Param.Para32[0] > MaxNetNumber)) { ++ + return (SK_PNMI_ERR_UNKNOWN_NET); + } + +- if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */ +- pAC->Pnmi.DualNetActiveFlag = SK_FALSE; +- } +- else { /* dual net mode */ +- pAC->Pnmi.DualNetActiveFlag = SK_TRUE; +- } +- break; ++ if ((unsigned int)Param.Para32[0] == 1) { /* SingleNet mode. */ ++ pAC->Pnmi.DualNetActiveFlag = SK_FALSE; ++ } ++ else { /* DualNet mode. */ ++ pAC->Pnmi.DualNetActiveFlag = SK_TRUE; ++ } ++ break; + +- case SK_PNMI_EVT_VCT_RESET: ++ case SK_PNMI_EVT_VCT_RESET: + PhysPortIndex = Param.Para32[0]; +- pPrt = &pAC->GIni.GP[PhysPortIndex]; +- pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; +- ++ + if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { ++ + RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); ++ + if (RetCode == 2) { + /* + * VCT test is still running. + * Start VCT timer counter again. + */ +- SK_MEMSET((char *) &Param, 0, sizeof(Param)); ++ SK_MEMSET((char *)&Param, 0, sizeof(Param)); ++ + Param.Para32[0] = PhysPortIndex; + Param.Para32[1] = -1; +- SkTimerStart(pAC, IoC, +- &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer, +- 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param); ++ ++ SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex], ++ SK_PNMI_VCT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param); ++ + break; + } +- pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING; +- pAC->Pnmi.VctStatus[PhysPortIndex] |= +- (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE); +- +- /* Copy results for later use to PNMI struct. */ +- for (i = 0; i < 4; i++) { +- if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) { +- if ((pPrt->PMdiPairLen[i] > 35) && +- (pPrt->PMdiPairLen[i] < 0xff)) { +- pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH; +- } +- } +- if ((pPrt->PMdiPairLen[i] > 35) && +- (pPrt->PMdiPairLen[i] != 0xff)) { +- CableLength = 1000 * +- (((175 * pPrt->PMdiPairLen[i]) / 210) - 28); +- } +- else { +- CableLength = 0; +- } +- pVctBackupData->PMdiPairLen[i] = CableLength; +- pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i]; +- } +- +- Param.Para32[0] = PhysPortIndex; +- Param.Para32[1] = -1; +- SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param); +- SkEventDispatcher(pAC, IoC); ++ ++ VctGetResults(pAC, IoC, PhysPortIndex); ++ ++ EventParam.Para32[0] = PhysPortIndex; ++ EventParam.Para32[1] = -1; ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, EventParam); ++ ++ /* SkEventDispatcher(pAC, IoC); */ + } +- ++ + break; + + default: +@@ -1706,14 +1621,13 @@ + unsigned int TableIndex; + int Ret; + +- + if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_OID); + } +- +- /* Check NetIndex */ ++ ++ /* Check NetIndex. */ + if (NetIndex >= pAC->Rlmt.NumNets) { + return (SK_PNMI_ERR_UNKNOWN_NET); + } +@@ -1763,26 +1677,24 @@ + SK_U32 Instance; + SK_U32 Id; + +- +- /* Check if the passed buffer has the right size */ ++ /* Check if the passed buffer has the right size. */ + if (*pLen < SK_PNMI_STRUCT_SIZE) { + +- /* Check if we can return the error within the buffer */ ++ /* Check if we can return the error within the buffer. */ + if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) { + +- SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, +- (SK_U32)(-1)); ++ SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, (SK_U32)(-1)); + } + + *pLen = SK_PNMI_STRUCT_SIZE; + return (SK_PNMI_ERR_TOO_SHORT); + } +- +- /* Check NetIndex */ ++ ++ /* Check NetIndex. */ + if (NetIndex >= pAC->Rlmt.NumNets) { + return (SK_PNMI_ERR_UNKNOWN_NET); + } +- ++ + SK_PNMI_CHECKFLAGS("PnmiStruct: On call"); + + /* +@@ -1806,12 +1718,11 @@ + pAC->Pnmi.RlmtUpdatedFlag ++; + pAC->Pnmi.SirqUpdatedFlag ++; + +- /* Preset/Set values */ ++ /* PRESET/SET values. */ + for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) { + + if ((IdTable[TableIndex].Access != SK_PNMI_RW) && + (IdTable[TableIndex].Access != SK_PNMI_WO)) { +- + continue; + } + +@@ -1822,8 +1733,7 @@ + InstanceCnt ++) { + + DstOffset = IdTable[TableIndex].Offset + +- (InstanceCnt - 1) * +- IdTable[TableIndex].StructSize; ++ (InstanceCnt - 1) * IdTable[TableIndex].StructSize; + + /* + * Because VPD multiple instance variables are +@@ -1833,9 +1743,7 @@ + */ + Instance = (SK_U32)InstanceCnt; + +- /* +- * Evaluate needed buffer length +- */ ++ /* Evaluate needed buffer length. */ + Len = 0; + Ret = IdTable[TableIndex].Func(pAC, IoC, + SK_PNMI_GET, IdTable[TableIndex].Id, +@@ -1851,8 +1759,7 @@ + pAC->Pnmi.SirqUpdatedFlag --; + + SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); +- SK_PNMI_SET_STAT(pBuf, +- SK_PNMI_ERR_GENERAL, DstOffset); ++ SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_GENERAL, DstOffset); + *pLen = SK_PNMI_MIN_STRUCT_SIZE; + return (SK_PNMI_ERR_GENERAL); + } +@@ -1874,7 +1781,7 @@ + } + } + +- /* Call the OID handler function */ ++ /* Call the OID handler function. */ + Ret = IdTable[TableIndex].Func(pAC, IoC, Action, + IdTable[TableIndex].Id, pBuf + DstOffset, + &Len, Instance, TableIndex, NetIndex); +@@ -1885,8 +1792,7 @@ + pAC->Pnmi.SirqUpdatedFlag --; + + SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); +- SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE, +- DstOffset); ++ SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE, DstOffset); + *pLen = SK_PNMI_MIN_STRUCT_SIZE; + return (SK_PNMI_ERR_BAD_VALUE); + } +@@ -1920,7 +1826,7 @@ + + if (IdTable[i].Id == Id) { + +- return i; ++ return (i); + } + } + +@@ -1961,16 +1867,13 @@ + { + if (Id != OID_SKGE_ALL_DATA) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003, +- SK_PNMI_ERR003MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003, SK_PNMI_ERR003MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + +- /* +- * Check instance. We only handle single instance variables +- */ ++ /* Check instance. We only handle single instance variables. */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; +@@ -2029,10 +1932,7 @@ + int Ret; + SK_U32 ActionOp; + +- +- /* +- * Check instance. We only handle single instance variables +- */ ++ /* Check instance. We only handle single instance variables. */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; +@@ -2045,10 +1945,10 @@ + return (SK_PNMI_ERR_TOO_SHORT); + } + +- /* Check if a get should be performed */ ++ /* Check if a GET should be performed. */ + if (Action == SK_PNMI_GET) { + +- /* A get is easy. We always return the same value */ ++ /* A GET is easy. We always return the same value. */ + ActionOp = (SK_U32)SK_PNMI_ACT_IDLE; + SK_PNMI_STORE_U32(pBuf, ActionOp); + *pLen = sizeof(SK_U32); +@@ -2056,13 +1956,13 @@ + return (SK_PNMI_ERR_OK); + } + +- /* Continue with PRESET/SET action */ ++ /* Continue with PRESET/SET action. */ + if (*pLen > sizeof(SK_U32)) { + + return (SK_PNMI_ERR_BAD_VALUE); + } + +- /* Check if the command is a known one */ ++ /* Check if the command is a known one. */ + SK_PNMI_READ_U32(pBuf, ActionOp); + if (*pLen > sizeof(SK_U32) || + (ActionOp != SK_PNMI_ACT_IDLE && +@@ -2074,7 +1974,7 @@ + return (SK_PNMI_ERR_BAD_VALUE); + } + +- /* A preset ends here */ ++ /* A PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); +@@ -2083,19 +1983,15 @@ + switch (ActionOp) { + + case SK_PNMI_ACT_IDLE: +- /* Nothing to do */ ++ /* Nothing to do. */ + break; + + case SK_PNMI_ACT_RESET: +- /* +- * Perform a driver reset or something that comes near +- * to this. +- */ ++ /* Perform a driver reset or something that comes near to this. */ + Ret = SK_DRIVER_RESET(pAC, IoC); + if (Ret != 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005, +- SK_PNMI_ERR005MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005, SK_PNMI_ERR005MSG); + + return (SK_PNMI_ERR_GENERAL); + } +@@ -2112,13 +2008,12 @@ + break; + + case SK_PNMI_ACT_RESETCNT: +- /* Set all counters and timestamps to zero */ ++ /* Set all counters and timestamps to zero. */ + ResetCounter(pAC, IoC, NetIndex); + break; + + default: +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006, +- SK_PNMI_ERR006MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006, SK_PNMI_ERR006MSG); + + return (SK_PNMI_ERR_GENERAL); + } +@@ -2162,25 +2057,21 @@ + SK_U32 StatVal32; + SK_BOOL Is64BitReq = SK_FALSE; + +- /* +- * Only the active Mac is returned +- */ ++ /* Only the active MAC is returned. */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + +- /* +- * Check action type +- */ ++ /* Check action type. */ + if (Action != SK_PNMI_GET) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + +- /* Check length */ ++ /* Check length. */ + switch (Id) { + + case OID_802_3_PERMANENT_ADDRESS: +@@ -2201,12 +2092,12 @@ + + #else /* SK_NDIS_64BIT_CTR */ + +- /* for compatibility, at least 32bit are required for OID */ ++ /* For compatibility, at least 32 bits are required for OID. */ + if (*pLen < sizeof(SK_U32)) { + /* +- * but indicate handling for 64bit values, +- * if insufficient space is provided +- */ ++ * Indicate handling for 64 bit values, ++ * if insufficient space is provided. ++ */ + *pLen = sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } +@@ -2222,16 +2113,14 @@ + * to indicate that an update was already done. + */ + Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); +- if ( Ret != SK_PNMI_ERR_OK) { ++ if (Ret != SK_PNMI_ERR_OK) { + + *pLen = 0; + return (Ret); + } + pAC->Pnmi.MacUpdatedFlag ++; + +- /* +- * Get value (MAC Index 0 identifies the virtual MAC) +- */ ++ /* Get value (MAC index 0 identifies the virtual MAC). */ + switch (Id) { + + case OID_802_3_PERMANENT_ADDRESS: +@@ -2247,7 +2136,7 @@ + default: + StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex); + +- /* by default 32bit values are evaluated */ ++ /* By default 32 bit values are evaluated. */ + if (!Is64BitReq) { + StatVal32 = (SK_U32)StatVal; + SK_PNMI_STORE_U32(pBuf, StatVal32); +@@ -2301,21 +2190,19 @@ + int MacType; + int Ret; + SK_U64 StatVal; +- +- + +- /* Calculate instance if wished. MAC index 0 is the virtual MAC */ ++ /* Calculate instance if wished. MAC index 0 is the virtual MAC. */ + PhysPortMax = pAC->GIni.GIMacsFound; + LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); + + MacType = pAC->GIni.GIMacType; + +- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ ++ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */ + LogPortMax--; + } + +- if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */ +- /* Check instance range */ ++ if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */ ++ /* Check instance range. */ + if ((Instance < 1) || (Instance > LogPortMax)) { + + *pLen = 0; +@@ -2325,20 +2212,20 @@ + Limit = LogPortIndex + 1; + } + +- else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ ++ else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */ + + LogPortIndex = 0; + Limit = LogPortMax; + } + +- /* Check action */ ++ /* Check action. */ + if (Action != SK_PNMI_GET) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + +- /* Check length */ ++ /* Check length. */ + if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) { + + *pLen = (Limit - LogPortIndex) * sizeof(SK_U64); +@@ -2357,7 +2244,7 @@ + } + pAC->Pnmi.MacUpdatedFlag ++; + +- /* Get value */ ++ /* Get value. */ + Offset = 0; + for (; LogPortIndex < Limit; LogPortIndex ++) { + +@@ -2463,19 +2350,16 @@ + unsigned int Limit; + unsigned int Offset = 0; + +- /* +- * Calculate instance if wished. MAC index 0 is the virtual +- * MAC. +- */ ++ /* Calculate instance if wished. MAC index 0 is the virtual MAC. */ + PhysPortMax = pAC->GIni.GIMacsFound; + LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); + +- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ ++ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */ + LogPortMax--; + } + +- if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */ +- /* Check instance range */ ++ if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */ ++ /* Check instance range. */ + if ((Instance < 1) || (Instance > LogPortMax)) { + + *pLen = 0; +@@ -2484,27 +2368,23 @@ + LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); + Limit = LogPortIndex + 1; + } +- else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ ++ else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */ + + LogPortIndex = 0; + Limit = LogPortMax; + } + +- /* +- * Perform Action +- */ ++ /* Perform action. */ + if (Action == SK_PNMI_GET) { + +- /* Check length */ ++ /* Check length. */ + if (*pLen < (Limit - LogPortIndex) * 6) { + + *pLen = (Limit - LogPortIndex) * 6; + return (SK_PNMI_ERR_TOO_SHORT); + } + +- /* +- * Get value +- */ ++ /* Get value. */ + for (; LogPortIndex < Limit; LogPortIndex ++) { + + switch (Id) { +@@ -2528,8 +2408,7 @@ + &pAC->Addr.Net[NetIndex].PermanentMacAddress); + } + else { +- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( +- pAC, LogPortIndex); ++ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + + CopyMac(pBuf + Offset, + &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress); +@@ -2538,8 +2417,7 @@ + break; + + default: +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008, +- SK_PNMI_ERR008MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008, SK_PNMI_ERR008MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -2550,8 +2428,8 @@ + } + else { + /* +- * The logical MAC address may not be changed only +- * the physical ones ++ * The logical MAC address may not be changed, ++ * only the physical ones. + */ + if (Id == OID_SKGE_PHYS_FAC_ADDR) { + +@@ -2559,19 +2437,16 @@ + return (SK_PNMI_ERR_READ_ONLY); + } + +- /* +- * Only the current address may be changed +- */ ++ /* Only the current address may be changed. */ + if (Id != OID_SKGE_PHYS_CUR_ADDR) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009, +- SK_PNMI_ERR009MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009, SK_PNMI_ERR009MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + +- /* Check length */ ++ /* Check length. */ + if (*pLen < (Limit - LogPortIndex) * 6) { + + *pLen = (Limit - LogPortIndex) * 6; +@@ -2583,32 +2458,26 @@ + return (SK_PNMI_ERR_BAD_VALUE); + } + +- /* +- * Check Action +- */ ++ /* Check action. */ + if (Action == SK_PNMI_PRESET) { + + *pLen = 0; + return (SK_PNMI_ERR_OK); + } + +- /* +- * Set OID_SKGE_MAC_CUR_ADDR +- */ ++ /* Set OID_SKGE_MAC_CUR_ADDR. */ + for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) { + + /* + * A set to virtual port and set of broadcast +- * address will be ignored ++ * address will be ignored. + */ + if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset, + "\xff\xff\xff\xff\xff\xff", 6) == 0) { +- + continue; + } + +- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, +- LogPortIndex); ++ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + + Ret = SkAddrOverride(pAC, IoC, PhysPortIndex, + (SK_MAC_ADDR *)(pBuf + Offset), +@@ -2661,10 +2530,7 @@ + unsigned int Offset = 0; + SK_U64 StatVal; + +- +- /* +- * Calculate instance if wished +- */ ++ /* Calculate instance if wished. */ + if (Instance != (SK_U32)(-1)) { + + if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) { +@@ -2680,25 +2546,21 @@ + Limit = SKCS_NUM_PROTOCOLS; + } + +- /* +- * Check action +- */ ++ /* Check action. */ + if (Action != SK_PNMI_GET) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + +- /* Check length */ ++ /* Check length. */ + if (*pLen < (Limit - Index) * sizeof(SK_U64)) { + + *pLen = (Limit - Index) * sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } + +- /* +- * Get value +- */ ++ /* Get value. */ + for (; Index < Limit; Index ++) { + + switch (Id) { +@@ -2724,8 +2586,7 @@ + break; + + default: +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010, +- SK_PNMI_ERR010MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010, SK_PNMI_ERR010MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -2735,9 +2596,7 @@ + Offset += sizeof(SK_U64); + } + +- /* +- * Store used buffer space +- */ ++ /* Store used buffer space. */ + *pLen = Offset; + + return (SK_PNMI_ERR_OK); +@@ -2780,10 +2639,7 @@ + SK_U32 Val32; + SK_U64 Val64; + +- +- /* +- * Calculate instance if wished +- */ ++ /* Calculate instance if wished. */ + if ((Instance != (SK_U32)(-1))) { + + if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) { +@@ -2800,16 +2656,14 @@ + Limit = (unsigned int) pAC->I2c.MaxSens; + } + +- /* +- * Check action +- */ ++ /* Check action. */ + if (Action != SK_PNMI_GET) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + +- /* Check length */ ++ /* Check length. */ + switch (Id) { + + case OID_SKGE_SENSOR_VALUE: +@@ -2831,8 +2685,7 @@ + SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1; + if (Len >= SK_PNMI_STRINGLEN2) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011, +- SK_PNMI_ERR011MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011, SK_PNMI_ERR011MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -2868,38 +2721,32 @@ + break; + + default: +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012, +- SK_PNMI_ERR012MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012, SK_PNMI_ERR012MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +- + } + +- /* +- * Get value +- */ ++ /* Get value. */ + for (Offset = 0; Index < Limit; Index ++) { + + switch (Id) { + + case OID_SKGE_SENSOR_INDEX: + *(pBuf + Offset) = (char)Index; +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_SENSOR_DESCR: + Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc); +- SK_MEMCPY(pBuf + Offset + 1, +- pAC->I2c.SenTable[Index].SenDesc, Len); ++ SK_MEMCPY(pBuf + Offset + 1, pAC->I2c.SenTable[Index].SenDesc, Len); + *(pBuf + Offset) = (char)Len; + Offset += Len + 1; + break; + + case OID_SKGE_SENSOR_TYPE: +- *(pBuf + Offset) = +- (char)pAC->I2c.SenTable[Index].SenType; +- Offset += sizeof(char); ++ *(pBuf + Offset) = (char)pAC->I2c.SenTable[Index].SenType; ++ Offset++; + break; + + case OID_SKGE_SENSOR_VALUE: +@@ -2936,9 +2783,8 @@ + break; + + case OID_SKGE_SENSOR_STATUS: +- *(pBuf + Offset) = +- (char)pAC->I2c.SenTable[Index].SenErrFlag; +- Offset += sizeof(char); ++ *(pBuf + Offset) = (char)pAC->I2c.SenTable[Index].SenErrFlag; ++ Offset++; + break; + + case OID_SKGE_SENSOR_WAR_CTS: +@@ -2975,9 +2821,7 @@ + } + } + +- /* +- * Store used buffer space +- */ ++ /* Store used buffer space. */ + *pLen = Offset; + + return (SK_PNMI_ERR_OK); +@@ -3032,8 +2876,29 @@ + SK_U32 Val32; + + /* +- * Get array of all currently stored VPD keys ++ * VpdKeyReadError will be set in GetVpdKeyArr() if an error occurs. ++ * Due to the fact that some drivers use SkPnmiGetStruct() to retrieve ++ * all statistical data, an error in GetVpdKeyArr() will generate a PNMI ++ * error and terminate SkPnmiGetStruct() without filling in statistical ++ * data into the PNMI struct. In this case the driver will get no values ++ * for statistical purposes (netstat, ifconfig etc.). GetVpdKeyArr() is ++ * the first function to be called in SkPnmiGetStruct(), so any error ++ * will terminate SkPnmiGetStruct() immediately. Hence, VpdKeyReadError will ++ * be set during the first call to GetVpdKeyArr() to make successful calls ++ * to SkPnmiGetStruct() possible. But there is another point to consider: ++ * When filling in the statistical data into the PNMI struct, the VPD ++ * handler Vpd() will also be called. If GetVpdKeyArr() in Vpd() would ++ * return with SK_PNMI_ERR_GENERAL, SkPnmiGetStruct() would fail again. ++ * For this reason VpdKeyReadError is checked here and, if set, Vpd() ++ * will return without doing anything and the return value SK_PNMI_ERR_OK. ++ * Therefore SkPnmiGetStruct() is able to continue and fill in all other ++ * statistical data. + */ ++ if (pAC->Pnmi.VpdKeyReadError == SK_TRUE) { ++ return (SK_PNMI_ERR_OK); ++ } ++ ++ /* Get array of all currently stored VPD keys. */ + Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo); + if (Ret != SK_PNMI_ERR_OK) { + *pLen = 0; +@@ -3078,46 +2943,45 @@ + } + } + +- /* +- * Get value, if a query should be performed +- */ ++ /* Get value, if a query should be performed. */ + if (Action == SK_PNMI_GET) { + + switch (Id) { + + case OID_SKGE_VPD_FREE_BYTES: +- /* Check length of buffer */ ++ /* Check length of buffer. */ + if (*pLen < sizeof(SK_U32)) { + + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } +- /* Get number of free bytes */ ++ /* Get number of free bytes. */ + pVpdStatus = VpdStat(pAC, IoC); ++ + if (pVpdStatus == NULL) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017, +- SK_PNMI_ERR017MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR017MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + if ((pVpdStatus->vpd_status & VPD_VALID) == 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018, +- SK_PNMI_ERR018MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR018MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } +- ++ + Val32 = (SK_U32)pVpdStatus->vpd_free_rw; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_VPD_ENTRIES_LIST: +- /* Check length */ ++ /* Check length. */ + for (Len = 0, Index = 0; Index < KeyNo; Index ++) { + + Len += SK_STRLEN(KeyArr[Index]) + 1; +@@ -3128,7 +2992,7 @@ + return (SK_PNMI_ERR_TOO_SHORT); + } + +- /* Get value */ ++ /* Get value. */ + *(pBuf) = (char)Len - 1; + for (Offset = 1, Index = 0; Index < KeyNo; Index ++) { + +@@ -3140,14 +3004,14 @@ + if (Index < KeyNo - 1) { + + *(pBuf + Offset) = ' '; +- Offset ++; ++ Offset++; + } + } + *pLen = Offset; + break; + + case OID_SKGE_VPD_ENTRIES_NUMBER: +- /* Check length */ ++ /* Check length. */ + if (*pLen < sizeof(SK_U32)) { + + *pLen = sizeof(SK_U32); +@@ -3160,7 +3024,7 @@ + break; + + case OID_SKGE_VPD_KEY: +- /* Check buffer length, if it is large enough */ ++ /* Check buffer length, if it is large enough. */ + for (Len = 0, Index = FirstIndex; + Index < LastIndex; Index ++) { + +@@ -3174,34 +3038,29 @@ + + /* + * Get the key to an intermediate buffer, because +- * we have to prepend a length byte. ++ * we have to pretend a length byte. + */ +- for (Offset = 0, Index = FirstIndex; +- Index < LastIndex; Index ++) { ++ for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) { + + Len = SK_STRLEN(KeyArr[Index]); + + *(pBuf + Offset) = (char)Len; +- SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index], +- Len); ++ SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index], Len); + Offset += Len + 1; + } + *pLen = Offset; + break; + + case OID_SKGE_VPD_VALUE: +- /* Check the buffer length if it is large enough */ +- for (Offset = 0, Index = FirstIndex; +- Index < LastIndex; Index ++) { ++ /* Check the buffer length if it is large enough. */ ++ for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) { + + BufLen = 256; +- if (VpdRead(pAC, IoC, KeyArr[Index], Buf, +- (int *)&BufLen) > 0 || ++ if (VpdRead(pAC, IoC, KeyArr[Index], Buf, (int *)&BufLen) > 0 || + BufLen >= SK_PNMI_VPD_DATALEN) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, +- SK_PNMI_ERR021, +- SK_PNMI_ERR021MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR021MSG)); + + return (SK_PNMI_ERR_GENERAL); + } +@@ -3215,19 +3074,16 @@ + + /* + * Get the value to an intermediate buffer, because +- * we have to prepend a length byte. ++ * we have to pretend a length byte. + */ +- for (Offset = 0, Index = FirstIndex; +- Index < LastIndex; Index ++) { ++ for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) { + + BufLen = 256; +- if (VpdRead(pAC, IoC, KeyArr[Index], Buf, +- (int *)&BufLen) > 0 || ++ if (VpdRead(pAC, IoC, KeyArr[Index], Buf, (int *)&BufLen) > 0 || + BufLen >= SK_PNMI_VPD_DATALEN) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, +- SK_PNMI_ERR022, +- SK_PNMI_ERR022MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR022MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3247,8 +3103,7 @@ + return (SK_PNMI_ERR_TOO_SHORT); + } + +- for (Offset = 0, Index = FirstIndex; +- Index < LastIndex; Index ++) { ++ for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) { + + if (VpdMayWrite(KeyArr[Index])) { + +@@ -3257,7 +3112,7 @@ + else { + *(pBuf + Offset) = SK_PNMI_VPD_RO; + } +- Offset ++; ++ Offset++; + } + *pLen = Offset; + break; +@@ -3274,15 +3129,15 @@ + break; + + default: +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023, +- SK_PNMI_ERR023MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR023MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + else { +- /* The only OID which can be set is VPD_ACTION */ ++ /* The only OID which can be set is VPD_ACTION. */ + if (Id != OID_SKGE_VPD_ACTION) { + + if (Id == OID_SKGE_VPD_FREE_BYTES || +@@ -3296,8 +3151,8 @@ + return (SK_PNMI_ERR_READ_ONLY); + } + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024, +- SK_PNMI_ERR024MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR024MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3313,14 +3168,11 @@ + return (SK_PNMI_ERR_TOO_SHORT); + } + +- /* +- * The first byte contains the VPD action type we should +- * perform. +- */ ++ /* The first byte contains the VPD action type we should perform. */ + switch (*pBuf) { + + case SK_PNMI_VPD_IGNORE: +- /* Nothing to do */ ++ /* Nothing to do. */ + break; + + case SK_PNMI_VPD_CREATE: +@@ -3352,13 +3204,13 @@ + SK_MEMCPY(Buf, pBuf + 4, Offset); + Buf[Offset] = 0; + +- /* A preset ends here */ ++ /* A PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + +- /* Write the new entry or modify an existing one */ ++ /* Write the new entry or modify an existing one .*/ + Ret = VpdWrite(pAC, IoC, KeyStr, Buf); + if (Ret == SK_PNMI_VPD_NOWRITE ) { + +@@ -3367,8 +3219,8 @@ + } + else if (Ret != SK_PNMI_VPD_OK) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025, +- SK_PNMI_ERR025MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR025MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3381,8 +3233,8 @@ + Ret = VpdUpdate(pAC, IoC); + if (Ret != SK_PNMI_VPD_OK) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026, +- SK_PNMI_ERR026MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR026MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3390,7 +3242,7 @@ + break; + + case SK_PNMI_VPD_DELETE: +- /* Check if the buffer size is plausible */ ++ /* Check if the buffer size is plausible. */ + if (*pLen < 3) { + + *pLen = 3; +@@ -3405,7 +3257,7 @@ + KeyStr[1] = pBuf[2]; + KeyStr[2] = 0; + +- /* Find the passed key in the array */ ++ /* Find the passed key in the array. */ + for (Index = 0; Index < KeyNo; Index ++) { + + if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) { +@@ -3413,6 +3265,7 @@ + break; + } + } ++ + /* + * If we cannot find the key it is wrong, so we + * return an appropriate error value. +@@ -3428,12 +3281,12 @@ + return (SK_PNMI_ERR_OK); + } + +- /* Ok, you wanted it and you will get it */ ++ /* Ok, you wanted it and you will get it. */ + Ret = VpdDelete(pAC, IoC, KeyStr); + if (Ret != SK_PNMI_VPD_OK) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027, +- SK_PNMI_ERR027MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR027MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3446,8 +3299,8 @@ + Ret = VpdUpdate(pAC, IoC); + if (Ret != SK_PNMI_VPD_OK) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028, +- SK_PNMI_ERR028MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR028MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3501,34 +3354,30 @@ + SK_U32 Val32; + SK_U64 Val64; + SK_U64 Val64RxHwErrs = 0; ++ SK_U64 Val64RxRunt = 0; ++ SK_U64 Val64RxFcs = 0; + SK_U64 Val64TxHwErrs = 0; + SK_BOOL Is64BitReq = SK_FALSE; + char Buf[256]; + int MacType; + +- /* +- * Check instance. We only handle single instance variables. +- */ ++ /* Check instance. We only handle single instance variables. */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + +- /* +- * Check action. We only allow get requests. +- */ ++ /* Check action. We only allow get requests. */ + if (Action != SK_PNMI_GET) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } +- ++ + MacType = pAC->GIni.GIMacType; +- +- /* +- * Check length for the various supported OIDs +- */ ++ ++ /* Check length for the various supported OIDs. */ + switch (Id) { + + case OID_GEN_XMIT_ERROR: +@@ -3542,14 +3391,12 @@ + + #else /* SK_NDIS_64BIT_CTR */ + +- /* +- * for compatibility, at least 32bit are required for oid +- */ ++ /* For compatibility, at least 32bit are required for OID. */ + if (*pLen < sizeof(SK_U32)) { + /* +- * but indicate handling for 64bit values, +- * if insufficient space is provided +- */ ++ * Indicate handling for 64bit values, ++ * if insufficient space is provided. ++ */ + *pLen = sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } +@@ -3620,11 +3467,11 @@ + break; + + default: +- /* Checked later */ ++ /* Checked later. */ + break; + } + +- /* Update statistic */ ++ /* Update statistics. */ + if (Id == OID_SKGE_RX_HW_ERROR_CTS || + Id == OID_SKGE_TX_HW_ERROR_CTS || + Id == OID_SKGE_IN_ERRORS_CTS || +@@ -3632,7 +3479,8 @@ + Id == OID_GEN_XMIT_ERROR || + Id == OID_GEN_RCV_ERROR) { + +- /* Force the XMAC to update its statistic counters and ++ /* ++ * Force the XMAC to update its statistic counters and + * Increment semaphore to indicate that an update was + * already done. + */ +@@ -3663,11 +3511,26 @@ + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) + +- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) + +- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex); +- break; ++ ++ ++ /* ++ * In some cases the runt and fcs counters are incremented when collisions ++ * occur. We have to correct those counters here. ++ */ ++ Val64RxRunt = GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex); ++ Val64RxFcs = GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex); ++ ++ if (Val64RxRunt > Val64RxFcs) { ++ Val64RxRunt -= Val64RxFcs; ++ Val64RxHwErrs += Val64RxRunt; ++ } ++ else { ++ Val64RxFcs -= Val64RxRunt; ++ Val64RxHwErrs += Val64RxFcs; ++ } ++ break; + + case OID_SKGE_TX_HW_ERROR_CTS: + case OID_SKGE_OUT_ERROR_CTS: +@@ -3681,9 +3544,7 @@ + } + } + +- /* +- * Retrieve value +- */ ++ /* Retrieve value. */ + switch (Id) { + + case OID_SKGE_SUPPORTED_LIST: +@@ -3693,11 +3554,11 @@ + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } +- for (Offset = 0, Index = 0; Offset < Len; +- Offset += sizeof(SK_U32), Index ++) { ++ for (Offset = 0, Index = 0; Offset < Len; Index ++) { + + Val32 = (SK_U32)IdTable[Index].Id; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); ++ Offset += sizeof(SK_U32); + } + *pLen = Len; + break; +@@ -3723,8 +3584,7 @@ + case OID_SKGE_DRIVER_DESCR: + if (pAC->Pnmi.pDriverDescription == NULL) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007, +- SK_PNMI_ERR007MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007, SK_PNMI_ERR007MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3733,8 +3593,7 @@ + Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1; + if (Len > SK_PNMI_STRINGLEN1) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029, +- SK_PNMI_ERR029MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029, SK_PNMI_ERR029MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3753,8 +3612,7 @@ + case OID_SKGE_DRIVER_VERSION: + if (pAC->Pnmi.pDriverVersion == NULL) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, +- SK_PNMI_ERR030MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, SK_PNMI_ERR030MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3763,8 +3621,7 @@ + Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1; + if (Len > SK_PNMI_STRINGLEN1) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, +- SK_PNMI_ERR031MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, SK_PNMI_ERR031MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3783,8 +3640,7 @@ + case OID_SKGE_DRIVER_RELDATE: + if (pAC->Pnmi.pDriverReleaseDate == NULL) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, +- SK_PNMI_ERR053MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR053, SK_PNMI_ERR053MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3793,8 +3649,7 @@ + Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1; + if (Len > SK_PNMI_STRINGLEN1) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, +- SK_PNMI_ERR054MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR054, SK_PNMI_ERR054MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3813,8 +3668,7 @@ + case OID_SKGE_DRIVER_FILENAME: + if (pAC->Pnmi.pDriverFileName == NULL) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, +- SK_PNMI_ERR055MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR055, SK_PNMI_ERR055MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3823,8 +3677,7 @@ + Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1; + if (Len > SK_PNMI_STRINGLEN1) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, +- SK_PNMI_ERR056MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR056, SK_PNMI_ERR056MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3846,12 +3699,16 @@ + * query may move to the initialisation routine. But + * the VPD data is cached and therefore a call here + * will not make much difference. ++ * Please read comment in Vpd(). + */ ++ if (pAC->Pnmi.VpdKeyReadError == SK_TRUE) { ++ return (SK_PNMI_ERR_OK); ++ } ++ + Len = 256; + if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032, +- SK_PNMI_ERR032MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032, SK_PNMI_ERR032MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3859,8 +3716,7 @@ + Len ++; + if (Len > SK_PNMI_STRINGLEN1) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033, +- SK_PNMI_ERR033MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033, SK_PNMI_ERR033MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -3876,7 +3732,6 @@ + break; + + case OID_SKGE_HW_VERSION: +- /* Oh, I love to do some string manipulation */ + if (*pLen < 5) { + + *pLen = 5; +@@ -3885,9 +3740,9 @@ + Val8 = (SK_U8)pAC->GIni.GIPciHwRev; + pBuf[0] = 4; + pBuf[1] = 'v'; +- pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F)); ++ pBuf[2] = (char)('0' | ((Val8 >> 4) & 0x0f)); + pBuf[3] = '.'; +- pBuf[4] = (char)(0x30 | (Val8 & 0x0F)); ++ pBuf[4] = (char)('0' | (Val8 & 0x0f)); + *pLen = 5; + break; + +@@ -3910,12 +3765,12 @@ + break; + + case OID_SKGE_VAUXAVAIL: +- *pBuf = (char) pAC->GIni.GIVauxAvail; ++ *pBuf = (char)pAC->GIni.GIVauxAvail; + *pLen = sizeof(char); + break; + + case OID_SKGE_BUS_TYPE: +- *pBuf = (char) SK_PNMI_BUS_PCI; ++ *pBuf = (char)SK_PNMI_BUS_PCI; + *pLen = sizeof(char); + break; + +@@ -3964,31 +3819,31 @@ + break; + + case OID_SKGE_RLMT_MONITOR_NUMBER: +-/* XXX Not yet implemented by RLMT therefore we return zero elements */ ++ /* Not yet implemented by RLMT, therefore we return zero elements. */ + Val32 = 0; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_TX_SW_QUEUE_LEN: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen + + pAC->Pnmi.BufPort[1].TxSwQueueLen; + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].TxSwQueueLen + + pAC->Pnmi.Port[1].TxSwQueueLen; +@@ -4000,24 +3855,24 @@ + + + case OID_SKGE_TX_SW_QUEUE_MAX: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax + + pAC->Pnmi.BufPort[1].TxSwQueueMax; + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].TxSwQueueMax + + pAC->Pnmi.Port[1].TxSwQueueMax; +@@ -4028,24 +3883,24 @@ + break; + + case OID_SKGE_TX_RETRY: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxRetryCts + + pAC->Pnmi.BufPort[1].TxRetryCts; + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].TxRetryCts + + pAC->Pnmi.Port[1].TxRetryCts; +@@ -4056,24 +3911,24 @@ + break; + + case OID_SKGE_RX_INTR_CTS: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].RxIntrCts + + pAC->Pnmi.BufPort[1].RxIntrCts; + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].RxIntrCts + + pAC->Pnmi.Port[1].RxIntrCts; +@@ -4084,24 +3939,24 @@ + break; + + case OID_SKGE_TX_INTR_CTS: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxIntrCts + + pAC->Pnmi.BufPort[1].TxIntrCts; + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].TxIntrCts + + pAC->Pnmi.Port[1].TxIntrCts; +@@ -4112,24 +3967,24 @@ + break; + + case OID_SKGE_RX_NO_BUF_CTS: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts + + pAC->Pnmi.BufPort[1].RxNoBufCts; + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].RxNoBufCts + + pAC->Pnmi.Port[1].RxNoBufCts; +@@ -4140,24 +3995,24 @@ + break; + + case OID_SKGE_TX_NO_BUF_CTS: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts + + pAC->Pnmi.BufPort[1].TxNoBufCts; + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].TxNoBufCts + + pAC->Pnmi.Port[1].TxNoBufCts; +@@ -4168,24 +4023,24 @@ + break; + + case OID_SKGE_TX_USED_DESCR_NO: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo + + pAC->Pnmi.BufPort[1].TxUsedDescrNo; + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo + + pAC->Pnmi.Port[1].TxUsedDescrNo; +@@ -4196,24 +4051,24 @@ + break; + + case OID_SKGE_RX_DELIVERED_CTS: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts + + pAC->Pnmi.BufPort[1].RxDeliveredCts; + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].RxDeliveredCts + + pAC->Pnmi.Port[1].RxDeliveredCts; +@@ -4224,24 +4079,24 @@ + break; + + case OID_SKGE_RX_OCTETS_DELIV_CTS: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts + + pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts; + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts + + pAC->Pnmi.Port[1].RxOctetsDeliveredCts; +@@ -4262,13 +4117,13 @@ + break; + + case OID_SKGE_IN_ERRORS_CTS: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = Val64RxHwErrs + + pAC->Pnmi.BufPort[0].RxNoBufCts + +@@ -4276,11 +4131,11 @@ + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = Val64RxHwErrs + + pAC->Pnmi.Port[0].RxNoBufCts + +@@ -4292,13 +4147,13 @@ + break; + + case OID_SKGE_OUT_ERROR_CTS: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = Val64TxHwErrs + + pAC->Pnmi.BufPort[0].TxNoBufCts + +@@ -4306,11 +4161,11 @@ + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = Val64TxHwErrs + + pAC->Pnmi.Port[0].TxNoBufCts + +@@ -4322,24 +4177,24 @@ + break; + + case OID_SKGE_ERR_RECOVERY_CTS: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts + + pAC->Pnmi.BufPort[1].ErrRecoveryCts; + } + } + else { +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts; + } +- /* Single net mode */ ++ /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts + + pAC->Pnmi.Port[1].ErrRecoveryCts; +@@ -4363,7 +4218,7 @@ + break; + + case OID_GEN_RCV_ERROR: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; + } +@@ -4372,7 +4227,7 @@ + } + + /* +- * by default 32bit values are evaluated ++ * By default 32bit values are evaluated. + */ + if (!Is64BitReq) { + Val32 = (SK_U32)Val64; +@@ -4386,7 +4241,7 @@ + break; + + case OID_GEN_XMIT_ERROR: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; + } +@@ -4395,7 +4250,7 @@ + } + + /* +- * by default 32bit values are evaluated ++ * By default 32bit values are evaluated. + */ + if (!Is64BitReq) { + Val32 = (SK_U32)Val64; +@@ -4409,16 +4264,19 @@ + break; + + case OID_GEN_RCV_NO_BUFFER: +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { +- Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; ++ Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts + ++ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex); ++ + } + else { +- Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; ++ Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts + ++ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex); + } + + /* +- * by default 32bit values are evaluated ++ * By default 32bit values are evaluated. + */ + if (!Is64BitReq) { + Val32 = (SK_U32)Val64; +@@ -4438,8 +4296,7 @@ + break; + + default: +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034, +- SK_PNMI_ERR034MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034, SK_PNMI_ERR034MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -4496,25 +4353,17 @@ + SK_U32 Val32; + SK_U64 Val64; + +- +- /* +- * Check instance. Only single instance OIDs are allowed here. +- */ ++ /* Check instance. Only single instance OIDs are allowed here. */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + +- /* +- * Perform the requested action. +- */ ++ /* Perform the requested action. */ + if (Action == SK_PNMI_GET) { + +- /* +- * Check if the buffer length is large enough. +- */ +- ++ /* Check if the buffer length is large enough. */ + switch (Id) { + + case OID_SKGE_RLMT_MODE: +@@ -4547,8 +4396,7 @@ + break; + + default: +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035, +- SK_PNMI_ERR035MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035, SK_PNMI_ERR035MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -4567,9 +4415,7 @@ + } + pAC->Pnmi.RlmtUpdatedFlag ++; + +- /* +- * Retrieve Value +- */ ++ /* Retrieve value. */ + switch (Id) { + + case OID_SKGE_RLMT_MODE: +@@ -4647,17 +4493,17 @@ + pAC->Pnmi.RlmtUpdatedFlag --; + } + else { +- /* Perform a preset or set */ ++ /* Perform a PRESET or SET. */ + switch (Id) { + + case OID_SKGE_RLMT_MODE: +- /* Check if the buffer length is plausible */ ++ /* Check if the buffer length is plausible. */ + if (*pLen < sizeof(char)) { + + *pLen = sizeof(char); + return (SK_PNMI_ERR_TOO_SHORT); + } +- /* Check if the value range is correct */ ++ /* Check if the value range is correct. */ + if (*pLen != sizeof(char) || + (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 || + *(SK_U8 *)pBuf > 15) { +@@ -4665,21 +4511,21 @@ + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } +- /* The preset ends here */ ++ /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + *pLen = 0; + return (SK_PNMI_ERR_OK); + } +- /* Send an event to RLMT to change the mode */ ++ /* Send an event to RLMT to change the mode. */ + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); ++ + EventParam.Para32[0] |= (SK_U32)(*pBuf); + EventParam.Para32[1] = 0; + if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, + EventParam) > 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037, +- SK_PNMI_ERR037MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037, SK_PNMI_ERR037MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -4687,20 +4533,25 @@ + break; + + case OID_SKGE_RLMT_PORT_PREFERRED: +- /* Check if the buffer length is plausible */ ++ /* PRESET/SET action makes no sense in Dual Net mode. */ ++ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { ++ break; ++ } ++ ++ /* Check if the buffer length is plausible. */ + if (*pLen < sizeof(char)) { + + *pLen = sizeof(char); + return (SK_PNMI_ERR_TOO_SHORT); + } +- /* Check if the value range is correct */ ++ /* Check if the value range is correct. */ + if (*pLen != sizeof(char) || *(SK_U8 *)pBuf > + (SK_U8)pAC->GIni.GIMacsFound) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } +- /* The preset ends here */ ++ /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + *pLen = 0; +@@ -4713,13 +4564,13 @@ + * make the decision which is the preferred port. + */ + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); ++ + EventParam.Para32[0] = (SK_U32)(*pBuf) - 1; + EventParam.Para32[1] = NetIndex; + if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, + EventParam) > 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038, +- SK_PNMI_ERR038MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038, SK_PNMI_ERR038MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -4727,22 +4578,20 @@ + break; + + case OID_SKGE_RLMT_CHANGE_THRES: +- /* Check if the buffer length is plausible */ ++ /* Check if the buffer length is plausible. */ + if (*pLen < sizeof(SK_U64)) { + + *pLen = sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } +- /* +- * There are not many restrictions to the +- * value range. +- */ ++ ++ /* There are not many restrictions to the value range. */ + if (*pLen != sizeof(SK_U64)) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } +- /* A preset ends here */ ++ /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + *pLen = 0; +@@ -4757,7 +4606,7 @@ + break; + + default: +- /* The other OIDs are not be able for set */ ++ /* The other OIDs are not be able for set. */ + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } +@@ -4802,54 +4651,48 @@ + SK_U32 Val32; + SK_U64 Val64; + +- /* +- * Calculate the port indexes from the instance. +- */ ++ /* Calculate the port indexes from the instance. */ + PhysPortMax = pAC->GIni.GIMacsFound; + + if ((Instance != (SK_U32)(-1))) { +- /* Check instance range */ ++ /* Check instance range. */ + if ((Instance < 1) || (Instance > PhysPortMax)) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + +- /* Single net mode */ ++ /* SingleNet mode. */ + PhysPortIndex = Instance - 1; + +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + PhysPortIndex = NetIndex; + } + +- /* Both net modes */ ++ /* Both net modes. */ + Limit = PhysPortIndex + 1; + } + else { +- /* Single net mode */ ++ /* SingleNet mode. */ + PhysPortIndex = 0; + Limit = PhysPortMax; + +- /* Dual net mode */ ++ /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + PhysPortIndex = NetIndex; + Limit = PhysPortIndex + 1; + } + } + +- /* +- * Currently only get requests are allowed. +- */ ++ /* Currently only GET requests are allowed. */ + if (Action != SK_PNMI_GET) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + +- /* +- * Check if the buffer length is large enough. +- */ ++ /* Check if the buffer length is large enough. */ + switch (Id) { + + case OID_SKGE_RLMT_PORT_INDEX: +@@ -4873,8 +4716,7 @@ + break; + + default: +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039, +- SK_PNMI_ERR039MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039, SK_PNMI_ERR039MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -4892,9 +4734,7 @@ + } + pAC->Pnmi.RlmtUpdatedFlag ++; + +- /* +- * Get value +- */ ++ /* Get value. */ + Offset = 0; + for (; PhysPortIndex < Limit; PhysPortIndex ++) { + +@@ -5007,19 +4847,20 @@ + int Ret; + SK_EVPARA EventParam; + SK_U32 Val32; ++#ifdef SK_PHY_LP_MODE ++ SK_U8 CurrentPhyPowerState; ++#endif /* SK_PHY_LP_MODE */ + +- /* +- * Calculate instance if wished. MAC index 0 is the virtual MAC. +- */ ++ /* Calculate instance if wished. MAC index 0 is the virtual MAC. */ + PhysPortMax = pAC->GIni.GIMacsFound; + LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); + +- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ ++ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */ + LogPortMax--; + } + +- if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */ +- /* Check instance range */ ++ if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */ ++ /* Check instance range. */ + if ((Instance < 1) || (Instance > LogPortMax)) { + + *pLen = 0; +@@ -5029,18 +4870,16 @@ + Limit = LogPortIndex + 1; + } + +- else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ ++ else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */ + + LogPortIndex = 0; + Limit = LogPortMax; + } + +- /* +- * Perform action +- */ ++ /* Perform action. */ + if (Action == SK_PNMI_GET) { + +- /* Check length */ ++ /* Check length. */ + switch (Id) { + + case OID_SKGE_PMD: +@@ -5058,6 +4897,9 @@ + case OID_SKGE_SPEED_CAP: + case OID_SKGE_SPEED_MODE: + case OID_SKGE_SPEED_STATUS: ++#ifdef SK_PHY_LP_MODE ++ case OID_SKGE_PHY_LP_MODE: ++#endif + if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) { + + *pLen = (Limit - LogPortIndex) * sizeof(SK_U8); +@@ -5065,8 +4907,8 @@ + } + break; + +- case OID_SKGE_MTU: +- case OID_SKGE_PHY_TYPE: ++ case OID_SKGE_MTU: ++ case OID_SKGE_PHY_TYPE: + if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) { + + *pLen = (Limit - LogPortIndex) * sizeof(SK_U32); +@@ -5075,8 +4917,7 @@ + break; + + default: +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041, +- SK_PNMI_ERR041MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041, SK_PNMI_ERR041MSG); + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } +@@ -5092,97 +4933,109 @@ + } + pAC->Pnmi.SirqUpdatedFlag ++; + +- /* +- * Get value +- */ ++ /* Get value. */ + Offset = 0; + for (; LogPortIndex < Limit; LogPortIndex ++) { + + pBufPtr = pBuf + Offset; +- ++ + switch (Id) { + + case OID_SKGE_PMD: + *pBufPtr = pAC->Pnmi.PMD; +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_CONNECTOR: + *pBufPtr = pAC->Pnmi.Connector; +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_PHY_TYPE: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + continue; + } +- else { +- /* Get value for physical ports */ +- PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( +- pAC, LogPortIndex); +- Val32 = pAC->GIni.GP[PhysPortIndex].PhyType; +- SK_PNMI_STORE_U32(pBufPtr, Val32); +- } ++ /* Get value for physical port. */ ++ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); ++ Val32 = pAC->GIni.GP[PhysPortIndex].PhyType; + } +- else { /* DualNetMode */ ++ else { /* DualNet mode. */ + + Val32 = pAC->GIni.GP[NetIndex].PhyType; +- SK_PNMI_STORE_U32(pBufPtr, Val32); + } ++ SK_PNMI_STORE_U32(pBufPtr, Val32); + Offset += sizeof(SK_U32); + break; + ++#ifdef SK_PHY_LP_MODE ++ case OID_SKGE_PHY_LP_MODE: ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ ++ if (LogPortIndex == 0) { ++ continue; ++ } ++ /* Get value for physical port. */ ++ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); ++ *pBufPtr = (SK_U8)pAC->GIni.GP[PhysPortIndex].PPhyPowerState; ++ } ++ else { /* DualNet mode. */ ++ ++ *pBufPtr = (SK_U8)pAC->GIni.GP[NetIndex].PPhyPowerState; ++ } ++ Offset += sizeof(SK_U8); ++ break; ++#endif ++ + case OID_SKGE_LINK_CAP: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical ports */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap; + } + } +- else { /* DualNetMode */ ++ else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap; + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_LINK_MODE: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical ports */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf; + } + } +- else { /* DualNetMode */ +- ++ else { /* DualNet mode. */ ++ + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf; + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_LINK_MODE_STATUS: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical port */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + +@@ -5190,223 +5043,223 @@ + CalculateLinkModeStatus(pAC, IoC, PhysPortIndex); + } + } +- else { /* DualNetMode */ +- ++ else { /* DualNet mode. */ ++ + *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex); + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_LINK_STATUS: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical ports */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex); + } + } +- else { /* DualNetMode */ ++ else { /* DualNet mode. */ + + *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex); + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_FLOWCTRL_CAP: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical ports */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap; + } + } +- else { /* DualNetMode */ +- ++ else { /* DualNet mode. */ ++ + *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap; + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_FLOWCTRL_MODE: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical port */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode; + } + } +- else { /* DualNetMode */ ++ else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode; + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_FLOWCTRL_STATUS: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical port */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus; + } + } +- else { /* DualNetMode */ ++ else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus; + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_PHY_OPERATION_CAP: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet Mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical ports */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap; + } + } +- else { /* DualNetMode */ +- ++ else { /* DualNet mode. */ ++ + *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap; + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_PHY_OPERATION_MODE: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical port */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode; + } + } +- else { /* DualNetMode */ +- ++ else { /* DualNet mode. */ ++ + *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode; + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_PHY_OPERATION_STATUS: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical port */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); +- ++ + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus; + } + } + else { +- ++ + *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus; + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_SPEED_CAP: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical ports */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap; + } + } +- else { /* DualNetMode */ +- ++ else { /* DualNet mode. */ ++ + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap; + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_SPEED_MODE: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical port */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed; + } + } +- else { /* DualNetMode */ ++ else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed; + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_SPEED_STATUS: +- if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { +- /* Get value for virtual port */ ++ /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { +- /* Get value for physical port */ ++ /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed; + } + } +- else { /* DualNetMode */ ++ else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed; + } +- Offset += sizeof(char); ++ Offset++; + break; +- ++ + case OID_SKGE_MTU: + Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex); + SK_PNMI_STORE_U32(pBufPtr, Val32); +@@ -5449,38 +5302,41 @@ + } + break; + +- case OID_SKGE_MTU: +- if (*pLen < sizeof(SK_U32)) { ++#ifdef SK_PHY_LP_MODE ++ case OID_SKGE_PHY_LP_MODE: ++ if (*pLen < Limit - LogPortIndex) { + +- *pLen = sizeof(SK_U32); ++ *pLen = Limit - LogPortIndex; + return (SK_PNMI_ERR_TOO_SHORT); + } +- if (*pLen != sizeof(SK_U32)) { ++ break; ++#endif /* SK_PHY_LP_MODE */ + +- *pLen = 0; +- return (SK_PNMI_ERR_BAD_VALUE); ++ case OID_SKGE_MTU: ++ if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) { ++ ++ *pLen = (Limit - LogPortIndex) * sizeof(SK_U32); ++ return (SK_PNMI_ERR_TOO_SHORT); + } + break; + +- default: ++ default: + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + +- /* +- * Perform preset or set +- */ ++ /* Perform PRESET or SET. */ + Offset = 0; + for (; LogPortIndex < Limit; LogPortIndex ++) { + ++ Val8 = *(pBuf + Offset); ++ + switch (Id) { + + case OID_SKGE_LINK_MODE: +- /* Check the value range */ +- Val8 = *(pBuf + Offset); ++ /* Check the value range. */ + if (Val8 == 0) { +- +- Offset += sizeof(char); ++ Offset++; + break; + } + if (Val8 < SK_LMODE_HALF || +@@ -5491,37 +5347,51 @@ + return (SK_PNMI_ERR_BAD_VALUE); + } + +- /* The preset ends here */ ++ /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + +- if (LogPortIndex == 0) { ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ ++ if (LogPortIndex == 0) { ++ /* ++ * The virtual port consists of all currently ++ * active ports. Find them and send an event ++ * with the new link mode to SIRQ. ++ */ ++ for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; ++ PhysPortIndex ++) { + +- /* +- * The virtual port consists of all currently +- * active ports. Find them and send an event +- * with the new link mode to SIRQ. +- */ +- for (PhysPortIndex = 0; +- PhysPortIndex < PhysPortMax; +- PhysPortIndex ++) { ++ if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { ++ continue; ++ } + +- if (!pAC->Pnmi.Port[PhysPortIndex]. +- ActiveFlag) { ++ EventParam.Para32[0] = PhysPortIndex; ++ EventParam.Para32[1] = (SK_U32)Val8; ++ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE, ++ EventParam) > 0) { + +- continue; +- } ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR043, ++ SK_PNMI_ERR043MSG); + +- EventParam.Para32[0] = PhysPortIndex; ++ *pLen = 0; ++ return (SK_PNMI_ERR_GENERAL); ++ } ++ } /* for */ ++ } ++ else { ++ /* ++ * Send an event with the new link mode to ++ * the SIRQ module. ++ */ ++ EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( ++ pAC, LogPortIndex); + EventParam.Para32[1] = (SK_U32)Val8; +- if (SkGeSirqEvent(pAC, IoC, +- SK_HWEV_SET_LMODE, ++ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE, + EventParam) > 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, +- SK_PNMI_ERR043, ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR043, + SK_PNMI_ERR043MSG); + + *pLen = 0; +@@ -5529,34 +5399,31 @@ + } + } + } +- else { ++ else { /* DualNet mode. */ ++ + /* + * Send an event with the new link mode to + * the SIRQ module. + */ +- EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( +- pAC, LogPortIndex); ++ EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE, + EventParam) > 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, +- SK_PNMI_ERR043, ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR043, + SK_PNMI_ERR043MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_FLOWCTRL_MODE: +- /* Check the value range */ +- Val8 = *(pBuf + Offset); ++ /* Check the value range. */ + if (Val8 == 0) { +- +- Offset += sizeof(char); ++ Offset++; + break; + } + if (Val8 < SK_FLOW_MODE_NONE || +@@ -5567,37 +5434,51 @@ + return (SK_PNMI_ERR_BAD_VALUE); + } + +- /* The preset ends here */ ++ /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + +- if (LogPortIndex == 0) { ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ ++ if (LogPortIndex == 0) { ++ /* ++ * The virtual port consists of all currently ++ * active ports. Find them and send an event ++ * with the new flow control mode to SIRQ. ++ */ ++ for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; ++ PhysPortIndex ++) { + +- /* +- * The virtual port consists of all currently +- * active ports. Find them and send an event +- * with the new flow control mode to SIRQ. +- */ +- for (PhysPortIndex = 0; +- PhysPortIndex < PhysPortMax; +- PhysPortIndex ++) { ++ if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { ++ continue; ++ } + +- if (!pAC->Pnmi.Port[PhysPortIndex]. +- ActiveFlag) { ++ EventParam.Para32[0] = PhysPortIndex; ++ EventParam.Para32[1] = (SK_U32)Val8; ++ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_FLOWMODE, ++ EventParam) > 0) { + +- continue; +- } ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR044, ++ SK_PNMI_ERR044MSG); + +- EventParam.Para32[0] = PhysPortIndex; ++ *pLen = 0; ++ return (SK_PNMI_ERR_GENERAL); ++ } ++ } ++ } ++ else { ++ /* ++ * Send an event with the new flow control ++ * mode to the SIRQ module. ++ */ ++ EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( ++ pAC, LogPortIndex); + EventParam.Para32[1] = (SK_U32)Val8; +- if (SkGeSirqEvent(pAC, IoC, +- SK_HWEV_SET_FLOWMODE, ++ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_FLOWMODE, + EventParam) > 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, +- SK_PNMI_ERR044, ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR044, + SK_PNMI_ERR044MSG); + + *pLen = 0; +@@ -5605,17 +5486,16 @@ + } + } + } +- else { ++ else { /* DualNet mode. */ ++ + /* +- * Send an event with the new flow control +- * mode to the SIRQ module. ++ * Send an event with the new link mode to ++ * the SIRQ module. + */ +- EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( +- pAC, LogPortIndex); ++ EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)Val8; +- if (SkGeSirqEvent(pAC, IoC, +- SK_HWEV_SET_FLOWMODE, EventParam) +- > 0) { ++ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_FLOWMODE, ++ EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR044, +@@ -5625,15 +5505,14 @@ + return (SK_PNMI_ERR_GENERAL); + } + } +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_PHY_OPERATION_MODE : +- /* Check the value range */ +- Val8 = *(pBuf + Offset); ++ /* Check the value range. */ + if (Val8 == 0) { +- /* mode of this port remains unchanged */ +- Offset += sizeof(char); ++ /* Mode of this port remains unchanged. */ ++ Offset++; + break; + } + if (Val8 < SK_MS_MODE_AUTO || +@@ -5644,37 +5523,51 @@ + return (SK_PNMI_ERR_BAD_VALUE); + } + +- /* The preset ends here */ ++ /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + +- if (LogPortIndex == 0) { ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ ++ if (LogPortIndex == 0) { ++ /* ++ * The virtual port consists of all currently ++ * active ports. Find them and send an event ++ * with new master/slave (role) mode to SIRQ. ++ */ ++ for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; ++ PhysPortIndex ++) { ++ ++ if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { ++ continue; ++ } + +- /* +- * The virtual port consists of all currently +- * active ports. Find them and send an event +- * with new master/slave (role) mode to SIRQ. +- */ +- for (PhysPortIndex = 0; +- PhysPortIndex < PhysPortMax; +- PhysPortIndex ++) { ++ EventParam.Para32[0] = PhysPortIndex; ++ EventParam.Para32[1] = (SK_U32)Val8; ++ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_ROLE, ++ EventParam) > 0) { + +- if (!pAC->Pnmi.Port[PhysPortIndex]. +- ActiveFlag) { ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR042, ++ SK_PNMI_ERR042MSG); + +- continue; ++ *pLen = 0; ++ return (SK_PNMI_ERR_GENERAL); ++ } + } +- +- EventParam.Para32[0] = PhysPortIndex; ++ } ++ else { ++ /* ++ * Send an event with the new master/slave ++ * (role) mode to the SIRQ module. ++ */ ++ EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( ++ pAC, LogPortIndex); + EventParam.Para32[1] = (SK_U32)Val8; +- if (SkGeSirqEvent(pAC, IoC, +- SK_HWEV_SET_ROLE, ++ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_ROLE, + EventParam) > 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, +- SK_PNMI_ERR042, ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR042, + SK_PNMI_ERR042MSG); + + *pLen = 0; +@@ -5682,35 +5575,31 @@ + } + } + } +- else { ++ else { /* DualNet mode. */ ++ + /* +- * Send an event with the new master/slave +- * (role) mode to the SIRQ module. ++ * Send an event with the new link mode to ++ * the SIRQ module. + */ +- EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( +- pAC, LogPortIndex); ++ EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)Val8; +- if (SkGeSirqEvent(pAC, IoC, +- SK_HWEV_SET_ROLE, EventParam) > 0) { ++ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_ROLE, ++ EventParam) > 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, +- SK_PNMI_ERR042, ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR042, + SK_PNMI_ERR042MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } +- +- Offset += sizeof(char); ++ Offset++; + break; + + case OID_SKGE_SPEED_MODE: +- /* Check the value range */ +- Val8 = *(pBuf + Offset); ++ /* Check the value range. */ + if (Val8 == 0) { +- +- Offset += sizeof(char); ++ Offset++; + break; + } + if (Val8 < (SK_LSPEED_AUTO) || +@@ -5721,36 +5610,52 @@ + return (SK_PNMI_ERR_BAD_VALUE); + } + +- /* The preset ends here */ ++ /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + +- if (LogPortIndex == 0) { ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ ++ if (LogPortIndex == 0) { + +- /* +- * The virtual port consists of all currently +- * active ports. Find them and send an event +- * with the new flow control mode to SIRQ. +- */ +- for (PhysPortIndex = 0; +- PhysPortIndex < PhysPortMax; +- PhysPortIndex ++) { ++ /* ++ * The virtual port consists of all currently ++ * active ports. Find them and send an event ++ * with the new flow control mode to SIRQ. ++ */ ++ for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; ++ PhysPortIndex ++) { ++ ++ if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { ++ continue; ++ } + +- if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { ++ EventParam.Para32[0] = PhysPortIndex; ++ EventParam.Para32[1] = (SK_U32)Val8; ++ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_SPEED, ++ EventParam) > 0) { + +- continue; +- } ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR045, ++ SK_PNMI_ERR045MSG); + +- EventParam.Para32[0] = PhysPortIndex; ++ *pLen = 0; ++ return (SK_PNMI_ERR_GENERAL); ++ } ++ } ++ } ++ else { ++ /* ++ * Send an event with the new flow control ++ * mode to the SIRQ module. ++ */ ++ EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( ++ pAC, LogPortIndex); + EventParam.Para32[1] = (SK_U32)Val8; +- if (SkGeSirqEvent(pAC, IoC, +- SK_HWEV_SET_SPEED, ++ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_SPEED, + EventParam) > 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, +- SK_PNMI_ERR045, ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR045, + SK_PNMI_ERR045MSG); + + *pLen = 0; +@@ -5758,43 +5663,43 @@ + } + } + } +- else { ++ else { /* DualNet mode. */ ++ + /* +- * Send an event with the new flow control +- * mode to the SIRQ module. ++ * Send an event with the new link mode to ++ * the SIRQ module. + */ +- EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( +- pAC, LogPortIndex); ++ EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)Val8; +- if (SkGeSirqEvent(pAC, IoC, +- SK_HWEV_SET_SPEED, ++ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_SPEED, + EventParam) > 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, +- SK_PNMI_ERR045, ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR045, + SK_PNMI_ERR045MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } +- Offset += sizeof(char); ++ Offset++; + break; + +- case OID_SKGE_MTU : +- /* Check the value range */ +- Val32 = *(SK_U32*)(pBuf + Offset); ++ case OID_SKGE_MTU: ++ /* Check the value range. */ ++ SK_PNMI_READ_U32((pBuf + Offset), Val32); ++ + if (Val32 == 0) { +- /* mtu of this port remains unchanged */ ++ /* MTU of this port remains unchanged. */ + Offset += sizeof(SK_U32); + break; + } ++ + if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) { + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + +- /* The preset ends here */ ++ /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + return (SK_PNMI_ERR_OK); + } +@@ -5805,10 +5710,73 @@ + + Offset += sizeof(SK_U32); + break; +- ++ ++#ifdef SK_PHY_LP_MODE ++ case OID_SKGE_PHY_LP_MODE: ++ /* The PRESET ends here. */ ++ if (Action == SK_PNMI_PRESET) { ++ ++ return (SK_PNMI_ERR_OK); ++ } ++ ++ if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ ++ if (LogPortIndex == 0) { ++ Offset = 0; ++ continue; ++ } ++ } ++ /* Set value for physical port. */ ++ PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); ++ CurrentPhyPowerState = pAC->GIni.GP[PhysPortIndex].PPhyPowerState; ++ ++ switch (Val8) { ++ case PHY_PM_OPERATIONAL_MODE: ++ /* If LowPowerMode is active, we can leave it. */ ++ if (CurrentPhyPowerState) { ++ ++ Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); ++ ++ if (CurrentPhyPowerState == PHY_PM_DEEP_SLEEP || ++ CurrentPhyPowerState == PHY_PM_IEEE_POWER_DOWN) { ++ ++ SkDrvInitAdapter(pAC); ++ } ++ break; ++ } ++ else { ++ *pLen = 0; ++ return (SK_PNMI_ERR_GENERAL); ++ } ++ case PHY_PM_DEEP_SLEEP: ++ case PHY_PM_IEEE_POWER_DOWN: ++ /* If no LowPowerMode is active, we can enter it. */ ++ if (!CurrentPhyPowerState) { ++ SkDrvDeInitAdapter(pAC); ++ } ++ ++ case PHY_PM_ENERGY_DETECT: ++ case PHY_PM_ENERGY_DETECT_PLUS: ++ /* If no LowPowerMode is active, we can enter it. */ ++ if (!CurrentPhyPowerState) { ++ ++ Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); ++ break; ++ } ++ else { ++ *pLen = 0; ++ return (SK_PNMI_ERR_GENERAL); ++ } ++ default: ++ *pLen = 0; ++ return (SK_PNMI_ERR_BAD_VALUE); ++ } ++ Offset++; ++ break; ++#endif /* SK_PHY_LP_MODE */ ++ + default: +- SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, +- ("MacPrivateConf: Unknown OID should be handled before set")); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, ++ ("MacPrivateConf: Unknown OID should be handled before set")); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -5855,13 +5823,10 @@ + unsigned int Offset; + unsigned int Entries; + +- +- /* +- * Calculate instance if wished. +- */ +- /* XXX Not yet implemented. Return always an empty table. */ ++ /* Not implemented yet. Return always an empty table. */ + Entries = 0; + ++ /* Calculate instance if wished. */ + if ((Instance != (SK_U32)(-1))) { + + if ((Instance < 1) || (Instance > Entries)) { +@@ -5878,12 +5843,10 @@ + Limit = Entries; + } + +- /* +- * Get/Set value +- */ ++ /* GET/SET value. */ + if (Action == SK_PNMI_GET) { + +- for (Offset=0; Index < Limit; Index ++) { ++ for (Offset = 0; Index < Limit; Index ++) { + + switch (Id) { + +@@ -5895,8 +5858,7 @@ + break; + + default: +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046, +- SK_PNMI_ERR046MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046, SK_PNMI_ERR046MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -5905,32 +5867,29 @@ + *pLen = Offset; + } + else { +- /* Only MONITOR_ADMIN can be set */ ++ /* Only MONITOR_ADMIN can be set. */ + if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + +- /* Check if the length is plausible */ ++ /* Check if the length is plausible. */ + if (*pLen < (Limit - Index)) { + + return (SK_PNMI_ERR_TOO_SHORT); + } +- /* Okay, we have a wide value range */ ++ /* Okay, we have a wide value range. */ + if (*pLen != (Limit - Index)) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } +-/* +- for (Offset=0; Index < Limit; Index ++) { +- } +-*/ +-/* +- * XXX Not yet implemented. Return always BAD_VALUE, because the table +- * is empty. +- */ ++ ++ /* ++ * Not yet implemented. Return always BAD_VALUE, ++ * because the table is empty. ++ */ + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } +@@ -5970,15 +5929,13 @@ + *pBuf = 0; + PortActiveFlag = SK_FALSE; + PhysPortMax = pAC->GIni.GIMacsFound; +- +- for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; +- PhysPortIndex ++) { ++ ++ for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; PhysPortIndex ++) { + + pPrt = &pAC->GIni.GP[PhysPortIndex]; + +- /* Check if the physical port is active */ ++ /* Check if the physical port is active. */ + if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { +- + continue; + } + +@@ -5987,12 +5944,13 @@ + switch (Id) { + + case OID_SKGE_PHY_TYPE: +- /* Check if it is the first active port */ ++ /* Check if it is the first active port. */ + if (*pBuf == 0) { + Val32 = pPrt->PhyType; + SK_PNMI_STORE_U32(pBuf, Val32); + continue; + } ++ break; + + case OID_SKGE_LINK_CAP: + +@@ -6006,7 +5964,7 @@ + break; + + case OID_SKGE_LINK_MODE: +- /* Check if it is the first active port */ ++ /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PLinkModeConf; +@@ -6014,9 +5972,8 @@ + } + + /* +- * If we find an active port with a different link +- * mode than the first one we return a value that +- * indicates that the link mode is indeterminated. ++ * If we find an active port with a different link mode ++ * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PLinkModeConf) { + +@@ -6025,10 +5982,10 @@ + break; + + case OID_SKGE_LINK_MODE_STATUS: +- /* Get the link mode of the physical port */ ++ /* Get the link mode of the physical port. */ + Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex); + +- /* Check if it is the first active port */ ++ /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = Val8; +@@ -6036,10 +5993,8 @@ + } + + /* +- * If we find an active port with a different link +- * mode status than the first one we return a value +- * that indicates that the link mode status is +- * indeterminated. ++ * If we find an active port with a different link mode status ++ * than the first one we return indeterminated. + */ + if (*pBuf != Val8) { + +@@ -6048,10 +6003,10 @@ + break; + + case OID_SKGE_LINK_STATUS: +- /* Get the link status of the physical port */ ++ /* Get the link status of the physical port. */ + Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex); + +- /* Check if it is the first active port */ ++ /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = Val8; +@@ -6059,10 +6014,8 @@ + } + + /* +- * If we find an active port with a different link +- * status than the first one, we return a value +- * that indicates that the link status is +- * indeterminated. ++ * If we find an active port with a different link status ++ * than the first one we return indeterminated. + */ + if (*pBuf != Val8) { + +@@ -6071,7 +6024,7 @@ + break; + + case OID_SKGE_FLOWCTRL_CAP: +- /* Check if it is the first active port */ ++ /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PFlowCtrlCap; +@@ -6086,7 +6039,7 @@ + break; + + case OID_SKGE_FLOWCTRL_MODE: +- /* Check if it is the first active port */ ++ /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PFlowCtrlMode; +@@ -6094,9 +6047,8 @@ + } + + /* +- * If we find an active port with a different flow +- * control mode than the first one, we return a value +- * that indicates that the mode is indeterminated. ++ * If we find an active port with a different flow-control mode ++ * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PFlowCtrlMode) { + +@@ -6105,7 +6057,7 @@ + break; + + case OID_SKGE_FLOWCTRL_STATUS: +- /* Check if it is the first active port */ ++ /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PFlowCtrlStatus; +@@ -6113,19 +6065,17 @@ + } + + /* +- * If we find an active port with a different flow +- * control status than the first one, we return a +- * value that indicates that the status is +- * indeterminated. ++ * If we find an active port with a different flow-control status ++ * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PFlowCtrlStatus) { + + *pBuf = SK_FLOW_STAT_INDETERMINATED; + } + break; +- ++ + case OID_SKGE_PHY_OPERATION_CAP: +- /* Check if it is the first active port */ ++ /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PMSCap; +@@ -6140,7 +6090,7 @@ + break; + + case OID_SKGE_PHY_OPERATION_MODE: +- /* Check if it is the first active port */ ++ /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PMSMode; +@@ -6148,9 +6098,8 @@ + } + + /* +- * If we find an active port with a different master/ +- * slave mode than the first one, we return a value +- * that indicates that the mode is indeterminated. ++ * If we find an active port with a different master/slave mode ++ * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PMSMode) { + +@@ -6159,7 +6108,7 @@ + break; + + case OID_SKGE_PHY_OPERATION_STATUS: +- /* Check if it is the first active port */ ++ /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PMSStatus; +@@ -6167,19 +6116,17 @@ + } + + /* +- * If we find an active port with a different master/ +- * slave status than the first one, we return a +- * value that indicates that the status is +- * indeterminated. ++ * If we find an active port with a different master/slave status ++ * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PMSStatus) { + + *pBuf = SK_MS_STAT_INDETERMINATED; + } + break; +- ++ + case OID_SKGE_SPEED_MODE: +- /* Check if it is the first active port */ ++ /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PLinkSpeed; +@@ -6187,18 +6134,17 @@ + } + + /* +- * If we find an active port with a different flow +- * control mode than the first one, we return a value +- * that indicates that the mode is indeterminated. ++ * If we find an active port with a different link speed ++ * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PLinkSpeed) { + + *pBuf = SK_LSPEED_INDETERMINATED; + } + break; +- ++ + case OID_SKGE_SPEED_STATUS: +- /* Check if it is the first active port */ ++ /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PLinkSpeedUsed; +@@ -6206,10 +6152,8 @@ + } + + /* +- * If we find an active port with a different flow +- * control status than the first one, we return a +- * value that indicates that the status is +- * indeterminated. ++ * If we find an active port with a different link speed used ++ * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PLinkSpeedUsed) { + +@@ -6219,9 +6163,7 @@ + } + } + +- /* +- * If no port is active return an indeterminated answer +- */ ++ /* If no port is active return an indeterminated answer. */ + if (!PortActiveFlag) { + + switch (Id) { +@@ -6324,7 +6266,7 @@ + * + * Description: + * The COMMON module only tells us if the mode is half or full duplex. +- * But in the decade of auto sensing it is useful for the user to ++ * But in the decade of auto sensing it is usefull for the user to + * know if the mode was negotiated or forced. Therefore we have a + * look to the mode, which was last used by the negotiation process. + * +@@ -6338,16 +6280,15 @@ + { + SK_U8 Result; + +- /* Get the current mode, which can be full or half duplex */ ++ /* Get the current mode, which can be full or half duplex. */ + Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus; + +- /* Check if no valid mode could be found (link is down) */ ++ /* Check if no valid mode could be found (link is down). */ + if (Result < SK_LMODE_STAT_HALF) { + + Result = SK_LMODE_STAT_UNKNOWN; + } + else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) { +- + /* + * Auto-negotiation was used to bring up the link. Change + * the already found duplex status that it indicates +@@ -6392,22 +6333,21 @@ + int Index; + int Ret; + +- + SK_MEMSET(pKeyArr, 0, KeyArrLen); + +- /* +- * Get VPD key list +- */ +- Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen, +- (int *)pKeyNo); ++ /* Get VPD key list. */ ++ Ret = VpdKeys(pAC, IoC, BufKeys, (int *)&BufKeysLen, (int *)pKeyNo); ++ + if (Ret > 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014, +- SK_PNMI_ERR014MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR014MSG)); + ++ /* Please read comment in Vpd(). */ ++ pAC->Pnmi.VpdKeyReadError = SK_TRUE; + return (SK_PNMI_ERR_GENERAL); + } +- /* If no keys are available return now */ ++ /* If no keys are available return now. */ + if (*pKeyNo == 0 || BufKeysLen == 0) { + + return (SK_PNMI_ERR_OK); +@@ -6415,12 +6355,12 @@ + /* + * If the key list is too long for us trunc it and give a + * errorlog notification. This case should not happen because +- * the maximum number of keys is limited due to RAM limitations ++ * the maximum number of keys is limited due to RAM limitations. + */ + if (*pKeyNo > SK_PNMI_VPD_ENTRIES) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015, +- SK_PNMI_ERR015MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR015MSG)); + + *pKeyNo = SK_PNMI_VPD_ENTRIES; + } +@@ -6433,14 +6373,14 @@ + Offset ++) { + + if (BufKeys[Offset] != 0) { +- + continue; + } + + if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016, +- SK_PNMI_ERR016MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, ++ (SK_PNMI_ERR016MSG)); ++ + return (SK_PNMI_ERR_GENERAL); + } + +@@ -6451,7 +6391,7 @@ + StartOffset = Offset + 1; + } + +- /* Last key not zero terminated? Get it anyway */ ++ /* Last key not zero terminated? Get it anyway. */ + if (StartOffset < Offset) { + + SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE, +@@ -6480,19 +6420,18 @@ + { + SK_EVPARA EventParam; + +- + /* Was the module already updated during the current PNMI call? */ + if (pAC->Pnmi.SirqUpdatedFlag > 0) { + + return (SK_PNMI_ERR_OK); + } + +- /* Send an synchronuous update event to the module */ ++ /* Send an synchronuous update event to the module. */ + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); +- if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) { ++ ++ if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam)) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047, +- SK_PNMI_ERR047MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047, SK_PNMI_ERR047MSG); + + return (SK_PNMI_ERR_GENERAL); + } +@@ -6516,25 +6455,23 @@ + PNMI_STATIC int RlmtUpdate( + SK_AC *pAC, /* Pointer to adapter context */ + SK_IOC IoC, /* IO context handle */ +-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ ++SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ + { + SK_EVPARA EventParam; + +- + /* Was the module already updated during the current PNMI call? */ + if (pAC->Pnmi.RlmtUpdatedFlag > 0) { + + return (SK_PNMI_ERR_OK); + } + +- /* Send an synchronuous update event to the module */ ++ /* Send an synchronuous update event to the module. */ + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); + EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)-1; + if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) { + +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048, +- SK_PNMI_ERR048MSG); ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048, SK_PNMI_ERR048MSG); + + return (SK_PNMI_ERR_GENERAL); + } +@@ -6572,20 +6509,20 @@ + return (SK_PNMI_ERR_OK); + } + +- /* Send an update command to all MACs specified */ ++ /* Send an update command to all MACs specified. */ + for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) { + + /* + * 2002-09-13 pweber: Freeze the current SW counters. + * (That should be done as close as + * possible to the update of the +- * HW counters) ++ * HW counters). + */ + if (pAC->GIni.GIMacType == SK_MAC_XMAC) { + pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex]; + } + +- /* 2002-09-13 pweber: Update the HW counter */ ++ /* 2002-09-13 pweber: Update the HW counter. */ + if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) { + + return (SK_PNMI_ERR_GENERAL); +@@ -6616,26 +6553,25 @@ + SK_IOC IoC, /* IO context handle */ + unsigned int LogPortIndex, /* Index of the logical Port to be processed */ + unsigned int StatIndex, /* Index to statistic value */ +-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ ++SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ + { + unsigned int PhysPortIndex; + unsigned int PhysPortMax; + SK_U64 Val = 0; + +- +- if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ ++ if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */ + + PhysPortIndex = NetIndex; +- ++ + Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); + } +- else { /* Single Net mode */ ++ else { /* SingleNet mode. */ + + if (LogPortIndex == 0) { + + PhysPortMax = pAC->GIni.GIMacsFound; + +- /* Add counter of all active ports */ ++ /* Add counter of all active ports. */ + for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; + PhysPortIndex ++) { + +@@ -6645,13 +6581,13 @@ + } + } + +- /* Correct value because of port switches */ ++ /* Correct value because of port switches. */ + Val += pAC->Pnmi.VirtualCounterOffset[StatIndex]; + } + else { +- /* Get counter value of physical port */ ++ /* Get counter value of physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); +- ++ + Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); + } + } +@@ -6687,22 +6623,22 @@ + int MacType; + unsigned int HelpIndex; + SK_GEPORT *pPrt; +- ++ + SK_PNMI_PORT *pPnmiPrt; + SK_GEMACFUNC *pFnMac; +- ++ + pPrt = &pAC->GIni.GP[PhysPortIndex]; +- ++ + MacType = pAC->GIni.GIMacType; +- +- /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ ++ ++ /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex]; + } + else { + pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex]; + } +- ++ + pFnMac = &pAC->GIni.GIFunc; + + switch (StatIndex) { +@@ -6727,7 +6663,7 @@ + } + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; +- ++ + case SK_PNMI_HRX: + if (MacType == SK_MAC_GMAC) { + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, +@@ -6763,7 +6699,7 @@ + case SK_PNMI_HTX_BURST: + case SK_PNMI_HTX_EXCESS_DEF: + case SK_PNMI_HTX_CARRIER: +- /* Not supported by GMAC */ ++ /* Not supported by GMAC. */ + if (MacType == SK_MAC_GMAC) { + return (Val); + } +@@ -6775,14 +6711,14 @@ + break; + + case SK_PNMI_HTX_MACC: +- /* GMAC only supports PAUSE MAC control frames */ ++ /* GMAC only supports PAUSE MAC control frames. */ + if (MacType == SK_MAC_GMAC) { + HelpIndex = SK_PNMI_HTX_PMACC; + } + else { + HelpIndex = StatIndex; + } +- ++ + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[HelpIndex][MacType].Reg, + &LowVal); +@@ -6792,7 +6728,7 @@ + + case SK_PNMI_HTX_COL: + case SK_PNMI_HRX_UNDERSIZE: +- /* Not supported by XMAC */ ++ /* Not supported by XMAC. */ + if (MacType == SK_MAC_XMAC) { + return (Val); + } +@@ -6804,11 +6740,11 @@ + break; + + case SK_PNMI_HTX_DEFFERAL: +- /* Not supported by GMAC */ ++ /* Not supported by GMAC. */ + if (MacType == SK_MAC_GMAC) { + return (Val); + } +- ++ + /* + * XMAC counts frames with deferred transmission + * even in full-duplex mode. +@@ -6822,7 +6758,7 @@ + HighVal = 0; + } + else { +- /* Otherwise get contents of hardware register */ ++ /* Otherwise get contents of hardware register. */ + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); +@@ -6831,7 +6767,7 @@ + break; + + case SK_PNMI_HRX_BADOCTET: +- /* Not supported by XMAC */ ++ /* Not supported by XMAC. */ + if (MacType == SK_MAC_XMAC) { + return (Val); + } +@@ -6841,7 +6777,7 @@ + &HighVal); + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex + 1][MacType].Reg, +- &LowVal); ++ &LowVal); + break; + + case SK_PNMI_HTX_OCTETLOW: +@@ -6850,27 +6786,27 @@ + return (Val); + + case SK_PNMI_HRX_LONGFRAMES: +- /* For XMAC the SW counter is managed by PNMI */ ++ /* For XMAC the SW counter is managed by PNMI. */ + if (MacType == SK_MAC_XMAC) { + return (pPnmiPrt->StatRxLongFrameCts); + } +- ++ + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; +- ++ + case SK_PNMI_HRX_TOO_LONG: + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; +- ++ + Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); + + if (MacType == SK_MAC_GMAC) { +- /* For GMAC the SW counter is additionally managed by PNMI */ ++ /* For GMAC the SW counter is additionally managed by PNMI. */ + Val += pPnmiPrt->StatRxFrameTooLongCts; + } + else { +@@ -6886,22 +6822,21 @@ + LowVal = (SK_U32)Val; + HighVal = (SK_U32)(Val >> 32); + break; +- ++ + case SK_PNMI_HRX_SHORTS: +- /* Not supported by GMAC */ ++ /* Not supported by GMAC. */ + if (MacType == SK_MAC_GMAC) { + /* GM_RXE_FRAG?? */ + return (Val); + } +- ++ + /* +- * XMAC counts short frame errors even if link down (#10620) +- * +- * If link-down the counter remains constant ++ * XMAC counts short frame errors even if link down (#10620). ++ * If the link is down, the counter remains constant. + */ + if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) { + +- /* Otherwise get incremental difference */ ++ /* Otherwise get incremental difference. */ + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); +@@ -6924,7 +6859,7 @@ + case SK_PNMI_HRX_IRLENGTH: + case SK_PNMI_HRX_SYMBOL: + case SK_PNMI_HRX_CEXT: +- /* Not supported by GMAC */ ++ /* Not supported by GMAC. */ + if (MacType == SK_MAC_GMAC) { + return (Val); + } +@@ -6936,24 +6871,24 @@ + break; + + case SK_PNMI_HRX_PMACC_ERR: +- /* For GMAC the SW counter is managed by PNMI */ ++ /* For GMAC the SW counter is managed by PNMI. */ + if (MacType == SK_MAC_GMAC) { + return (pPnmiPrt->StatRxPMaccErr); + } +- ++ + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + +- /* SW counter managed by PNMI */ ++ /* SW counter managed by PNMI. */ + case SK_PNMI_HTX_SYNC: + LowVal = (SK_U32)pPnmiPrt->StatSyncCts; + HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32); + break; + +- /* SW counter managed by PNMI */ ++ /* SW counter managed by PNMI. */ + case SK_PNMI_HTX_SYNC_OCTET: + LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts; + HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32); +@@ -6961,17 +6896,19 @@ + + case SK_PNMI_HRX_FCS: + /* +- * Broadcom filters FCS errors and counts it in +- * Receive Error Counter register ++ * Broadcom filters FCS errors and counts them in ++ * Receive Error Counter register. + */ + if (pPrt->PhyType == SK_PHY_BCOM) { +- /* do not read while not initialized (PHY_READ hangs!)*/ ++#ifdef GENESIS ++ /* Do not read while not initialized (PHY_READ hangs!). */ + if (pPrt->PState != SK_PRT_RESET) { + SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word); + + LowVal = Word; + } + HighVal = pPnmiPrt->CounterHigh[StatIndex]; ++#endif /* GENESIS */ + } + else { + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, +@@ -6991,7 +6928,7 @@ + + Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); + +- /* Correct value because of possible XMAC reset. XMAC Errata #2 */ ++ /* Correct value because of possible XMAC reset (XMAC Errata #2). */ + Val += pPnmiPrt->CounterOffset[StatIndex]; + + return (Val); +@@ -7016,30 +6953,29 @@ + unsigned int PhysPortIndex; + SK_EVPARA EventParam; + +- + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); + +- /* Notify sensor module */ ++ /* Notify sensor module. */ + SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam); + +- /* Notify RLMT module */ ++ /* Notify RLMT module. */ + EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)-1; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam); + EventParam.Para32[1] = 0; + +- /* Notify SIRQ module */ ++ /* Notify SIRQ module. */ + SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam); + +- /* Notify CSUM module */ ++ /* Notify CSUM module. */ + #ifdef SK_USE_CSUM + EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)-1; + SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS, + EventParam); + #endif /* SK_USE_CSUM */ +- +- /* Clear XMAC statistic */ ++ ++ /* Clear XMAC statistics. */ + for (PhysPortIndex = 0; PhysPortIndex < + (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) { + +@@ -7047,32 +6983,33 @@ + + SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh, + 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh)); +- SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. +- CounterOffset, 0, sizeof(pAC->Pnmi.Port[ +- PhysPortIndex].CounterOffset)); ++ ++ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterOffset, ++ 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterOffset)); ++ + SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts, + 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts)); +- SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. +- StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[ +- PhysPortIndex].StatSyncOctetsCts)); +- SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. +- StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[ +- PhysPortIndex].StatRxLongFrameCts)); +- SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. +- StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[ +- PhysPortIndex].StatRxFrameTooLongCts)); +- SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. +- StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[ +- PhysPortIndex].StatRxPMaccErr)); ++ ++ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncOctetsCts, ++ 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncOctetsCts)); ++ ++ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatRxLongFrameCts, ++ 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatRxLongFrameCts)); ++ ++ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatRxFrameTooLongCts, ++ 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatRxFrameTooLongCts)); ++ ++ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatRxPMaccErr, ++ 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatRxPMaccErr)); + } + +- /* +- * Clear local statistics +- */ ++ /* Clear local statistics. */ + SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0, + sizeof(pAC->Pnmi.VirtualCounterOffset)); ++ + pAC->Pnmi.RlmtChangeCts = 0; + pAC->Pnmi.RlmtChangeTime = 0; ++ + SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0, + sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue)); + pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0; +@@ -7109,23 +7046,21 @@ + SK_U32 TrapId, /* SNMP ID of the trap */ + unsigned int Size) /* Space needed for trap entry */ + { +- unsigned int BufPad = pAC->Pnmi.TrapBufPad; +- unsigned int BufFree = pAC->Pnmi.TrapBufFree; +- unsigned int Beg = pAC->Pnmi.TrapQueueBeg; +- unsigned int End = pAC->Pnmi.TrapQueueEnd; ++ unsigned int BufPad = pAC->Pnmi.TrapBufPad; ++ unsigned int BufFree = pAC->Pnmi.TrapBufFree; ++ unsigned int Beg = pAC->Pnmi.TrapQueueBeg; ++ unsigned int End = pAC->Pnmi.TrapQueueEnd; + char *pBuf = &pAC->Pnmi.TrapBuf[0]; + int Wrap; +- unsigned int NeededSpace; +- unsigned int EntrySize; ++ unsigned int NeededSpace; ++ unsigned int EntrySize; + SK_U32 Val32; + SK_U64 Val64; + +- +- /* Last byte of entry will get a copy of the entry length */ ++ /* Last byte of entry will get a copy of the entry length. */ + Size ++; + +- /* +- * Calculate needed buffer space */ ++ /* Calculate needed buffer space. */ + if (Beg >= Size) { + + NeededSpace = Size; +@@ -7140,7 +7075,7 @@ + * Check if enough buffer space is provided. Otherwise + * free some entries. Leave one byte space between begin + * and end of buffer to make it possible to detect whether +- * the buffer is full or empty ++ * the buffer is full or empty. + */ + while (BufFree < NeededSpace + 1) { + +@@ -7179,13 +7114,13 @@ + } + BufFree -= NeededSpace; + +- /* Save the current offsets */ ++ /* Save the current offsets. */ + pAC->Pnmi.TrapQueueBeg = Beg; + pAC->Pnmi.TrapQueueEnd = End; + pAC->Pnmi.TrapBufPad = BufPad; + pAC->Pnmi.TrapBufFree = BufFree; + +- /* Initialize the trap entry */ ++ /* Initialize the trap entry. */ + *(pBuf + Beg + Size - 1) = (char)Size; + *(pBuf + Beg) = (char)Size; + Val32 = (pAC->Pnmi.TrapUnique) ++; +@@ -7220,7 +7155,6 @@ + unsigned int Len; + unsigned int DstOff = 0; + +- + while (Trap != End) { + + Len = (unsigned int)*(pBuf + Trap); +@@ -7265,7 +7199,6 @@ + unsigned int Entries = 0; + unsigned int TotalLen = 0; + +- + while (Trap != End) { + + Len = (unsigned int)*(pBuf + Trap); +@@ -7322,14 +7255,14 @@ + unsigned int DescrLen; + SK_U32 Val32; + +- +- /* Get trap buffer entry */ ++ /* Get trap buffer entry. */ + DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc); ++ + pBuf = GetTrapEntry(pAC, TrapId, + SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen); + Offset = SK_PNMI_TRAP_SIMPLE_LEN; + +- /* Store additionally sensor trap related data */ ++ /* Store additionally sensor trap related data. */ + Val32 = OID_SKGE_SENSOR_INDEX; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + *(pBuf + Offset + 4) = 4; +@@ -7374,7 +7307,6 @@ + char *pBuf; + SK_U32 Val32; + +- + pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT, + SK_PNMI_TRAP_RLMT_CHANGE_LEN); + +@@ -7402,7 +7334,6 @@ + char *pBuf; + SK_U32 Val32; + +- + pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN); + + Val32 = OID_SKGE_RLMT_PORT_INDEX; +@@ -7422,12 +7353,11 @@ + * Nothing + */ + PNMI_STATIC void CopyMac( +-char *pDst, /* Pointer to destination buffer */ ++char *pDst, /* Pointer to destination buffer */ + SK_MAC_ADDR *pMac) /* Pointer of Source */ + { + int i; + +- + for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) { + + *(pDst + i) = pMac->a[i]; +@@ -7462,43 +7392,45 @@ + unsigned int *pLen, /* On call: buffer length. On return: used buffer */ + SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ + unsigned int TableIndex, /* Index to the Id table */ +-SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ ++SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ + { +- ++ int i; ++ unsigned int HwPortIndex; ++ + SK_U32 RetCode = SK_PNMI_ERR_GENERAL; + +- /* +- * Check instance. We only handle single instance variables +- */ +- if (Instance != (SK_U32)(-1) && Instance != 1) { ++ /* Check instance. We only handle single instance variables. */ ++ if ((Instance != (SK_U32)(-1))) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } +- +- +- /* Check length */ +- switch (Id) { +- +- case OID_PNP_CAPABILITIES: +- if (*pLen < sizeof(SK_PNP_CAPABILITIES)) { +- +- *pLen = sizeof(SK_PNP_CAPABILITIES); +- return (SK_PNMI_ERR_TOO_SHORT); +- } +- break; ++ ++ /* Get hardware port index */ ++ HwPortIndex = NetIndex; ++ ++ /* Check length. */ ++ switch (Id) { ++ ++ case OID_PNP_CAPABILITIES: ++ if (*pLen < sizeof(SK_PNP_CAPABILITIES)) { ++ ++ *pLen = sizeof(SK_PNP_CAPABILITIES); ++ return (SK_PNMI_ERR_TOO_SHORT); ++ } ++ break; + + case OID_PNP_SET_POWER: +- case OID_PNP_QUERY_POWER: +- if (*pLen < sizeof(SK_DEVICE_POWER_STATE)) +- { +- *pLen = sizeof(SK_DEVICE_POWER_STATE); +- return (SK_PNMI_ERR_TOO_SHORT); +- } +- break; ++ case OID_PNP_QUERY_POWER: ++ if (*pLen < sizeof(SK_DEVICE_POWER_STATE)) { ++ ++ *pLen = sizeof(SK_DEVICE_POWER_STATE); ++ return (SK_PNMI_ERR_TOO_SHORT); ++ } ++ break; + +- case OID_PNP_ADD_WAKE_UP_PATTERN: +- case OID_PNP_REMOVE_WAKE_UP_PATTERN: ++ case OID_PNP_ADD_WAKE_UP_PATTERN: ++ case OID_PNP_REMOVE_WAKE_UP_PATTERN: + if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) { + + *pLen = sizeof(SK_PM_PACKET_PATTERN); +@@ -7506,23 +7438,19 @@ + } + break; + +- case OID_PNP_ENABLE_WAKE_UP: +- if (*pLen < sizeof(SK_U32)) { ++ case OID_PNP_ENABLE_WAKE_UP: ++ if (*pLen < sizeof(SK_U32)) { + +- *pLen = sizeof(SK_U32); +- return (SK_PNMI_ERR_TOO_SHORT); +- } +- break; +- } +- +- /* +- * Perform action +- */ ++ *pLen = sizeof(SK_U32); ++ return (SK_PNMI_ERR_TOO_SHORT); ++ } ++ break; ++ } ++ ++ /* Perform action. */ + if (Action == SK_PNMI_GET) { + +- /* +- * Get value +- */ ++ /* Get value. */ + switch (Id) { + + case OID_PNP_CAPABILITIES: +@@ -7530,28 +7458,31 @@ + break; + + case OID_PNP_QUERY_POWER: +- /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests +- the miniport to indicate whether it can transition its NIC +- to the low-power state. +- A miniport driver must always return NDIS_STATUS_SUCCESS +- to a query of OID_PNP_QUERY_POWER. */ ++ /* ++ * The Windows DDK describes: An OID_PNP_QUERY_POWER requests ++ * the miniport to indicate whether it can transition its NIC ++ * to the low-power state. ++ * A miniport driver must always return NDIS_STATUS_SUCCESS ++ * to a query of OID_PNP_QUERY_POWER. ++ */ + *pLen = sizeof(SK_DEVICE_POWER_STATE); +- RetCode = SK_PNMI_ERR_OK; ++ RetCode = SK_PNMI_ERR_OK; + break; + +- /* NDIS handles these OIDs as write-only. ++ /* ++ * NDIS handles these OIDs as write-only. + * So in case of get action the buffer with written length = 0 +- * is returned ++ * is returned. + */ + case OID_PNP_SET_POWER: + case OID_PNP_ADD_WAKE_UP_PATTERN: + case OID_PNP_REMOVE_WAKE_UP_PATTERN: +- *pLen = 0; +- RetCode = SK_PNMI_ERR_NOT_SUPPORTED; ++ *pLen = 0; ++ RetCode = SK_PNMI_ERR_NOT_SUPPORTED; + break; + + case OID_PNP_ENABLE_WAKE_UP: +- RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen); ++ RetCode = SkPowerGetEnableWakeUp(pAC, IoC, HwPortIndex, pBuf, pLen); + break; + + default: +@@ -7561,38 +7492,55 @@ + + return (RetCode); + } +- + +- /* +- * Perform preset or set +- */ +- +- /* POWER module does not support PRESET action */ ++ /* Perform PRESET or SET. */ ++ ++ /* The POWER module does not support PRESET action. */ + if (Action == SK_PNMI_PRESET) { ++ + return (SK_PNMI_ERR_OK); + } + ++ i = HwPortIndex; ++ + switch (Id) { + case OID_PNP_SET_POWER: +- RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen); ++ /* Dual net mode? */ ++ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { ++ if (RetCode = SkPowerSetPower(pAC, IoC, i, pBuf, pLen)) { ++ break; ++ } ++ } + break; + + case OID_PNP_ADD_WAKE_UP_PATTERN: +- RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen); ++ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { ++ if (RetCode = SkPowerAddWakeUpPattern(pAC, IoC, i, pBuf, pLen)) { ++ break; ++ } ++ } + break; +- ++ + case OID_PNP_REMOVE_WAKE_UP_PATTERN: +- RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen); ++ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { ++ if (RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, i, pBuf, pLen)) { ++ break; ++ } ++ } + break; +- ++ + case OID_PNP_ENABLE_WAKE_UP: +- RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen); ++ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { ++ if (RetCode = SkPowerSetEnableWakeUp(pAC, IoC, i, pBuf, pLen)) { ++ break; ++ } ++ } + break; +- ++ + default: + RetCode = SK_PNMI_ERR_READ_ONLY; + } +- ++ + return (RetCode); + } + #endif /* SK_POWER_MGMT */ +@@ -7600,7 +7548,7 @@ + #ifdef SK_DIAG_SUPPORT + /***************************************************************************** + * +- * DiagActions - OID handler function of Diagnostic driver ++ * DiagActions - OID handler function of Diagnostic driver + * + * Description: + * The code is simple. No description necessary. +@@ -7627,22 +7575,17 @@ + unsigned int TableIndex, /* Index to the Id table */ + SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ + { +- + SK_U32 DiagStatus; + SK_U32 RetCode = SK_PNMI_ERR_GENERAL; + +- /* +- * Check instance. We only handle single instance variables. +- */ ++ /* Check instance. We only handle single instance variables. */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + +- /* +- * Check length. +- */ ++ /* Check length. */ + switch (Id) { + + case OID_SKGE_DIAG_MODE: +@@ -7660,32 +7603,32 @@ + } + + /* Perform action. */ +- +- /* GET value. */ + if (Action == SK_PNMI_GET) { + ++ /* Get value. */ + switch (Id) { + + case OID_SKGE_DIAG_MODE: + DiagStatus = pAC->Pnmi.DiagAttached; + SK_PNMI_STORE_U32(pBuf, DiagStatus); +- *pLen = sizeof(SK_U32); ++ *pLen = sizeof(SK_U32); + RetCode = SK_PNMI_ERR_OK; + break; + + default: +- *pLen = 0; ++ *pLen = 0; + RetCode = SK_PNMI_ERR_GENERAL; + break; + } +- return (RetCode); ++ return (RetCode); + } + + /* From here SET or PRESET value. */ +- ++ + /* PRESET value is not supported. */ + if (Action == SK_PNMI_PRESET) { +- return (SK_PNMI_ERR_OK); ++ ++ return (SK_PNMI_ERR_OK); + } + + /* SET value. */ +@@ -7697,23 +7640,20 @@ + + /* Attach the DIAG to this adapter. */ + case SK_DIAG_ATTACHED: +- /* Check if we come from running */ ++ /* Check if we come from running. */ + if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { + + RetCode = SkDrvLeaveDiagMode(pAC); +- + } + else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) { + + RetCode = SK_PNMI_ERR_OK; +- } +- ++ } + else { + + RetCode = SK_PNMI_ERR_GENERAL; +- + } +- ++ + if (RetCode == SK_PNMI_ERR_OK) { + + pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED; +@@ -7723,7 +7663,7 @@ + /* Enter the DIAG mode in the driver. */ + case SK_DIAG_RUNNING: + RetCode = SK_PNMI_ERR_OK; +- ++ + /* + * If DiagAttached is set, we can tell the driver + * to enter the DIAG mode. +@@ -7732,7 +7672,7 @@ + /* If DiagMode is not active, we can enter it. */ + if (!pAC->DiagModeActive) { + +- RetCode = SkDrvEnterDiagMode(pAC); ++ RetCode = SkDrvEnterDiagMode(pAC); + } + else { + +@@ -7743,7 +7683,7 @@ + + RetCode = SK_PNMI_ERR_GENERAL; + } +- ++ + if (RetCode == SK_PNMI_ERR_OK) { + + pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING; +@@ -7751,7 +7691,7 @@ + break; + + case SK_DIAG_IDLE: +- /* Check if we come from running */ ++ /* Check if we come from running. */ + if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { + + RetCode = SkDrvLeaveDiagMode(pAC); +@@ -7760,12 +7700,10 @@ + else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { + + RetCode = SK_PNMI_ERR_OK; +- } +- ++ } + else { + + RetCode = SK_PNMI_ERR_GENERAL; +- + } + + if (RetCode == SK_PNMI_ERR_OK) { +@@ -7797,7 +7735,7 @@ + + /***************************************************************************** + * +- * Vct - OID handler function of OIDs ++ * Vct - OID handler function of OIDs for Virtual Cable Tester (VCT) + * + * Description: + * The code is simple. No description necessary. +@@ -7833,153 +7771,152 @@ + SK_U32 PhysPortIndex; + SK_U32 Limit; + SK_U32 Offset; +- SK_BOOL Link; +- SK_U32 RetCode = SK_PNMI_ERR_GENERAL; +- int i; ++ SK_U32 RetCode; ++ int i; + SK_EVPARA Para; +- SK_U32 CableLength; +- +- /* +- * Calculate the port indexes from the instance. +- */ ++ ++ RetCode = SK_PNMI_ERR_GENERAL; ++ ++ /* Calculate the port indexes from the instance. */ + PhysPortMax = pAC->GIni.GIMacsFound; + LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); +- ++ + /* Dual net mode? */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + LogPortMax--; + } +- ++ + if ((Instance != (SK_U32) (-1))) { +- /* Check instance range. */ +- if ((Instance < 2) || (Instance > LogPortMax)) { +- *pLen = 0; +- return (SK_PNMI_ERR_UNKNOWN_INST); +- } +- ++ /* ++ * Get one instance of that OID, so check the instance range: ++ * There is no virtual port with an Instance == 1, so we get ++ * the values from one physical port only. ++ */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + PhysPortIndex = NetIndex; + } + else { ++ if ((Instance < 2) || (Instance > LogPortMax)) { ++ *pLen = 0; ++ return (SK_PNMI_ERR_UNKNOWN_INST); ++ } + PhysPortIndex = Instance - 2; + } + Limit = PhysPortIndex + 1; + } + else { + /* +- * Instance == (SK_U32) (-1), get all Instances of that OID. +- * +- * Not implemented yet. May be used in future releases. ++ * Instance == (SK_U32) (-1), so get all instances of that OID. ++ * There is no virtual port with an Instance == 1, so we get ++ * the values from all physical ports. + */ + PhysPortIndex = 0; + Limit = PhysPortMax; + } +- ++ + pPrt = &pAC->GIni.GP[PhysPortIndex]; +- if (pPrt->PHWLinkUp) { +- Link = SK_TRUE; +- } +- else { +- Link = SK_FALSE; +- } +- +- /* Check MAC type */ +- if (pPrt->PhyType != SK_PHY_MARV_COPPER) { ++ ++ /* Check MAC type. */ ++ if ((Id != OID_SKGE_VCT_CAPABILITIES) && ++ (pPrt->PhyType != SK_PHY_MARV_COPPER)) { + *pLen = 0; +- return (SK_PNMI_ERR_GENERAL); ++ return (SK_PNMI_ERR_NOT_SUPPORTED); + } +- +- /* Initialize backup data pointer. */ +- pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; +- +- /* Check action type */ ++ ++ /* Check action type. */ + if (Action == SK_PNMI_GET) { +- /* Check length */ ++ /* Check length. */ + switch (Id) { +- ++ + case OID_SKGE_VCT_GET: + if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) { + *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; +- ++ + case OID_SKGE_VCT_STATUS: ++ case OID_SKGE_VCT_CAPABILITIES: + if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) { + *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; +- ++ + default: + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +- } +- +- /* Get value */ ++ } ++ ++ /* Get value. */ + Offset = 0; + for (; PhysPortIndex < Limit; PhysPortIndex++) { ++ ++ pPrt = &pAC->GIni.GP[PhysPortIndex]; ++ + switch (Id) { +- ++ + case OID_SKGE_VCT_GET: +- if ((Link == SK_FALSE) && ++ if (!pPrt->PHWLinkUp && + (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) { ++ + RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); ++ + if (RetCode == 0) { +- pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING; +- pAC->Pnmi.VctStatus[PhysPortIndex] |= +- (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE); +- +- /* Copy results for later use to PNMI struct. */ +- for (i = 0; i < 4; i++) { +- if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) { +- if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) { +- pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH; +- } +- } +- if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) { +- CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28); +- } +- else { +- CableLength = 0; +- } +- pVctBackupData->PMdiPairLen[i] = CableLength; +- pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i]; +- } ++ ++ /* VCT test is finished, so save the data. */ ++ VctGetResults(pAC, IoC, PhysPortIndex); + + Para.Para32[0] = PhysPortIndex; + Para.Para32[1] = -1; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); +- SkEventDispatcher(pAC, IoC); +- } +- else { +- ; /* VCT test is running. */ ++ ++ /* SkEventDispatcher(pAC, IoC); */ + } + } +- ++ ++ /* Initialize backup data pointer. */ ++ pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; ++ + /* Get all results. */ + CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex); +- Offset += sizeof(SK_U8); ++ ++ Offset++; + *(pBuf + Offset) = pPrt->PCableLen; +- Offset += sizeof(SK_U8); +- for (i = 0; i < 4; i++) { +- SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]); ++ Offset++; ++ for (i = 0; i < 4; i++) { ++ ++ SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->MdiPairLen[i]); + Offset += sizeof(SK_U32); + } +- for (i = 0; i < 4; i++) { +- *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i]; +- Offset += sizeof(SK_U8); ++ for (i = 0; i < 4; i++) { ++ ++ *(pBuf + Offset) = pVctBackupData->MdiPairSts[i]; ++ Offset++; + } +- ++ + RetCode = SK_PNMI_ERR_OK; + break; +- ++ + case OID_SKGE_VCT_STATUS: + CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex); +- Offset += sizeof(SK_U8); ++ ++ Offset++; + RetCode = SK_PNMI_ERR_OK; + break; +- ++ ++ case OID_SKGE_VCT_CAPABILITIES: ++ if (pPrt->PhyType != SK_PHY_MARV_COPPER) { ++ *(pBuf + Offset) = SK_PNMI_VCT_NOT_SUPPORTED; ++ } ++ else { ++ *(pBuf + Offset) = SK_PNMI_VCT_SUPPORTED_VERSION; ++ } ++ Offset++; ++ ++ RetCode = SK_PNMI_ERR_OK; ++ break; ++ + default: + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -7987,15 +7924,15 @@ + } /* for */ + *pLen = Offset; + return (RetCode); +- ++ + } /* if SK_PNMI_GET */ +- ++ + /* + * From here SET or PRESET action. Check if the passed + * buffer length is plausible. + */ +- +- /* Check length */ ++ ++ /* Check length. */ + switch (Id) { + case OID_SKGE_VCT_SET: + if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) { +@@ -8003,42 +7940,45 @@ + return (SK_PNMI_ERR_TOO_SHORT); + } + break; +- ++ + default: + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } +- +- /* +- * Perform preset or set. +- */ +- ++ ++ /* Perform PRESET or SET. */ ++ + /* VCT does not support PRESET action. */ + if (Action == SK_PNMI_PRESET) { ++ + return (SK_PNMI_ERR_OK); + } +- ++ + Offset = 0; + for (; PhysPortIndex < Limit; PhysPortIndex++) { ++ ++ pPrt = &pAC->GIni.GP[PhysPortIndex]; ++ + switch (Id) { + case OID_SKGE_VCT_SET: /* Start VCT test. */ +- if (Link == SK_FALSE) { ++ if (!pPrt->PHWLinkUp) { + SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST); +- ++ + RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE); ++ + if (RetCode == 0) { /* RetCode: 0 => Start! */ + pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING; +- pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA; +- pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK; +- +- /* +- * Start VCT timer counter. +- */ +- SK_MEMSET((char *) &Para, 0, sizeof(Para)); ++ pAC->Pnmi.VctStatus[PhysPortIndex] &= ++ ~(SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_LINK); ++ ++ /* Start VCT timer counter. */ ++ SK_MEMSET((char *)&Para, 0, sizeof(Para)); + Para.Para32[0] = PhysPortIndex; + Para.Para32[1] = -1; +- SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer, +- 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para); ++ ++ SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex], ++ SK_PNMI_VCT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para); ++ + SK_PNMI_STORE_U32((pBuf + Offset), RetCode); + RetCode = SK_PNMI_ERR_OK; + } +@@ -8054,7 +7994,7 @@ + } + Offset += sizeof(SK_U32); + break; +- ++ + default: + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +@@ -8066,6 +8006,28 @@ + } /* Vct */ + + ++PNMI_STATIC void VctGetResults( ++SK_AC *pAC, ++SK_IOC IoC, ++SK_U32 Port) ++{ ++ SK_GEPORT *pPrt; ++ int i; ++ ++ pPrt = &pAC->GIni.GP[Port]; ++ ++ /* Copy results for later use to PNMI struct. */ ++ for (i = 0; i < 4; i++) { ++ pAC->Pnmi.VctBackup[Port].MdiPairLen[i] = pPrt->PMdiPairLen[i]; ++ pAC->Pnmi.VctBackup[Port].MdiPairSts[i] = pPrt->PMdiPairSts[i]; ++ } ++ ++ pAC->Pnmi.VctStatus[Port] &= ~SK_PNMI_VCT_PENDING; ++ pAC->Pnmi.VctStatus[Port] |= (SK_PNMI_VCT_NEW_VCT_DATA | ++ SK_PNMI_VCT_TEST_DONE); ++ ++} /* GetVctResults */ ++ + PNMI_STATIC void CheckVctStatus( + SK_AC *pAC, + SK_IOC IoC, +@@ -8075,51 +8037,53 @@ + { + SK_GEPORT *pPrt; + SK_PNMI_VCT *pVctData; ++ SK_U8 VctStatus; + SK_U32 RetCode; +- ++ + pPrt = &pAC->GIni.GP[PhysPortIndex]; +- ++ + pVctData = (SK_PNMI_VCT *) (pBuf + Offset); + pVctData->VctStatus = SK_PNMI_VCT_NONE; +- ++ ++ VctStatus = pAC->Pnmi.VctStatus[PhysPortIndex]; ++ + if (!pPrt->PHWLinkUp) { +- ++ + /* Was a VCT test ever made before? */ +- if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) { +- if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) { ++ if (VctStatus & SK_PNMI_VCT_TEST_DONE) { ++ if (VctStatus & SK_PNMI_VCT_LINK) { + pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA; + } + else { + pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA; + } + } +- ++ + /* Check VCT test status. */ +- RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE); ++ RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); ++ + if (RetCode == 2) { /* VCT test is running. */ + pVctData->VctStatus |= SK_PNMI_VCT_RUNNING; + } + else { /* VCT data was copied to pAC here. Check PENDING state. */ +- if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { ++ if (VctStatus & SK_PNMI_VCT_PENDING) { + pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA; + } + } +- ++ + if (pPrt->PCableLen != 0xff) { /* Old DSP value. */ + pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA; + } + } + else { +- + /* Was a VCT test ever made before? */ +- if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) { ++ if (VctStatus & SK_PNMI_VCT_TEST_DONE) { + pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA; + pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA; + } +- ++ + /* DSP only valid in 100/1000 modes. */ +- if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed != +- SK_LSPEED_STAT_10MBPS) { ++ if (pPrt->PLinkSpeedUsed != SK_LSPEED_STAT_10MBPS) { + pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA; + } + } +@@ -8163,31 +8127,31 @@ + int HeaderLength; /* Length of desired action plus OID. */ + + ReturnCode = SK_PNMI_ERR_GENERAL; +- ++ + SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32)); +- SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32)); ++ SK_MEMCPY(&Oid, (char *)pBuf + sizeof(SK_I32), sizeof(SK_U32)); + HeaderLength = sizeof(SK_I32) + sizeof(SK_U32); + *pLen = *pLen - HeaderLength; +- SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen); +- +- switch(Mode) { ++ SK_MEMCPY((char *)pBuf + sizeof(SK_I32), (char *)pBuf + HeaderLength, *pLen); ++ ++ switch (Mode) { + case SK_GET_SINGLE_VAR: +- ReturnCode = SkPnmiGetVar(pAC, IoC, Oid, +- (char *) pBuf + sizeof(SK_I32), pLen, ++ ReturnCode = SkPnmiGetVar(pAC, IoC, Oid, ++ (char *)pBuf + sizeof(SK_I32), pLen, + ((SK_U32) (-1)), NetIndex); + SK_PNMI_STORE_U32(pBuf, ReturnCode); + *pLen = *pLen + sizeof(SK_I32); + break; + case SK_PRESET_SINGLE_VAR: +- ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid, +- (char *) pBuf + sizeof(SK_I32), pLen, ++ ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid, ++ (char *)pBuf + sizeof(SK_I32), pLen, + ((SK_U32) (-1)), NetIndex); + SK_PNMI_STORE_U32(pBuf, ReturnCode); + *pLen = *pLen + sizeof(SK_I32); + break; + case SK_SET_SINGLE_VAR: +- ReturnCode = SkPnmiSetVar(pAC, IoC, Oid, +- (char *) pBuf + sizeof(SK_I32), pLen, ++ ReturnCode = SkPnmiSetVar(pAC, IoC, Oid, ++ (char *)pBuf + sizeof(SK_I32), pLen, + ((SK_U32) (-1)), NetIndex); + SK_PNMI_STORE_U32(pBuf, ReturnCode); + *pLen = *pLen + sizeof(SK_I32); +@@ -8208,3 +8172,86 @@ + return (ReturnCode); + + } /* SkGeIocGen */ ++ ++#ifdef SK_ASF ++/***************************************************************************** ++ * ++ * Asf ++ * ++ * Description: ++ * The code is simple. No description necessary. ++ * ++ * Returns: ++ * SK_PNMI_ERR_OK The request was successfully performed. ++ * SK_PNMI_ERR_GENERAL A general severe internal error occured. ++ * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain ++ * the correct data (e.g. a 32bit value is ++ * needed, but a 16 bit value was passed). ++ * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't ++ * exist (e.g. port instance 3 on a two port ++ * adapter. ++ */ ++ ++PNMI_STATIC int Asf( ++SK_AC *pAC, /* Pointer to adapter context */ ++SK_IOC IoC, /* IO context handle */ ++int Action, /* GET/PRESET/SET action */ ++SK_U32 Id, /* Object ID that is to be processed */ ++char *pBuf, /* Buffer used for the management data transfer */ ++unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ ++SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ ++unsigned int TableIndex, /* Index to the Id table */ ++SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ ++{ ++ SK_U32 RetCode = SK_PNMI_ERR_GENERAL; ++ ++ /* ++ * Check instance. We only handle single instance variables. ++ */ ++ if (Instance != (SK_U32)(-1) && Instance != 1) { ++ ++ *pLen = 0; ++ return (SK_PNMI_ERR_UNKNOWN_INST); ++ } ++ ++ /* Perform action. */ ++ /* GET value. */ ++ if (Action == SK_PNMI_GET) { ++ switch (Id) { ++ case OID_SKGE_ASF: ++ RetCode = SkAsfGet(pAC, IoC, (SK_U8 *) pBuf, pLen); ++ break; ++ default: ++ RetCode = SkAsfGetOid( pAC, IoC, Id, Instance, (SK_U8 *)pBuf, pLen); ++ break; ++ } ++ ++ return (RetCode); ++ } ++ ++ /* PRESET value. */ ++ if (Action == SK_PNMI_PRESET) { ++ switch (Id) { ++ case OID_SKGE_ASF: ++ RetCode = SkAsfPreSet(pAC, IoC, (SK_U8 *) pBuf, pLen); ++ break; ++ default: ++ RetCode = SkAsfPreSetOid( pAC, IoC, Id, Instance, (SK_U8 *)pBuf, pLen); ++ break; ++ } ++ } ++ ++ /* SET value. */ ++ if (Action == SK_PNMI_SET) { ++ switch (Id) { ++ case OID_SKGE_ASF: ++ RetCode = SkAsfSet(pAC, IoC, (SK_U8 *) pBuf, pLen); ++ break; ++ default: ++ RetCode = SkAsfSetOid( pAC, IoC, Id, Instance, (SK_U8 *)pBuf, pLen); ++ break; ++ } ++ } ++ return (RetCode); ++} ++#endif /* SK_ASF */ +diff -ruN linux/drivers/net/sk98lin/skgesirq.c linux-new/drivers/net/sk98lin/skgesirq.c +--- linux/drivers/net/sk98lin/skgesirq.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skgesirq.c 2007-01-24 13:58:33.000000000 +0100 +@@ -2,23 +2,24 @@ + * + * Name: skgesirq.c + * Project: Gigabit Ethernet Adapters, Common Modules +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Special IRQ module + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2007 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. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -38,7 +39,7 @@ + * right after this ISR. + * + * The Interrupt source register of the adapter is NOT read by this module. +- * SO if the drivers implementor needs a while loop around the ++ * SO if the drivers implementor needs a while loop around the + * slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for + * each loop entered. + * +@@ -46,11 +47,6 @@ + * + */ + +-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) +-static const char SysKonnectFileId[] = +- "@(#) $Id$ (C) Marvell."; +-#endif +- + #include "h/skdrv1st.h" /* Driver Specific Definitions */ + #ifndef SK_SLIM + #include "h/skgepnmi.h" /* PNMI Definitions */ +@@ -58,6 +54,13 @@ + #endif + #include "h/skdrv2nd.h" /* Adapter Control and Driver specific Def. */ + ++/* local variables ************************************************************/ ++ ++#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) ++static const char SysKonnectFileId[] = ++ "@(#) $Id$ (C) Marvell."; ++#endif ++ + /* local function prototypes */ + #ifdef GENESIS + static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL); +@@ -86,7 +89,7 @@ + XM_RXF_511B, + XM_RXF_1023B, + XM_RXF_MAX_SZ +-} ; ++}; + #endif /* GENESIS */ + + #ifdef __C2MAN__ +@@ -109,8 +112,8 @@ + * Returns: N/A + */ + static void SkHWInitDefSense( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; /* GIni Port struct pointer */ +@@ -119,7 +122,7 @@ + + pPrt->PAutoNegTimeOut = 0; + +- if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) { ++ if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { + pPrt->PLinkMode = pPrt->PLinkModeConf; + return; + } +@@ -145,8 +148,8 @@ + * + */ + static SK_U8 SkHWSenseGetNext( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; /* GIni Port struct pointer */ +@@ -155,18 +158,18 @@ + + pPrt->PAutoNegTimeOut = 0; + +- if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { ++ if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { + /* Leave all as configured */ + return(pPrt->PLinkModeConf); + } + +- if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) { ++ if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) { + /* Return next mode AUTOBOTH */ +- return ((SK_U8)SK_LMODE_AUTOBOTH); ++ return((SK_U8)SK_LMODE_AUTOBOTH); + } + + /* Return default autofull */ +- return ((SK_U8)SK_LMODE_AUTOFULL); ++ return((SK_U8)SK_LMODE_AUTOFULL); + } /* SkHWSenseGetNext */ + + +@@ -179,8 +182,8 @@ + * Returns: N/A + */ + static void SkHWSenseSetNext( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O context */ + int Port, /* Port Index (MAC_1 + n) */ + SK_U8 NewMode) /* New Mode to be written in sense mode */ + { +@@ -190,7 +193,7 @@ + + pPrt->PAutoNegTimeOut = 0; + +- if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { ++ if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { + return; + } + +@@ -214,8 +217,8 @@ + * Returns: N/A + */ + void SkHWLinkDown( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; /* GIni Port struct pointer */ +@@ -227,26 +230,28 @@ + + /* Disable Receiver and Transmitter */ + SkMacRxTxDisable(pAC, IoC, Port); +- ++ + /* Init default sense mode */ + SkHWInitDefSense(pAC, IoC, Port); + +- if (pPrt->PHWLinkUp == SK_FALSE) { ++ if (!pPrt->PHWLinkUp) { + return; + } + +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Link down Port %d\n", Port)); + + /* Set Link to DOWN */ + pPrt->PHWLinkUp = SK_FALSE; + ++#ifndef SK_SLIM + /* Reset Port stati */ +- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; +- pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; ++ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; ++ pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED; ++#endif /* !SK_SLIM */ + +- /* Re-init Phy especially when the AutoSense default is set now */ ++ /* Re-init PHY especially when the AutoSense default is set now */ + SkMacInitPhy(pAC, IoC, Port, SK_FALSE); + + /* GP0: used for workaround of Rev. C Errata 2 */ +@@ -265,9 +270,9 @@ + * + * Returns: N/A + */ +-static void SkHWLinkUp( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++void SkHWLinkUp( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; /* GIni Port struct pointer */ +@@ -280,12 +285,14 @@ + } + + pPrt->PHWLinkUp = SK_TRUE; ++ ++#ifndef SK_SLIM + pPrt->PAutoNegFail = SK_FALSE; +- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; ++ pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; + +- if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF && +- pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL && +- pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) { ++ if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF && ++ pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL && ++ pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) { + /* Link is up and no Auto-negotiation should be done */ + + /* Link speed should be the configured one */ +@@ -293,7 +300,9 @@ + case SK_LSPEED_AUTO: + /* default is 1000 Mbps */ + case SK_LSPEED_1000MBPS: +- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; ++ pPrt->PLinkSpeedUsed = (SK_U8) ++ ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) ? ++ SK_LSPEED_STAT_1000MBPS : SK_LSPEED_STAT_100MBPS; + break; + case SK_LSPEED_100MBPS: + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; +@@ -304,19 +313,18 @@ + } + + /* Set Link Mode Status */ +- if (pPrt->PLinkMode == SK_LMODE_FULL) { +- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL; +- } +- else { +- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF; +- } ++ pPrt->PLinkModeStatus = (SK_U8)((pPrt->PLinkMode == SK_LMODE_FULL) ? ++ SK_LMODE_STAT_FULL : SK_LMODE_STAT_HALF); + + /* No flow control without auto-negotiation */ +- pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; ++ pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; ++#endif /* !SK_SLIM */ + + /* enable Rx/Tx */ +- (void)SkMacRxTxEnable(pAC, IoC, Port); ++ (void)SkMacRxTxEnable(pAC, IoC, Port); ++#ifndef SK_SLIM + } ++#endif /* !SK_SLIM */ + } /* SkHWLinkUp */ + + +@@ -329,14 +337,16 @@ + * Returns: N/A + */ + static void SkMacParity( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ +-int Port) /* Port Index of the port failed */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O context */ ++int Port) /* Port Index (MAC_1 + n) */ + { + SK_EVPARA Para; + SK_GEPORT *pPrt; /* GIni Port struct pointer */ + SK_U32 TxMax; /* Tx Max Size Counter */ + ++ TxMax = 0; ++ + pPrt = &pAC->GIni.GP[Port]; + + /* Clear IRQ Tx Parity Error */ +@@ -346,7 +356,7 @@ + SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { + /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */ +@@ -355,7 +365,7 @@ + pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE)); + } + #endif /* YUKON */ +- ++ + if (pPrt->PCheckPar) { + + if (Port == MAC_1) { +@@ -366,7 +376,7 @@ + } + Para.Para64 = Port; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); +- ++ + Para.Para32[0] = Port; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); + +@@ -378,18 +388,18 @@ + if (pAC->GIni.GIGenesis) { + /* Snap statistic counters */ + (void)SkXmUpdateStats(pAC, IoC, Port); +- ++ + (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { + + (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax); + } + #endif /* YUKON */ +- ++ + if (TxMax > 0) { + /* From now on check the parity */ + pPrt->PCheckPar = SK_TRUE; +@@ -399,20 +409,23 @@ + + /****************************************************************************** + * +- * SkGeHwErr() - Hardware Error service routine ++ * SkGeYuHwErr() - Hardware Error service routine (Genesis and Yukon) + * + * Description: handles all HW Error interrupts + * + * Returns: N/A + */ +-static void SkGeHwErr( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++static void SkGeYuHwErr( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O context */ + SK_U32 HwStatus) /* Interrupt status word */ + { + SK_EVPARA Para; + SK_U16 Word; + ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ++ ("HW-Error Status: 0x%08lX\n", HwStatus)); ++ + if ((HwStatus & (IS_IRQ_MST_ERR | IS_IRQ_STAT)) != 0) { + /* PCI Errors occured */ + if ((HwStatus & IS_IRQ_STAT) != 0) { +@@ -423,10 +436,10 @@ + } + + /* Reset all bits in the PCI STATUS register */ +- SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); +- ++ SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word); ++ + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); +- SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); ++ SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + + Para.Para64 = 0; +@@ -461,7 +474,7 @@ + } + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { + /* This is necessary only for Rx timing measurements */ +@@ -484,14 +497,18 @@ + #endif /* YUKON */ + + if ((HwStatus & IS_RAM_RD_PAR) != 0) { ++ + SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR); ++ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG); + Para.Para64 = 0; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); + } + + if ((HwStatus & IS_RAM_WR_PAR) != 0) { ++ + SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR); ++ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG); + Para.Para64 = 0; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); +@@ -512,7 +529,7 @@ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG); + Para.Para64 = MAC_1; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); +- ++ + Para.Para32[0] = MAC_1; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); + } +@@ -524,37 +541,298 @@ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG); + Para.Para64 = MAC_2; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); +- ++ + Para.Para32[0] = MAC_2; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); + } +-} /* SkGeHwErr */ ++} /* SkGeYuHwErr */ ++ ++#ifdef YUK2 ++/****************************************************************************** ++ * ++ * SkYuk2HwPortErr() - Service HW Errors for specified port (Yukon-2 only) ++ * ++ * Description: handles the HW Error interrupts for a specific port. ++ * ++ * Returns: N/A ++ */ ++static void SkYuk2HwPortErr( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++SK_U32 HwStatus, /* Interrupt status word */ ++int Port) /* Port Index (MAC_1 + n) */ ++{ ++ SK_EVPARA Para; ++ int Queue; ++ ++ if (Port == MAC_2) { ++ HwStatus >>= 8; ++ } + ++ if ((HwStatus & Y2_HWE_L1_MASK) == 0) { ++ return; ++ } ++ ++ if ((HwStatus & Y2_IS_PAR_RD1) != 0) { ++ /* Clear IRQ */ ++ SK_OUT16(IoC, SELECT_RAM_BUFFER(Port, B3_RI_CTRL), RI_CLR_RD_PERR); ++ ++ if (Port == MAC_1) { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E028, SKERR_SIRQ_E028MSG); ++ } ++ else { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E030, SKERR_SIRQ_E030MSG); ++ } ++ } ++ ++ if ((HwStatus & Y2_IS_PAR_WR1) != 0) { ++ /* Clear IRQ */ ++ SK_OUT16(IoC, SELECT_RAM_BUFFER(Port, B3_RI_CTRL), RI_CLR_WR_PERR); ++ ++ if (Port == MAC_1) { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E029, SKERR_SIRQ_E029MSG); ++ } ++ else { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E031, SKERR_SIRQ_E031MSG); ++ } ++ } ++ ++ if ((HwStatus & Y2_IS_PAR_MAC1) != 0) { ++ /* Clear IRQ */ ++ SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), GMF_CLI_TX_PE); ++ ++ if (Port == MAC_1) { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG); ++ } ++ else { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG); ++ } ++ } ++ ++ if ((HwStatus & Y2_IS_PAR_RX1) != 0) { ++ if (Port == MAC_1) { ++ Queue = Q_R1; ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG); ++ } ++ else { ++ Queue = Q_R2; ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG); ++ } ++ /* Clear IRQ */ ++ SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_PAR); ++ } ++ ++ if ((HwStatus & Y2_IS_TCP_TXS1) != 0) { ++ if (Port == MAC_1) { ++ Queue = Q_XS1; ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E033, SKERR_SIRQ_E033MSG); ++ } ++ else { ++ Queue = Q_XS2; ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E035, SKERR_SIRQ_E035MSG); ++ } ++ /* Clear IRQ */ ++ SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_TCP); ++ } ++ ++ if ((HwStatus & Y2_IS_TCP_TXA1) != 0) { ++ if (Port == MAC_1) { ++ Queue = Q_XA1; ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E032, SKERR_SIRQ_E032MSG); ++ } ++ else { ++ Queue = Q_XA2; ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E034, SKERR_SIRQ_E034MSG); ++ } ++ /* Clear IRQ */ ++ SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_TCP); ++ } ++ ++ Para.Para64 = Port; ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); ++ ++ Para.Para32[0] = Port; ++ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); ++ ++} /* SkYuk2HwPortErr */ + + /****************************************************************************** + * +- * SkGeSirqIsr() - Special Interrupt Service Routine ++ * SkYuk2HwErr() - Hardware Error service routine (Yukon-2 only) + * +- * Description: handles all non data transfer specific interrupts (slow path) ++ * Description: handles all HW Error interrupts ++ * ++ * Returns: N/A ++ */ ++static void SkYuk2HwErr( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++SK_U32 HwStatus) /* Interrupt status word */ ++{ ++ SK_EVPARA Para; ++ SK_U16 Word; ++ SK_U32 DWord; ++ SK_U32 TlpHead[4]; ++ int i; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ++ ("HW-Error Status: 0x%08lX\n", HwStatus)); ++ ++ /* This is necessary only for Rx timing measurements */ ++ if ((HwStatus & Y2_IS_TIST_OV) != 0) { ++ /* increment Time Stamp Timer counter (high) */ ++ pAC->GIni.GITimeStampCnt++; ++ ++ /* Clear Time Stamp Timer IRQ */ ++ SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ); ++ } ++ ++ /* Evaluate Y2_IS_PCI_NEXP before Y2_IS_MST_ERR or Y2_IS_IRQ_STAT */ ++ if ((HwStatus & Y2_IS_PCI_NEXP) != 0) { ++ /* ++ * This error is also mapped either to Master Abort (Y2_IS_MST_ERR) ++ * or Target Abort (Y2_IS_IRQ_STAT) bit and can only be cleared there. ++ * Therefore handle this event just by printing an error log entry. ++ */ ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E027, SKERR_SIRQ_E027MSG); ++ } ++ ++ if ((HwStatus & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) != 0) { ++ /* PCI Errors occured */ ++ if ((HwStatus & Y2_IS_IRQ_STAT) != 0) { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG); ++ } ++ else { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG); ++ } ++ ++ /* Reset all bits in the PCI STATUS register */ ++ SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word); ++ ++ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); ++ SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); ++ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); ++ ++ Para.Para64 = 0; ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); ++ } ++ ++ /* check for PCI-Express Uncorrectable Error */ ++ if ((HwStatus & Y2_IS_PCI_EXP) != 0) { ++ /* ++ * On PCI-Express bus bridges are called root complexes (RC). ++ * PCI-Express errors are recognized by the root complex too, ++ * which requests the system to handle the problem. After error ++ * occurence it may be that no access to the adapter may be performed ++ * any longer. ++ */ ++ ++ /* Get uncorrectable error status */ ++ SK_IN32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), &DWord); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ++ ("PEX Uncorr.Error Status: 0x%08lX\n", DWord)); ++ ++ if (DWord != PEX_UNSUP_REQ) { ++ /* ignore Unsupported Request Errors */ ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E026, SKERR_SIRQ_E026MSG); ++ } ++ ++ if ((DWord & (PEX_FATAL_ERRORS | PEX_POIS_TLP)) != 0) { ++ /* ++ * Stop only, if the uncorrectable error is fatal or ++ * Poisoned TLP occured ++ */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Header Log:")); ++ ++ for (i = 0; i < 4; i++) { ++ /* get TLP Header from Log Registers */ ++ SK_IN32(IoC, PCI_C(pAC, PEX_HEADER_LOG + i*4), &TlpHead[i]); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ++ (" 0x%08lX", TlpHead[i])); ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("\n")); ++ ++ /* check for vendor defined broadcast message */ ++ if (TlpHead[0] == 0x73004001 && (SK_U8)TlpHead[1] == 0x7f) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ++ ("Vendor defined broadcast message\n")); ++ } ++ else { ++ Para.Para64 = 0; ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); ++ ++ pAC->GIni.GIValHwIrqMask &= ~Y2_IS_PCI_EXP; ++ /* Rewrite HW IRQ mask */ ++ SK_OUT32(IoC, B0_HWE_IMSK, pAC->GIni.GIValHwIrqMask); ++ } ++ } ++ ++ /* clear any PEX errors */ ++ SK_OUT32(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); ++ SK_OUT32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), 0xffffffffUL); ++ SK_OUT32(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); ++ ++ SK_IN32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), &DWord); ++ ++ if ((DWord & PEX_RX_OV) != 0) { ++ /* Dev #4.205 occured */ ++ pAC->GIni.GIValHwIrqMask &= ~Y2_IS_PCI_EXP; ++ pAC->GIni.GIValIrqMask &= ~Y2_IS_HW_ERR; ++ } ++ } ++ ++ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { ++ ++ SkYuk2HwPortErr(pAC, IoC, HwStatus, i); ++ } ++ ++} /* SkYuk2HwErr */ ++#endif /* YUK2 */ ++ ++/****************************************************************************** ++ * ++ * SkGeSirqIsr() - Wrapper for Special Interrupt Service Routine ++ * ++ * Description: calls the preselected special ISR (slow path) + * + * Returns: N/A + */ + void SkGeSirqIsr( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O context */ ++SK_U32 Istatus) /* Interrupt status word */ ++{ ++ pAC->GIni.GIFunc.pSkGeSirqIsr(pAC, IoC, Istatus); ++} ++ ++/****************************************************************************** ++ * ++ * SkGeYuSirqIsr() - Special Interrupt Service Routine ++ * ++ * Description: handles all non data transfer specific interrupts (slow path) ++ * ++ * Returns: N/A ++ */ ++void SkGeYuSirqIsr( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + SK_U32 Istatus) /* Interrupt status word */ + { + SK_EVPARA Para; + SK_U32 RegVal32; /* Read register value */ + SK_GEPORT *pPrt; /* GIni Port struct pointer */ +- SK_U16 PhyInt; ++ SK_U16 PhyInt; + int i; ++ int Rtv; + + if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) { + /* read the HW Error Interrupt source */ + SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); +- +- SkGeHwErr(pAC, IoC, RegVal32); ++ ++ SkGeYuHwErr(pAC, IoC, RegVal32); + } + + /* +@@ -569,7 +847,7 @@ + } + + if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) && +- pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) { ++ pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) { + /* MAC 2 was not initialized but Packet timeout occured */ + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005, + SKERR_SIRQ_E005MSG); +@@ -590,8 +868,8 @@ + } + + if ((Istatus & IS_PA_TO_TX1) != 0) { +- +- pPrt = &pAC->GIni.GP[0]; ++ ++ pPrt = &pAC->GIni.GP[MAC_1]; + + /* May be a normal situation in a server with a slow network */ + SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1); +@@ -612,17 +890,18 @@ + * we ignore those + */ + pPrt->HalfDupTimerActive = SK_TRUE; ++ + /* Snap statistic counters */ + (void)SkXmUpdateStats(pAC, IoC, 0); + + (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32); + + pPrt->LastOctets = (SK_U64)RegVal32 << 32; +- ++ + (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32); + + pPrt->LastOctets += RegVal32; +- ++ + Para.Para32[0] = 0; + SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, + SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); +@@ -632,8 +911,8 @@ + } + + if ((Istatus & IS_PA_TO_TX2) != 0) { +- +- pPrt = &pAC->GIni.GP[1]; ++ ++ pPrt = &pAC->GIni.GP[MAC_2]; + + /* May be a normal situation in a server with a slow network */ + SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2); +@@ -645,17 +924,18 @@ + pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && + !pPrt->HalfDupTimerActive) { + pPrt->HalfDupTimerActive = SK_TRUE; ++ + /* Snap statistic counters */ + (void)SkXmUpdateStats(pAC, IoC, 1); + + (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32); + + pPrt->LastOctets = (SK_U64)RegVal32 << 32; +- ++ + (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32); + + pPrt->LastOctets += RegVal32; +- ++ + Para.Para32[0] = 1; + SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, + SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); +@@ -668,6 +948,7 @@ + if ((Istatus & IS_R1_C) != 0) { + /* Clear IRQ */ + SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C); ++ + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006, + SKERR_SIRQ_E006MSG); + Para.Para64 = MAC_1; +@@ -679,6 +960,7 @@ + if ((Istatus & IS_R2_C) != 0) { + /* Clear IRQ */ + SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C); ++ + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007, + SKERR_SIRQ_E007MSG); + Para.Para64 = MAC_2; +@@ -690,6 +972,7 @@ + if ((Istatus & IS_XS1_C) != 0) { + /* Clear IRQ */ + SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C); ++ + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008, + SKERR_SIRQ_E008MSG); + Para.Para64 = MAC_1; +@@ -701,6 +984,7 @@ + if ((Istatus & IS_XA1_C) != 0) { + /* Clear IRQ */ + SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C); ++ + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009, + SKERR_SIRQ_E009MSG); + Para.Para64 = MAC_1; +@@ -712,6 +996,7 @@ + if ((Istatus & IS_XS2_C) != 0) { + /* Clear IRQ */ + SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C); ++ + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010, + SKERR_SIRQ_E010MSG); + Para.Para64 = MAC_2; +@@ -723,6 +1008,7 @@ + if ((Istatus & IS_XA2_C) != 0) { + /* Clear IRQ */ + SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C); ++ + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011, + SKERR_SIRQ_E011MSG); + Para.Para64 = MAC_2; +@@ -735,39 +1021,37 @@ + if ((Istatus & IS_EXT_REG) != 0) { + /* Test IRQs from PHY */ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { +- ++ + pPrt = &pAC->GIni.GP[i]; +- ++ + if (pPrt->PState == SK_PRT_RESET) { + continue; + } +- ++ + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +- ++ + switch (pPrt->PhyType) { +- ++ + case SK_PHY_XMAC: + break; +- ++ + case SK_PHY_BCOM: + SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt); +- ++ + if ((PhyInt & ~PHY_B_DEF_MSK) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, +- ("Port %d Bcom Int: 0x%04X\n", +- i, PhyInt)); ++ ("Port %d PHY Int: 0x%04X\n", i, PhyInt)); + SkPhyIsrBcom(pAC, IoC, i, PhyInt); + } + break; + #ifdef OTHER_PHY + case SK_PHY_LONE: + SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt); +- ++ + if ((PhyInt & PHY_L_DEF_MSK) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, +- ("Port %d Lone Int: %x\n", +- i, PhyInt)); ++ ("Port %d PHY Int: 0x%04X\n", i, PhyInt)); + SkPhyIsrLone(pAC, IoC, i, PhyInt); + } + break; +@@ -775,16 +1059,16 @@ + } + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { + /* Read PHY Interrupt Status */ +- SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt); ++ Rtv = SkGmPhyRead(pAC, IoC, i, PHY_MARV_INT_STAT, &PhyInt); + +- if ((PhyInt & PHY_M_DEF_MSK) != 0) { ++ if (Rtv == 0 && (PhyInt & PHY_M_DEF_MSK) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, +- ("Port %d Marv Int: 0x%04X\n", +- i, PhyInt)); ++ ("Port %d PHY Int: 0x%04X\n", i, PhyInt)); ++ + SkPhyIsrGmac(pAC, IoC, i, PhyInt); + } + } +@@ -792,13 +1076,13 @@ + } + } + +- /* I2C Ready interrupt */ ++ /* TWSI Ready interrupt */ + if ((Istatus & IS_I2C_READY) != 0) { + #ifdef SK_SLIM +- SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); +-#else ++ SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); ++#else + SkI2cIsr(pAC, IoC); +-#endif ++#endif + } + + /* SW forced interrupt */ +@@ -813,7 +1097,7 @@ + * us only a link going down. + */ + /* clear interrupt */ +- SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ); ++ SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LNK_CLR_IRQ); + } + + /* Check MAC after link sync counter */ +@@ -828,7 +1112,7 @@ + * us only a link going down. + */ + /* clear interrupt */ +- SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ); ++ SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LNK_CLR_IRQ); + } + + /* Check MAC after link sync counter */ +@@ -838,19 +1122,210 @@ + } + + /* Timer interrupt (served last) */ +- if ((Istatus & IS_TIMINT) != 0) { +- /* check for HW Errors */ +- if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) { ++ if ((Istatus & IS_TIMINT) != 0) { ++ /* check for HW Errors */ ++ if (((Istatus & IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) { ++ /* read the HW Error Interrupt source */ ++ SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); ++ ++ SkGeYuHwErr(pAC, IoC, RegVal32); ++ } ++ ++ SkHwtIsr(pAC, IoC); ++ } ++ ++} /* SkGeYuSirqIsr */ ++ ++#ifdef YUK2 ++/****************************************************************************** ++ * ++ * SkYuk2PortSirq() - Service HW Errors for specified port (Yukon-2 only) ++ * ++ * Description: handles the HW Error interrupts for a specific port. ++ * ++ * Returns: N/A ++ */ ++static void SkYuk2PortSirq( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++SK_U32 IStatus, /* Interrupt status word */ ++int Port) /* Port Index (MAC_1 + n) */ ++{ ++ SK_EVPARA Para; ++ int Queue; ++ int Rtv; ++ SK_U16 PhyInt; ++ ++ if (Port == MAC_2) { ++ IStatus >>= 8; ++ } ++ ++ /* Interrupt from PHY */ ++ if ((IStatus & Y2_IS_IRQ_PHY1) != 0 && ++ pAC->GIni.GP[Port].PState != SK_PRT_RESET) { ++ /* Read PHY Interrupt Status */ ++ Rtv = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyInt); ++ ++ if (Rtv == 0 && (PhyInt & PHY_M_DEF_MSK) != 0) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ++ ("Port %d PHY Int: 0x%04X\n", Port, PhyInt)); ++ ++ SkPhyIsrGmac(pAC, IoC, Port, PhyInt); ++ } ++ } ++ ++ /* Interrupt from MAC */ ++ if ((IStatus & Y2_IS_IRQ_MAC1) != 0) { ++ SkMacIrq(pAC, IoC, Port); ++ } ++ ++ if ((IStatus & (Y2_IS_CHK_RX1 | Y2_IS_CHK_TXS1 | Y2_IS_CHK_TXA1)) != 0) { ++ if ((IStatus & Y2_IS_CHK_RX1) != 0) { ++ if (Port == MAC_1) { ++ Queue = Q_R1; ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E006, ++ SKERR_SIRQ_E006MSG); ++ } ++ else { ++ Queue = Q_R2; ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E007, ++ SKERR_SIRQ_E007MSG); ++ } ++ /* Clear IRQ */ ++ SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK); ++ } ++ ++ if ((IStatus & Y2_IS_CHK_TXS1) != 0) { ++ if (Port == MAC_1) { ++ Queue = Q_XS1; ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E008, ++ SKERR_SIRQ_E008MSG); ++ } ++ else { ++ Queue = Q_XS2; ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E010, ++ SKERR_SIRQ_E010MSG); ++ } ++ /* Clear IRQ */ ++ SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK); ++ } ++ ++ if ((IStatus & Y2_IS_CHK_TXA1) != 0) { ++ if (Port == MAC_1) { ++ Queue = Q_XA1; ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E009, ++ SKERR_SIRQ_E009MSG); ++ } ++ else { ++ Queue = Q_XA2; ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E011, ++ SKERR_SIRQ_E011MSG); ++ } ++ /* Clear IRQ */ ++ SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK); ++ } ++ ++ Para.Para64 = Port; ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); ++ ++ Para.Para32[0] = Port; ++ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); ++ } ++} /* SkYuk2PortSirq */ ++#endif /* YUK2 */ ++ ++/****************************************************************************** ++ * ++ * SkYuk2SirqIsr() - Special Interrupt Service Routine (Yukon-2 only) ++ * ++ * Description: handles all non data transfer specific interrupts (slow path) ++ * ++ * Returns: N/A ++ */ ++void SkYuk2SirqIsr( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++SK_U32 Istatus) /* Interrupt status word */ ++{ ++#ifdef YUK2 ++ SK_EVPARA Para; ++ SK_U32 RegVal32; /* Read register value */ ++ SK_U8 Value; ++ ++ /* HW Error indicated ? */ ++ if (((Istatus & Y2_IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) { ++ /* read the HW Error Interrupt source */ ++ SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); ++ ++ SkYuk2HwErr(pAC, IoC, RegVal32); ++ } ++ ++ /* Interrupt from ASF Subsystem */ ++ if ((Istatus & Y2_IS_ASF) != 0) { ++ /* clear IRQ */ ++ /* later on clearing should be done in ASF ISR handler */ ++ SK_IN8(IoC, B28_Y2_ASF_STAT_CMD, &Value); ++ Value |= Y2_ASF_CLR_HSTI; ++ SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, Value); ++ /* Call IRQ handler in ASF Module */ ++ /* TBD */ ++ } ++ ++ /* Check IRQ from polling unit */ ++ if ((Istatus & Y2_IS_POLL_CHK) != 0) { ++ /* Clear IRQ */ ++ SK_OUT32(IoC, POLL_CTRL, PC_CLR_IRQ_CHK); ++ ++ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E036, ++ SKERR_SIRQ_E036MSG); ++ Para.Para64 = 0; ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); ++ } ++ ++ /* TWSI Ready interrupt */ ++ if ((Istatus & Y2_IS_TWSI_RDY) != 0) { ++#ifdef SK_SLIM ++ SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); ++#else ++ SkI2cIsr(pAC, IoC); ++#endif ++ } ++ ++ /* SW forced interrupt */ ++ if ((Istatus & Y2_IS_IRQ_SW) != 0) { ++ /* clear the software IRQ */ ++ SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ); ++ } ++ ++ if ((Istatus & Y2_IS_L1_MASK) != 0) { ++ SkYuk2PortSirq(pAC, IoC, Istatus, MAC_1); ++ } ++ ++ if ((Istatus & Y2_IS_L2_MASK) != 0) { ++ SkYuk2PortSirq(pAC, IoC, Istatus, MAC_2); ++ } ++ ++ /* Timer interrupt (served last) */ ++ if ((Istatus & Y2_IS_TIMINT) != 0) { ++ ++ if (((Istatus & Y2_IS_HW_ERR) & ~pAC->GIni.GIValIrqMask) != 0) { + /* read the HW Error Interrupt source */ + SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); + +- SkGeHwErr(pAC, IoC, RegVal32); ++ /* otherwise we would generate error log entries periodically */ ++ RegVal32 &= pAC->GIni.GIValHwIrqMask; ++ if (RegVal32 != 0) { ++ SkYuk2HwErr(pAC, IoC, RegVal32); ++ } + } + ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ++ ("Timer Int: 0x%08lX\n", Istatus)); + SkHwtIsr(pAC, IoC); + } ++#endif /* YUK2 */ + +-} /* SkGeSirqIsr */ ++} /* SkYuk2SirqIsr */ + + + #ifdef GENESIS +@@ -864,8 +1339,8 @@ + */ + static int SkGePortCheckShorts( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* IO Context */ +-int Port) /* Which port should be checked */ ++SK_IOC IoC, /* I/O Context */ ++int Port) /* Port Index (MAC_1 + n) */ + { + SK_U32 Shorts; /* Short Event Counter */ + SK_U32 CheckShorts; /* Check value for Short Event Counter */ +@@ -893,9 +1368,9 @@ + RxCts = 0; + + for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) { +- ++ + (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp); +- ++ + RxCts += (SK_U64)RxTmp; + } + +@@ -912,11 +1387,11 @@ + CheckShorts = 2; + + (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts); +- +- if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && +- pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN && +- (pPrt->PLinkMode == SK_LMODE_HALF || +- pPrt->PLinkMode == SK_LMODE_FULL)) { ++ ++ if (pPrt->PLinkModeConf == (SK_U8)SK_LMODE_AUTOSENSE && ++ pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_UNKNOWN && ++ (pPrt->PLinkMode == (SK_U8)SK_LMODE_HALF || ++ pPrt->PLinkMode == (SK_U8)SK_LMODE_FULL)) { + /* + * This is autosensing and we are in the fallback + * manual full/half duplex mode. +@@ -925,16 +1400,16 @@ + /* Nothing received, restart link */ + pPrt->PPrevFcs = FcsErrCts; + pPrt->PPrevShorts = Shorts; +- ++ + return(SK_HW_PS_RESTART); + } + else { +- pPrt->PLipaAutoNeg = SK_LIPA_MANUAL; ++ pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_MANUAL; + } + } + + if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) || +- (!(FcsErrCts - pPrt->PPrevFcs))) { ++ (!(FcsErrCts - pPrt->PPrevFcs))) { + /* + * Note: The compare with zero above has to be done the way shown, + * otherwise the Linux driver will have a problem. +@@ -979,29 +1454,25 @@ + */ + static int SkGePortCheckUp( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* IO Context */ +-int Port) /* Which port should be checked */ ++SK_IOC IoC, /* I/O Context */ ++int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; /* GIni Port struct pointer */ + SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ + int Rtv; /* Return value */ + + Rtv = SK_HW_PS_NONE; +- ++ + pPrt = &pAC->GIni.GP[Port]; + +- if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { +- AutoNeg = SK_FALSE; +- } +- else { +- AutoNeg = SK_TRUE; +- } ++ AutoNeg = pPrt->PLinkMode != SK_LMODE_HALF && ++ pPrt->PLinkMode != SK_LMODE_FULL; + + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { + + switch (pPrt->PhyType) { +- ++ + case SK_PHY_XMAC: + Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg); + break; +@@ -1019,15 +1490,15 @@ + } + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { +- ++ + Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg); + } + #endif /* YUKON */ + +- return(Rtv); ++ return(Rtv); + } /* SkGePortCheckUp */ + + +@@ -1043,20 +1514,20 @@ + */ + static int SkGePortCheckUpXmac( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* IO Context */ +-int Port, /* Which port should be checked */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (MAC_1 + n) */ + SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ + { +- SK_U32 Shorts; /* Short Event Counter */ ++ SK_U32 Shorts; /* Short Event Counter */ ++ int Done; ++ SK_U16 Isrc; /* Interrupt source register */ ++ SK_U16 IsrcSum; /* Interrupt source register sum */ ++ SK_U16 LpAb; /* Link Partner Ability */ ++ SK_U16 ResAb; /* Resolved Ability */ ++ SK_U16 ExtStat; /* Extended Status Register */ ++ SK_U8 NextMode; /* Next AutoSensing Mode */ + SK_GEPORT *pPrt; /* GIni Port struct pointer */ +- int Done; +- SK_U32 GpReg; /* General Purpose register value */ +- SK_U16 Isrc; /* Interrupt source register */ +- SK_U16 IsrcSum; /* Interrupt source register sum */ +- SK_U16 LpAb; /* Link Partner Ability */ +- SK_U16 ResAb; /* Resolved Ability */ +- SK_U16 ExtStat; /* Extended Status Register */ +- SK_U8 NextMode; /* Next AutoSensing Mode */ ++ SK_U32 SK_FAR GpReg; /* General Purpose register value */ + + pPrt = &pAC->GIni.GP[Port]; + +@@ -1082,7 +1553,7 @@ + XM_IN16(IoC, Port, XM_ISRC, &Isrc); + IsrcSum |= Isrc; + SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); +- ++ + if ((Isrc & XM_IS_INP_ASS) == 0) { + /* It has been in sync since last time */ + /* Restart the PORT */ +@@ -1101,14 +1572,14 @@ + * Link Restart Workaround: + * it may be possible that the other Link side + * restarts its link as well an we detect +- * another LinkBroken. To prevent this ++ * another PLinkBroken. To prevent this + * happening we check for a maximum number + * of consecutive restart. If those happens, + * we do NOT restart the active link and + * check whether the link is now o.k. + */ + pPrt->PLinkResCt++; +- ++ + pPrt->PAutoNegTimeOut = 0; + + if (pPrt->PLinkResCt < SK_MAX_LRESTART) { +@@ -1116,13 +1587,13 @@ + } + + pPrt->PLinkResCt = 0; +- ++ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum)); + } + else { + pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND); +- ++ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum)); + +@@ -1149,7 +1620,7 @@ + if ((Isrc & XM_IS_INP_ASS) != 0) { + pPrt->PLinkBroken = SK_TRUE; + /* Re-Init Link partner Autoneg flag */ +- pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; ++ pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN; + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Link broken Port %d\n", Port)); + +@@ -1162,7 +1633,7 @@ + } + else { + SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc); +- ++ + if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) { + return(SK_HW_PS_RESTART); + } +@@ -1178,7 +1649,7 @@ + IsrcSum |= Isrc; + + SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); +- ++ + if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) { + if ((GpReg & XM_GP_INP_ASS) == 0) { + /* Save Auto-negotiation Done interrupt only if link is in sync */ +@@ -1194,20 +1665,26 @@ + } + + if (AutoNeg) { ++ /* Auto-Negotiation Done ? */ + if ((IsrcSum & XM_IS_AND) != 0) { ++ + SkHWLinkUp(pAC, IoC, Port); ++ + Done = SkMacAutoNegDone(pAC, IoC, Port); ++ + if (Done != SK_AND_OK) { + /* Get PHY parameters, for debugging only */ + SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb); + SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb); +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n", +- Port, LpAb, ResAb)); +- ++ Port, LpAb, ResAb)); ++ + /* Try next possible mode */ + NextMode = SkHWSenseGetNext(pAC, IoC, Port); ++ + SkHWLinkDown(pAC, IoC, Port); ++ + if (Done == SK_AND_DUP_CAP) { + /* GoTo next mode */ + SkHWSenseSetNext(pAC, IoC, Port, NextMode); +@@ -1220,42 +1697,41 @@ + * (clear Page Received bit if set) + */ + SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat); +- ++ + return(SK_HW_PS_LINK); + } +- ++ + /* AutoNeg not done, but HW link is up. Check for timeouts */ +- pPrt->PAutoNegTimeOut++; +- if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) { ++ if (pPrt->PAutoNegTimeOut++ >= SK_AND_MAX_TO) { + /* Increase the Timeout counter */ + pPrt->PAutoNegTOCt++; + + /* Timeout occured */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("AutoNeg timeout Port %d\n", Port)); +- if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && +- pPrt->PLipaAutoNeg != SK_LIPA_AUTO) { ++ if (pPrt->PLinkModeConf == (SK_U8)SK_LMODE_AUTOSENSE && ++ pPrt->PLipaAutoNeg != (SK_U8)SK_LIPA_AUTO) { + /* Set Link manually up */ + SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Set manual full duplex Port %d\n", Port)); + } + +- if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && +- pPrt->PLipaAutoNeg == SK_LIPA_AUTO && ++ if (pPrt->PLinkModeConf == (SK_U8)SK_LMODE_AUTOSENSE && ++ pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO && + pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) { + /* + * This is rather complicated. + * we need to check here whether the LIPA_AUTO + * we saw before is false alert. We saw at one +- * switch ( SR8800) that on boot time it sends ++ * switch (SR8800) that on boot time it sends + * just one auto-neg packet and does no further + * auto-negotiation. + * Solution: we restart the autosensing after + * a few timeouts. + */ + pPrt->PAutoNegTOCt = 0; +- pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; ++ pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN; + SkHWInitDefSense(pAC, IoC, Port); + } + +@@ -1266,18 +1742,18 @@ + else { + /* Link is up and we don't need more */ + #ifdef DEBUG +- if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("ERROR: Lipa auto detected on port %d\n", Port)); ++ if (pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("ERROR: LiPa auto detected on port %d\n", Port)); + } + #endif /* DEBUG */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Link sync(GP), Port %d\n", Port)); + SkHWLinkUp(pAC, IoC, Port); +- ++ + /* +- * Link sync (GP) and so assume a good connection. But if not received +- * a bunch of frames received in a time slot (maybe broken tx cable) ++ * Link sync (GP) and so assume a good connection. But if no ++ * bunch of frames received in a time slot (maybe broken Tx cable) + * the port is restart. + */ + return(SK_HW_PS_LINK); +@@ -1298,14 +1774,14 @@ + */ + static int SkGePortCheckUpBcom( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* IO Context */ +-int Port, /* Which port should be checked */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (MAC_1 + n) */ + SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ + { + SK_GEPORT *pPrt; /* GIni Port struct pointer */ + int Done; + SK_U16 Isrc; /* Interrupt source register */ +- SK_U16 PhyStat; /* Phy Status Register */ ++ SK_U16 PhyStat; /* PHY Status Register */ + SK_U16 ResAb; /* Master/Slave resolution */ + SK_U16 Ctrl; /* Broadcom control flags */ + #ifdef DEBUG +@@ -1318,74 +1794,6 @@ + /* Check for No HCD Link events (#10523) */ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc); + +-#ifdef xDEBUG +- if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) == +- (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) { +- +- SK_U32 Stat1, Stat2, Stat3; +- +- Stat1 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1); +- CMSMPrintString( +- pAC->pConfigTable, +- MSG_TYPE_RUNTIME_INFO, +- "CheckUp1 - Stat: %x, Mask: %x", +- (void *)Isrc, +- (void *)Stat1); +- +- Stat1 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1); +- Stat2 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2); +- Stat1 = Stat1 << 16 | Stat2; +- Stat2 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2); +- Stat3 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3); +- Stat2 = Stat2 << 16 | Stat3; +- CMSMPrintString( +- pAC->pConfigTable, +- MSG_TYPE_RUNTIME_INFO, +- "Ctrl/Stat: %x, AN Adv/LP: %x", +- (void *)Stat1, +- (void *)Stat2); +- +- Stat1 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1); +- Stat2 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2); +- Stat1 = Stat1 << 16 | Stat2; +- Stat2 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2); +- Stat3 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3); +- Stat2 = Stat2 << 16 | Stat3; +- CMSMPrintString( +- pAC->pConfigTable, +- MSG_TYPE_RUNTIME_INFO, +- "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x", +- (void *)Stat1, +- (void *)Stat2); +- +- Stat1 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); +- Stat2 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2); +- Stat1 = Stat1 << 16 | Stat2; +- Stat2 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2); +- Stat3 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3); +- Stat2 = Stat2 << 16 | Stat3; +- CMSMPrintString( +- pAC->pConfigTable, +- MSG_TYPE_RUNTIME_INFO, +- "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x", +- (void *)Stat1, +- (void *)Stat2); +- } +-#endif /* DEBUG */ +- + if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) { + /* + * Workaround BCom Errata: +@@ -1398,14 +1806,6 @@ + (SK_U16)(Ctrl & ~PHY_CT_LOOP)); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("No HCD Link event, Port %d\n", Port)); +-#ifdef xDEBUG +- CMSMPrintString( +- pAC->pConfigTable, +- MSG_TYPE_RUNTIME_INFO, +- "No HCD link event, port %d.", +- (void *)Port, +- (void *)NULL); +-#endif /* DEBUG */ + } + + /* Not obsolete: link status bit is latched to 0 and autoclearing! */ +@@ -1415,72 +1815,6 @@ + return(SK_HW_PS_NONE); + } + +-#ifdef xDEBUG +- { +- SK_U32 Stat1, Stat2, Stat3; +- +- Stat1 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1); +- CMSMPrintString( +- pAC->pConfigTable, +- MSG_TYPE_RUNTIME_INFO, +- "CheckUp1a - Stat: %x, Mask: %x", +- (void *)Isrc, +- (void *)Stat1); +- +- Stat1 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1); +- Stat2 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); +- Stat1 = Stat1 << 16 | PhyStat; +- Stat2 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2); +- Stat3 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3); +- Stat2 = Stat2 << 16 | Stat3; +- CMSMPrintString( +- pAC->pConfigTable, +- MSG_TYPE_RUNTIME_INFO, +- "Ctrl/Stat: %x, AN Adv/LP: %x", +- (void *)Stat1, +- (void *)Stat2); +- +- Stat1 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1); +- Stat2 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2); +- Stat1 = Stat1 << 16 | Stat2; +- Stat2 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2); +- Stat3 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); +- Stat2 = Stat2 << 16 | ResAb; +- CMSMPrintString( +- pAC->pConfigTable, +- MSG_TYPE_RUNTIME_INFO, +- "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x", +- (void *)Stat1, +- (void *)Stat2); +- +- Stat1 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); +- Stat2 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2); +- Stat1 = Stat1 << 16 | Stat2; +- Stat2 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2); +- Stat3 = 0; +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3); +- Stat2 = Stat2 << 16 | Stat3; +- CMSMPrintString( +- pAC->pConfigTable, +- MSG_TYPE_RUNTIME_INFO, +- "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x", +- (void *)Stat1, +- (void *)Stat2); +- } +-#endif /* DEBUG */ +- + /* + * Here we usually can check whether the link is in sync and + * auto-negotiation is done. +@@ -1488,97 +1822,71 @@ + + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); + +- SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); +- + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat)); + ++ SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); ++ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); + + if ((ResAb & PHY_B_1000S_MSF) != 0) { + /* Error */ +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Master/Slave Fault port %d\n", Port)); +- ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("Master/Slave Fault, ResAb: 0x%04X\n", ResAb)); ++ + pPrt->PAutoNegFail = SK_TRUE; + pPrt->PMSStatus = SK_MS_STAT_FAULT; +- ++ + return(SK_HW_PS_RESTART); + } + + if ((PhyStat & PHY_ST_LSYNC) == 0) { + return(SK_HW_PS_NONE); + } +- ++ + pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? + SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; +- ++ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Port %d, ResAb: 0x%04X\n", Port, ResAb)); + + if (AutoNeg) { ++ /* Auto-Negotiation Over ? */ + if ((PhyStat & PHY_ST_AN_OVER) != 0) { +- ++ + SkHWLinkUp(pAC, IoC, Port); +- ++ + Done = SkMacAutoNegDone(pAC, IoC, Port); +- ++ + if (Done != SK_AND_OK) { + #ifdef DEBUG + /* Get PHY parameters, for debugging only */ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat); +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n", + Port, LpAb, ExtStat)); + #endif /* DEBUG */ + return(SK_HW_PS_RESTART); + } + else { +-#ifdef xDEBUG +- /* Dummy read ISR to prevent extra link downs/ups */ +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat); +- +- if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) { +- CMSMPrintString( +- pAC->pConfigTable, +- MSG_TYPE_RUNTIME_INFO, +- "CheckUp2 - Stat: %x", +- (void *)ExtStat, +- (void *)NULL); +- } +-#endif /* DEBUG */ + return(SK_HW_PS_LINK); + } + } + } + else { /* !AutoNeg */ +- /* Link is up and we don't need more. */ ++ /* Link is up and we don't need more */ + #ifdef DEBUG +- if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("ERROR: Lipa auto detected on port %d\n", Port)); ++ if (pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("ERROR: LiPa auto detected on port %d\n", Port)); + } + #endif /* DEBUG */ + +-#ifdef xDEBUG +- /* Dummy read ISR to prevent extra link downs/ups */ +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat); +- +- if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) { +- CMSMPrintString( +- pAC->pConfigTable, +- MSG_TYPE_RUNTIME_INFO, +- "CheckUp3 - Stat: %x", +- (void *)ExtStat, +- (void *)NULL); +- } +-#endif /* DEBUG */ +- + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Link sync(GP), Port %d\n", Port)); + SkHWLinkUp(pAC, IoC, Port); +- ++ + return(SK_HW_PS_LINK); + } + +@@ -1599,19 +1907,23 @@ + */ + static int SkGePortCheckUpGmac( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* IO Context */ +-int Port, /* Which port should be checked */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (MAC_1 + n) */ + SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ + { + SK_GEPORT *pPrt; /* GIni Port struct pointer */ + int Done; +- SK_U16 PhyIsrc; /* PHY Interrupt source */ +- SK_U16 PhyStat; /* PPY Status */ ++ SK_U16 PhyStat; /* PHY Status */ + SK_U16 PhySpecStat;/* PHY Specific Status */ + SK_U16 ResAb; /* Master/Slave resolution */ ++#ifndef SK_SLIM + SK_EVPARA Para; +-#ifdef DEBUG +- SK_U16 Word; /* I/O helper */ ++ int i; ++ SK_U16 Word; /* I/O helper */ ++#endif /* !SK_SLIM */ ++ ++#ifdef xDEBUG ++ SK_U64 StartTime; + #endif /* DEBUG */ + + pPrt = &pAC->GIni.GP[Port]; +@@ -1626,107 +1938,181 @@ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat)); + +- /* Read PHY Interrupt Status */ +- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc); ++ SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); + +- if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) { +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc)); +- } ++ if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { ++ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); + +- if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc)); +- } ++ ("Phy1000BT: 0x%04X, ", ResAb)); + +- SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); +- +- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); ++ if ((ResAb & PHY_B_1000S_MSF) != 0) { ++ /* Error */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("Master/Slave Fault, ResAb: 0x%04X\n", ResAb)); + +- if ((ResAb & PHY_B_1000S_MSF) != 0) { +- /* Error */ +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Master/Slave Fault port %d\n", Port)); +- +- pPrt->PAutoNegFail = SK_TRUE; +- pPrt->PMSStatus = SK_MS_STAT_FAULT; +- +- return(SK_HW_PS_RESTART); ++ pPrt->PAutoNegFail = SK_TRUE; ++ pPrt->PMSStatus = SK_MS_STAT_FAULT; ++ ++ return(SK_HW_PS_RESTART); ++ } + } + + /* Read PHY Specific Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); +- ++ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat)); ++ ("PhySpecStat: 0x%04X\n", PhySpecStat)); + +-#ifdef DEBUG ++#if (defined(DEBUG) && !defined(SK_SLIM)) ++ /* Read PHY Auto-Negotiation Expansion */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word); + +- if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 || +- (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) { ++ if ((Word & PHY_ANE_RX_PG) != 0 || ++ (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) { + /* Read PHY Next Page Link Partner */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Page Received, NextPage: 0x%04X\n", Word)); ++ ("Page received, NextPage: 0x%04X\n", Word)); + } +-#endif /* DEBUG */ ++#endif /* DEBUG && !SK_SLIM */ + + if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) { ++ /* Link down */ + return(SK_HW_PS_NONE); + } +- +- if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 || +- (PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) { +- /* Downshift detected */ +- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG); +- +- Para.Para64 = Port; +- SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para); +- +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc)); ++ ++#ifndef SK_SLIM ++ if (pAC->GIni.GICopperType) { ++ ++#ifdef DEBUG ++ if ((Word & PHY_ANE_LP_CAP) == 0) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Link Partner is not AN able, AN Exp.: 0x%04X\n", Word)); ++ } ++ ++ if ((Word & PHY_ANE_PAR_DF) == 0) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Parallel Detection Fault, AN Exp.: 0x%04X\n", Word)); ++ } ++#endif /* DEBUG */ ++ ++ if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { ++ ++ if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0) { ++ /* Downshift detected */ ++ Para.Para64 = Port; ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Downshift detected, PhySpecStat: 0x%04X\n", PhySpecStat)); ++ ++ SK_ERR_LOG(pAC, SK_ERRCL_INFO, SKERR_SIRQ_E025, ++ SKERR_SIRQ_E025MSG); ++ } ++ ++ pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? ++ SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; ++ } ++ ++ if ((PhySpecStat & PHY_M_PS_MDI_X_STAT) != 0) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("MDI Xover detected, PhyStat: 0x%04X\n", PhySpecStat)); ++ } ++ ++ /* on PHY 88E1112 & 88E1145 cable length is in Reg. 26, Page 5 */ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) { ++ /* select page 5 to access VCT DSP distance register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 5); ++ ++ /* get VCT DSP distance */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL_2, &PhySpecStat); ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); ++ ++ pPrt->PCableLen = (SK_U8)(PhySpecStat & PHY_M_EC2_FO_AM_MSK); ++ } ++ else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EX) { ++ /* select page 0xff to access VCT DSP distance register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0x00ff); ++ ++ for (Word = 0, i = 0; i < 4; i++) { ++ /* select register for MDI pair 0..3 */ ++ SkGmPhyWrite(pAC, IoC, Port, 19, 0x1018 + i); ++ ++ /* get length for MDI pair 0..3 */ ++ SkGmPhyRead(pAC, IoC, Port, 21, &PhySpecStat); ++ ++ Word += PhySpecStat; ++ } ++ ++ pPrt->PCableLen = Word / 4; /* calculate the average */ ++ ++ /* set page register to 0 */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); ++ } ++ else { ++ pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7); ++ } + } + +- pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? +- SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; +- +- pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7); +- ++#ifdef xDEBUG ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("LinkUp Port %d, PHY register dump: 0x%04X\n", Port)); ++ ++ for (i = 0; i < PHY_MARV_PAGE_ADDR; i++) { ++ /* dump all PHY register */ ++ SkGmPhyRead(pAC, IoC, Port, i, &Word); ++ } ++ ++ StartTime = SkOsGetTime(pAC); ++ ++ while (SkOsGetTime(pAC) - StartTime < SK_TICKS_PER_SEC / 2) { ++ /* dummy PHY read */ ++ SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word); ++ } ++#endif /* DEBUG */ ++ ++#endif /* !SK_SLIM */ ++ + if (AutoNeg) { +- /* Auto-Negotiation Over ? */ ++ /* Auto-Negotiation Complete ? */ + if ((PhyStat & PHY_ST_AN_OVER) != 0) { +- ++ + SkHWLinkUp(pAC, IoC, Port); +- ++ + Done = SkMacAutoNegDone(pAC, IoC, Port); +- ++ + if (Done != SK_AND_OK) { + return(SK_HW_PS_RESTART); + } +- ++ + return(SK_HW_PS_LINK); + } + } + else { /* !AutoNeg */ +- /* Link is up and we don't need more */ +-#ifdef DEBUG +- if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("ERROR: Lipa auto detected on port %d\n", Port)); ++#if (defined(DEBUG) && !defined(SK_SLIM)) ++ if (pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("ERROR: LiPa auto detected on port %d\n", Port)); + } +-#endif /* DEBUG */ ++#endif /* DEBUG && !SK_SLIM */ + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Link sync, Port %d\n", Port)); + SkHWLinkUp(pAC, IoC, Port); +- ++ + return(SK_HW_PS_LINK); + } + + return(SK_HW_PS_NONE); + } /* SkGePortCheckUpGmac */ ++ + #endif /* YUKON */ + + +@@ -1742,8 +2128,8 @@ + */ + static int SkGePortCheckUpLone( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* IO Context */ +-int Port, /* Which port should be checked */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (MAC_1 + n) */ + SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ + { + SK_GEPORT *pPrt; /* GIni Port struct pointer */ +@@ -1751,7 +2137,7 @@ + SK_U16 Isrc; /* Interrupt source register */ + SK_U16 LpAb; /* Link Partner Ability */ + SK_U16 ExtStat; /* Extended Status Register */ +- SK_U16 PhyStat; /* Phy Status Register */ ++ SK_U16 PhyStat; /* PHY Status Register */ + SK_U16 StatSum; + SK_U8 NextMode; /* Next AutoSensing Mode */ + +@@ -1771,8 +2157,10 @@ + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_STAT, &PhyStat); + StatSum |= PhyStat; + ++#ifdef XXX + SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); +- ++#endif ++ + if ((PhyStat & PHY_ST_LSYNC) == 0) { + /* Save Auto-negotiation Done bit */ + pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER); +@@ -1786,20 +2174,26 @@ + } + + if (AutoNeg) { ++ /* Auto-Negotiation Over ? */ + if ((StatSum & PHY_ST_AN_OVER) != 0) { ++ + SkHWLinkUp(pAC, IoC, Port); ++ + Done = SkMacAutoNegDone(pAC, IoC, Port); ++ + if (Done != SK_AND_OK) { + /* Get PHY parameters, for debugging only */ + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb); + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat); +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n", + Port, LpAb, ExtStat)); +- ++ + /* Try next possible mode */ + NextMode = SkHWSenseGetNext(pAC, IoC, Port); ++ + SkHWLinkDown(pAC, IoC, Port); ++ + if (Done == SK_AND_DUP_CAP) { + /* GoTo next mode */ + SkHWSenseSetNext(pAC, IoC, Port, NextMode); +@@ -1817,15 +2211,14 @@ + return(SK_HW_PS_LINK); + } + } +- ++ + /* AutoNeg not done, but HW link is up. Check for timeouts */ +- pPrt->PAutoNegTimeOut++; +- if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) { ++ if (pPrt->PAutoNegTimeOut++ >= SK_AND_MAX_TO) { + /* Timeout occured */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("AutoNeg timeout Port %d\n", Port)); +- if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && +- pPrt->PLipaAutoNeg != SK_LIPA_AUTO) { ++ if (pPrt->PLinkModeConf == (SK_U8)SK_LMODE_AUTOSENSE && ++ pPrt->PLipaAutoNeg != (SK_U8)SK_LIPA_AUTO) { + /* Set Link manually up */ + SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, +@@ -1839,9 +2232,9 @@ + else { + /* Link is up and we don't need more */ + #ifdef DEBUG +- if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("ERROR: Lipa auto detected on port %d\n", Port)); ++ if (pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("ERROR: LiPa auto detected on port %d\n", Port)); + } + #endif /* DEBUG */ + +@@ -1850,11 +2243,12 @@ + * extra link down/ups + */ + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat); +- ++ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Link sync(GP), Port %d\n", Port)); ++ + SkHWLinkUp(pAC, IoC, Port); +- ++ + return(SK_HW_PS_LINK); + } + +@@ -1873,8 +2267,8 @@ + */ + static int SkGePortCheckUpNat( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* IO Context */ +-int Port, /* Which port should be checked */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (MAC_1 + n) */ + SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ + { + /* todo: National */ +@@ -1893,38 +2287,43 @@ + */ + int SkGeSirqEvent( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* Io Context */ ++SK_IOC IoC, /* I/O Context */ + SK_U32 Event, /* Module specific Event */ + SK_EVPARA Para) /* Event specific Parameter */ + { + SK_GEPORT *pPrt; /* GIni Port struct pointer */ +- SK_U32 Port; ++ int Port; + SK_U32 Val32; + int PortStat; ++#ifndef SK_SLIM + SK_U8 Val8; ++#endif + #ifdef GENESIS + SK_U64 Octets; + #endif /* GENESIS */ + +- Port = Para.Para32[0]; ++ Port = (int)Para.Para32[0]; + pPrt = &pAC->GIni.GP[Port]; + ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ++ ("SIRQ HW Event: %u\n", Event)); ++ + switch (Event) { + case SK_HWEV_WATIM: + if (pPrt->PState == SK_PRT_RESET) { +- ++ + PortStat = SK_HW_PS_NONE; + } + else { + /* Check whether port came up */ +- PortStat = SkGePortCheckUp(pAC, IoC, (int)Port); ++ PortStat = SkGePortCheckUp(pAC, IoC, Port); + } + + switch (PortStat) { + case SK_HW_PS_RESTART: + if (pPrt->PHWLinkUp) { + /* Set Link to down */ +- SkHWLinkDown(pAC, IoC, (int)Port); ++ SkHWLinkDown(pAC, IoC, Port); + + /* + * Signal directly to RLMT to ensure correct +@@ -1942,22 +2341,28 @@ + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para); + break; + } +- ++ + /* Start again the check Timer */ + if (pPrt->PHWLinkUp) { ++ + Val32 = SK_WA_ACT_TIME; + } + else { + Val32 = SK_WA_INA_TIME; +- } + +- /* Todo: still needed for non-XMAC PHYs??? */ ++ if (pAC->GIni.GIYukon) { ++ Val32 *= 5; ++ } ++ } + /* Start workaround Errata #2 timer */ + SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32, + SKGE_HWAC, SK_HWEV_WATIM, Para); ++ + break; + + case SK_HWEV_PORT_START: ++ ++#ifndef SK_SLIM + if (pPrt->PHWLinkUp) { + /* + * Signal directly to RLMT to ensure correct +@@ -1965,8 +2370,9 @@ + */ + SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para); + } ++#endif /* !SK_SLIM */ + +- SkHWLinkDown(pAC, IoC, (int)Port); ++ SkHWLinkDown(pAC, IoC, Port); + + /* Schedule Port RESET */ + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); +@@ -1974,9 +2380,11 @@ + /* Start workaround Errata #2 timer */ + SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME, + SKGE_HWAC, SK_HWEV_WATIM, Para); ++ + break; + + case SK_HWEV_PORT_STOP: ++#ifndef SK_SLIM + if (pPrt->PHWLinkUp) { + /* + * Signal directly to RLMT to ensure correct +@@ -1984,20 +2392,22 @@ + */ + SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para); + } ++#endif /* !SK_SLIM */ + + /* Stop Workaround Timer */ + SkTimerStop(pAC, IoC, &pPrt->PWaTimer); + +- SkHWLinkDown(pAC, IoC, (int)Port); ++ SkHWLinkDown(pAC, IoC, Port); + break; + ++#ifndef SK_SLIM + case SK_HWEV_UPDATE_STAT: + /* We do NOT need to update any statistics */ + break; + + case SK_HWEV_CLEAR_STAT: + /* We do NOT need to clear any statistics */ +- for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) { ++ for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) { + pPrt->PPrevRx = 0; + pPrt->PPrevFcs = 0; + pPrt->PPrevShorts = 0; +@@ -2058,6 +2468,7 @@ + SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); + } + break; ++#endif /* !SK_SLIM */ + + #ifdef GENESIS + case SK_HWEV_HALFDUP_CHK: +@@ -2069,17 +2480,18 @@ + pPrt->HalfDupTimerActive = SK_FALSE; + if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || + pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) { ++ + /* Snap statistic counters */ + (void)SkXmUpdateStats(pAC, IoC, Port); + + (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32); + + Octets = (SK_U64)Val32 << 32; +- ++ + (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32); + + Octets += Val32; +- ++ + if (pPrt->LastOctets == Octets) { + /* Tx hanging, a FIFO flush restarts it */ + SkMacFlushTxFifo(pAC, IoC, Port); +@@ -2088,7 +2500,7 @@ + } + break; + #endif /* GENESIS */ +- ++ + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG); + break; +@@ -2109,8 +2521,8 @@ + */ + static void SkPhyIsrBcom( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* Io Context */ +-int Port, /* Port Num = PHY Num */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (MAC_1 + n) */ + SK_U16 IStatus) /* Interrupt Status */ + { + SK_GEPORT *pPrt; /* GIni Port struct pointer */ +@@ -2123,7 +2535,7 @@ + SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022, + SKERR_SIRQ_E022MSG); + } +- ++ + if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) { + + SkHWLinkDown(pAC, IoC, Port); +@@ -2152,47 +2564,106 @@ + */ + static void SkPhyIsrGmac( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* Io Context */ +-int Port, /* Port Num = PHY Num */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (MAC_1 + n) */ + SK_U16 IStatus) /* Interrupt Status */ + { +- SK_GEPORT *pPrt; /* GIni Port struct pointer */ ++ SK_GEPORT *pPrt; /* GIni Port struct pointer */ + SK_EVPARA Para; ++#ifdef xDEBUG ++ int i; + SK_U16 Word; ++ SK_U32 DWord; ++#endif /* DEBUG */ + + pPrt = &pAC->GIni.GP[Port]; + +- if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Port %d PHY IRQ, PhyIsrc: 0x%04X\n", Port, IStatus)); + +- SkHWLinkDown(pAC, IoC, Port); ++ if ((IStatus & PHY_M_IS_LST_CHANGE) != 0) { + +- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word); ++ Para.Para32[0] = (SK_U32)Port; + +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("AutoNeg.Adv: 0x%04X\n", Word)); +- +- /* Set Auto-negotiation advertisement */ +- if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) { +- /* restore Asymmetric Pause bit */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, +- (SK_U16)(Word | PHY_M_AN_ASP)); ++ if (pPrt->PHWLinkUp) { ++ ++#ifdef xDEBUG ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &Word); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Link Status changed, PhySpecStat: 0x%04X, ", Word)); ++ ++ /* read the GMAC Interrupt source register */ ++ SK_IN16(IoC, MR_ADDR(Port, GMAC_IRQ_SRC), &Word); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("GmacIrqSrc: 0x%02X\n", Word)); ++ ++ if (Word != 0 && (IStatus & PHY_M_IS_SYMB_ERROR) != 0) { ++ /* read all MIB Counters */ ++ for (i = 0; i < GM_MIB_CNT_SIZE; i++) { ++ GM_IN32(IoC, Port, GM_MIB_CNT_BASE + 8*i, &DWord); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("MIB Addr 0x%04X: 0x%08X\n", ++ BASE_GMAC_1 + GM_MIB_CNT_BASE + 8*i, DWord)); ++ } ++ } ++#endif /* DEBUG */ ++ ++ SkHWLinkDown(pAC, IoC, Port); ++ ++#ifdef XXX ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("AutoNeg.Adv: 0x%04X\n", Word)); ++ ++ /* Set Auto-negotiation advertisement */ ++ if (pAC->GIni.GIChipId != CHIP_ID_YUKON_FE && ++ pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) { ++ /* restore Asymmetric Pause bit */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, ++ (SK_U16)(Word | PHY_M_AN_ASP)); ++ } ++#endif /* XXX */ ++ ++ /* Signal to RLMT */ ++ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); ++ } ++ else { ++ if ((IStatus & PHY_M_IS_AN_COMPL) != 0) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Auto-Negotiation completed\n")); ++ } ++ ++ if ((IStatus & PHY_M_IS_LSP_CHANGE) != 0) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Link Speed changed\n")); ++ } ++ ++ SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_WATIM, Para); + } +- +- Para.Para32[0] = (SK_U32)Port; +- /* Signal to RLMT */ +- SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); + } +- ++ + if ((IStatus & PHY_M_IS_AN_ERROR) != 0) { +- /* Auto-Negotiation Error */ +- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG); ++ /* the copper PHY makes 1 retry */ ++ if (pAC->GIni.GICopperType) { ++ /* not logged as error, it might be the first attempt */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Auto-Negotiation Error\n")); ++ } ++ else { ++ /* Auto-Negotiation Error */ ++ SK_ERR_LOG(pAC, SK_ERRCL_INFO, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG); ++ } + } +- ++ + if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) { + /* FIFO Overflow/Underrun Error */ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG); + } +- ++ + } /* SkPhyIsrGmac */ + #endif /* YUKON */ + +@@ -2208,14 +2679,14 @@ + */ + static void SkPhyIsrLone( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* Io Context */ +-int Port, /* Port Num = PHY Num */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (MAC_1 + n) */ + SK_U16 IStatus) /* Interrupt Status */ + { + SK_EVPARA Para; + + if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) { +- ++ + SkHWLinkDown(pAC, IoC, Port); + + Para.Para32[0] = (SK_U32)Port; +@@ -2227,3 +2698,4 @@ + #endif /* OTHER_PHY */ + + /* End of File */ ++ +diff -ruN linux/drivers/net/sk98lin/skgespi.c linux-new/drivers/net/sk98lin/skgespi.c +--- linux/drivers/net/sk98lin/skgespi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/skgespi.c 2007-01-24 13:58:33.000000000 +0100 +@@ -0,0 +1,1513 @@ ++/****************************************************************************** ++ * ++ * Name: skspi.c ++ * Project: Flash Programmer, Manufacturing and Diagnostic Tools ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Contains SPI-Flash EEPROM specific functions ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * (C)Copyright 1998-2002 SysKonnect ++ * (C)Copyright 2002-2003 Marvell ++ * ++ * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT ++ * The copyright notice above does not evidence any ++ * actual or intended publication of such source code. ++ * ++ * This Module contains Proprietary Information of SysKonnect ++ * and should be treated as Confidential. ++ * ++ * The information in this file is provided for the exclusive use of ++ * the licensees of SysKonnect. ++ * Such users have the right to use, modify, and incorporate this code ++ * into products for purposes authorized by the license agreement ++ * provided they include this notice and the associated copyright notice ++ * with any such product. ++ * The information in this file is provided "AS IS" without warranty. ++ * ++ ******************************************************************************/ ++ ++static const char SysKonnectFileId[] = ++ "@(#) $Id$ (C) Marvell."; ++ ++/* ++#include ++#include ++#include ++*/ ++ ++#include "h/skdrv1st.h" ++#include "h/skdrv2nd.h" ++#include "h/skgespi.h" ++ ++#ifdef Core ++ #include "h/skdrv1st.h" ++ #include "h/skdrv2nd.h" ++ #define fl_print pAC->Gui.WPrint ++#else ++ extern void fl_print(char *msg, ...); ++#endif /* Core */ ++ ++extern int fl_type; ++extern long max_pages; ++extern long max_faddr; ++ ++/* low level SPI programming external interface */ ++ ++extern void spi_in8(unsigned short, unsigned char *); ++extern void spi_in16(unsigned short, unsigned short *); ++extern void spi_in32(unsigned short, unsigned long *); ++extern void spi_out8(unsigned short, unsigned char); ++extern void spi_out16(unsigned short, unsigned short); ++extern void spi_out32(unsigned short, unsigned long); ++extern int spi_timer(unsigned int); ++extern void *spi_malloc(unsigned long); ++extern void spi_free(void *); ++ ++/* global variables */ ++unsigned char chip_id; ++ ++/* local variables */ ++static int spi_yuk2_dev = -1; ++ ++/* ++ * Yukon 2/EC SPI flash device structure/table ++ */ ++static struct { ++ char *man_name; ++ unsigned char man_id; ++ char *dev_name; ++ unsigned char dev_id; ++ unsigned long sector_size; ++ unsigned long sector_num; ++ char set_protocol; ++ ++ struct { ++ unsigned char op_read; ++ unsigned char op_write; ++ unsigned char op_write_enable; ++ unsigned char op_write_disable; ++ unsigned char op_read_status; ++ unsigned char op_read_id; ++ unsigned char op_sector_erase; ++ unsigned char op_chip_erase; ++ } opcodes; ++} spi_yuk2_dev_table[] = { ++ { "Atmel", SPI_MAN_ID_ATMEL, "AT25F2048", 0x63, 0x10000, 4, 0, {0x03,0x02,0x06,0x04,0x05,0x15,0x52,0x62} } , ++ { "Atmel", SPI_MAN_ID_ATMEL, "AT25F1024", 0x60, 0x8000, 4, 0, {0x03,0x02,0x06,0x04,0x05,0x15,0x52,0x62} } , ++ { "SST", SPI_MAN_ID_SST, "SST25VF512", 0x48, 0x1000, 16, 1, {0x03,0x02,0x06,0x04,0x05,0x90,0x20,0x60} } , ++ { "SST", SPI_MAN_ID_SST, "SST25VF010", 0x49, 0x1000, 32, 1, {0x03,0x02,0x06,0x04,0x05,0x90,0x20,0x60} } , ++ { "SST", SPI_MAN_ID_SST, "SST25VF020", 0x43, 0x1000, 64, 1, {0x03,0x02,0x06,0x04,0x05,0x90,0x20,0x60} } , ++ { "SST", SPI_MAN_ID_SST, "SST25VF040", 0x44, 0x1000, 128, 1, {0x03,0x02,0x06,0x04,0x05,0x90,0x20,0x60} } , ++ { "ST", SPI_MAN_ID_ST_M25P20, "M25P20", 0x11, 0x10000, 4, 1, {0x03,0x02,0x06,0x04,0x05,0xab,0xd8,0xc7} } , ++ { "ST", SPI_MAN_ID_ST_M25P10, "M25P10", 0x10, 0x8000, 4, 1, {0x03,0x02,0x06,0x04,0x05,0xab,0xd8,0xc7} } ++}; ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_yuk_flash_erase(unsigned long off,unsigned long len) ++ * ++ * Send chip erase command to SPI Eprom ++ * ++ * Uses: spi_in32, spi_out32, spi_in8, spi_timer ++ * ++ * IN: ++ * off start offset in flash eprom for erase ++ * len length in flash eprom for erase ++ * (all nessesory sectors will be erased) ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++static int spi_yuk_flash_erase( ++unsigned long off, ++unsigned long len) ++{ ++ char cr; ++ unsigned long creg, i; ++ /* Save SPI control register */ ++ spi_in32(SPI_CTRL_REG, &creg); ++ ++ if ((off+len-1) > 0x1ffffL) { ++ return(1); /* more than 4 segments for erase */ ++ } ++ ++#ifdef XXX ++ /* there is some problem with chip erase. dr */ ++ ++ /* use faster chip erase command if all sectors should be erased */ ++ if(len > SPI_SECT_SIZE*3L) { ++ ++ spi_out32(SPI_CTRL_REG, SPI_CHIP_ERASE); ++ ++ spi_timer(SPI_TIMER_SET); ++ ++ do { ++ /* Read device status */ ++ spi_in8(SPI_CTRL_REG, &cr); ++ ++ if (spi_timer(SPI_TIMEOUT)) { ++ fl_print("\nSPI chip erase timeout: %d sec\n", SPI_TIMER_SET); ++ return(1); ++ } ++ } ++ while (cr & 1); /* is chip busy ? */ ++ /* Restore SPI control register */ ++ spi_out32(SPI_CTRL_REG, creg); ++ ++ return(0); ++ } ++#endif ++ ++ for (i = (off >> 15); i <= ((off + len - 1) >> 15); i++) { ++ /* Clear chip command */ ++ spi_out32(SPI_CTRL_REG, (i << 22) | SPI_SECT_ERASE); ++ ++ spi_timer(SPI_TIMER_SET); ++ ++ do { ++ /* Read device status */ ++ spi_in8(SPI_CTRL_REG, &cr); ++ ++ if (spi_timer(SPI_TIMEOUT)) { ++ fl_print("\nSPI chip erase timeout: %d sec\n", SPI_TIMER_SET); ++ return(1); ++ } ++ } ++ while (cr & 1); /* is chip busy ? */ ++ } ++ /* Restore SPI control register */ ++ spi_out32(SPI_CTRL_REG, creg); ++ ++ return(0); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_yuk_flash_manage( ++ * unsigned char *data, ++ * unsigned long off, ++ * unsigned long len, ++ * int flag) ++ * ++ * Read, Verify or Write SPI Eprom ++ * ++ * Uses: spi_in32, spi_out32, spi_in8, spi_out8, spi_in16, spi_out16, spi_timer ++ * ++ * IN: ++ * data data buffer ++ * off start offset in flash eprom for operation ++ * len length in flash eprom ++ * flag SPI_READ ++ * SPI_VERIFY ++ * SPI_WRITE ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++static unsigned short rol2( ++unsigned short adr) ++{ ++ unsigned short adr2; ++ ++ /* YUKON-Lite Rev. A1 */ ++ if (chip_id == CHIP_ID_YUKON_LITE || chip_id == CHIP_ID_YUKON_LP) { ++ ++ /* switch address bits [1:0] with [14:13] */ ++ adr2 = adr & 0x6000; ++ adr2 = adr2 >> 13; ++ adr2 = adr2 & 0x0003; ++ adr = adr << 2; ++ adr = adr & 0x7ffc; ++ adr = adr | adr2; ++ } ++ ++ return(adr); ++} ++ ++static int spi_yuk_flash_manage( ++unsigned char *data, ++unsigned long off, ++unsigned long len, ++int flag) ++{ ++ unsigned long a1, a2, cr, i; ++ unsigned short adr, as, ret=0; ++ unsigned char ch, tr; ++ unsigned long progress; ++ unsigned long last_progress; ++ ++ /* Save VPD lower address */ ++ spi_in32(SPI_ADR_REG1, &a1); ++ ++ /* Save VPD higher address */ ++ spi_in32(SPI_ADR_REG2, &a2); ++ ++ /* Set VPD lower address to 0 (15 higher bit)*/ ++ spi_out32(SPI_ADR_REG1, SPI_VPD_MIN); ++ ++ /* Set VPD higher address to 0x7fff (15 higher bit)*/ ++ spi_out32(SPI_ADR_REG2, SPI_VPD_MAX); ++ ++ /* Save SPI control register */ ++ spi_in32(SPI_CTRL_REG, &cr); ++ ++ /* Enable VPD to SPI mapping (set bit 19) */ ++ spi_out32(SPI_CTRL_REG, SPI_VPD_MAP); ++ ++ /* Save Test Control Register 1 */ ++ spi_in8(B2_TST_REG1, &tr); ++ ++ /* Enable write to mapped PCI config register file */ ++ spi_out8(B2_TST_REG1, 2); ++ ++ progress = last_progress = 0; ++ ++ for (i = off, adr = (unsigned short)(off >> 2); i < off + len; i++) { ++ progress = (i * 100) / len; ++ ++ if((progress - last_progress) >= 10) { ++ fl_print("."); ++ last_progress += 10; ++ } ++ ++ /* Set new address to VPD Address reg, initiate reading */ ++ if ((i % 4) == 0) { ++ ++ spi_out16(VPD_ADR_REG, rol2(adr++)); ++ ++ /* Wait for termination */ ++ spi_timer(SPI_TIMER_SET); ++ do { ++ /* Read VPD_ADDR reg for flag check */ ++ spi_in16(VPD_ADR_REG, &as); ++ ++ if (spi_timer(SPI_TIMEOUT)) { ++ fl_print("\nSPI read timeout: %d sec. Offset:0x%05lx\n", ++ SPI_TIMER_SET, i); ++ ret = 1; ++ break; ++ } ++ } ++ while (!(as & VPD_FLAG_MASK)); /* check flag */ ++ ++ if (ret) { ++ break; ++ } ++ } ++ ++ switch (flag) { ++ case SPI_READ: ++ /* Read byte from VPD port */ ++ spi_in8((unsigned short)(VPD_DATA_PORT + ++ (unsigned short)(i % 4)), &ch); ++ *(data++) = ch; ++ break; ++ case SPI_VERIFY: ++ /* Read and verify byte from VPD port */ ++ spi_in8((unsigned short)(VPD_DATA_PORT + ++ (unsigned short)(i % 4)), &ch); ++ if (ch != *(data++)) { ++ fl_print("\n*** SPI data verify error at address 0x%05lx, ", ++ "is %x, should %x\n", ++ i, ch, *(data - 1)); ++ ret = 1; ++ } ++ break; ++ case SPI_WRITE: ++ /* Write byte to VPD port */ ++ spi_out8((unsigned short)(VPD_DATA_PORT + ++ (unsigned short)(i % 4)), *(data++)); ++ ++ if ((i % 4) == 3) { ++ /* Set old Address to VPD_ADDR reg, initiate writing */ ++ spi_out16((unsigned short)VPD_ADR_REG, ++ (unsigned short)(rol2((unsigned short)(adr - 1)) | VPD_FLAG_MASK)); ++ ++ /* Wait for termination */ ++ spi_timer(SPI_TIMER_SET); ++ do { ++ /* Read VPD_ADDR reg for flag check*/ ++ spi_in16(VPD_ADR_REG, &as); ++ ++ if (spi_timer(SPI_TIMEOUT)) { ++ fl_print("\nSPI write timeout: %d sec. Offset:0x%05lx\n", ++ SPI_TIMER_SET, i); ++ ret = 1; ++ break; ++ } ++ } ++ while (as & VPD_FLAG_MASK); /* check flag */ ++ } ++ break; ++ } ++ ++ if (ret) { ++ break; ++ } ++ } ++ /* Restore Test Control Register 1 */ ++ spi_out8(B2_TST_REG1, tr); ++ ++ /* Restore VPD lower address*/ ++ spi_out32(SPI_ADR_REG1, a1); ++ ++ /* Restore VPD higher address*/ ++ spi_out32(SPI_ADR_REG2, a2); ++ ++ /* Restore SPI control register */ ++ spi_out32(SPI_CTRL_REG, cr); ++ ++ fl_print("."); ++ return(ret); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_yuk_update_config( ++ * unsigned char *data, ++ * unsigned long off, ++ * unsigned long len) ++ * ++ * Update part of config area ++ * ++ * Uses: spi_flash_manage, spi_flash_erase ++ * ++ * IN: ++ * data data buffer ++ * off start offset in flash eprom (config area) for operation ++ * len length of changing data ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++static int spi_yuk_update_config( ++unsigned char *data, ++unsigned long off, ++unsigned long len) ++{ ++ unsigned char *spibuf; ++ unsigned long i; ++ ++ spibuf = spi_malloc((unsigned long)SPI_SECT_SIZE); ++ ++ if(spibuf == NULL) { ++ return(51); ++ } ++ ++ if (spi_flash_manage(spibuf, SPI_LSECT_OFF, SPI_SECT_SIZE, SPI_READ)) { ++ ++ spi_free(spibuf); ++ return(1); ++ } ++ ++ for (i = 0; i < len; i++) { ++ spibuf[off + i - SPI_LSECT_OFF] = data[i]; ++ } ++ ++ if (spi_flash_erase(SPI_LSECT_OFF, SPI_SECT_SIZE)) { ++ ++ spi_free(spibuf); ++ return(7); ++ } ++ ++ if (spi_flash_manage(spibuf, SPI_LSECT_OFF, SPI_SECT_SIZE, SPI_WRITE)) { ++ ++ spi_free(spibuf); ++ return(8); ++ } ++ spi_free(spibuf); ++ return(0); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * void spi_yuk2_write_enable() ++ * ++ * This function will set the Write enable setting of the SPI EPROM ++ * ++ * Uses: ++ * ++ * IN: ++ * ++ * return: ++ * nothing ++ * ++ * END_MANUAL_ENTRY() ++ */ ++void spi_yuk2_write_enable() ++{ ++ unsigned long spi_ctrl_reg; ++ ++ /* execute write enable command */ ++ spi_in32(SPI_Y2_CONTROL_REG, &spi_ctrl_reg); ++ spi_ctrl_reg &= ~SPI_Y2_CMD_MASK; ++ spi_ctrl_reg |= SPI_Y2_WEN; ++ spi_out32(SPI_Y2_CONTROL_REG, spi_ctrl_reg); ++ ++ /* wait for the SPI to finish command */ ++ SPI_Y2_WAIT_SE_FINISH_WR(); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * static unsigned long spi_yuk2_read_dword( ++ * unsigned long address) ++ * ++ * The function reads a dword from the specified address in the SPI EPROM. ++ * ++ * Uses: ++ * ++ * IN: ++ * ++ * return: ++ * dword read from given address ++ * ++ * END_MANUAL_ENTRY() ++ */ ++static unsigned long spi_yuk2_read_dword( ++unsigned long address) /* addres in the SPI EPROM to read from */ ++{ ++ unsigned long reg_val = 0; ++ unsigned long spi_ctrl_reg; ++ ++ /* write spi address */ ++ spi_out32(SPI_Y2_ADDRESS_REG, address); ++ ++ /* execute spi read command */ ++ spi_in32(SPI_Y2_CONTROL_REG, &spi_ctrl_reg); ++ spi_ctrl_reg &= ~SPI_Y2_CMD_MASK; ++ spi_ctrl_reg |= SPI_Y2_RD; ++ spi_out32(SPI_Y2_CONTROL_REG, spi_ctrl_reg); ++ ++ /* wait for the SPI to finish RD operation */ ++ SPI_Y2_WAIT_SE_FINISH_CMD(); ++ ++ /* read the returned data */ ++ spi_in32(SPI_Y2_DATA_REG, ®_val); ++ ++ return reg_val; ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * static int spi_yuk2_write_dword( ++ * unsigned long address, ++ * unsigned long value) ++ * ++ * This function writes the specified dword in the specified SPI EPROM location. ++ * The SPI EPROM should have been put previously in write enable mode and ++ * the target sector erased for the access to succeed. ++ * ++ * Uses: ++ * ++ * IN: ++ * ++ * return: ++ * 0 - if successful ++ * 1 - if fails ++ * ++ * END_MANUAL_ENTRY() ++ */ ++static int spi_yuk2_write_dword( ++unsigned long address, /* address to write to */ ++unsigned long value) /* new value to be written */ ++{ ++ unsigned long spi_ctrl_reg; ++ unsigned long verify_value; ++ ++ spi_yuk2_write_enable(); ++ ++ /* write spi address */ ++ spi_out32(SPI_Y2_ADDRESS_REG, address); ++ /* write the new value */ ++ spi_out32(SPI_Y2_DATA_REG, value); ++ ++ /* execute the spi write command */ ++ spi_in32(SPI_Y2_CONTROL_REG, &spi_ctrl_reg); ++ spi_ctrl_reg &= ~SPI_Y2_CMD_MASK; ++ spi_ctrl_reg |= SPI_Y2_WR; ++ spi_out32(SPI_Y2_CONTROL_REG, spi_ctrl_reg); ++ ++ /* wait for write to finish */ ++ SPI_Y2_WAIT_SE_FINISH_WR(); ++ ++ verify_value = spi_yuk2_read_dword(address); ++ ++ /* verify if write was successful*/ ++ if ( verify_value == value ) { ++ return 0; ++ } ++ else { ++ fl_print("\n*** SPI data write error at address 0x%08x, ","is 0x%08x, should 0x%08x\n", address, ++ verify_value, value); ++ return 1; ++ } ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * static int spi_yuk2_sst_write_dword( ++ * unsigned long address, ++ * unsigned long value) ++ * ++ * This function writes the specified dword in the specified SPI EPROM location. ++ * The SPI EPROM should have been put previously in write enable mode and ++ * the target sector erased for the access to succeed. ++ * ++ * Uses: ++ * ++ * IN: ++ * ++ * return: ++ * 0 - if successful ++ * 1 - if fails ++ * ++ * END_MANUAL_ENTRY() ++ */ ++static int spi_yuk2_sst_write_dword( ++unsigned long address, /* address to write to */ ++unsigned long value) /* new value to be written */ ++{ ++ unsigned long spi_ctrl_reg; ++ unsigned long verify_value; ++ unsigned long i; ++ ++ for (i = 0; i < 4; i++) { ++ ++ spi_yuk2_write_enable(); ++ ++ /* write spi address */ ++ spi_out32(SPI_Y2_ADDRESS_REG, address + i); ++ /* write the new value */ ++ spi_out32(SPI_Y2_DATA_REG, (value >> i*8) & 0x000000ff); ++ ++ /* execute the spi write command */ ++ spi_in32(SPI_Y2_CONTROL_REG, &spi_ctrl_reg); ++ spi_ctrl_reg &= ~SPI_Y2_CMD_MASK; ++ spi_ctrl_reg |= SPI_Y2_WR; ++ spi_out32(SPI_Y2_CONTROL_REG, spi_ctrl_reg); ++ ++ /* wait for write to finish */ ++ SPI_Y2_WAIT_SE_FINISH_WR(); ++ ++ verify_value = spi_yuk2_read_dword(address); ++ ++ /* verify if write was successful*/ ++ if ( ((verify_value >> i*8) & 0x000000ff) != ((value >> i*8) & 0x000000ff) ) { ++ fl_print("\n*** SPI data write error at address 0x%08x, ","is 0x%08x, should 0x%08x\n", address + i, ++ ((verify_value >> i*8) & 0x000000ff), ((value >> i*8) & 0x000000ff)); ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_yuk2_sst_clear_write_protection() ++ * ++ * Clear the write protection bits for SST flash types because ++ * they are set by default. ++ * ++ * Uses: ++ * ++ * IN: ++ * ++ * return: ++ * nothing ++ * ++ * END_MANUAL_ENTRY() ++ */ ++void spi_yuk2_sst_clear_write_protection() ++{ ++ unsigned long spi_ctrl_reg; ++ unsigned long op; ++ unsigned long addr; ++ unsigned char status; ++ ++ spi_in32(SPI_Y2_OPCODE_REG1, &op); ++ op &= 0xffff00ff; ++ op |= 0x00000100; ++ spi_out32(SPI_Y2_OPCODE_REG1, op); ++ ++ spi_in32(SPI_Y2_OPCODE_REG2, &op); ++ op &= 0xffffff00; ++ op |= 0x00000050; ++ spi_out32(SPI_Y2_OPCODE_REG2, op); ++ ++ /* execute write status register enable command */ ++ spi_in32(SPI_Y2_CONTROL_REG, &spi_ctrl_reg); ++ spi_ctrl_reg &= ~SPI_Y2_CMD_MASK; ++ spi_ctrl_reg |= SPI_Y2_WEN; ++ spi_out32(SPI_Y2_CONTROL_REG, spi_ctrl_reg); ++ ++ /* wait for the SPI to finish RD operation */ ++ SPI_Y2_WAIT_SE_FINISH_CMD(); ++ ++ spi_in32(SPI_Y2_CONTROL_REG, &spi_ctrl_reg); ++ status = (unsigned char)(spi_ctrl_reg & 0xfffffff3); ++ addr = ((unsigned long)status | (unsigned long)(status << 8) | (unsigned long)(status << 16) | (unsigned long)(status << 24)); ++ ++ /* write spi address */ ++ spi_out32(SPI_Y2_ADDRESS_REG, addr); ++ /* write the new value */ ++ spi_out32(SPI_Y2_DATA_REG, addr); ++ ++ /* execute the write status register command */ ++ spi_in32(SPI_Y2_CONTROL_REG, &spi_ctrl_reg); ++ spi_ctrl_reg &= ~SPI_Y2_CMD_MASK; ++ spi_ctrl_reg |= SPI_Y2_RD; ++ spi_out32(SPI_Y2_CONTROL_REG, spi_ctrl_reg); ++ ++ /* wait for the SPI to finish RD operation */ ++ SPI_Y2_WAIT_SE_FINISH_CMD(); ++ ++ spi_in32(SPI_Y2_CONTROL_REG, &spi_ctrl_reg); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * static void spi_yuk2_erase_sector( ++ * unsigned long sector_num) ++ * ++ * This function will erase the sector specified allowing thus data to be written ++ * ++ * Uses: ++ * ++ * IN: ++ * ++ * return: ++ * nothing ++ * ++ * END_MANUAL_ENTRY() ++ */ ++static void spi_yuk2_erase_sector( ++unsigned long sector_num) /* sector to be erased */ ++{ ++ unsigned long spi_ctrl_reg; ++ ++ spi_yuk2_write_enable(); ++ ++ /* write sector start address */ ++ spi_out32(SPI_Y2_ADDRESS_REG, spi_yuk2_dev_table[spi_yuk2_dev].sector_size * sector_num); ++ ++ /* execute erase sector command */ ++ spi_in32(SPI_Y2_CONTROL_REG, &spi_ctrl_reg); ++ spi_ctrl_reg &= ~SPI_Y2_CMD_MASK; ++ spi_ctrl_reg |= SPI_Y2_SERS; ++ spi_out32(SPI_Y2_CONTROL_REG, spi_ctrl_reg); ++ SPI_Y2_WAIT_SE_FINISH_WR(); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * void spi_yuk2_erase_chip() ++ * ++ * This function will erase the complete SPI EPROM chip ++ * ++ * Uses: ++ * ++ * IN: ++ * ++ * return: ++ * nothing ++ * ++ * END_MANUAL_ENTRY() ++ */ ++void spi_yuk2_erase_chip() ++{ ++ unsigned long spi_ctrl_reg; ++ ++ spi_yuk2_write_enable(); ++ ++ /* execute erase chip command */ ++ spi_in32(SPI_Y2_CONTROL_REG, &spi_ctrl_reg); ++ spi_ctrl_reg &= ~SPI_Y2_CMD_MASK; ++ spi_ctrl_reg |= SPI_Y2_CERS; ++ spi_out32(SPI_Y2_CONTROL_REG, spi_ctrl_reg); ++ SPI_Y2_WAIT_SE_FINISH_WR(); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * unsigned short spi_yuk2_read_chip_id() ++ * ++ * Read SPI vendor and device id ++ * ++ * Uses: ++ * ++ * IN: ++ * ++ * return: ++ * The lower byte containes the device id and the upper the vendor id ++ * ++ * END_MANUAL_ENTRY() ++ */ ++unsigned short spi_yuk2_read_chip_id() ++{ ++ unsigned short chip_id_local; ++ unsigned long spi_ctrl_reg = 0; ++ unsigned long opcode_reg1; ++ ++ /* ++ * set read id opcode for flash currently selected ++ */ ++ spi_in32(SPI_Y2_OPCODE_REG1, &opcode_reg1); ++ opcode_reg1 &= 0xff00ffffL; ++ opcode_reg1 |= (((unsigned long)spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_read_id) << 16); ++ spi_out32(SPI_Y2_OPCODE_REG1, opcode_reg1); ++ ++ /* ++ * read spi control register ++ */ ++ spi_in32(SPI_Y2_CONTROL_REG, &spi_ctrl_reg); ++ spi_ctrl_reg &= ~(SPI_Y2_CMD_MASK | SPI_Y2_RDID_PROT); ++ ++ /* select protocol for chip id read out */ ++ if( spi_yuk2_dev_table[spi_yuk2_dev].set_protocol ) { ++ spi_ctrl_reg |= SPI_Y2_RDID_PROT; ++ } ++ ++ /* execute read chip id command */ ++ spi_ctrl_reg |= SPI_Y2_RDID; ++ spi_out32(SPI_Y2_CONTROL_REG, spi_ctrl_reg); ++ SPI_Y2_WAIT_SE_FINISH_CMD(); ++ ++ spi_in16(SPI_Y2_VENDOR_DEVICE_ID_REG, &chip_id_local); ++ return (chip_id_local); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_yuk2_get_dev_index(void) ++ * ++ * Identify the SPI device and return its device ++ * table index ++ * ++ * Uses: ++ * ++ * IN: ++ * ++ * return: ++ * -1 unknown or no flash device ++ * >=0 flash device table index ++ * ++ * END_MANUAL_ENTRY() ++ */ ++int spi_yuk2_get_dev_index() ++{ ++ unsigned short chip_id_local; ++ unsigned char man_id; ++ unsigned char dev_id; ++ int i; ++ ++ /* search for flash in device table */ ++ for(i = 0; i < (sizeof(spi_yuk2_dev_table) / sizeof(spi_yuk2_dev_table[0])); i++) { ++ spi_yuk2_dev = i; ++ chip_id_local = spi_yuk2_read_chip_id(); ++ ++ man_id = (unsigned char)((chip_id_local & SPI_Y2_MAN_ID_MASK) >> 8); ++ dev_id = (unsigned char)(chip_id_local & SPI_Y2_DEV_ID_MASK); ++ ++ if(spi_yuk2_dev_table[i].man_id == man_id && ++ spi_yuk2_dev_table[i].dev_id == dev_id) { ++ fl_print("\nFlash Device %s found\n", spi_yuk2_dev_table[i].dev_name); ++ fl_print(" - Vendor ID : 0x%2.2x \n", man_id); ++ fl_print(" - Device ID : 0x%2.2x \n", dev_id); ++ return(i); ++ } ++ } ++ ++ spi_yuk2_dev = -1; ++ return(-1); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * static int spi_yuk2_flash_erase(unsigned long off,unsigned long len) ++ * ++ * Erase all sectors of the flash prom affected by the address ++ * range denoted by parameters "off" (address offset) and "len" ++ * (length of address range). ++ * ++ * Uses: spi_in32, spi_out32, spi_in8, spi_timer ++ * ++ * IN: ++ * off: start offset in flash eprom for erase ++ * len: length in flash eprom for erase ++ * (all necessary sectors will be erased) ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++ ++static int spi_yuk2_flash_erase( ++unsigned long off, ++unsigned long len) ++{ ++ unsigned long flash_size; ++ unsigned long i; ++ unsigned long start_sector; ++ unsigned long end_sector; ++ ++ if(len == 0) { ++ return(0); ++ } ++ ++ flash_size = spi_yuk2_dev_table[spi_yuk2_dev].sector_size * ++ spi_yuk2_dev_table[spi_yuk2_dev].sector_num; ++ ++ /* ++ * flash size is smaller than address range which ++ * should be erased --> don't erase flash. ++ */ ++ if ((off+len-1) > flash_size) { ++ return(1); ++ } ++ ++ /* ++ * Erase complete flash if all sectors of flash are affected ++ */ ++ if(len > (spi_yuk2_dev_table[spi_yuk2_dev].sector_size * ++ (spi_yuk2_dev_table[spi_yuk2_dev].sector_num - 1))) { ++ ++ spi_yuk2_erase_chip(); ++ } ++ /* ++ * Erase all affected sectors ++ */ ++ else { ++ start_sector = off / spi_yuk2_dev_table[spi_yuk2_dev].sector_size; ++ end_sector = (off + len - 1) / spi_yuk2_dev_table[spi_yuk2_dev].sector_size; ++ ++ for (i = start_sector; i <= end_sector; i++) { ++ spi_yuk2_erase_sector(i); ++ } ++ } ++ ++ return(0); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * static int spi_yuk2_flash_manage( ++ * unsigned char *data, ++ * unsigned long off, ++ * unsigned long len, ++ * int flag) ++ * ++ * Read, Verify or Write SPI Eprom ++ * ++ * Uses: spi_in32, spi_out32, spi_in8, spi_out8, spi_in16, spi_out16, spi_timer ++ * ++ * IN: ++ * data data buffer ++ * off start offset in flash eprom for operation ++ * len length in flash eprom ++ * flag SPI_READ ++ * SPI_VERIFY ++ * SPI_WRITE ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++static int spi_yuk2_flash_manage( ++unsigned char *data, ++unsigned long off, ++unsigned long len, ++int flag) ++{ ++ unsigned long addr; ++ unsigned long spi_data; ++ unsigned int *spi_data_ptr; ++ int ret = 0; ++ len = (len + 3) & ~3; ++ ++ for (addr = off, spi_data_ptr = (unsigned int *)data; addr < off + len; addr+=4, spi_data_ptr++) { ++ ++ switch (flag) { ++ case SPI_READ: ++ /* Read a dword from SPI flash */ ++ *(spi_data_ptr) = spi_yuk2_read_dword(addr); ++ break; ++ ++ case SPI_VERIFY: ++ /* Read and verify dword from SPI flash */ ++ spi_data = spi_yuk2_read_dword(addr); ++ break; ++ ++ if (spi_data != *(spi_data_ptr)) { ++ fl_print("\n*** SPI data verify error at address 0x%08lx, ","is %x, should %x\n", addr, ++ spi_data, *(spi_data_ptr)); ++ ret = 1; ++ } ++ break; ++ ++ case SPI_WRITE: ++ /* Write a dword to SPI flash */ ++ if (spi_yuk2_dev_table[spi_yuk2_dev].man_id == SPI_MAN_ID_SST) { ++ ret = spi_yuk2_sst_write_dword(addr, *(spi_data_ptr)); ++ } ++ else { ++ ret = spi_yuk2_write_dword(addr, *(spi_data_ptr)); ++ } ++ break; ++ } ++ ++ if (ret) { ++ break; ++ } ++ } ++ ++ return(ret); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * static int spi_yuk2_update_config( ++ * unsigned char *data, ++ * unsigned long off, ++ * unsigned long len) ++ * ++ * Update part of config area ++ * ++ * Uses: spi_flash_manage, spi_flash_erase ++ * ++ * IN: ++ * data data buffer ++ * off start offset in flash eprom (config area) for operation ++ * len length of changing data ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++static int spi_yuk2_update_config( ++unsigned char *data, ++unsigned long off, ++unsigned long len) ++{ ++ unsigned char *spibuf; ++ unsigned long start_sector; ++ unsigned long end_sector; ++ unsigned long i; ++ ++ /* determine the affected sectors */ ++ start_sector = off / spi_yuk2_dev_table[spi_yuk2_dev].sector_size; ++ end_sector = (off + len - 1) / spi_yuk2_dev_table[spi_yuk2_dev].sector_size; ++ ++ /* ++ * allocate the necessary memory for temporary ++ * save of the affected sectors ++ */ ++ spibuf = spi_malloc((unsigned long)(((end_sector - start_sector) + 1) * spi_yuk2_dev_table[spi_yuk2_dev].sector_size)); ++ ++ if(spibuf == NULL) { ++ return(51); ++ } ++ ++ /* read out the affected sectors */ ++ if (spi_flash_manage(spibuf, ++ start_sector * spi_yuk2_dev_table[spi_yuk2_dev].sector_size, ++ ((end_sector - start_sector) + 1) * spi_yuk2_dev_table[spi_yuk2_dev].sector_size, ++ SPI_READ)) { ++ ++ spi_free(spibuf); ++ return(1); ++ } ++ ++ /* update the just read out data */ ++ for (i = 0; i < len; i++) { ++ spibuf[off + i - SPI_LSECT_OFF] = data[i]; ++ } ++ ++ /* erase the affected sectors */ ++ if (spi_flash_erase(start_sector * spi_yuk2_dev_table[spi_yuk2_dev].sector_size, ++ ((end_sector - start_sector) + 1) * spi_yuk2_dev_table[spi_yuk2_dev].sector_size)) { ++ ++ spi_free(spibuf); ++ return(7); ++ } ++ ++ /* write the updated data back to the flash */ ++ if (spi_flash_manage(spibuf, ++ start_sector * spi_yuk2_dev_table[spi_yuk2_dev].sector_size, ++ ((end_sector - start_sector) + 1) * spi_yuk2_dev_table[spi_yuk2_dev].sector_size, ++ SPI_WRITE)) { ++ ++ spi_free(spibuf); ++ return(8); ++ } ++ ++ spi_free(spibuf); ++ return(0); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * static int spi_update_config( ++ * unsigned char *data, ++ * unsigned long off, ++ * unsigned long len) ++ * ++ * Update part of config area ++ * ++ * Uses: spi_flash_manage, spi_flash_erase ++ * ++ * IN: ++ * data data buffer ++ * off start offset in flash eprom (config area) for operation ++ * len length of changing data ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++static int spi_update_config( ++unsigned char *data, ++unsigned long off, ++unsigned long len) ++{ ++ switch (fl_type) { ++ case FT_SPI: ++ return(spi_yuk_update_config(data, off, len)); ++ break; ++ ++ case FT_SPI_Y2: ++ return(spi_yuk2_update_config(data, off, len)); ++ break; ++ } ++ ++ return(1); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int flash_check_spi( unsigned long *FlashSize ) ++ * ++ * Determines whether a SPI Eprom present ++ * ++ * Uses: spi_in32, spi_out32 ++ * ++ * IN: ++ * ++ * return: ++ * 0 No SPI ++ * 1 SPI detected ++ * ++ * END_MANUAL_ENTRY() ++ */ ++ ++int flash_check_spi( ++unsigned long *FlashSize ) ++{ ++ unsigned long a1,a2; ++ unsigned long opcodes; ++ ++ *FlashSize = 0; ++ ++ spi_in8(B2_CHIP_ID, &chip_id); ++ ++ if (chip_id == CHIP_ID_YUKON_LITE || chip_id == CHIP_ID_YUKON_LP) { ++ /* YUKON-Lite Rev. A1 */ ++ fl_type = FT_SPI; ++ *FlashSize = max_pages * max_faddr; ++ return(1); ++ } ++ ++ if (chip_id == CHIP_ID_YUKON_XL || chip_id == CHIP_ID_YUKON_EC) { ++ fl_type = FT_SPI_Y2; ++ spi_yuk2_dev = spi_yuk2_get_dev_index(); ++ ++ /* unknown or no flash */ ++ if(spi_yuk2_dev < 0) { ++ fl_print("\nNo SPI flash found !\n"); ++ fl_type = FT_SPI_UNKNOWN; ++ return(0); ++ } ++ ++ max_pages = (long)(spi_yuk2_dev_table[spi_yuk2_dev].sector_num); ++ max_faddr = (long)(spi_yuk2_dev_table[spi_yuk2_dev].sector_size); ++ *FlashSize = spi_yuk2_dev_table[spi_yuk2_dev].sector_num * spi_yuk2_dev_table[spi_yuk2_dev].sector_size; ++ ++ /* ++ * work around for SST flash types to clear write ++ * protection bits which are set by default. ++ */ ++ if (spi_yuk2_dev_table[spi_yuk2_dev].man_id == SPI_MAN_ID_SST) { ++ spi_yuk2_sst_clear_write_protection(); ++ } ++ ++ /* ++ * set the opcodes for the SPI flash found ++ */ ++ spi_in32(SPI_Y2_OPCODE_REG1, &opcodes); ++ opcodes &= 0x000000ffL; ++ opcodes |= ((((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_read)) << 8) | ++ (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_read_id)) << 16) | ++ (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_read_status)) << 24)); ++ ++ spi_out32(SPI_Y2_OPCODE_REG1, opcodes); ++ ++ opcodes = (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_write_enable)) | ++ (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_write)) << 8) | ++ (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_sector_erase)) << 16) | ++ (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_chip_erase)) << 24)); ++ ++ spi_out32(SPI_Y2_OPCODE_REG2, opcodes); ++ ++ return(1); ++ } ++ ++ /* Save Eprom Address Register 1 */ ++ spi_in32(SPI_ADR_REG1, &a1); ++ ++ /* Write SPI pattern */ ++ spi_out32(SPI_ADR_REG1, SPI_PATTERN); ++ ++ /* Read SPI pattern */ ++ spi_in32(SPI_ADR_REG1, &a2); ++ ++ /* Restore Eprom Address Register 1 */ ++ spi_out32(SPI_ADR_REG1, a1); ++ ++ /* This is a SPI Eprom if one of bits 31..16 are set */ ++ if ((a2 & SPI_COMP_MASK) != 0) { ++ /* YUKON-Lite Rev. A0 */ ++ fl_type = FT_SPI; ++ *FlashSize = max_pages * max_faddr; ++ return(1); ++ } ++ return(0); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_flash_erase(unsigned long off,unsigned long len) ++ * ++ * Send chip erase command to SPI Eprom ++ * ++ * Uses: spi_in32, spi_out32, spi_in8, spi_timer ++ * ++ * IN: ++ * off start offset in flash eprom for erase ++ * len length in flash eprom for erase ++ * (all nessesory sectors will be erased) ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++int spi_flash_erase( ++unsigned long off, ++unsigned long len) ++{ ++ switch (fl_type) { ++ case FT_SPI: ++ return(spi_yuk_flash_erase(off, len)); ++ break; ++ ++ case FT_SPI_Y2: ++ return(spi_yuk2_flash_erase(off, len)); ++ break; ++ } ++ ++ return(1); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_flash_manage( ++ * unsigned char *data, ++ * unsigned long off, ++ * unsigned long len, ++ * int flag) ++ * ++ * Read, Verify or Write SPI Eprom ++ * ++ * Uses: spi_in32, spi_out32, spi_in8, spi_out8, spi_in16, spi_out16, spi_timer ++ * ++ * IN: ++ * data data buffer ++ * off start offset in flash eprom for operation ++ * len length in flash eprom ++ * flag SPI_READ ++ * SPI_VERIFY ++ * SPI_WRITE ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++int spi_flash_manage( ++unsigned char *data, ++unsigned long off, ++unsigned long len, ++int flag) ++{ ++ switch (fl_type) { ++ case FT_SPI: ++ return(spi_yuk_flash_manage(data, off, len, flag)); ++ break; ++ ++ case FT_SPI_Y2: ++ return(spi_yuk2_flash_manage(data, off, len, flag)); ++ break; ++ } ++ ++ return(1); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_get_pig( ++ * unsigned char *data, ++ * unsigned long len) ++ * ++ * Get data from PiG area in SPI eprom ++ * ++ * Uses: spi_update_config ++ * ++ * IN: ++ * data data buffer ++ * len length of wanted data ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++int spi_get_pig( ++unsigned char *data, ++unsigned long len) ++{ ++ return(spi_flash_manage(data, SPI_PIG_OFF, len, SPI_READ)); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_get_noc( ++ * unsigned char *data, ++ * unsigned long len) ++ * ++ * Get data from VPD area in SPI eprom ++ * ++ * Uses: spi_update_config ++ * ++ * IN: ++ * data data buffer ++ * len length of wanted data ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++int spi_get_noc( ++unsigned char *data, ++unsigned long len) ++{ ++ return(spi_flash_manage(data, SPI_NOC_OFF, len, SPI_READ)); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_update_pig( ++ * unsigned char *data, ++ * unsigned long len) ++ * ++ * Update data in PiG area in SPI eprom ++ * ++ * Uses: spi_update_config ++ * ++ * IN: ++ * data data buffer ++ * len length of data to update ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++int spi_update_pig( ++unsigned char *data, ++unsigned long len) ++{ ++ return(spi_update_config(data, SPI_PIG_OFF, len)); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_update_noc( ++ * unsigned char *data, ++ * unsigned long len) ++ * ++ * Update data in NOC area in SPI eprom ++ * ++ * Uses: spi_update_config ++ * ++ * IN: ++ * data data buffer ++ * len length of data to update ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++int spi_update_noc( ++unsigned char *data, ++unsigned long len) ++{ ++ return(spi_update_config(data, SPI_NOC_OFF, len)); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_vpd_tranfer( ++ * char *buf, ++ * int addr, ++ * int len, ++ * int dir) ++ * ++ * Read or update data in VPD area in SPI eprom ++ * ++ * Uses: spi_update_config ++ * ++ * IN: ++ * buf data buffer ++ * addr VPD start address ++ * len number of bytes to read / to write ++ * dir transfer direction may be VPD_READ or VPD_WRITE ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++int spi_vpd_transfer( ++char *buf, /* data buffer */ ++int addr, /* VPD start address */ ++int len, /* number of bytes to read / to write */ ++int dir) /* transfer direction may be VPD_READ or VPD_WRITE */ ++{ ++ if (dir == 0) { ++ return(spi_flash_manage(buf, SPI_VPD_OFF + addr, len, SPI_READ)); ++ } ++ else { ++ return(spi_update_config(buf, SPI_VPD_OFF + addr, len)); ++ } ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_update_pet( ++ * unsigned char *data, ++ * unsigned long len) ++ * ++ * Update data in PET area in SPI eprom ++ * ++ * Uses: spi_update_config ++ * ++ * IN: ++ * data data buffer ++ * len length of data to update ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++int spi_update_pet( ++unsigned char *data, ++unsigned long len) ++{ ++ return(spi_update_config(data, SPI_PET_OFF, len)); ++} ++ ++/* ++ * BEGIN_MANUAL_ENTRY() ++ * ++ * int spi_get_pet( ++ * unsigned char *data, ++ * unsigned long len) ++ * ++ * Get data from Pet frames area in SPI eprom ++ * ++ * Uses: spi_update_config ++ * ++ * IN: ++ * data data buffer ++ * len length of wanted data ++ * ++ * return: ++ * 0 Success ++ * 1 Timeout ++ * ++ * END_MANUAL_ENTRY() ++ */ ++int spi_get_pet( ++unsigned char *data, ++unsigned long len) ++{ ++ return(spi_flash_manage(data, SPI_PET_OFF, len, SPI_READ)); ++} +diff -ruN linux/drivers/net/sk98lin/skgespilole.c linux-new/drivers/net/sk98lin/skgespilole.c +--- linux/drivers/net/sk98lin/skgespilole.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/skgespilole.c 2007-01-24 14:03:40.000000000 +0100 +@@ -0,0 +1,107 @@ ++/****************************************************************************** ++ * ++ * Name: skspilole.c ++ * Project: Flash Programmer, Manufacturing and Diagnostic Tools ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Contains Low Level Functions for the integration of the skspi.c module ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * (C)Copyright 1998-2002 SysKonnect ++ * (C)Copyright 2002-2003 Marvell ++ * ++ * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SYSKONNECT ++ * The copyright notice above does not evidence any ++ * actual or intended publication of such source code. ++ * ++ * This Module contains Proprietary Information of SysKonnect ++ * and should be treated as Confidential. ++ * ++ * The information in this file is provided for the exclusive use of ++ * the licensees of SysKonnect. ++ * Such users have the right to use, modify, and incorporate this code ++ * into products for purposes authorized by the license agreement ++ * provided they include this notice and the associated copyright notice ++ * with any such product. ++ * The information in this file is provided "AS IS" without warranty. ++ * ++ ******************************************************************************/ ++ ++static const char SysKonnectFileId[] = ++ "@(#) $Id$ (C) Marvell."; ++ ++#include "h/skdrv1st.h" ++#include "h/skdrv2nd.h" ++#include "h/skgespi.h" ++ ++ ++SK_AC *lpAC; ++static SK_U32 timebuf; ++ ++int fl_type; ++/* ++ * global vars ++ */ ++long max_pages = 0; ++long max_faddr = 0; ++ ++ ++/* low level SPI programming interface */ ++ ++void spi_init_pac( SK_AC *pAC ) { ++ lpAC = pAC; ++} ++ ++void spi_in8(unsigned short offs, unsigned char *val ) { ++ SK_IN8( lpAC->IoBase, offs, val ); ++} ++ ++void spi_in16(unsigned short offs, unsigned short *val ){ ++ SK_IN16( lpAC->IoBase, offs, val ); ++} ++ ++void spi_in32(unsigned short offs, unsigned long *val ){ ++ SK_IN32( lpAC->IoBase, offs, val ); ++} ++ ++void spi_out8(unsigned short offs, unsigned char val ){ ++ SK_OUT8( lpAC->IoBase, offs, val ); ++} ++ ++void spi_out16(unsigned short offs, unsigned short val ){ ++ SK_OUT16( lpAC->IoBase, offs, val ); ++} ++ ++void spi_out32(unsigned short offs, unsigned long val ){ ++ SK_OUT32( lpAC->IoBase, offs, val ); ++} ++ ++int spi_timer(unsigned int t){ ++ if(t) ++ { ++ timebuf = (SK_U32)SkOsGetTime(lpAC)+(SK_U32)t*SK_TICKS_PER_SEC ; ++ } else ++ { ++ if((timebuf <= (SK_U32)SkOsGetTime(lpAC))) ++ { ++ return(1); ++ } ++ } ++ return(0); ++} ++ ++/* dummies */ ++void fl_print(char *msg, ...) { ++} ++ ++unsigned char *spi_malloc( unsigned short size ) { ++ return( kmalloc(size,GFP_KERNEL) ); ++} ++ ++void spi_free( unsigned char *buf ) { ++ kfree(buf); ++} ++ +diff -ruN linux/drivers/net/sk98lin/ski2c.c linux-new/drivers/net/sk98lin/ski2c.c +--- linux/drivers/net/sk98lin/ski2c.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/ski2c.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1296 +0,0 @@ +-/****************************************************************************** +- * +- * Name: ski2c.c +- * Project: Gigabit Ethernet Adapters, TWSI-Module +- * Version: $Revision$ +- * Date: $Date$ +- * Purpose: Functions 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. +- * +- ******************************************************************************/ +- +-/* +- * I2C Protocol +- */ +-#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) +-static const char SysKonnectFileId[] = +- "@(#) $Id$ (C) Marvell. "; +-#endif +- +-#include "h/skdrv1st.h" /* Driver Specific Definitions */ +-#include "h/lm80.h" +-#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ +- +-#ifdef __C2MAN__ +-/* +- I2C protocol implementation. +- +- General Description: +- +- The I2C protocol is used for the temperature sensors and for +- the serial EEPROM which hold the configuration. +- +- This file covers functions that allow to read write and do +- some bulk requests a specified I2C address. +- +- The Genesis has 2 I2C buses. One for the EEPROM which holds +- the VPD Data and one for temperature and voltage sensor. +- The following picture shows the I2C buses, I2C devices and +- their control registers. +- +- Note: The VPD functions are in skvpd.c +-. +-. PCI Config I2C Bus for VPD Data: +-. +-. +------------+ +-. | VPD EEPROM | +-. +------------+ +-. | +-. | <-- I2C +-. | +-. +-----------+-----------+ +-. | | +-. +-----------------+ +-----------------+ +-. | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG | +-. +-----------------+ +-----------------+ +-. +-. +-. I2C Bus for LM80 sensor: +-. +-. +-----------------+ +-. | Temperature and | +-. | Voltage Sensor | +-. | LM80 | +-. +-----------------+ +-. | +-. | +-. I2C --> | +-. | +-. +----+ +-. +-------------->| OR |<--+ +-. | +----+ | +-. +------+------+ | +-. | | | +-. +--------+ +--------+ +----------+ +-. | B2_I2C | | B2_I2C | | B2_I2C | +-. | _CTRL | | _DATA | | _SW | +-. +--------+ +--------+ +----------+ +-. +- The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL +- and B2_I2C_DATA registers. +- For driver software it is recommended to use the I2C control and +- data register, because I2C bus timing is done by the ASIC and +- an interrupt may be received when the I2C request is completed. +- +- Clock Rate Timing: MIN MAX generated by +- VPD EEPROM: 50 kHz 100 kHz HW +- LM80 over I2C Ctrl/Data reg. 50 kHz 100 kHz HW +- LM80 over B2_I2C_SW register 0 400 kHz SW +- +- Note: The clock generated by the hardware is dependend on the +- PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD +- clock is 50 kHz. +- */ +-intro() +-{} +-#endif +- +-#ifdef SK_DIAG +-/* +- * I2C Fast Mode timing values used by the LM80. +- * If new devices are added to the I2C bus the timing values have to be checked. +- */ +-#ifndef I2C_SLOW_TIMING +-#define T_CLK_LOW 1300L /* clock low time in ns */ +-#define T_CLK_HIGH 600L /* clock high time in ns */ +-#define T_DATA_IN_SETUP 100L /* data in Set-up Time */ +-#define T_START_HOLD 600L /* start condition hold time */ +-#define T_START_SETUP 600L /* start condition Set-up time */ +-#define T_STOP_SETUP 600L /* stop condition Set-up time */ +-#define T_BUS_IDLE 1300L /* time the bus must free after Tx */ +-#define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */ +-#else /* I2C_SLOW_TIMING */ +-/* I2C Standard Mode Timing */ +-#define T_CLK_LOW 4700L /* clock low time in ns */ +-#define T_CLK_HIGH 4000L /* clock high time in ns */ +-#define T_DATA_IN_SETUP 250L /* data in Set-up Time */ +-#define T_START_HOLD 4000L /* start condition hold time */ +-#define T_START_SETUP 4700L /* start condition Set-up time */ +-#define T_STOP_SETUP 4000L /* stop condition Set-up time */ +-#define T_BUS_IDLE 4700L /* time the bus must free after Tx */ +-#endif /* !I2C_SLOW_TIMING */ +- +-#define NS2BCLK(x) (((x)*125)/10000) +- +-/* +- * I2C Wire Operations +- * +- * About I2C_CLK_LOW(): +- * +- * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting +- * clock to low, to prevent the ASIC and the I2C data client from driving the +- * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client +- * send an 'ACK'). See also Concentrator Bugreport No. 10192. +- */ +-#define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA) +-#define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA) +-#define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR) +-#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA) +-#define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK) +-#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR) +-#define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK) +- +-#define NS2CLKT(x) ((x*125L)/10000) +- +-/*--------------- I2C Interface Register Functions --------------- */ +- +-/* +- * sending one bit +- */ +-void SkI2cSndBit( +-SK_IOC IoC, /* I/O Context */ +-SK_U8 Bit) /* Bit to send */ +-{ +- I2C_DATA_OUT(IoC); +- if (Bit) { +- I2C_DATA_HIGH(IoC); +- } +- else { +- I2C_DATA_LOW(IoC); +- } +- SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP)); +- I2C_CLK_HIGH(IoC); +- SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH)); +- I2C_CLK_LOW(IoC); +-} /* SkI2cSndBit*/ +- +- +-/* +- * Signal a start to the I2C Bus. +- * +- * A start is signaled when data goes to low in a high clock cycle. +- * +- * Ends with Clock Low. +- * +- * Status: not tested +- */ +-void SkI2cStart( +-SK_IOC IoC) /* I/O Context */ +-{ +- /* Init data and Clock to output lines */ +- /* Set Data high */ +- I2C_DATA_OUT(IoC); +- I2C_DATA_HIGH(IoC); +- /* Set Clock high */ +- I2C_CLK_HIGH(IoC); +- +- SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP)); +- +- /* Set Data Low */ +- I2C_DATA_LOW(IoC); +- +- SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD)); +- +- /* Clock low without Data to Input */ +- I2C_START_COND(IoC); +- +- SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW)); +-} /* SkI2cStart */ +- +- +-void SkI2cStop( +-SK_IOC IoC) /* I/O Context */ +-{ +- /* Init data and Clock to output lines */ +- /* Set Data low */ +- I2C_DATA_OUT(IoC); +- I2C_DATA_LOW(IoC); +- +- SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT)); +- +- /* Set Clock high */ +- I2C_CLK_HIGH(IoC); +- +- SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP)); +- +- /* +- * Set Data High: Do it by setting the Data Line to Input. +- * Because of a pull up resistor the Data Line +- * floods to high. +- */ +- I2C_DATA_IN(IoC); +- +- /* +- * When I2C activity is stopped +- * o DATA should be set to input and +- * o CLOCK should be set to high! +- */ +- SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE)); +-} /* SkI2cStop */ +- +- +-/* +- * Receive just one bit via the I2C bus. +- * +- * Note: Clock must be set to LOW before calling this function. +- * +- * Returns The received bit. +- */ +-int SkI2cRcvBit( +-SK_IOC IoC) /* I/O Context */ +-{ +- int Bit; +- SK_U8 I2cSwCtrl; +- +- /* Init data as input line */ +- I2C_DATA_IN(IoC); +- +- SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT)); +- +- I2C_CLK_HIGH(IoC); +- +- SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH)); +- +- SK_I2C_GET_SW(IoC, &I2cSwCtrl); +- +- Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0; +- +- I2C_CLK_LOW(IoC); +- SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT)); +- +- return(Bit); +-} /* SkI2cRcvBit */ +- +- +-/* +- * Receive an ACK. +- * +- * returns 0 If acknowledged +- * 1 in case of an error +- */ +-int SkI2cRcvAck( +-SK_IOC IoC) /* I/O Context */ +-{ +- /* +- * Received bit must be zero. +- */ +- return(SkI2cRcvBit(IoC) != 0); +-} /* SkI2cRcvAck */ +- +- +-/* +- * Send an NACK. +- */ +-void SkI2cSndNAck( +-SK_IOC IoC) /* I/O Context */ +-{ +- /* +- * Received bit must be zero. +- */ +- SkI2cSndBit(IoC, 1); +-} /* SkI2cSndNAck */ +- +- +-/* +- * Send an ACK. +- */ +-void SkI2cSndAck( +-SK_IOC IoC) /* I/O Context */ +-{ +- /* +- * Received bit must be zero. +- */ +- SkI2cSndBit(IoC, 0); +-} /* SkI2cSndAck */ +- +- +-/* +- * Send one byte to the I2C device and wait for ACK. +- * +- * Return acknowleged status. +- */ +-int SkI2cSndByte( +-SK_IOC IoC, /* I/O Context */ +-int Byte) /* byte to send */ +-{ +- int i; +- +- for (i = 0; i < 8; i++) { +- if (Byte & (1<<(7-i))) { +- SkI2cSndBit(IoC, 1); +- } +- else { +- SkI2cSndBit(IoC, 0); +- } +- } +- +- return(SkI2cRcvAck(IoC)); +-} /* SkI2cSndByte */ +- +- +-/* +- * Receive one byte and ack it. +- * +- * Return byte. +- */ +-int SkI2cRcvByte( +-SK_IOC IoC, /* I/O Context */ +-int Last) /* Last Byte Flag */ +-{ +- int i; +- int Byte = 0; +- +- for (i = 0; i < 8; i++) { +- Byte <<= 1; +- Byte |= SkI2cRcvBit(IoC); +- } +- +- if (Last) { +- SkI2cSndNAck(IoC); +- } +- else { +- SkI2cSndAck(IoC); +- } +- +- return(Byte); +-} /* SkI2cRcvByte */ +- +- +-/* +- * Start dialog and send device address +- * +- * Return 0 if acknowleged, 1 in case of an error +- */ +-int SkI2cSndDev( +-SK_IOC IoC, /* I/O Context */ +-int Addr, /* Device Address */ +-int Rw) /* Read / Write Flag */ +-{ +- SkI2cStart(IoC); +- Rw = ~Rw; +- Rw &= I2C_WRITE; +- return(SkI2cSndByte(IoC, (Addr<<1) | Rw)); +-} /* SkI2cSndDev */ +- +-#endif /* SK_DIAG */ +- +-/*----------------- I2C CTRL Register Functions ----------*/ +- +-/* +- * waits for a completion of an I2C transfer +- * +- * returns 0: success, transfer completes +- * 1: error, transfer does not complete, I2C transfer +- * killed, wait loop terminated. +- */ +-static int SkI2cWait( +-SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* I/O Context */ +-int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */ +-{ +- SK_U64 StartTime; +- SK_U64 CurrentTime; +- SK_U32 I2cCtrl; +- +- StartTime = SkOsGetTime(pAC); +- +- do { +- CurrentTime = SkOsGetTime(pAC); +- +- if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) { +- +- SK_I2C_STOP(IoC); +-#ifndef SK_DIAG +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG); +-#endif /* !SK_DIAG */ +- return(1); +- } +- +- SK_I2C_GET_CTL(IoC, &I2cCtrl); +- +-#ifdef xYUKON_DBG +- printf("StartTime=%lu, CurrentTime=%lu\n", +- StartTime, CurrentTime); +- if (kbhit()) { +- return(1); +- } +-#endif /* YUKON_DBG */ +- +- } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31); +- +- return(0); +-} /* SkI2cWait */ +- +- +-/* +- * waits for a completion of an I2C transfer +- * +- * Returns +- * Nothing +- */ +-void SkI2cWaitIrq( +-SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC) /* I/O Context */ +-{ +- SK_SENSOR *pSen; +- SK_U64 StartTime; +- SK_U32 IrqSrc; +- +- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; +- +- if (pSen->SenState == SK_SEN_IDLE) { +- return; +- } +- +- StartTime = SkOsGetTime(pAC); +- +- do { +- if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) { +- +- SK_I2C_STOP(IoC); +-#ifndef SK_DIAG +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG); +-#endif /* !SK_DIAG */ +- return; +- } +- +- SK_IN32(IoC, B0_ISRC, &IrqSrc); +- +- } while ((IrqSrc & IS_I2C_READY) == 0); +- +- pSen->SenState = SK_SEN_IDLE; +- return; +-} /* SkI2cWaitIrq */ +- +-/* +- * writes a single byte or 4 bytes into the I2C device +- * +- * returns 0: success +- * 1: error +- */ +-static int SkI2cWrite( +-SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* I/O Context */ +-SK_U32 I2cData, /* I2C Data to write */ +-int I2cDev, /* I2C Device Address */ +-int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ +-int I2cReg, /* I2C Device Register Address */ +-int I2cBurst) /* I2C Burst Flag */ +-{ +- SK_OUT32(IoC, B2_I2C_DATA, I2cData); +- +- SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst); +- +- return(SkI2cWait(pAC, IoC, I2C_WRITE)); +-} /* SkI2cWrite*/ +- +- +-#ifdef SK_DIAG +-/* +- * reads a single byte or 4 bytes from the I2C device +- * +- * returns the word read +- */ +-SK_U32 SkI2cRead( +-SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* I/O Context */ +-int I2cDev, /* I2C Device Address */ +-int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ +-int I2cReg, /* I2C Device Register Address */ +-int I2cBurst) /* I2C Burst Flag */ +-{ +- SK_U32 Data; +- +- SK_OUT32(IoC, B2_I2C_DATA, 0); +- SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst); +- +- if (SkI2cWait(pAC, IoC, I2C_READ) != 0) { +- w_print("%s\n", SKERR_I2C_E002MSG); +- } +- +- SK_IN32(IoC, B2_I2C_DATA, &Data); +- +- return(Data); +-} /* SkI2cRead */ +-#endif /* SK_DIAG */ +- +- +-/* +- * read a sensor's value +- * +- * This function reads a sensor's value from the I2C sensor chip. The sensor +- * is defined by its index into the sensors database in the struct pAC points +- * to. +- * Returns +- * 1 if the read is completed +- * 0 if the read must be continued (I2C Bus still allocated) +- */ +-static int SkI2cReadSensor( +-SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* I/O Context */ +-SK_SENSOR *pSen) /* Sensor to be read */ +-{ +- if (pSen->SenRead != NULL) { +- return((*pSen->SenRead)(pAC, IoC, pSen)); +- } +- else { +- return(0); /* no success */ +- } +-} /* SkI2cReadSensor */ +- +-/* +- * Do the Init state 0 initialization +- */ +-static int SkI2cInit0( +-SK_AC *pAC) /* Adapter Context */ +-{ +- int i; +- +- /* Begin with first sensor */ +- pAC->I2c.CurrSens = 0; +- +- /* Begin with timeout control for state machine */ +- pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; +- +- /* Set sensor number to zero */ +- pAC->I2c.MaxSens = 0; +- +-#ifndef SK_DIAG +- /* Initialize Number of Dummy Reads */ +- pAC->I2c.DummyReads = SK_MAX_SENSORS; +-#endif +- +- for (i = 0; i < SK_MAX_SENSORS; i++) { +- pAC->I2c.SenTable[i].SenDesc = "unknown"; +- pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN; +- pAC->I2c.SenTable[i].SenThreErrHigh = 0; +- pAC->I2c.SenTable[i].SenThreErrLow = 0; +- pAC->I2c.SenTable[i].SenThreWarnHigh = 0; +- pAC->I2c.SenTable[i].SenThreWarnLow = 0; +- pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN; +- pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE; +- pAC->I2c.SenTable[i].SenValue = 0; +- pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT; +- pAC->I2c.SenTable[i].SenErrCts = 0; +- pAC->I2c.SenTable[i].SenBegErrTS = 0; +- pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE; +- pAC->I2c.SenTable[i].SenRead = NULL; +- pAC->I2c.SenTable[i].SenDev = 0; +- } +- +- /* Now we are "INIT data"ed */ +- pAC->I2c.InitLevel = SK_INIT_DATA; +- return(0); +-} /* SkI2cInit0*/ +- +- +-/* +- * Do the init state 1 initialization +- * +- * initialize the following register of the LM80: +- * Configuration register: +- * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT +- * +- * Interrupt Mask Register 1: +- * - all interrupts are Disabled (0xff) +- * +- * Interrupt Mask Register 2: +- * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter. +- * +- * Fan Divisor/RST_OUT register: +- * - Divisors set to 1 (bits 00), all others 0s. +- * +- * OS# Configuration/Temperature resolution Register: +- * - all 0s +- * +- */ +-static int SkI2cInit1( +-SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC) /* I/O Context */ +-{ +- int i; +- SK_U8 I2cSwCtrl; +- SK_GEPORT *pPrt; /* GIni Port struct pointer */ +- +- if (pAC->I2c.InitLevel != SK_INIT_DATA) { +- /* ReInit not needed in I2C module */ +- return(0); +- } +- +- /* Set the Direction of I2C-Data Pin to IN */ +- SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA); +- /* Check for 32-Bit Yukon with Low at I2C-Data Pin */ +- SK_I2C_GET_SW(IoC, &I2cSwCtrl); +- +- if ((I2cSwCtrl & I2C_DATA) == 0) { +- /* this is a 32-Bit board */ +- pAC->GIni.GIYukon32Bit = SK_TRUE; +- return(0); +- } +- +- /* Check for 64 Bit Yukon without sensors */ +- if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) { +- return(0); +- } +- +- (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0); +- +- (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0); +- +- (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0); +- +- (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0); +- +- (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV, +- LM80_CFG, 0); +- +- /* +- * MaxSens has to be updated here, because PhyType is not +- * set when performing Init Level 0 +- */ +- pAC->I2c.MaxSens = 5; +- +- pPrt = &pAC->GIni.GP[0]; +- +- if (pAC->GIni.GIGenesis) { +- if (pPrt->PhyType == SK_PHY_BCOM) { +- if (pAC->GIni.GIMacsFound == 1) { +- pAC->I2c.MaxSens += 1; +- } +- else { +- pAC->I2c.MaxSens += 3; +- } +- } +- } +- else { +- pAC->I2c.MaxSens += 3; +- } +- +- for (i = 0; i < pAC->I2c.MaxSens; i++) { +- switch (i) { +- case 0: +- pAC->I2c.SenTable[i].SenDesc = "Temperature"; +- pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP; +- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR; +- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN; +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN; +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR; +- pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN; +- break; +- case 1: +- pAC->I2c.SenTable[i].SenDesc = "Voltage PCI"; +- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; +- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR; +- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN; +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN; +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR; +- pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN; +- break; +- case 2: +- pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO"; +- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; +- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR; +- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN; +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN; +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR; +- pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN; +- pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO; +- break; +- case 3: +- pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC"; +- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; +- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR; +- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN; +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN; +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR; +- pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN; +- break; +- case 4: +- if (pAC->GIni.GIGenesis) { +- if (pPrt->PhyType == SK_PHY_BCOM) { +- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL"; +- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; +- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; +- } +- else { +- pAC->I2c.SenTable[i].SenDesc = "Voltage PMA"; +- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; +- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; +- } +- } +- else { +- pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX"; +- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR; +- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN; +- if (pAC->GIni.GIVauxAvail) { +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; +- } +- else { +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR; +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR; +- } +- } +- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; +- pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN; +- break; +- case 5: +- if (pAC->GIni.GIGenesis) { +- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5"; +- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; +- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; +- } +- else { +- pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5"; +- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR; +- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN; +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN; +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR; +- } +- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; +- pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN; +- break; +- case 6: +- if (pAC->GIni.GIGenesis) { +- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL"; +- } +- else { +- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3"; +- } +- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; +- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; +- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; +- pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN; +- break; +- case 7: +- if (pAC->GIni.GIGenesis) { +- pAC->I2c.SenTable[i].SenDesc = "Speed Fan"; +- pAC->I2c.SenTable[i].SenType = SK_SEN_FAN; +- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR; +- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN; +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN; +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR; +- pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN; +- } +- else { +- pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5"; +- pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; +- pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; +- pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; +- pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; +- pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; +- pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN; +- } +- break; +- default: +- SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW, +- SKERR_I2C_E001, SKERR_I2C_E001MSG); +- break; +- } +- +- pAC->I2c.SenTable[i].SenValue = 0; +- pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK; +- pAC->I2c.SenTable[i].SenErrCts = 0; +- pAC->I2c.SenTable[i].SenBegErrTS = 0; +- pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE; +- pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor; +- pAC->I2c.SenTable[i].SenDev = LM80_ADDR; +- } +- +-#ifndef SK_DIAG +- pAC->I2c.DummyReads = pAC->I2c.MaxSens; +-#endif /* !SK_DIAG */ +- +- /* Clear I2C IRQ */ +- SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); +- +- /* Now we are I/O initialized */ +- pAC->I2c.InitLevel = SK_INIT_IO; +- return(0); +-} /* SkI2cInit1 */ +- +- +-/* +- * Init level 2: Start first sensor read. +- */ +-static int SkI2cInit2( +-SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC) /* I/O Context */ +-{ +- int ReadComplete; +- SK_SENSOR *pSen; +- +- if (pAC->I2c.InitLevel != SK_INIT_IO) { +- /* ReInit not needed in I2C module */ +- /* Init0 and Init2 not permitted */ +- return(0); +- } +- +- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; +- ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); +- +- if (ReadComplete) { +- SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG); +- } +- +- /* Now we are correctly initialized */ +- pAC->I2c.InitLevel = SK_INIT_RUN; +- +- return(0); +-} /* SkI2cInit2*/ +- +- +-/* +- * Initialize I2C devices +- * +- * Get the first voltage value and discard it. +- * Go into temperature read mode. A default pointer is not set. +- * +- * The things to be done depend on the init level in the parameter list: +- * Level 0: +- * Initialize only the data structures. Do NOT access hardware. +- * Level 1: +- * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts. +- * Level 2: +- * Everything is possible. Interrupts may be used from now on. +- * +- * return: +- * 0 = success +- * other = error. +- */ +-int SkI2cInit( +-SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */ +-int Level) /* Init Level */ +-{ +- +- switch (Level) { +- case SK_INIT_DATA: +- return(SkI2cInit0(pAC)); +- case SK_INIT_IO: +- return(SkI2cInit1(pAC, IoC)); +- case SK_INIT_RUN: +- return(SkI2cInit2(pAC, IoC)); +- default: +- break; +- } +- +- return(0); +-} /* SkI2cInit */ +- +- +-#ifndef SK_DIAG +- +-/* +- * Interrupt service function for the I2C Interface +- * +- * Clears the Interrupt source +- * +- * Reads the register and check it for sending a trap. +- * +- * Starts the timer if necessary. +- */ +-void SkI2cIsr( +-SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC) /* I/O Context */ +-{ +- SK_EVPARA Para; +- +- /* Clear I2C IRQ */ +- SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); +- +- Para.Para64 = 0; +- SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para); +-} /* SkI2cIsr */ +- +- +-/* +- * Check this sensors Value against the threshold and send events. +- */ +-static void SkI2cCheckSensor( +-SK_AC *pAC, /* Adapter Context */ +-SK_SENSOR *pSen) +-{ +- SK_EVPARA ParaLocal; +- SK_BOOL TooHigh; /* Is sensor too high? */ +- SK_BOOL TooLow; /* Is sensor too low? */ +- SK_U64 CurrTime; /* Current Time */ +- SK_BOOL DoTrapSend; /* We need to send a trap */ +- SK_BOOL DoErrLog; /* We need to log the error */ +- SK_BOOL IsError; /* We need to log the error */ +- +- /* Check Dummy Reads first */ +- if (pAC->I2c.DummyReads > 0) { +- pAC->I2c.DummyReads--; +- return; +- } +- +- /* Get the current time */ +- CurrTime = SkOsGetTime(pAC); +- +- /* Set para to the most useful setting: The current sensor. */ +- ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens; +- +- /* Check the Value against the thresholds. First: Error Thresholds */ +- TooHigh = (pSen->SenValue > pSen->SenThreErrHigh); +- TooLow = (pSen->SenValue < pSen->SenThreErrLow); +- +- IsError = SK_FALSE; +- if (TooHigh || TooLow) { +- /* Error condition is satisfied */ +- DoTrapSend = SK_TRUE; +- DoErrLog = SK_TRUE; +- +- /* Now error condition is satisfied */ +- IsError = SK_TRUE; +- +- if (pSen->SenErrFlag == SK_SEN_ERR_ERR) { +- /* This state is the former one */ +- +- /* So check first whether we have to send a trap */ +- if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD > +- CurrTime) { +- /* +- * Do NOT send the Trap. The hold back time +- * has to run out first. +- */ +- DoTrapSend = SK_FALSE; +- } +- +- /* Check now whether we have to log an Error */ +- if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD > +- CurrTime) { +- /* +- * Do NOT log the error. The hold back time +- * has to run out first. +- */ +- DoErrLog = SK_FALSE; +- } +- } +- else { +- /* We came from a different state -> Set Begin Time Stamp */ +- pSen->SenBegErrTS = CurrTime; +- pSen->SenErrFlag = SK_SEN_ERR_ERR; +- } +- +- if (DoTrapSend) { +- /* Set current Time */ +- pSen->SenLastErrTrapTS = CurrTime; +- pSen->SenErrCts++; +- +- /* Queue PNMI Event */ +- SkEventQueue(pAC, SKGE_PNMI, (TooHigh ? +- SK_PNMI_EVT_SEN_ERR_UPP : +- SK_PNMI_EVT_SEN_ERR_LOW), +- ParaLocal); +- } +- +- if (DoErrLog) { +- /* Set current Time */ +- pSen->SenLastErrLogTS = CurrTime; +- +- if (pSen->SenType == SK_SEN_TEMP) { +- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG); +- } +- else if (pSen->SenType == SK_SEN_VOLT) { +- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG); +- } +- else { +- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG); +- } +- } +- } +- +- /* Check the Value against the thresholds */ +- /* 2nd: Warning thresholds */ +- TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh); +- TooLow = (pSen->SenValue < pSen->SenThreWarnLow); +- +- if (!IsError && (TooHigh || TooLow)) { +- /* Error condition is satisfied */ +- DoTrapSend = SK_TRUE; +- DoErrLog = SK_TRUE; +- +- if (pSen->SenErrFlag == SK_SEN_ERR_WARN) { +- /* This state is the former one */ +- +- /* So check first whether we have to send a trap */ +- if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) { +- /* +- * Do NOT send the Trap. The hold back time +- * has to run out first. +- */ +- DoTrapSend = SK_FALSE; +- } +- +- /* Check now whether we have to log an Error */ +- if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) { +- /* +- * Do NOT log the error. The hold back time +- * has to run out first. +- */ +- DoErrLog = SK_FALSE; +- } +- } +- else { +- /* We came from a different state -> Set Begin Time Stamp */ +- pSen->SenBegWarnTS = CurrTime; +- pSen->SenErrFlag = SK_SEN_ERR_WARN; +- } +- +- if (DoTrapSend) { +- /* Set current Time */ +- pSen->SenLastWarnTrapTS = CurrTime; +- pSen->SenWarnCts++; +- +- /* Queue PNMI Event */ +- SkEventQueue(pAC, SKGE_PNMI, (TooHigh ? +- SK_PNMI_EVT_SEN_WAR_UPP : +- SK_PNMI_EVT_SEN_WAR_LOW), +- ParaLocal); +- } +- +- if (DoErrLog) { +- /* Set current Time */ +- pSen->SenLastWarnLogTS = CurrTime; +- +- if (pSen->SenType == SK_SEN_TEMP) { +- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG); +- } +- else if (pSen->SenType == SK_SEN_VOLT) { +- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG); +- } +- else { +- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG); +- } +- } +- } +- +- /* Check for NO error at all */ +- if (!IsError && !TooHigh && !TooLow) { +- /* Set o.k. Status if no error and no warning condition */ +- pSen->SenErrFlag = SK_SEN_ERR_OK; +- } +- +- /* End of check against the thresholds */ +- +- /* Bug fix AF: 16.Aug.2001: Correct the init base +- * of LM80 sensor. +- */ +- if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) { +- +- pSen->SenInit = SK_SEN_DYN_INIT_NONE; +- +- if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) { +- /* 5V PCI-IO Voltage */ +- pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN; +- pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR; +- } +- else { +- /* 3.3V PCI-IO Voltage */ +- pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN; +- pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR; +- } +- } +- +-#ifdef TEST_ONLY +- /* Dynamic thresholds also for VAUX of LM80 sensor */ +- if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) { +- +- pSen->SenInit = SK_SEN_DYN_INIT_NONE; +- +- /* 3.3V VAUX Voltage */ +- if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) { +- pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; +- pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; +- } +- /* 0V VAUX Voltage */ +- else { +- pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR; +- pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR; +- } +- } +- +- /* +- * Check initialization state: +- * The VIO Thresholds need adaption +- */ +- if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && +- pSen->SenValue > SK_SEN_WARNLOW2C && +- pSen->SenValue < SK_SEN_WARNHIGH2) { +- pSen->SenThreErrLow = SK_SEN_ERRLOW2C; +- pSen->SenThreWarnLow = SK_SEN_WARNLOW2C; +- pSen->SenInit = SK_TRUE; +- } +- +- if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && +- pSen->SenValue > SK_SEN_WARNLOW2 && +- pSen->SenValue < SK_SEN_WARNHIGH2C) { +- pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C; +- pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C; +- pSen->SenInit = SK_TRUE; +- } +-#endif +- +- if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) { +- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG); +- } +-} /* SkI2cCheckSensor */ +- +- +-/* +- * The only Event to be served is the timeout event +- * +- */ +-int SkI2cEvent( +-SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* I/O Context */ +-SK_U32 Event, /* Module specific Event */ +-SK_EVPARA Para) /* Event specific Parameter */ +-{ +- int ReadComplete; +- SK_SENSOR *pSen; +- SK_U32 Time; +- SK_EVPARA ParaLocal; +- int i; +- +- /* New case: no sensors */ +- if (pAC->I2c.MaxSens == 0) { +- return(0); +- } +- +- switch (Event) { +- case SK_I2CEV_IRQ: +- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; +- ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); +- +- if (ReadComplete) { +- /* Check sensor against defined thresholds */ +- SkI2cCheckSensor(pAC, pSen); +- +- /* Increment Current sensor and set appropriate Timeout */ +- pAC->I2c.CurrSens++; +- if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) { +- pAC->I2c.CurrSens = 0; +- Time = SK_I2C_TIM_LONG; +- } +- else { +- Time = SK_I2C_TIM_SHORT; +- } +- +- /* Start Timer */ +- ParaLocal.Para64 = (SK_U64)0; +- +- pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; +- +- SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, +- SKGE_I2C, SK_I2CEV_TIM, ParaLocal); +- } +- else { +- /* Start Timer */ +- ParaLocal.Para64 = (SK_U64)0; +- +- pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; +- +- SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH, +- SKGE_I2C, SK_I2CEV_TIM, ParaLocal); +- } +- break; +- case SK_I2CEV_TIM: +- if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) { +- +- ParaLocal.Para64 = (SK_U64)0; +- SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer); +- +- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; +- ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); +- +- if (ReadComplete) { +- /* Check sensor against defined thresholds */ +- SkI2cCheckSensor(pAC, pSen); +- +- /* Increment Current sensor and set appropriate Timeout */ +- pAC->I2c.CurrSens++; +- if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { +- pAC->I2c.CurrSens = 0; +- Time = SK_I2C_TIM_LONG; +- } +- else { +- Time = SK_I2C_TIM_SHORT; +- } +- +- /* Start Timer */ +- ParaLocal.Para64 = (SK_U64)0; +- +- pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; +- +- SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, +- SKGE_I2C, SK_I2CEV_TIM, ParaLocal); +- } +- } +- else { +- pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; +- pSen->SenErrFlag = SK_SEN_ERR_FAULTY; +- SK_I2C_STOP(IoC); +- +- /* Increment Current sensor and set appropriate Timeout */ +- pAC->I2c.CurrSens++; +- if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { +- pAC->I2c.CurrSens = 0; +- Time = SK_I2C_TIM_LONG; +- } +- else { +- Time = SK_I2C_TIM_SHORT; +- } +- +- /* Start Timer */ +- ParaLocal.Para64 = (SK_U64)0; +- +- pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; +- +- SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, +- SKGE_I2C, SK_I2CEV_TIM, ParaLocal); +- } +- break; +- case SK_I2CEV_CLEAR: +- for (i = 0; i < SK_MAX_SENSORS; i++) { +- pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK; +- pAC->I2c.SenTable[i].SenErrCts = 0; +- pAC->I2c.SenTable[i].SenWarnCts = 0; +- pAC->I2c.SenTable[i].SenBegErrTS = 0; +- pAC->I2c.SenTable[i].SenBegWarnTS = 0; +- pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0; +- pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0; +- pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0; +- pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0; +- } +- break; +- default: +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG); +- } +- +- return(0); +-} /* SkI2cEvent*/ +- +-#endif /* !SK_DIAG */ +diff -ruN linux/drivers/net/sk98lin/sklm80.c linux-new/drivers/net/sk98lin/sklm80.c +--- linux/drivers/net/sk98lin/sklm80.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/sklm80.c 2007-01-24 14:03:40.000000000 +0100 +@@ -2,14 +2,15 @@ + * + * Name: sklm80.c + * Project: Gigabit Ethernet Adapters, TWSI-Module +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Functions to access Voltage and Temperature Sensor (LM80) + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. + * +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -27,24 +29,96 @@ + */ + #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) + static const char SysKonnectFileId[] = +- "@(#) $Id$ (C) Marvell. "; ++ "@(#) $Id$ (C) Marvell. "; + #endif + + #include "h/skdrv1st.h" /* Driver Specific Definitions */ + #include "h/lm80.h" + #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ + ++#ifdef SK_DIAG ++#define BREAK_OR_WAIT(pAC,IoC,Event) SkI2cWait(pAC,IoC,Event) ++#else /* nSK_DIAG */ + #define BREAK_OR_WAIT(pAC,IoC,Event) break ++#endif /* nSK_DIAG */ ++ ++#ifdef SK_DIAG ++/* ++ * read the register 'Reg' from the device 'Dev' ++ * ++ * return read error -1 ++ * success the read value ++ */ ++int SkLm80RcvReg( ++SK_IOC IoC, /* Adapter Context */ ++int Dev, /* I2C device address */ ++int Reg) /* register to read */ ++{ ++ int Val = 0; ++ int TempExt; ++ ++ /* Signal device number */ ++ if (SkI2cSndDev(IoC, Dev, I2C_WRITE)) { ++ return(-1); ++ } ++ ++ if (SkI2cSndByte(IoC, Reg)) { ++ return(-1); ++ } ++ ++ /* repeat start */ ++ if (SkI2cSndDev(IoC, Dev, I2C_READ)) { ++ return(-1); ++ } ++ ++ switch (Reg) { ++ case LM80_TEMP_IN: ++ Val = (int)SkI2cRcvByte(IoC, 1); ++ ++ /* First: correct the value: it might be negative */ ++ if ((Val & 0x80) != 0) { ++ /* Value is negative */ ++ Val = Val - 256; ++ } ++ Val = Val * SK_LM80_TEMP_LSB; ++ SkI2cStop(IoC); ++ ++ TempExt = (int)SkLm80RcvReg(IoC, LM80_ADDR, LM80_TEMP_CTRL); ++ ++ if (Val > 0) { ++ Val += ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB); ++ } ++ else { ++ Val -= ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB); ++ } ++ return(Val); ++ break; ++ case LM80_VT0_IN: ++ case LM80_VT1_IN: ++ case LM80_VT2_IN: ++ case LM80_VT3_IN: ++ Val = (int)SkI2cRcvByte(IoC, 1) * SK_LM80_VT_LSB; ++ break; ++ ++ default: ++ Val = (int)SkI2cRcvByte(IoC, 1); ++ break; ++ } ++ ++ SkI2cStop(IoC); ++ return(Val); ++} ++#endif /* SK_DIAG */ + + /* + * read a sensors value (LM80 specific) + * +- * This function reads a sensors value from the I2C sensor chip LM80. ++ * This function reads a sensors value from the TWSI sensor chip LM80. + * The sensor is defined by its index into the sensors database in the struct + * pAC points to. + * + * Returns 1 if the read is completed +- * 0 if the read must be continued (I2C Bus still allocated) ++ * 0 if the read must be continued (TWSI Bus still allocated) + */ + int SkLm80ReadSensor( + SK_AC *pAC, /* Adapter Context */ +diff -ruN linux/drivers/net/sk98lin/skproc.c linux-new/drivers/net/sk98lin/skproc.c +--- linux/drivers/net/sk98lin/skproc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/skproc.c 2007-01-24 14:03:43.000000000 +0100 +@@ -0,0 +1,477 @@ ++/****************************************************************************** ++ * ++ * Name: skproc.c ++ * Project: GEnesis, PCI Gigabit Ethernet Adapter ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Functions to display statictic data ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * (C)Copyright 1998-2002 SysKonnect GmbH. ++ * (C)Copyright 2002-2005 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 ++ * ++ * 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 ++#include ++ ++#include "h/skdrv1st.h" ++#include "h/skdrv2nd.h" ++#include "h/skversion.h" ++ ++extern struct SK_NET_DEVICE *SkGeRootDev; ++ ++/****************************************************************************** ++ * ++ * Local Function Prototypes and Local Variables ++ * ++ *****************************************************************************/ ++ ++static int sk_proc_print(void *writePtr, char *format, ...); ++static void sk_gen_browse(void *buffer); ++static int len; ++ ++static int sk_seq_show(struct seq_file *seq, void *v); ++static int sk_proc_open(struct inode *inode, struct file *file); ++struct file_operations sk_proc_fops = { ++ .owner = THIS_MODULE, ++ .open = sk_proc_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++struct net_device *currDev = NULL; ++ ++/***************************************************************************** ++ * ++ * sk_gen_browse -generic print "summaries" entry ++ * ++ * Description: ++ * This function fills the proc entry with statistic data about ++ * the ethernet device. ++ * ++ * Returns: N/A ++ * ++ */ ++static void sk_gen_browse( ++void *buffer) /* buffer where the statistics will be stored in */ ++{ ++ struct SK_NET_DEVICE *SkgeProcDev = SkGeRootDev; ++ struct SK_NET_DEVICE *next; ++ SK_BOOL DisableStatistic = 0; ++ SK_PNMI_STRUCT_DATA *pPnmiStruct; ++ SK_PNMI_STAT *pPnmiStat; ++ unsigned long Flags; ++ unsigned int Size; ++ DEV_NET *pNet; ++ SK_AC *pAC; ++ char sens_msg[50]; ++ int card_type; ++ int MaxSecurityCount = 0; ++ int t; ++ int i; ++ ++ while (SkgeProcDev) { ++ MaxSecurityCount++; ++ if (MaxSecurityCount > 100) { ++ printk("Max limit for sk_proc_read security counter!\n"); ++ return; ++ } ++ pNet = (DEV_NET*) SkgeProcDev->priv; ++ pAC = pNet->pAC; ++ next = pAC->Next; ++ pPnmiStruct = &pAC->PnmiStruct; ++ /* NetIndex in GetStruct is now required, zero is only dummy */ ++ ++ for (t=pAC->GIni.GIMacsFound; t > 0; t--) { ++ if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1) ++ t--; ++ ++ spin_lock_irqsave(&pAC->SlowPathLock, Flags); ++ Size = SK_PNMI_STRUCT_SIZE; ++ DisableStatistic = 0; ++ if (pAC->BoardLevel == SK_INIT_DATA) { ++ SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA)); ++ if (pAC->DiagModeActive == DIAG_NOTACTIVE) { ++ pAC->Pnmi.DiagAttached = SK_DIAG_IDLE; ++ } ++ } else { ++ SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1); ++ } ++ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); ++ if (strcmp(pAC->dev[t-1]->name, currDev->name) == 0) { ++ if (!pAC->GIni.GIYukon32Bit) ++ card_type = 64; ++ else ++ card_type = 32; ++ ++ pPnmiStat = &pPnmiStruct->Stat[0]; ++ len = sk_proc_print(buffer, ++ "\nDetailed statistic for device %s\n", ++ pAC->dev[t-1]->name); ++ len += sk_proc_print(buffer, ++ "=======================================\n"); ++ ++ /* Board statistics */ ++ len += sk_proc_print(buffer, ++ "\nBoard statistics\n\n"); ++ len += sk_proc_print(buffer, ++ "Card name %s\n", ++ pAC->DeviceStr); ++ len += sk_proc_print(buffer, ++ "Vendor/Device ID %x/%x\n", ++ pAC->PciDev->vendor, ++ pAC->PciDev->device); ++ len += sk_proc_print(buffer, ++ "Card type (Bit) %d\n", ++ card_type); ++ ++ len += sk_proc_print(buffer, ++ "Active Port %c\n", ++ 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt. ++ Net[t-1].PrefPort]->PortNumber); ++ len += sk_proc_print(buffer, ++ "Preferred Port %c\n", ++ 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt. ++ Net[t-1].PrefPort]->PortNumber); ++ ++ if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) { ++ len += sk_proc_print(buffer, ++ "Interrupt Moderation static (%d ints/sec)\n", ++ pAC->DynIrqModInfo.MaxModIntsPerSec); ++ } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) { ++ len += sk_proc_print(buffer, ++ "Interrupt Moderation dynamic (%d ints/sec)\n", ++ pAC->DynIrqModInfo.MaxModIntsPerSec); ++ } else { ++ len += sk_proc_print(buffer, ++ "Interrupt Moderation disabled\n"); ++ } ++ ++ if (pAC->GIni.GIPciBus == SK_PEX_BUS) { ++ len += sk_proc_print(buffer, ++ "Bus type PCI-Express\n"); ++ len += sk_proc_print(buffer, ++ "Bus width (Lanes) %d\n", ++ pAC->GIni.GIPexWidth); ++ } else { ++ if (pAC->GIni.GIPciBus == SK_PCIX_BUS) { ++ len += sk_proc_print(buffer, ++ "Bus type PCI-X\n"); ++ if (pAC->GIni.GIPciMode == PCI_OS_SPD_X133) { ++ len += sk_proc_print(buffer, ++ "Bus speed (MHz) 133\n"); ++ } else if (pAC->GIni.GIPciMode == PCI_OS_SPD_X100) { ++ len += sk_proc_print(buffer, ++ "Bus speed (MHz) 100\n"); ++ } else if (pAC->GIni.GIPciMode == PCI_OS_SPD_X66) { ++ len += sk_proc_print(buffer, ++ "Bus speed (MHz) 66\n"); ++ } else { ++ len += sk_proc_print(buffer, ++ "Bus speed (MHz) 33\n"); ++ } ++ } else { ++ len += sk_proc_print(buffer, ++ "Bus type PCI\n"); ++ len += sk_proc_print(buffer, ++ "Bus speed (MHz) %d\n", ++ pPnmiStruct->BusSpeed); ++ } ++ len += sk_proc_print(buffer, ++ "Bus width (Bit) %d\n", ++ pPnmiStruct->BusWidth); ++ } ++ ++ len += sk_proc_print(buffer, ++ "Driver version %s (%s)\n", ++ VER_STRING, PATCHLEVEL); ++ len += sk_proc_print(buffer, ++ "Driver release date %s\n", ++ pAC->Pnmi.pDriverReleaseDate); ++ len += sk_proc_print(buffer, ++ "Hardware revision v%d.%d\n", ++ (pAC->GIni.GIPciHwRev >> 4) & 0x0F, ++ pAC->GIni.GIPciHwRev & 0x0F); ++ ++ if (!netif_running(pAC->dev[t-1])) { ++ len += sk_proc_print(buffer, ++ "\n Device %s is down.\n" ++ " Therefore no statistics are available.\n" ++ " After bringing the device up (ifconfig)" ++ " statistics will\n" ++ " be displayed.\n", ++ pAC->dev[t-1]->name); ++ DisableStatistic = 1; ++ } ++ ++ /* Display only if statistic info available */ ++ /* Print sensor informations */ ++ if (!DisableStatistic) { ++ for (i=0; i < pAC->I2c.MaxSens; i ++) { ++ /* Check type */ ++ switch (pAC->I2c.SenTable[i].SenType) { ++ case 1: ++ strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); ++ strcat(sens_msg, " (C)"); ++ len += sk_proc_print(buffer, ++ "%-25s %d.%02d\n", ++ sens_msg, ++ pAC->I2c.SenTable[i].SenValue / 10, ++ pAC->I2c.SenTable[i].SenValue % ++ 10); ++ ++ strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); ++ strcat(sens_msg, " (F)"); ++ len += sk_proc_print(buffer, ++ "%-25s %d.%02d\n", ++ sens_msg, ++ ((((pAC->I2c.SenTable[i].SenValue) ++ *10)*9)/5 + 3200)/100, ++ ((((pAC->I2c.SenTable[i].SenValue) ++ *10)*9)/5 + 3200) % 10); ++ break; ++ case 2: ++ strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); ++ strcat(sens_msg, " (V)"); ++ len += sk_proc_print(buffer, ++ "%-25s %d.%03d\n", ++ sens_msg, ++ pAC->I2c.SenTable[i].SenValue / 1000, ++ pAC->I2c.SenTable[i].SenValue % 1000); ++ break; ++ case 3: ++ strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); ++ strcat(sens_msg, " (rpm)"); ++ len += sk_proc_print(buffer, ++ "%-25s %d\n", ++ sens_msg, ++ pAC->I2c.SenTable[i].SenValue); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ /*Receive statistics */ ++ len += sk_proc_print(buffer, ++ "\nReceive statistics\n\n"); ++ ++ len += sk_proc_print(buffer, ++ "Received bytes %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxOctetsOkCts); ++ len += sk_proc_print(buffer, ++ "Received packets %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxOkCts); ++#if 0 ++ if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && ++ pAC->HWRevision < 12) { ++ pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - ++ pPnmiStat->StatRxShortsCts; ++ pPnmiStat->StatRxShortsCts = 0; ++ } ++#endif ++ if (pAC->dev[t-1]->mtu > 1500) ++ pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - ++ pPnmiStat->StatRxTooLongCts; ++ ++ len += sk_proc_print(buffer, ++ "Receive errors %Lu\n", ++ (unsigned long long) pPnmiStruct->InErrorsCts); ++ len += sk_proc_print(buffer, ++ "Receive dropped %Lu\n", ++ (unsigned long long) pPnmiStruct->RxNoBufCts); ++ len += sk_proc_print(buffer, ++ "Received multicast %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxMulticastOkCts); ++#ifdef ADVANCED_STATISTIC_OUTPUT ++ len += sk_proc_print(buffer, ++ "Receive error types\n"); ++ len += sk_proc_print(buffer, ++ " length %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxRuntCts); ++ len += sk_proc_print(buffer, ++ " buffer overflow %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxFifoOverflowCts); ++ len += sk_proc_print(buffer, ++ " bad crc %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxFcsCts); ++ len += sk_proc_print(buffer, ++ " framing %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxFramingCts); ++ len += sk_proc_print(buffer, ++ " missed frames %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxMissedCts); ++ ++ if (pAC->dev[t-1]->mtu > 1500) ++ pPnmiStat->StatRxTooLongCts = 0; ++ ++ len += sk_proc_print(buffer, ++ " too long %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxTooLongCts); ++ len += sk_proc_print(buffer, ++ " carrier extension %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxCextCts); ++ len += sk_proc_print(buffer, ++ " too short %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxShortsCts); ++ len += sk_proc_print(buffer, ++ " symbol %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxSymbolCts); ++ len += sk_proc_print(buffer, ++ " LLC MAC size %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxIRLengthCts); ++ len += sk_proc_print(buffer, ++ " carrier event %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxCarrierCts); ++ len += sk_proc_print(buffer, ++ " jabber %Lu\n", ++ (unsigned long long) pPnmiStat->StatRxJabberCts); ++#endif ++ ++ /*Transmit statistics */ ++ len += sk_proc_print(buffer, ++ "\nTransmit statistics\n\n"); ++ ++ len += sk_proc_print(buffer, ++ "Transmitted bytes %Lu\n", ++ (unsigned long long) pPnmiStat->StatTxOctetsOkCts); ++ len += sk_proc_print(buffer, ++ "Transmitted packets %Lu\n", ++ (unsigned long long) pPnmiStat->StatTxOkCts); ++ len += sk_proc_print(buffer, ++ "Transmit errors %Lu\n", ++ (unsigned long long) pPnmiStat->StatTxSingleCollisionCts); ++ len += sk_proc_print(buffer, ++ "Transmit dropped %Lu\n", ++ (unsigned long long) pPnmiStruct->TxNoBufCts); ++ len += sk_proc_print(buffer, ++ "Transmit collisions %Lu\n", ++ (unsigned long long) pPnmiStat->StatTxSingleCollisionCts); ++#ifdef ADVANCED_STATISTIC_OUTPUT ++ len += sk_proc_print(buffer, ++ "Transmit error types\n"); ++ len += sk_proc_print(buffer, ++ " excessive collision %ld\n", ++ pAC->stats.tx_aborted_errors); ++ len += sk_proc_print(buffer, ++ " carrier %Lu\n", ++ (unsigned long long) pPnmiStat->StatTxCarrierCts); ++ len += sk_proc_print(buffer, ++ " fifo underrun %Lu\n", ++ (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts); ++ len += sk_proc_print(buffer, ++ " heartbeat %Lu\n", ++ (unsigned long long) pPnmiStat->StatTxCarrierCts); ++ len += sk_proc_print(buffer, ++ " window %ld\n", ++ pAC->stats.tx_window_errors); ++#endif ++ } /* if (!DisableStatistic) */ ++ ++ } /* if (strcmp(pACname, currDeviceName) == 0) */ ++ } ++ SkgeProcDev = next; ++ } ++} ++ ++/***************************************************************************** ++ * ++ * sk_proc_print - generic line print ++ * ++ * Description: ++ * This function fills the proc entry with statistic data about the ++ * ethernet device. ++ * ++ * Returns: ++ * the number of bytes written ++ * ++ */ ++static int sk_proc_print( ++void *writePtr, /* the buffer pointer */ ++char *format, /* the format of the string */ ++...) /* variable list of arguments */ ++{ ++#define MAX_LEN_SINGLE_LINE 256 ++ char str[MAX_LEN_SINGLE_LINE]; ++ va_list a_start; ++ int lenght = 0; ++ ++ struct seq_file *seq = (struct seq_file *) writePtr; ++ ++ SK_MEMSET(str, 0, MAX_LEN_SINGLE_LINE); ++ ++ va_start(a_start, format); ++ vsprintf(str, format, a_start); ++ va_end(a_start); ++ ++ lenght = strlen(str); ++ ++ seq_printf(seq, str); ++ return lenght; ++} ++ ++/***************************************************************************** ++ * ++ * sk_seq_show - show proc information of a particular adapter ++ * ++ * Description: ++ * This function fills the proc entry with statistic data about the ++ * ethernet device. It invokes the generic sk_gen_browse() to print ++ * out all items one per one. ++ * ++ * Returns: ++ * the number of bytes written ++ * ++ */ ++static int sk_seq_show( ++struct seq_file *seq, /* the sequence pointer */ ++void *v) /* additional pointer */ ++{ ++ void *castedBuffer = (void *) seq; ++ currDev = seq->private; ++ sk_gen_browse(castedBuffer); ++ return 0; ++} ++ ++/***************************************************************************** ++ * ++ * sk_proc_open - register the show function when proc is open'ed ++ * ++ * Description: ++ * This function is called whenever a sk98lin proc file is queried. ++ * ++ * Returns: ++ * the return value of single_open() ++ * ++ */ ++static int sk_proc_open( ++struct inode *inode, /* the inode of the file */ ++struct file *file) /* the file pointer itself */ ++{ ++ return single_open(file, sk_seq_show, PDE(inode)->data); ++} ++ ++/******************************************************************************* ++ * ++ * End of file ++ * ++ ******************************************************************************/ +diff -ruN linux/drivers/net/sk98lin/skqueue.c linux-new/drivers/net/sk98lin/skqueue.c +--- linux/drivers/net/sk98lin/skqueue.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skqueue.c 2007-01-24 14:03:40.000000000 +0100 +@@ -2,14 +2,15 @@ + * + * Name: skqueue.c + * Project: Gigabit Ethernet Adapters, Event Scheduler Module +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Management of an event queue. + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. + * +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -28,7 +30,7 @@ + */ + #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) + static const char SysKonnectFileId[] = +- "@(#) $Id$ (C) Marvell."; ++ "@(#) $Id$ (C) Marvell."; + #endif + + #include "h/skdrv1st.h" /* Driver Specific Definitions */ +@@ -48,10 +50,16 @@ + + #define PRINTF(a,b,c) + +-/* +- * init event queue management ++/****************************************************************************** ++ * ++ * SkEventInit() - init event queue management + * +- * Must be called during init level 0. ++ * Description: ++ * This function initializes event queue management. ++ * It must be called during init level 0. ++ * ++ * Returns: ++ * nothing + */ + void SkEventInit( + SK_AC *pAC, /* Adapter context */ +@@ -67,8 +75,17 @@ + } + } + +-/* +- * add event to queue ++/****************************************************************************** ++ * ++ * SkEventQueue() - add event to queue ++ * ++ * Description: ++ * This function adds an event to the event queue. ++ * At least Init Level 1 is required to queue events, ++ * but will be scheduled add Init Level 2. ++ * ++ * returns: ++ * nothing + */ + void SkEventQueue( + SK_AC *pAC, /* Adapters context */ +@@ -76,26 +93,45 @@ + SK_U32 Event, /* Event to be queued */ + SK_EVPARA Para) /* Event parameter */ + { +- pAC->Event.EvPut->Class = Class; +- pAC->Event.EvPut->Event = Event; +- pAC->Event.EvPut->Para = Para; ++ ++ if (pAC->GIni.GILevel == SK_INIT_DATA) { ++ SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E003, SKERR_Q_E003MSG); ++ } ++ else { ++ pAC->Event.EvPut->Class = Class; ++ pAC->Event.EvPut->Event = Event; ++ pAC->Event.EvPut->Para = Para; + +- if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT]) +- pAC->Event.EvPut = pAC->Event.EvQueue; ++ if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT]) ++ pAC->Event.EvPut = pAC->Event.EvQueue; + +- if (pAC->Event.EvPut == pAC->Event.EvGet) { +- SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG); ++ if (pAC->Event.EvPut == pAC->Event.EvGet) { ++ SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG); ++ } + } + } + +-/* +- * event dispatcher +- * while event queue is not empty +- * get event from queue +- * send command to state machine +- * end +- * return error reported by individual Event function +- * 0 if no error occured. ++/****************************************************************************** ++ * ++ * SkEventDispatcher() - Event Dispatcher ++ * ++ * Description: ++ * The event dispatcher performs the following operations: ++ * o while event queue is not empty ++ * - get event from queue ++ * - send event to state machine ++ * end ++ * ++ * CAUTION: ++ * The event functions MUST report an error if performing a reinitialization ++ * of the event queue, e.g. performing level Init 0..2 while in dispatcher ++ * call! ++ * ANY OTHER return value delays scheduling the other events in the ++ * queue. In this case the event blocks the queue until ++ * the error condition is cleared! ++ * ++ * Returns: ++ * The return value error reported by individual event function + */ + int SkEventDispatcher( + SK_AC *pAC, /* Adapters Context */ +@@ -105,6 +141,10 @@ + SK_U32 Class; + int Rtv; + ++ if (pAC->GIni.GILevel != SK_INIT_RUN) { ++ SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E005, SKERR_Q_E005MSG); ++ } ++ + pEv = pAC->Event.EvGet; + + PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put); +@@ -138,7 +178,7 @@ + Rtv = SkSwtEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; + #endif /* !SK_USE_SW_TIMER */ +-#ifdef SK_USE_LAC_EV ++#if defined(SK_USE_LAC_EV) || defined(SK_LBFO) + case SKGE_LACP : + Rtv = SkLacpEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; +@@ -152,6 +192,11 @@ + Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para); + break; + #endif /* SK_USE_LAC_EV */ ++#ifdef SK_ASF ++ case SKGE_ASF : ++ Rtv = SkAsfEvent(pAC,Ioc,pEv->Event,pEv->Para); ++ break ; ++#endif + #ifdef SK_USE_CSUM + case SKGE_CSUM : + Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para); +@@ -163,6 +208,20 @@ + } + + if (Rtv != 0) { ++ /* ++ * Special Case: See CAUTION statement above. ++ * We assume the event queue is reset. ++ */ ++ if (pAC->Event.EvGet != pAC->Event.EvQueue && ++ pAC->Event.EvGet != pEv) { ++ /* ++ * Create an error log entry if the ++ * event queue isn't reset. ++ * In this case it may be blocked. ++ */ ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E004, SKERR_Q_E004MSG); ++ } ++ + return(Rtv); + } + +diff -ruN linux/drivers/net/sk98lin/skrlmt.c linux-new/drivers/net/sk98lin/skrlmt.c +--- linux/drivers/net/sk98lin/skrlmt.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skrlmt.c 2007-01-24 14:03:40.000000000 +0100 +@@ -2,14 +2,15 @@ + * + * Name: skrlmt.c + * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Manage links on SK-NET Adapters, esp. redundant ones. + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. + * +@@ -19,6 +20,7 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -39,7 +41,7 @@ + + #ifndef lint + static const char SysKonnectFileId[] = +- "@(#) $Id$ (C) Marvell."; ++ "@(#) $Id$ (C) Marvell."; + #endif /* !defined(lint) */ + + #define __SKRLMT_C +@@ -282,6 +284,7 @@ + + SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}}; + SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}}; ++SK_MAC_ADDR BcAddr = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; + + /* local variables ************************************************************/ + +@@ -349,7 +352,7 @@ + SK_BOOL PhysicalAMacAddressSet; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, +- ("RLMT Init level %d.\n", Level)) ++ ("RLMT Init level %d.\n", Level)); + + switch (Level) { + case SK_INIT_DATA: /* Initialize data structures. */ +@@ -389,7 +392,7 @@ + + case SK_INIT_IO: /* GIMacsFound first available here. */ + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, +- ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound)) ++ ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound)); + + pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound; + +@@ -511,7 +514,7 @@ + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SkRlmtBuildCheckChain.\n")) ++ ("SkRlmtBuildCheckChain.\n")); + + NumMacsUp = 0; + +@@ -557,7 +560,7 @@ + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, + ("Port %d checks %d other ports: %2X.\n", i, + pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked, +- pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5])) ++ pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5])); + } + #endif /* DEBUG */ + +@@ -603,7 +606,7 @@ + if ((CheckSrc == 0) || (CheckDest == 0)) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR, + ("SkRlmtBuildPacket: Invalid %s%saddr.\n", +- (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : ""))) ++ (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : ""))); + } + #endif + +@@ -795,7 +798,7 @@ + + SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX, +- ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber)) ++ ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber)); + } + } + return; +@@ -834,7 +837,7 @@ + * Bring it up. + */ + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: Received on PortDown.\n")) ++ ("SkRlmtPacketReceive: Received on PortDown.\n")); + + pRPort->PortState = SK_RLMT_PS_GOING_UP; + pRPort->GuTimeStamp = SkOsGetTime(pAC); +@@ -848,7 +851,7 @@ + } /* PortDown && !SuspectTx */ + else if (pRPort->CheckingState & SK_RLMT_PCS_RX) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: Stop bringing port down.\n")) ++ ("SkRlmtPacketReceive: Stop bringing port down.\n")); + SkTimerStop(pAC, IoC, &pRPort->DownRxTimer); + pRPort->CheckingState &= ~SK_RLMT_PCS_RX; + /* pAC->Rlmt.CheckSwitch = SK_TRUE; */ +@@ -895,7 +898,7 @@ + pRPort = &pAC->Rlmt.Port[PortNumber]; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber)) ++ ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber)); + + pRPacket = (SK_RLMT_PACKET*)pMb->pData; + pSPacket = (SK_SPTREE_PACKET*)pRPacket; +@@ -916,7 +919,7 @@ + + /* Not sent to current MAC or registered MC address => Trash it. */ + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: Not for me.\n")) ++ ("SkRlmtPacketReceive: Not for me.\n")); + + SkDrvFreeRlmtMbuf(pAC, IoC, pMb); + return; +@@ -954,7 +957,7 @@ + pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 && + pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: Duplicate MAC Address.\n")) ++ ("SkRlmtPacketReceive: Duplicate MAC Address.\n")); + + /* Error Log entry. */ + SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG); +@@ -962,7 +965,7 @@ + else { + /* Simply trash it. */ + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: Sent by me.\n")) ++ ("SkRlmtPacketReceive: Sent by me.\n")); + } + + SkDrvFreeRlmtMbuf(pAC, IoC, pMb); +@@ -1006,7 +1009,7 @@ + #endif /* 0 */ + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: Announce.\n")) ++ ("SkRlmtPacketReceive: Announce.\n")); + + SkDrvFreeRlmtMbuf(pAC, IoC, pMb); + break; +@@ -1014,7 +1017,7 @@ + case SK_PACKET_ALIVE: + if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: Alive Reply.\n")) ++ ("SkRlmtPacketReceive: Alive Reply.\n")); + + if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) || + SK_ADDR_EQUAL( +@@ -1045,7 +1048,7 @@ + } + else { /* Alive Request Packet. */ + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: Alive Request.\n")) ++ ("SkRlmtPacketReceive: Alive Request.\n")); + + pRPort->RxHelloCts++; + +@@ -1064,7 +1067,7 @@ + + case SK_PACKET_CHECK_TX: + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: Check your tx line.\n")) ++ ("SkRlmtPacketReceive: Check your tx line.\n")); + + /* A port checking us requests us to check our tx line. */ + pRPort->CheckingState |= SK_RLMT_PCS_TX; +@@ -1087,7 +1090,7 @@ + + case SK_PACKET_ADDR_CHANGED: + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: Address Change.\n")) ++ ("SkRlmtPacketReceive: Address Change.\n")); + + /* Build the check chain. */ + SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber); +@@ -1096,7 +1099,7 @@ + + default: + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: Unknown RLMT packet.\n")) ++ ("SkRlmtPacketReceive: Unknown RLMT packet.\n")); + + /* RA;:;: ??? */ + SkDrvFreeRlmtMbuf(pAC, IoC, pMb); +@@ -1106,7 +1109,7 @@ + pSPacket->Ctrl == SK_RLMT_SPT_CTRL && + (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: BPDU Packet.\n")) ++ ("SkRlmtPacketReceive: BPDU Packet.\n")); + + /* Spanning Tree packet. */ + pRPort->RxSpHelloCts++; +@@ -1138,7 +1141,7 @@ + pRPort->Root.Id[0], pRPort->Root.Id[1], + pRPort->Root.Id[2], pRPort->Root.Id[3], + pRPort->Root.Id[4], pRPort->Root.Id[5], +- pRPort->Root.Id[6], pRPort->Root.Id[7])) ++ pRPort->Root.Id[6], pRPort->Root.Id[7])); + } + + SkDrvFreeRlmtMbuf(pAC, IoC, pMb); +@@ -1149,7 +1152,7 @@ + } + else { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, +- ("SkRlmtPacketReceive: Unknown Packet Type.\n")) ++ ("SkRlmtPacketReceive: Unknown Packet Type.\n")); + + /* Unknown packet. */ + SkDrvFreeRlmtMbuf(pAC, IoC, pMb); +@@ -1231,7 +1234,7 @@ + if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, + ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n", +- PortNumber, pRPort->PacketsPerTimeSlot)) ++ PortNumber, pRPort->PacketsPerTimeSlot)); + + /* + * Check segmentation if there was no receive at least twice +@@ -1248,7 +1251,7 @@ + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, + ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n", +- pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX)) ++ pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX)); + + if (pRPort->PortState != SK_RLMT_PS_DOWN) { + NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue); +@@ -1294,7 +1297,7 @@ + ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n", + PortNumber, + pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot, +- pRPort->PacketsPerTimeSlot)) ++ pRPort->PacketsPerTimeSlot)); + + SkRlmtPortReceives(pAC, IoC, PortNumber); + if (pAC->Rlmt.CheckSwitch) { +@@ -1344,7 +1347,7 @@ + i, + pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx, + *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32), +- *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32))) ++ *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32))); + + if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) { + if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) { +@@ -1357,7 +1360,7 @@ + + if (PortFound) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Port %d received the last broadcast.\n", *pSelect)) ++ ("Port %d received the last broadcast.\n", *pSelect)); + + /* Look if another port's time stamp is similar. */ + for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { +@@ -1372,7 +1375,7 @@ + PortFound = SK_FALSE; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Port %d received a broadcast at a similar time.\n", i)) ++ ("Port %d received a broadcast at a similar time.\n", i)); + break; + } + } +@@ -1384,7 +1387,7 @@ + ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially " + "latest broadcast (%u).\n", + *pSelect, +- BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp)) ++ BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp)); + } + #endif /* DEBUG */ + +@@ -1433,7 +1436,7 @@ + PortFound = SK_TRUE; + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, + ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n", +- *pSelect)) ++ *pSelect)); + break; + } + } +@@ -1482,7 +1485,7 @@ + } + PortFound = SK_TRUE; + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect)) ++ ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect)); + break; + } + } +@@ -1543,7 +1546,7 @@ + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect)) ++ ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect)); + return (SK_TRUE); + } /* SkRlmtSelectGoingUp */ + +@@ -1589,7 +1592,7 @@ + } + PortFound = SK_TRUE; + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect)) ++ ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect)); + break; + } + } +@@ -1679,16 +1682,19 @@ + Para.Para32[1] = NetIdx; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para); + +- if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 && +- (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, +- pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber, +- SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx]. +- CurrentMacAddress, &SkRlmtMcAddr)) != NULL) { +- /* +- * Send announce packet to RLMT multicast address to force +- * switches to learn the new location of the logical MAC address. +- */ +- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); ++ if (pAC->Rlmt.NumNets == 1) { ++ if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 && ++ (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, ++ pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber, ++ SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx]. ++ CurrentMacAddress, &SkRlmtMcAddr)) != NULL) { ++ ++ /* ++ * Send announce packet to RLMT multicast address to force ++ * switches to learn the new location of the logical MAC address. ++ */ ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); ++ } + } + } + else { +@@ -1787,7 +1793,7 @@ + + if (Para.Para32[1] != Active) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Active: %d, Para1: %d.\n", Active, Para.Para32[1])) ++ ("Active: %d, Para1: %d.\n", Active, Para.Para32[1])); + pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1]; + Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. + Port[Para.Para32[0]]->PortNumber; +@@ -1867,7 +1873,7 @@ + pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1], + pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3], + pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5], +- pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7])) ++ pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7])); + + if (!pNet->RootIdSet) { + pNet->Root = pNet->Port[i]->Root; +@@ -1962,13 +1968,13 @@ + SK_U32 i; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0])) ++ ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0])); + + if (Para.Para32[1] != (SK_U32)-1) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad Parameter.\n")) ++ ("Bad Parameter.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n")) ++ ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n")); + return; + } + +@@ -1989,7 +1995,7 @@ + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n")) ++ ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n")); + } /* SkRlmtEvtPortStartTim */ + + +@@ -2017,21 +2023,21 @@ + SK_EVPARA Para2; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0])) ++ ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0])); + + pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; + if (!pRPort->PortStarted) { + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG); + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_LINK_UP Event EMPTY.\n")) ++ ("SK_RLMT_LINK_UP Event EMPTY.\n")); + return; + } + + if (!pRPort->LinkDown) { + /* RA;:;: Any better solution? */ + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_LINK_UP Event EMPTY.\n")) ++ ("SK_RLMT_LINK_UP Event EMPTY.\n")); + return; + } + +@@ -2081,16 +2087,19 @@ + Para2.Para32[1] = (SK_U32)-1; + SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL, + SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2); +- ++ + /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */ +- if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 && +- (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 && +- (Para2.pParaPtr = +- SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE, +- &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr) +- ) != NULL) { +- /* Send "new" packet to RLMT multicast address. */ +- SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); ++ if (pAC->Rlmt.NumNets == 1) { ++ if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 && ++ (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 && ++ (Para2.pParaPtr = ++ SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE, ++ &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr) ++ ) != NULL) { ++ ++ /* Send "new" packet to RLMT multicast address. */ ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); ++ } + } + + if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) { +@@ -2109,7 +2118,7 @@ + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_LINK_UP Event END.\n")) ++ ("SK_RLMT_LINK_UP Event END.\n")); + } /* SkRlmtEvtLinkUp */ + + +@@ -2135,20 +2144,20 @@ + SK_RLMT_PORT *pRPort; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0])) ++ ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0])); + + if (Para.Para32[1] != (SK_U32)-1) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad Parameter.\n")) ++ ("Bad Parameter.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORTUP_TIM Event EMPTY.\n")) ++ ("SK_RLMT_PORTUP_TIM Event EMPTY.\n")); + return; + } + + pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; + if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0])) ++ ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0])); + return; + } + +@@ -2163,7 +2172,7 @@ + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORTUP_TIM Event END.\n")) ++ ("SK_RLMT_PORTUP_TIM Event END.\n")); + } /* SkRlmtEvtPortUpTim */ + + +@@ -2191,13 +2200,13 @@ + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, + ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n", +- Para.Para32[0], Event)) ++ Para.Para32[0], Event)); + + if (Para.Para32[1] != (SK_U32)-1) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad Parameter.\n")) ++ ("Bad Parameter.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORTDOWN* Event EMPTY.\n")) ++ ("SK_RLMT_PORTDOWN* Event EMPTY.\n")); + return; + } + +@@ -2205,7 +2214,7 @@ + if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM && + !(pRPort->CheckingState & SK_RLMT_PCS_TX))) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event)) ++ ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event)); + return; + } + +@@ -2242,7 +2251,7 @@ + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event)) ++ ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event)); + } /* SkRlmtEvtPortDownX */ + + +@@ -2269,7 +2278,7 @@ + + pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0])) ++ ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0])); + + if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) { + pRPort->Net->LinksUp--; +@@ -2288,7 +2297,7 @@ + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_LINK_DOWN Event END.\n")) ++ ("SK_RLMT_LINK_DOWN Event END.\n")); + } /* SkRlmtEvtLinkDown */ + + +@@ -2317,13 +2326,13 @@ + SK_MAC_ADDR *pNewMacAddr; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0])) ++ ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0])); + + if (Para.Para32[1] != (SK_U32)-1) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad Parameter.\n")) ++ ("Bad Parameter.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORT_ADDR Event EMPTY.\n")) ++ ("SK_RLMT_PORT_ADDR Event EMPTY.\n")); + return; + } + +@@ -2347,7 +2356,7 @@ + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PORT_ADDR Event END.\n")) ++ ("SK_RLMT_PORT_ADDR Event END.\n")); + } /* SkRlmtEvtPortAddr */ + + +@@ -2375,35 +2384,35 @@ + SK_U32 PortNumber; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0])) ++ ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0])); + + if (Para.Para32[1] != (SK_U32)-1) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad Parameter.\n")) ++ ("Bad Parameter.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_START Event EMPTY.\n")) ++ ("SK_RLMT_START Event EMPTY.\n")); + return; + } + + if (Para.Para32[0] >= pAC->Rlmt.NumNets) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad NetNumber %d.\n", Para.Para32[0])) ++ ("Bad NetNumber %d.\n", Para.Para32[0])); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_START Event EMPTY.\n")) ++ ("SK_RLMT_START Event EMPTY.\n")); + return; + } + + if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_START Event EMPTY.\n")) ++ ("SK_RLMT_START Event EMPTY.\n")); + return; + } + + if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("All nets should have been started.\n")) ++ ("All nets should have been started.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_START Event EMPTY.\n")) ++ ("SK_RLMT_START Event EMPTY.\n")); + return; + } + +@@ -2437,7 +2446,7 @@ + pAC->Rlmt.NetsStarted++; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_START Event END.\n")) ++ ("SK_RLMT_START Event END.\n")); + } /* SkRlmtEvtStart */ + + +@@ -2465,35 +2474,35 @@ + SK_U32 i; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0])) ++ ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0])); + + if (Para.Para32[1] != (SK_U32)-1) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad Parameter.\n")) ++ ("Bad Parameter.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STOP Event EMPTY.\n")) ++ ("SK_RLMT_STOP Event EMPTY.\n")); + return; + } + + if (Para.Para32[0] >= pAC->Rlmt.NumNets) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad NetNumber %d.\n", Para.Para32[0])) ++ ("Bad NetNumber %d.\n", Para.Para32[0])); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STOP Event EMPTY.\n")) ++ ("SK_RLMT_STOP Event EMPTY.\n")); + return; + } + + if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STOP Event EMPTY.\n")) ++ ("SK_RLMT_STOP Event EMPTY.\n")); + return; + } + + if (pAC->Rlmt.NetsStarted == 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("All nets are stopped.\n")) ++ ("All nets are stopped.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STOP Event EMPTY.\n")) ++ ("SK_RLMT_STOP Event EMPTY.\n")); + return; + } + +@@ -2528,7 +2537,7 @@ + pAC->Rlmt.NetsStarted--; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STOP Event END.\n")) ++ ("SK_RLMT_STOP Event END.\n")); + } /* SkRlmtEvtStop */ + + +@@ -2558,13 +2567,13 @@ + SK_U32 i; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_TIM Event BEGIN.\n")) ++ ("SK_RLMT_TIM Event BEGIN.\n")); + + if (Para.Para32[1] != (SK_U32)-1) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad Parameter.\n")) ++ ("Bad Parameter.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_TIM Event EMPTY.\n")) ++ ("SK_RLMT_TIM Event EMPTY.\n")); + return; + } + +@@ -2636,7 +2645,7 @@ + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_TIM Event END.\n")) ++ ("SK_RLMT_TIM Event END.\n")); + } /* SkRlmtEvtTim */ + + +@@ -2664,13 +2673,13 @@ + #endif /* DEBUG */ + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SEG_TIM Event BEGIN.\n")) ++ ("SK_RLMT_SEG_TIM Event BEGIN.\n")); + + if (Para.Para32[1] != (SK_U32)-1) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad Parameter.\n")) ++ ("Bad Parameter.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SEG_TIM Event EMPTY.\n")) ++ ("SK_RLMT_SEG_TIM Event EMPTY.\n")); + return; + } + +@@ -2694,7 +2703,7 @@ + InAddr8[3], InAddr8[4], InAddr8[5], + pAPort->Exact[k].a[0], pAPort->Exact[k].a[1], + pAPort->Exact[k].a[2], pAPort->Exact[k].a[3], +- pAPort->Exact[k].a[4], pAPort->Exact[k].a[5])) ++ pAPort->Exact[k].a[4], pAPort->Exact[k].a[5])); + } + } + #endif /* xDEBUG */ +@@ -2702,7 +2711,7 @@ + SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]); + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SEG_TIM Event END.\n")) ++ ("SK_RLMT_SEG_TIM Event END.\n")); + } /* SkRlmtEvtSegTim */ + + +@@ -2731,18 +2740,18 @@ + + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n")) ++ ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n")); + + /* Should we ignore frames during port switching? */ + + #ifdef DEBUG + pMb = Para.pParaPtr; + if (pMb == NULL) { +- SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n")) ++ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n")); + } + else if (pMb->pNext != NULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("More than one mbuf or pMb->pNext not set.\n")) ++ ("More than one mbuf or pMb->pNext not set.\n")); + } + #endif /* DEBUG */ + +@@ -2760,7 +2769,7 @@ + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PACKET_RECEIVED Event END.\n")) ++ ("SK_RLMT_PACKET_RECEIVED Event END.\n")); + } /* SkRlmtEvtPacketRx */ + + +@@ -2787,21 +2796,21 @@ + SK_RLMT_PORT *pRPort; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STATS_CLEAR Event BEGIN.\n")) ++ ("SK_RLMT_STATS_CLEAR Event BEGIN.\n")); + + if (Para.Para32[1] != (SK_U32)-1) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad Parameter.\n")) ++ ("Bad Parameter.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STATS_CLEAR Event EMPTY.\n")) ++ ("SK_RLMT_STATS_CLEAR Event EMPTY.\n")); + return; + } + + if (Para.Para32[0] >= pAC->Rlmt.NumNets) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad NetNumber %d.\n", Para.Para32[0])) ++ ("Bad NetNumber %d.\n", Para.Para32[0])); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STATS_CLEAR Event EMPTY.\n")) ++ ("SK_RLMT_STATS_CLEAR Event EMPTY.\n")); + return; + } + +@@ -2816,7 +2825,7 @@ + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STATS_CLEAR Event END.\n")) ++ ("SK_RLMT_STATS_CLEAR Event END.\n")); + } /* SkRlmtEvtStatsClear */ + + +@@ -2840,28 +2849,28 @@ + SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ + { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STATS_UPDATE Event BEGIN.\n")) ++ ("SK_RLMT_STATS_UPDATE Event BEGIN.\n")); + + if (Para.Para32[1] != (SK_U32)-1) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad Parameter.\n")) ++ ("Bad Parameter.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STATS_UPDATE Event EMPTY.\n")) ++ ("SK_RLMT_STATS_UPDATE Event EMPTY.\n")); + return; + } + + if (Para.Para32[0] >= pAC->Rlmt.NumNets) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad NetNumber %d.\n", Para.Para32[0])) ++ ("Bad NetNumber %d.\n", Para.Para32[0])); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STATS_UPDATE Event EMPTY.\n")) ++ ("SK_RLMT_STATS_UPDATE Event EMPTY.\n")); + return; + } + + /* Update statistics - currently always up-to-date. */ + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_STATS_UPDATE Event END.\n")) ++ ("SK_RLMT_STATS_UPDATE Event END.\n")); + } /* SkRlmtEvtStatsUpdate */ + + +@@ -2885,13 +2894,13 @@ + SK_EVPARA Para) /* SK_U32 PortIndex; SK_U32 NetNumber */ + { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0])) ++ ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0])); + + if (Para.Para32[1] >= pAC->Rlmt.NumNets) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad NetNumber %d.\n", Para.Para32[1])) ++ ("Bad NetNumber %d.\n", Para.Para32[1])); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n")) ++ ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n")); + return; + } + +@@ -2904,7 +2913,7 @@ + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG); + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n")) ++ ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n")); + return; + } + +@@ -2918,7 +2927,7 @@ + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_PREFPORT_CHANGE Event END.\n")) ++ ("SK_RLMT_PREFPORT_CHANGE Event END.\n")); + } /* SkRlmtEvtPrefportChange */ + + +@@ -2944,37 +2953,37 @@ + int i; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SET_NETS Event BEGIN.\n")) ++ ("SK_RLMT_SET_NETS Event BEGIN.\n")); + + if (Para.Para32[1] != (SK_U32)-1) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad Parameter.\n")) ++ ("Bad Parameter.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SET_NETS Event EMPTY.\n")) ++ ("SK_RLMT_SET_NETS Event EMPTY.\n")); + return; + } + + if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS || + Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad number of nets: %d.\n", Para.Para32[0])) ++ ("Bad number of nets: %d.\n", Para.Para32[0])); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SET_NETS Event EMPTY.\n")) ++ ("SK_RLMT_SET_NETS Event EMPTY.\n")); + return; + } + + if (Para.Para32[0] == pAC->Rlmt.NumNets) { /* No change. */ + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SET_NETS Event EMPTY.\n")) ++ ("SK_RLMT_SET_NETS Event EMPTY.\n")); + return; + } + + /* Entering and leaving dual mode only allowed while nets are stopped. */ + if (pAC->Rlmt.NetsStarted > 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Changing dual mode only allowed while all nets are stopped.\n")) ++ ("Changing dual mode only allowed while all nets are stopped.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SET_NETS Event EMPTY.\n")) ++ ("SK_RLMT_SET_NETS Event EMPTY.\n")); + return; + } + +@@ -3005,9 +3014,10 @@ + SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para); + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("RLMT: Changed to one net with two ports.\n")) ++ ("RLMT: Changed to one net with two ports.\n")); + } + else if (Para.Para32[0] == 2) { ++ pAC->Rlmt.RlmtOff = SK_TRUE; + pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1]; + pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1; + pAC->Rlmt.Net[0].NumPorts = +@@ -3034,19 +3044,19 @@ + SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para); + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("RLMT: Changed to two nets with one port each.\n")) ++ ("RLMT: Changed to two nets with one port each.\n")); + } + else { + /* Not implemented for more than two nets. */ + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SetNets not implemented for more than two nets.\n")) ++ ("SetNets not implemented for more than two nets.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SET_NETS Event EMPTY.\n")) ++ ("SK_RLMT_SET_NETS Event EMPTY.\n")); + return; + } + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_SET_NETS Event END.\n")) ++ ("SK_RLMT_SET_NETS Event END.\n")); + } /* SkRlmtSetNets */ + + +@@ -3074,13 +3084,13 @@ + SK_U32 PrevRlmtMode; + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_MODE_CHANGE Event BEGIN.\n")) ++ ("SK_RLMT_MODE_CHANGE Event BEGIN.\n")); + + if (Para.Para32[1] >= pAC->Rlmt.NumNets) { + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Bad NetNumber %d.\n", Para.Para32[1])) ++ ("Bad NetNumber %d.\n", Para.Para32[1])); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_MODE_CHANGE Event EMPTY.\n")) ++ ("SK_RLMT_MODE_CHANGE Event EMPTY.\n")); + return; + } + +@@ -3090,9 +3100,9 @@ + Para.Para32[0] != SK_RLMT_MODE_CLS) { + pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS; + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Forced RLMT mode to CLS on single port net.\n")) ++ ("Forced RLMT mode to CLS on single port net.\n")); + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_MODE_CHANGE Event EMPTY.\n")) ++ ("SK_RLMT_MODE_CHANGE Event EMPTY.\n")); + return; + } + +@@ -3158,7 +3168,7 @@ + } /* SK_RLMT_CHECK_SEG bit changed. */ + + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("SK_RLMT_MODE_CHANGE Event END.\n")) ++ ("SK_RLMT_MODE_CHANGE Event END.\n")); + } /* SkRlmtEvtModeChange */ + + +@@ -3244,7 +3254,7 @@ + + default: /* Create error log entry. */ + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, +- ("Unknown RLMT Event %d.\n", Event)) ++ ("Unknown RLMT Event %d.\n", Event)); + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG); + break; + } /* switch() */ +diff -ruN linux/drivers/net/sk98lin/sktimer.c linux-new/drivers/net/sk98lin/sktimer.c +--- linux/drivers/net/sk98lin/sktimer.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/sktimer.c 2007-01-24 13:58:33.000000000 +0100 +@@ -2,16 +2,17 @@ + * + * Name: sktimer.c + * Project: Gigabit Ethernet Adapters, Event Scheduler Module +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: High level timer functions. + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect GmbH. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2004 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 +@@ -19,16 +20,16 @@ + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. ++ * /LICENSE + * + ******************************************************************************/ + +- + /* + * Event queue and dispatcher + */ + #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) + static const char SysKonnectFileId[] = +- "@(#) $Id$ (C) Marvell."; ++ "@(#) $Id$ (C) Marvell."; + #endif + + #include "h/skdrv1st.h" /* Driver Specific Definitions */ +@@ -62,7 +63,7 @@ + { + switch (Level) { + case SK_INIT_DATA: +- pAC->Tim.StQueue = NULL; ++ pAC->Tim.StQueue = 0; + break; + case SK_INIT_IO: + SkHwtInit(pAC, Ioc); +@@ -85,22 +86,20 @@ + SK_TIMER **ppTimPrev; + SK_TIMER *pTm; + +- /* +- * remove timer from queue +- */ ++ /* remove timer from queue */ + pTimer->TmActive = SK_FALSE; +- ++ + if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) { + SkHwtStop(pAC, Ioc); + } +- ++ + for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev); + ppTimPrev = &pTm->TmNext ) { +- ++ + if (pTm == pTimer) { + /* + * Timer found in queue +- * - dequeue it and ++ * - dequeue it + * - correct delta of the next timer + */ + *ppTimPrev = pTm->TmNext; +@@ -121,7 +120,7 @@ + SK_AC *pAC, /* Adapters context */ + SK_IOC Ioc, /* IoContext */ + SK_TIMER *pTimer, /* Timer Pointer to be started */ +-SK_U32 Time, /* Time value */ ++SK_U32 Time, /* Time Value (in microsec.) */ + SK_U32 Class, /* Event Class for this timer */ + SK_U32 Event, /* Event Value for this timer */ + SK_EVPARA Para) /* Event Parameter for this timer */ +@@ -130,11 +129,6 @@ + SK_TIMER *pTm; + SK_U32 Delta; + +- Time /= 16; /* input is uS, clock ticks are 16uS */ +- +- if (!Time) +- Time = 1; +- + SkTimerStop(pAC, Ioc, pTimer); + + pTimer->TmClass = Class; +@@ -143,31 +137,26 @@ + pTimer->TmActive = SK_TRUE; + + if (!pAC->Tim.StQueue) { +- /* First Timer to be started */ ++ /* first Timer to be started */ + pAC->Tim.StQueue = pTimer; +- pTimer->TmNext = NULL; ++ pTimer->TmNext = 0; + pTimer->TmDelta = Time; +- ++ + SkHwtStart(pAC, Ioc, Time); +- ++ + return; + } + +- /* +- * timer correction +- */ ++ /* timer correction */ + timer_done(pAC, Ioc, 0); + +- /* +- * find position in queue +- */ ++ /* find position in queue */ + Delta = 0; + for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev); + ppTimPrev = &pTm->TmNext ) { +- ++ + if (Delta + pTm->TmDelta > Time) { +- /* Position found */ +- /* Here the timer needs to be inserted. */ ++ /* the timer needs to be inserted here */ + break; + } + Delta += pTm->TmDelta; +@@ -179,9 +168,7 @@ + pTimer->TmDelta = Time - Delta; + + if (pTm) { +- /* There is a next timer +- * -> correct its Delta value. +- */ ++ /* there is a next timer: correct its Delta value */ + pTm->TmDelta -= pTimer->TmDelta; + } + +@@ -210,7 +197,7 @@ + int Done = 0; + + Delta = SkHwtRead(pAC, Ioc); +- ++ + ppLast = &pAC->Tim.StQueue; + pTm = pAC->Tim.StQueue; + while (pTm && !Done) { +@@ -228,13 +215,13 @@ + Done = 1; + } + } +- *ppLast = NULL; ++ *ppLast = 0; + /* + * pTm points to the first Timer that did not run out. + * StQueue points to the first Timer that run out. + */ + +- for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) { ++ for (pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) { + SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara); + } + +diff -ruN linux/drivers/net/sk98lin/sktwsi.c linux-new/drivers/net/sk98lin/sktwsi.c +--- linux/drivers/net/sk98lin/sktwsi.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/sktwsi.c 2007-01-24 14:03:40.000000000 +0100 +@@ -0,0 +1,1362 @@ ++/****************************************************************************** ++ * ++ * Name: sktwsi.c ++ * Project: Gigabit Ethernet Adapters, TWSI-Module ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Functions to access Voltage and Temperature Sensor ++ * ++ ******************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * LICENSE: ++ * (C)Copyright 1998-2002 SysKonnect. ++ * (C)Copyright 2002-2006 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. ++ * /LICENSE ++ * ++ ******************************************************************************/ ++ ++/* ++ * TWSI Protocol ++ */ ++#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) ++static const char SysKonnectFileId[] = ++ "@(#) $Id$ (C) Marvell."; ++#endif ++ ++#include "h/skdrv1st.h" /* Driver Specific Definitions */ ++#include "h/lm80.h" ++#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ ++ ++#ifdef __C2MAN__ ++/* ++ TWSI protocol implementation. ++ ++ General Description: ++ ++ The TWSI protocol is used for the temperature sensors and for ++ the serial EEPROM which hold the configuration. ++ ++ This file covers functions that allow to read write and do ++ some bulk requests a specified TWSI address. ++ ++ The Genesis has 2 TWSI buses. One for the EEPROM which holds ++ the VPD Data and one for temperature and voltage sensor. ++ The following picture shows the TWSI buses, TWSI devices and ++ their control registers. ++ ++ Note: The VPD functions are in skvpd.c ++. ++. PCI Config TWSI Bus for VPD Data: ++. ++. +------------+ ++. | VPD EEPROM | ++. +------------+ ++. | ++. | <-- TWSI ++. | ++. +-----------+-----------+ ++. | | ++. +-----------------+ +-----------------+ ++. | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG | ++. +-----------------+ +-----------------+ ++. ++. ++. TWSI Bus for LM80 sensor: ++. ++. +-----------------+ ++. | Temperature and | ++. | Voltage Sensor | ++. | LM80 | ++. +-----------------+ ++. | ++. | ++. TWSI --> | ++. | ++. +----+ ++. +-------------->| OR |<--+ ++. | +----+ | ++. +------+------+ | ++. | | | ++. +--------+ +--------+ +----------+ ++. | B2_I2C | | B2_I2C | | B2_I2C | ++. | _CTRL | | _DATA | | _SW | ++. +--------+ +--------+ +----------+ ++. ++ The TWSI bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL ++ and B2_I2C_DATA registers. ++ For driver software it is recommended to use the TWSI control and ++ data register, because TWSI bus timing is done by the ASIC and ++ an interrupt may be received when the TWSI request is completed. ++ ++ Clock Rate Timing: MIN MAX generated by ++ VPD EEPROM: 50 kHz 100 kHz HW ++ LM80 over TWSI Ctrl/Data reg. 50 kHz 100 kHz HW ++ LM80 over B2_I2C_SW register 0 400 kHz SW ++ ++ Note: The clock generated by the hardware is dependend on the ++ PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD ++ clock is 50 kHz. ++ */ ++intro() ++{} ++#endif ++ ++#ifdef SK_DIAG ++/* ++ * TWSI Fast Mode timing values used by the LM80. ++ * If new devices are added to the TWSI bus the timing values have to be checked. ++ */ ++#ifndef I2C_SLOW_TIMING ++#define T_CLK_LOW 1300L /* clock low time in ns */ ++#define T_CLK_HIGH 600L /* clock high time in ns */ ++#define T_DATA_IN_SETUP 100L /* data in Set-up Time */ ++#define T_START_HOLD 600L /* start condition hold time */ ++#define T_START_SETUP 600L /* start condition Set-up time */ ++#define T_STOP_SETUP 600L /* stop condition Set-up time */ ++#define T_BUS_IDLE 1300L /* time the bus must free after Tx */ ++#define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */ ++#else /* I2C_SLOW_TIMING */ ++/* TWSI Standard Mode Timing */ ++#define T_CLK_LOW 4700L /* clock low time in ns */ ++#define T_CLK_HIGH 4000L /* clock high time in ns */ ++#define T_DATA_IN_SETUP 250L /* data in Set-up Time */ ++#define T_START_HOLD 4000L /* start condition hold time */ ++#define T_START_SETUP 4700L /* start condition Set-up time */ ++#define T_STOP_SETUP 4000L /* stop condition Set-up time */ ++#define T_BUS_IDLE 4700L /* time the bus must free after Tx */ ++#endif /* !I2C_SLOW_TIMING */ ++ ++#define NS2BCLK(x) (((x)*125)/10000) ++ ++/* ++ * TWSI Wire Operations ++ * ++ * About I2C_CLK_LOW(): ++ * ++ * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting ++ * clock to low, to prevent the ASIC and the TWSI data client from driving the ++ * serial data line simultaneously (ASIC: last bit of a byte = '1', TWSI client ++ * send an 'ACK'). See also Concentrator Bugreport No. 10192. ++ */ ++#define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA) ++#define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA) ++#define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR) ++#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA) ++#define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK) ++#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR) ++#define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK) ++ ++#define NS2CLKT(x) ((x*125L)/10000) ++ ++/*--------------- TWSI Interface Register Functions --------------- */ ++ ++/* ++ * sending one bit ++ */ ++void SkI2cSndBit( ++SK_IOC IoC, /* I/O Context */ ++SK_U8 Bit) /* Bit to send */ ++{ ++ I2C_DATA_OUT(IoC); ++ if (Bit) { ++ I2C_DATA_HIGH(IoC); ++ } ++ else { ++ I2C_DATA_LOW(IoC); ++ } ++ SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP)); ++ I2C_CLK_HIGH(IoC); ++ SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH)); ++ I2C_CLK_LOW(IoC); ++} /* SkI2cSndBit*/ ++ ++ ++/* ++ * Signal a start to the TWSI Bus. ++ * ++ * A start is signaled when data goes to low in a high clock cycle. ++ * ++ * Ends with Clock Low. ++ * ++ * Status: not tested ++ */ ++void SkI2cStart( ++SK_IOC IoC) /* I/O Context */ ++{ ++ /* Init data and Clock to output lines */ ++ /* Set Data high */ ++ I2C_DATA_OUT(IoC); ++ I2C_DATA_HIGH(IoC); ++ /* Set Clock high */ ++ I2C_CLK_HIGH(IoC); ++ ++ SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP)); ++ ++ /* Set Data Low */ ++ I2C_DATA_LOW(IoC); ++ ++ SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD)); ++ ++ /* Clock low without Data to Input */ ++ I2C_START_COND(IoC); ++ ++ SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW)); ++} /* SkI2cStart */ ++ ++ ++void SkI2cStop( ++SK_IOC IoC) /* I/O Context */ ++{ ++ /* Init data and Clock to output lines */ ++ /* Set Data low */ ++ I2C_DATA_OUT(IoC); ++ I2C_DATA_LOW(IoC); ++ ++ SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT)); ++ ++ /* Set Clock high */ ++ I2C_CLK_HIGH(IoC); ++ ++ SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP)); ++ ++ /* ++ * Set Data High: Do it by setting the Data Line to Input. ++ * Because of a pull up resistor the Data Line ++ * floods to high. ++ */ ++ I2C_DATA_IN(IoC); ++ ++ /* ++ * When TWSI activity is stopped ++ * o DATA should be set to input and ++ * o CLOCK should be set to high! ++ */ ++ SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE)); ++} /* SkI2cStop */ ++ ++ ++/* ++ * Receive just one bit via the TWSI bus. ++ * ++ * Note: Clock must be set to LOW before calling this function. ++ * ++ * Returns The received bit. ++ */ ++int SkI2cRcvBit( ++SK_IOC IoC) /* I/O Context */ ++{ ++ int Bit; ++ SK_U8 I2cSwCtrl; ++ ++ /* Init data as input line */ ++ I2C_DATA_IN(IoC); ++ ++ SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT)); ++ ++ I2C_CLK_HIGH(IoC); ++ ++ SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH)); ++ ++ SK_I2C_GET_SW(IoC, &I2cSwCtrl); ++ ++ Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0; ++ ++ I2C_CLK_LOW(IoC); ++ SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT)); ++ ++ return(Bit); ++} /* SkI2cRcvBit */ ++ ++ ++/* ++ * Receive an ACK. ++ * ++ * returns 0 If acknowledged ++ * 1 in case of an error ++ */ ++int SkI2cRcvAck( ++SK_IOC IoC) /* I/O Context */ ++{ ++ /* ++ * Received bit must be zero. ++ */ ++ return(SkI2cRcvBit(IoC) != 0); ++} /* SkI2cRcvAck */ ++ ++ ++/* ++ * Send an NACK. ++ */ ++void SkI2cSndNAck( ++SK_IOC IoC) /* I/O Context */ ++{ ++ /* ++ * Received bit must be zero. ++ */ ++ SkI2cSndBit(IoC, 1); ++} /* SkI2cSndNAck */ ++ ++ ++/* ++ * Send an ACK. ++ */ ++void SkI2cSndAck( ++SK_IOC IoC) /* I/O Context */ ++{ ++ /* ++ * Received bit must be zero. ++ */ ++ SkI2cSndBit(IoC, 0); ++} /* SkI2cSndAck */ ++ ++ ++/* ++ * Send one byte to the TWSI device and wait for ACK. ++ * ++ * Return acknowleged status. ++ */ ++int SkI2cSndByte( ++SK_IOC IoC, /* I/O Context */ ++int Byte) /* byte to send */ ++{ ++ int i; ++ ++ for (i = 0; i < 8; i++) { ++ if (Byte & (1<<(7-i))) { ++ SkI2cSndBit(IoC, 1); ++ } ++ else { ++ SkI2cSndBit(IoC, 0); ++ } ++ } ++ ++ return(SkI2cRcvAck(IoC)); ++} /* SkI2cSndByte */ ++ ++ ++/* ++ * Receive one byte and ack it. ++ * ++ * Return byte. ++ */ ++int SkI2cRcvByte( ++SK_IOC IoC, /* I/O Context */ ++int Last) /* Last Byte Flag */ ++{ ++ int i; ++ int Byte = 0; ++ ++ for (i = 0; i < 8; i++) { ++ Byte <<= 1; ++ Byte |= SkI2cRcvBit(IoC); ++ } ++ ++ if (Last) { ++ SkI2cSndNAck(IoC); ++ } ++ else { ++ SkI2cSndAck(IoC); ++ } ++ ++ return(Byte); ++} /* SkI2cRcvByte */ ++ ++ ++/* ++ * Start dialog and send device address ++ * ++ * Return 0 if acknowleged, 1 in case of an error ++ */ ++int SkI2cSndDev( ++SK_IOC IoC, /* I/O Context */ ++int Addr, /* Device Address */ ++int Rw) /* Read / Write Flag */ ++{ ++ SkI2cStart(IoC); ++ Rw = ~Rw; ++ Rw &= I2C_WRITE; ++ return(SkI2cSndByte(IoC, (Addr << 1) | Rw)); ++} /* SkI2cSndDev */ ++ ++#endif /* SK_DIAG */ ++ ++/*----------------- TWSI CTRL Register Functions ----------*/ ++ ++/* ++ * waits for a completion of a TWSI transfer ++ * ++ * returns 0: success, transfer completes ++ * 1: error, transfer does not complete, TWSI transfer ++ * killed, wait loop terminated. ++ */ ++int SkI2cWait( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */ ++{ ++ SK_U64 StartTime; ++ SK_U64 CurrTime; ++ SK_U32 I2cCtrl; ++ ++ StartTime = SkOsGetTime(pAC); ++ ++ do { ++ CurrTime = SkOsGetTime(pAC); ++ ++#ifdef YUKON_DBG ++// printf("StartTime=%lu, CurrTime=%lu\n", StartTime, CurrTime); ++ if (kbhit()) { ++ return(0); ++ } ++#endif /* YUKON_DBG */ ++ ++ if (CurrTime - StartTime > SK_TICKS_PER_SEC / 8) { ++ ++ SK_I2C_STOP(IoC); ++#ifndef SK_DIAG ++ if (pAC->I2c.InitLevel > SK_INIT_DATA) { ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG); ++ } ++#endif /* !SK_DIAG */ ++ return(1); ++ } ++ ++ SK_I2C_GET_CTL(IoC, &I2cCtrl); ++ ++ } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31); ++ ++ return(0); ++} /* SkI2cWait */ ++ ++ ++/* ++ * waits for a completion of a TWSI transfer ++ * ++ * Returns ++ * Nothing ++ */ ++void SkI2cWaitIrq( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ ++{ ++ SK_SENSOR *pSen; ++ SK_U64 StartTime; ++ SK_U32 IrqSrc; ++ SK_U32 IsTwsiReadyBit; ++ ++ pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; ++ ++ if (pSen->SenState == SK_SEN_IDLE) { ++ return; ++ } ++ ++ IsTwsiReadyBit = CHIP_ID_YUKON_2(pAC) ? Y2_IS_TWSI_RDY : IS_I2C_READY; ++ ++ StartTime = SkOsGetTime(pAC); ++ ++ do { ++ if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) { ++ ++ SK_I2C_STOP(IoC); ++#ifndef SK_DIAG ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG); ++#endif /* !SK_DIAG */ ++ return; ++ } ++ ++ SK_IN32(IoC, B0_ISRC, &IrqSrc); ++ ++ } while ((IrqSrc & IsTwsiReadyBit) == 0); ++ ++ pSen->SenState = SK_SEN_IDLE; ++ return; ++} /* SkI2cWaitIrq */ ++ ++/* ++ * writes a single byte or 4 bytes into the TWSI device ++ * ++ * returns 0: success ++ * 1: error ++ */ ++int SkI2cWrite( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++SK_U32 I2cData, /* TWSI Data to write */ ++int I2cDev, /* TWSI Device Address */ ++int I2cDevSize, /* TWSI Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ ++int I2cReg, /* TWSI Device Register Address */ ++int I2cBurst) /* TWSI Burst Flag */ ++{ ++ SK_OUT32(IoC, B2_I2C_DATA, I2cData); ++ ++ SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst); ++ ++ return(SkI2cWait(pAC, IoC, I2C_WRITE)); ++} /* SkI2cWrite*/ ++ ++ ++#ifdef SK_DIAG ++/* ++ * reads a single byte or 4 bytes from the TWSI device ++ * ++ * returns the word read ++ */ ++SK_U32 SkI2cRead( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int I2cDev, /* TWSI Device Address */ ++int I2cDevSize, /* TWSI Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ ++int I2cReg, /* TWSI Device Register Address */ ++int I2cBurst) /* TWSI Burst Flag */ ++{ ++ SK_U32 Data; ++ ++ SK_OUT32(IoC, B2_I2C_DATA, 0); ++ ++ SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst); ++ ++ if (SkI2cWait(pAC, IoC, I2C_READ) != 0) { ++ w_print("%s\n", SKERR_I2C_E002MSG); ++ } ++ ++ SK_IN32(IoC, B2_I2C_DATA, &Data); ++ ++ return(Data); ++} /* SkI2cRead */ ++#endif /* SK_DIAG */ ++ ++ ++/* ++ * read a sensor's value ++ * ++ * This function reads a sensor's value from the TWSI sensor chip. The sensor ++ * is defined by its index into the sensors database in the struct pAC points ++ * to. ++ * Returns ++ * 1 if the read is completed ++ * 0 if the read must be continued (TWSI Bus still allocated) ++ */ ++int SkI2cReadSensor( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++SK_SENSOR *pSen) /* Sensor to be read */ ++{ ++ if (pSen->SenRead != NULL) { ++ return((*pSen->SenRead)(pAC, IoC, pSen)); ++ } ++ ++ return(0); /* no success */ ++} /* SkI2cReadSensor */ ++ ++/* ++ * Do the Init state 0 initialization ++ */ ++static int SkI2cInit0( ++SK_AC *pAC) /* Adapter Context */ ++{ ++ int i; ++ SK_SENSOR *pSen; ++ ++ /* Begin with first sensor */ ++ pAC->I2c.CurrSens = 0; ++ ++ /* Begin with timeout control for state machine */ ++ pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; ++ ++ /* Set sensor number to zero */ ++ pAC->I2c.MaxSens = 0; ++ ++#ifndef SK_DIAG ++ /* Initialize Number of Dummy Reads */ ++ pAC->I2c.DummyReads = SK_MAX_SENSORS; ++#endif /* !SK_DIAG */ ++ ++ for (i = 0; i < SK_MAX_SENSORS; i++) { ++ pSen = &pAC->I2c.SenTable[i]; ++ ++ pSen->SenDesc = "unknown"; ++ pSen->SenType = SK_SEN_UNKNOWN; ++ pSen->SenThreErrHigh = 0; ++ pSen->SenThreErrLow = 0; ++ pSen->SenThreWarnHigh = 0; ++ pSen->SenThreWarnLow = 0; ++ pSen->SenReg = LM80_FAN2_IN; ++ pSen->SenInit = SK_SEN_DYN_INIT_NONE; ++ pSen->SenValue = 0; ++ pSen->SenErrFlag = SK_SEN_ERR_NOT_PRESENT; ++ pSen->SenErrCts = 0; ++ pSen->SenBegErrTS = 0; ++ pSen->SenState = SK_SEN_IDLE; ++ pSen->SenRead = NULL; ++ pSen->SenDev = 0; ++ } ++ ++ /* Now we are "INIT data"ed */ ++ pAC->I2c.InitLevel = SK_INIT_DATA; ++ return(0); ++} /* SkI2cInit0*/ ++ ++ ++/* ++ * Do the init state 1 initialization ++ * ++ * initialize the following register of the LM80: ++ * Configuration register: ++ * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT ++ * ++ * Interrupt Mask Register 1: ++ * - all interrupts are Disabled (0xff) ++ * ++ * Interrupt Mask Register 2: ++ * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter. ++ * ++ * Fan Divisor/RST_OUT register: ++ * - Divisors set to 1 (bits 00), all others 0s. ++ * ++ * OS# Configuration/Temperature resolution Register: ++ * - all 0s ++ * ++ */ ++static int SkI2cInit1( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ ++{ ++ int i; ++ SK_U8 I2cSwCtrl; ++ SK_GEPORT *pPrt; /* GIni Port struct pointer */ ++ SK_SENSOR *pSen; ++ ++ if (pAC->I2c.InitLevel != SK_INIT_DATA) { ++ /* Re-init not needed in TWSI module */ ++ return(0); ++ } ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_FE || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_EX) { ++ /* No sensors on Yukon-EC, -ECU and Yukon-FE */ ++ return(0); ++ } ++ ++ /* Set the Direction of TWSI-Data Pin to IN */ ++ SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA); ++ ++ /* Check for 32-Bit Yukon with Low at TWSI-Data Pin */ ++ SK_I2C_GET_SW(IoC, &I2cSwCtrl); ++ ++ if ((I2cSwCtrl & I2C_DATA) == 0) { ++ /* this is a 32-Bit board */ ++ pAC->GIni.GIYukon32Bit = SK_TRUE; ++ return(0); ++ } ++ ++ /* Check for 64 Bit Yukon without sensors */ ++ if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) { ++ return(0); ++ } ++ ++ (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0); ++ ++ (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0); ++ ++ (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0); ++ ++ (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0); ++ ++ (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV, ++ LM80_CFG, 0); ++ ++ /* ++ * MaxSens has to be updated here, because PhyType is not ++ * set when performing Init Level 0 ++ */ ++ pAC->I2c.MaxSens = 5; ++ ++ pPrt = &pAC->GIni.GP[0]; ++ ++ if (pAC->GIni.GIGenesis) { ++ if (pPrt->PhyType == SK_PHY_BCOM) { ++ if (pAC->GIni.GIMacsFound == 1) { ++ pAC->I2c.MaxSens += 1; ++ } ++ else { ++ pAC->I2c.MaxSens += 3; ++ } ++ } ++ } ++ else { ++ pAC->I2c.MaxSens += 3; ++ } ++ ++ for (i = 0; i < pAC->I2c.MaxSens; i++) { ++ pSen = &pAC->I2c.SenTable[i]; ++ switch (i) { ++ case 0: ++ pSen->SenDesc = "Temperature"; ++ pSen->SenType = SK_SEN_TEMP; ++ pSen->SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN; ++ pSen->SenThreWarnLow = SK_SEN_TEMP_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_TEMP_LOW_ERR; ++ pSen->SenReg = LM80_TEMP_IN; ++ break; ++ case 1: ++ pSen->SenDesc = "Voltage PCI"; ++ pSen->SenType = SK_SEN_VOLT; ++ pSen->SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN; ++ if (pAC->GIni.GIPciBus != SK_PEX_BUS) { ++ pSen->SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR; ++ } ++ else { ++ pSen->SenThreWarnLow = 0; ++ pSen->SenThreErrLow = 0; ++ } ++ pSen->SenReg = LM80_VT0_IN; ++ break; ++ case 2: ++ pSen->SenDesc = "Voltage PCI-IO"; ++ pSen->SenType = SK_SEN_VOLT; ++ pSen->SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN; ++ if (pAC->GIni.GIPciBus != SK_PEX_BUS) { ++ pSen->SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR; ++ } ++ else { ++ pSen->SenThreWarnLow = 0; ++ pSen->SenThreErrLow = 0; ++ } ++ pSen->SenReg = LM80_VT1_IN; ++ pSen->SenInit = SK_SEN_DYN_INIT_PCI_IO; ++ break; ++ case 3: ++ if (pAC->GIni.GIGenesis) { ++ pSen->SenDesc = "Voltage ASIC"; ++ } ++ else { ++ pSen->SenDesc = "Voltage VMAIN"; ++ } ++ pSen->SenType = SK_SEN_VOLT; ++ pSen->SenThreErrHigh = SK_SEN_VDD_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN; ++ pSen->SenThreWarnLow = SK_SEN_VDD_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_VDD_LOW_ERR; ++ pSen->SenReg = LM80_VT2_IN; ++ break; ++ case 4: ++ if (pAC->GIni.GIGenesis) { ++ if (pPrt->PhyType == SK_PHY_BCOM) { ++ pSen->SenDesc = "Voltage PHY A PLL"; ++ pSen->SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; ++ pSen->SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; ++ } ++ else { ++ pSen->SenDesc = "Voltage PMA"; ++ pSen->SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; ++ pSen->SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; ++ } ++ } ++ else { ++ pSen->SenDesc = "Voltage VAUX"; ++ pSen->SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN; ++ if (pAC->GIni.GIVauxAvail) { ++ pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; ++ } ++ else { ++ pSen->SenThreErrLow = 0; ++ pSen->SenThreWarnLow = 0; ++ } ++ } ++ pSen->SenType = SK_SEN_VOLT; ++ pSen->SenReg = LM80_VT3_IN; ++ break; ++ case 5: ++ if (CHIP_ID_YUKON_2(pAC)) { ++ if (pAC->GIni.GIChipRev == CHIP_REV_YU_XL_A0) { ++ pSen->SenDesc = "Voltage Core 1V3"; ++ pSen->SenThreErrHigh = SK_SEN_CORE_1V3_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_CORE_1V3_HIGH_WARN; ++ pSen->SenThreWarnLow = SK_SEN_CORE_1V3_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_CORE_1V3_LOW_ERR; ++ } ++ else { ++ pSen->SenDesc = "Voltage Core 1V2"; ++ pSen->SenThreErrHigh = SK_SEN_CORE_1V2_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_CORE_1V2_HIGH_WARN; ++ pSen->SenThreWarnLow = SK_SEN_CORE_1V2_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_CORE_1V2_LOW_ERR; ++ } ++ } ++ else { ++ if (pAC->GIni.GIGenesis) { ++ pSen->SenDesc = "Voltage PHY 2V5"; ++ pSen->SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; ++ pSen->SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; ++ } ++ else { ++ pSen->SenDesc = "Voltage Core 1V5"; ++ pSen->SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN; ++ pSen->SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR; ++ } ++ } ++ pSen->SenType = SK_SEN_VOLT; ++ pSen->SenReg = LM80_VT4_IN; ++ break; ++ case 6: ++ if (CHIP_ID_YUKON_2(pAC)) { ++ pSen->SenDesc = "Voltage PHY 1V5"; ++ pSen->SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN; ++ if (pAC->GIni.GIPciBus == SK_PEX_BUS) { ++ pSen->SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR; ++ } ++ else { ++ pSen->SenThreWarnLow = 0; ++ pSen->SenThreErrLow = 0; ++ } ++ } ++ else { ++ if (pAC->GIni.GIGenesis) { ++ pSen->SenDesc = "Voltage PHY B PLL"; ++ } ++ else { ++ pSen->SenDesc = "Voltage PHY 3V3"; ++ } ++ pSen->SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; ++ pSen->SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; ++ } ++ pSen->SenType = SK_SEN_VOLT; ++ pSen->SenReg = LM80_VT5_IN; ++ break; ++ case 7: ++ if (pAC->GIni.GIGenesis) { ++ pSen->SenDesc = "Speed Fan"; ++ pSen->SenType = SK_SEN_FAN; ++ pSen->SenThreErrHigh = SK_SEN_FAN_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN; ++ pSen->SenThreWarnLow = SK_SEN_FAN_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_FAN_LOW_ERR; ++ pSen->SenReg = LM80_FAN2_IN; ++ } ++ else { ++ pSen->SenDesc = "Voltage PHY 2V5"; ++ pSen->SenType = SK_SEN_VOLT; ++ pSen->SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; ++ pSen->SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; ++ pSen->SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; ++ pSen->SenReg = LM80_VT6_IN; ++ } ++ break; ++ default: ++ SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW, ++ SKERR_I2C_E001, SKERR_I2C_E001MSG); ++ break; ++ } ++ ++ pSen->SenValue = 0; ++ pSen->SenErrFlag = SK_SEN_ERR_OK; ++ pSen->SenErrCts = 0; ++ pSen->SenBegErrTS = 0; ++ pSen->SenState = SK_SEN_IDLE; ++ if (pSen->SenThreWarnLow != 0) { ++ pSen->SenRead = SkLm80ReadSensor; ++ } ++ pSen->SenDev = LM80_ADDR; ++ } ++ ++#ifndef SK_DIAG ++ pAC->I2c.DummyReads = pAC->I2c.MaxSens; ++#endif /* !SK_DIAG */ ++ ++ /* Clear TWSI IRQ */ ++ SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); ++ ++ /* Now we are I/O initialized */ ++ pAC->I2c.InitLevel = SK_INIT_IO; ++ return(0); ++} /* SkI2cInit1 */ ++ ++ ++/* ++ * Init level 2: Start first sensor read. ++ */ ++static int SkI2cInit2( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ ++{ ++ int ReadComplete; ++ SK_SENSOR *pSen; ++ ++ if (pAC->I2c.InitLevel != SK_INIT_IO) { ++ /* ReInit not needed in TWSI module */ ++ /* Init0 and Init2 not permitted */ ++ return(0); ++ } ++ ++ pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; ++ ++ ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); ++ ++ if (ReadComplete) { ++ SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG); ++ } ++ ++ /* Now we are correctly initialized */ ++ pAC->I2c.InitLevel = SK_INIT_RUN; ++ ++ return(0); ++} /* SkI2cInit2*/ ++ ++ ++/* ++ * Initialize TWSI devices ++ * ++ * Get the first voltage value and discard it. ++ * Go into temperature read mode. A default pointer is not set. ++ * ++ * The things to be done depend on the init level in the parameter list: ++ * Level 0: ++ * Initialize only the data structures. Do NOT access hardware. ++ * Level 1: ++ * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts. ++ * Level 2: ++ * Everything is possible. Interrupts may be used from now on. ++ * ++ * return: ++ * 0 = success ++ * other = error. ++ */ ++int SkI2cInit( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */ ++int Level) /* Init Level */ ++{ ++ ++ switch (Level) { ++ case SK_INIT_DATA: ++ return(SkI2cInit0(pAC)); ++ case SK_INIT_IO: ++ return(SkI2cInit1(pAC, IoC)); ++ case SK_INIT_RUN: ++ return(SkI2cInit2(pAC, IoC)); ++ default: ++ break; ++ } ++ ++ return(0); ++} /* SkI2cInit */ ++ ++ ++#ifndef SK_DIAG ++/* ++ * Interrupt service function for the TWSI Interface ++ * ++ * Clears the Interrupt source ++ * ++ * Reads the register and check it for sending a trap. ++ * ++ * Starts the timer if necessary. ++ */ ++void SkI2cIsr( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC) /* I/O Context */ ++{ ++ SK_EVPARA Para; ++ ++ /* Clear TWSI IRQ */ ++ SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); ++ ++ Para.Para64 = 0; ++ SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para); ++} /* SkI2cIsr */ ++ ++ ++/* ++ * Check this sensors Value against the threshold and send events. ++ */ ++static void SkI2cCheckSensor( ++SK_AC *pAC, /* Adapter Context */ ++SK_SENSOR *pSen) ++{ ++ SK_EVPARA ParaLocal; ++ SK_BOOL TooHigh; /* Is sensor too high? */ ++ SK_BOOL TooLow; /* Is sensor too low? */ ++ SK_U64 CurrTime; /* Current Time */ ++ SK_BOOL DoTrapSend; /* We need to send a trap */ ++ SK_BOOL DoErrLog; /* We need to log the error */ ++ SK_BOOL IsError; /* Error occured */ ++ ++ /* Check Dummy Reads first */ ++ if (pAC->I2c.DummyReads > 0) { ++ pAC->I2c.DummyReads--; ++ return; ++ } ++ ++ /* Get the current time */ ++ CurrTime = SkOsGetTime(pAC); ++ ++ /* Set para to the most useful setting: The current sensor. */ ++ ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens; ++ ++ /* Check the Value against the thresholds. First: Error Thresholds */ ++ TooHigh = pSen->SenValue > pSen->SenThreErrHigh; ++ TooLow = pSen->SenValue < pSen->SenThreErrLow; ++ ++ IsError = SK_FALSE; ++ ++ if (TooHigh || TooLow) { ++ /* Error condition is satisfied */ ++ DoTrapSend = SK_TRUE; ++ DoErrLog = SK_TRUE; ++ ++ /* Now error condition is satisfied */ ++ IsError = SK_TRUE; ++ ++ if (pSen->SenErrFlag == SK_SEN_ERR_ERR) { ++ /* This state is the former one */ ++ ++ /* So check first whether we have to send a trap */ ++ if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD > CurrTime) { ++ /* ++ * Do NOT send the Trap. The hold back time ++ * has to run out first. ++ */ ++ DoTrapSend = SK_FALSE; ++ } ++ ++ /* Check now whether we have to log an Error */ ++ if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD > CurrTime) { ++ /* ++ * Do NOT log the error. The hold back time ++ * has to run out first. ++ */ ++ DoErrLog = SK_FALSE; ++ } ++ } ++ else { ++ /* We came from a different state -> Set Begin Time Stamp */ ++ pSen->SenBegErrTS = CurrTime; ++ pSen->SenErrFlag = SK_SEN_ERR_ERR; ++ } ++ ++ if (DoTrapSend) { ++ /* Set current Time */ ++ pSen->SenLastErrTrapTS = CurrTime; ++ pSen->SenErrCts++; ++ ++ /* Queue PNMI Event */ ++ SkEventQueue(pAC, SKGE_PNMI, TooHigh ? ++ SK_PNMI_EVT_SEN_ERR_UPP : SK_PNMI_EVT_SEN_ERR_LOW, ++ ParaLocal); ++ } ++ ++ if (DoErrLog) { ++ /* Set current Time */ ++ pSen->SenLastErrLogTS = CurrTime; ++ ++ if (pSen->SenType == SK_SEN_TEMP) { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG); ++ } ++ else if (pSen->SenType == SK_SEN_VOLT) { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG); ++ } ++ else { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG); ++ } ++ } ++ } ++ ++ /* Check the Value against the thresholds */ ++ /* 2nd: Warning thresholds */ ++ TooHigh = pSen->SenValue > pSen->SenThreWarnHigh; ++ TooLow = pSen->SenValue < pSen->SenThreWarnLow; ++ ++ if (!IsError && (TooHigh || TooLow)) { ++ /* Error condition is satisfied */ ++ DoTrapSend = SK_TRUE; ++ DoErrLog = SK_TRUE; ++ ++ if (pSen->SenErrFlag == SK_SEN_ERR_WARN) { ++ /* This state is the former one */ ++ ++ /* So check first whether we have to send a trap */ ++ if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) { ++ /* ++ * Do NOT send the Trap. The hold back time ++ * has to run out first. ++ */ ++ DoTrapSend = SK_FALSE; ++ } ++ ++ /* Check now whether we have to log an Error */ ++ if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) { ++ /* ++ * Do NOT log the error. The hold back time ++ * has to run out first. ++ */ ++ DoErrLog = SK_FALSE; ++ } ++ } ++ else { ++ /* We came from a different state -> Set Begin Time Stamp */ ++ pSen->SenBegWarnTS = CurrTime; ++ pSen->SenErrFlag = SK_SEN_ERR_WARN; ++ } ++ ++ if (DoTrapSend) { ++ /* Set current Time */ ++ pSen->SenLastWarnTrapTS = CurrTime; ++ pSen->SenWarnCts++; ++ ++ /* Queue PNMI Event */ ++ SkEventQueue(pAC, SKGE_PNMI, TooHigh ? ++ SK_PNMI_EVT_SEN_WAR_UPP : SK_PNMI_EVT_SEN_WAR_LOW, ParaLocal); ++ } ++ ++ if (DoErrLog) { ++ /* Set current Time */ ++ pSen->SenLastWarnLogTS = CurrTime; ++ ++ if (pSen->SenType == SK_SEN_TEMP) { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG); ++ } ++ else if (pSen->SenType == SK_SEN_VOLT) { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG); ++ } ++ else { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG); ++ } ++ } ++ } ++ ++ /* Check for NO error at all */ ++ if (!IsError && !TooHigh && !TooLow) { ++ /* Set o.k. Status if no error and no warning condition */ ++ pSen->SenErrFlag = SK_SEN_ERR_OK; ++ } ++ ++ /* End of check against the thresholds */ ++ ++ if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) { ++ /* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */ ++ pSen->SenInit = SK_SEN_DYN_INIT_NONE; ++ ++ if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) { ++ /* 5V PCI-IO Voltage */ ++ pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR; ++ } ++ else { ++ /* 3.3V PCI-IO Voltage */ ++ pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN; ++ pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR; ++ } ++ } ++ ++#ifdef TEST_ONLY ++ /* Dynamic thresholds also for VAUX of LM80 sensor */ ++ if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) { ++ ++ pSen->SenInit = SK_SEN_DYN_INIT_NONE; ++ ++ /* 3.3V VAUX Voltage */ ++ if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) { ++ pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; ++ pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; ++ } ++ /* 0V VAUX Voltage */ ++ else { ++ pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR; ++ pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR; ++ } ++ } ++ ++ /* Check initialization state: the VIO Thresholds need adaption */ ++ if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && ++ pSen->SenValue > SK_SEN_WARNLOW2C && ++ pSen->SenValue < SK_SEN_WARNHIGH2) { ++ ++ pSen->SenThreErrLow = SK_SEN_ERRLOW2C; ++ pSen->SenThreWarnLow = SK_SEN_WARNLOW2C; ++ pSen->SenInit = SK_TRUE; ++ } ++ ++ if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && ++ pSen->SenValue > SK_SEN_WARNLOW2 && ++ pSen->SenValue < SK_SEN_WARNHIGH2C) { ++ ++ pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C; ++ pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C; ++ pSen->SenInit = SK_TRUE; ++ } ++#endif ++ ++ if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) { ++ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG); ++ } ++} /* SkI2cCheckSensor */ ++ ++ ++/* ++ * The only Event to be served is the timeout event ++ * ++ */ ++int SkI2cEvent( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++SK_U32 Event, /* Module specific Event */ ++SK_EVPARA Para) /* Event specific Parameter */ ++{ ++ int ReadComplete; ++ SK_SENSOR *pSen; ++ SK_U32 Time; ++ SK_EVPARA ParaLocal; ++ int i; ++ ++ /* New case: no sensors */ ++ if (pAC->I2c.MaxSens == 0) { ++ return(0); ++ } ++ ++ switch (Event) { ++ case SK_I2CEV_IRQ: ++ pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; ++ ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); ++ ++ if (ReadComplete) { ++ /* Check sensor against defined thresholds */ ++ SkI2cCheckSensor(pAC, pSen); ++ ++ /* Increment Current sensor and set appropriate Timeout */ ++ pAC->I2c.CurrSens++; ++ if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) { ++ pAC->I2c.CurrSens = 0; ++ Time = SK_I2C_TIM_LONG; ++ } ++ else { ++ Time = SK_I2C_TIM_SHORT; ++ } ++ ++ /* Start Timer */ ++ ParaLocal.Para64 = (SK_U64)0; ++ ++ pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; ++ ++ SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, ++ SKGE_I2C, SK_I2CEV_TIM, ParaLocal); ++ } ++ else { ++ /* Start Timer */ ++ ParaLocal.Para64 = (SK_U64)0; ++ ++ pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; ++ ++ SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH, ++ SKGE_I2C, SK_I2CEV_TIM, ParaLocal); ++ } ++ break; ++ case SK_I2CEV_TIM: ++ if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) { ++ ++ ParaLocal.Para64 = (SK_U64)0; ++ SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer); ++ ++ pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; ++ ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); ++ ++ if (ReadComplete) { ++ /* Check sensor against defined thresholds */ ++ SkI2cCheckSensor(pAC, pSen); ++ ++ /* Increment Current sensor and set appropriate Timeout */ ++ pAC->I2c.CurrSens++; ++ if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { ++ pAC->I2c.CurrSens = 0; ++ Time = SK_I2C_TIM_LONG; ++ } ++ else { ++ Time = SK_I2C_TIM_SHORT; ++ } ++ ++ /* Start Timer */ ++ ParaLocal.Para64 = (SK_U64)0; ++ ++ pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; ++ ++ SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, ++ SKGE_I2C, SK_I2CEV_TIM, ParaLocal); ++ } ++ } ++ else { ++ pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; ++ pSen->SenErrFlag = SK_SEN_ERR_FAULTY; ++ SK_I2C_STOP(IoC); ++ ++ /* Increment Current sensor and set appropriate Timeout */ ++ pAC->I2c.CurrSens++; ++ if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { ++ pAC->I2c.CurrSens = 0; ++ Time = SK_I2C_TIM_LONG; ++ } ++ else { ++ Time = SK_I2C_TIM_SHORT; ++ } ++ ++ /* Start Timer */ ++ ParaLocal.Para64 = (SK_U64)0; ++ ++ pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; ++ ++ SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, ++ SKGE_I2C, SK_I2CEV_TIM, ParaLocal); ++ } ++ break; ++ case SK_I2CEV_CLEAR: ++ for (i = 0; i < SK_MAX_SENSORS; i++) { ++ pSen = &pAC->I2c.SenTable[i]; ++ ++ pSen->SenErrFlag = SK_SEN_ERR_OK; ++ pSen->SenErrCts = 0; ++ pSen->SenWarnCts = 0; ++ pSen->SenBegErrTS = 0; ++ pSen->SenBegWarnTS = 0; ++ pSen->SenLastErrTrapTS = (SK_U64)0; ++ pSen->SenLastErrLogTS = (SK_U64)0; ++ pSen->SenLastWarnTrapTS = (SK_U64)0; ++ pSen->SenLastWarnLogTS = (SK_U64)0; ++ } ++ break; ++ default: ++ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG); ++ } ++ ++ return(0); ++} /* SkI2cEvent*/ ++ ++#endif /* !SK_DIAG */ ++ +diff -ruN linux/drivers/net/sk98lin/skvpd.c linux-new/drivers/net/sk98lin/skvpd.c +--- linux/drivers/net/sk98lin/skvpd.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skvpd.c 2007-01-24 13:58:33.000000000 +0100 +@@ -1,23 +1,25 @@ + /****************************************************************************** + * + * Name: skvpd.c +- * Project: GEnesis, PCI Gigabit Ethernet Adapter +- * Version: $Revision$ +- * Date: $Date$ +- * Purpose: Shared software to read and write VPD data ++ * Project: Gigabit Ethernet Adapters, VPD-Module ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Shared software to read and write VPD + * + ******************************************************************************/ + + /****************************************************************************** + * +- * (C)Copyright 1998-2003 SysKonnect GmbH. ++ * LICENSE: ++ * (C)Copyright 1998-2002 SysKonnect. ++ * (C)Copyright 2002-2005 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. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -25,7 +27,7 @@ + Please refer skvpd.txt for information how to include this module + */ + static const char SysKonnectFileId[] = +- "@(#)$Id$ (C) SK"; ++ "@(#) $Id$ (C) Marvell."; + + #include "h/skdrv1st.h" + #include "h/sktypes.h" +@@ -52,18 +54,23 @@ + * error exit(9) with a error message + */ + static int VpdWait( +-SK_AC *pAC, /* Adapters context */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC, /* IO Context */ + int event) /* event to wait for (VPD_READ / VPD_write) completion*/ + { +- SK_U64 start_time; ++ SK_I64 start_time; ++ SK_I64 curr_time; + SK_U16 state; + +- SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL, +- ("VPD wait for %s\n", event?"Write":"Read")); +- start_time = SkOsGetTime(pAC); ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ++ ("VPD wait for %s\n", event ? "Write" : "Read")); ++ ++ start_time = (SK_I64)SkOsGetTime(pAC); ++ + do { +- if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) { ++ curr_time = (SK_I64)SkOsGetTime(pAC); ++ ++ if (curr_time - start_time > SK_TICKS_PER_SEC) { + + /* Bug fix AF: Thu Mar 28 2002 + * Do not call: VPD_STOP(pAC, IoC); +@@ -81,18 +88,19 @@ + ("ERROR:VPD wait timeout\n")); + return(1); + } +- ++ + VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state); +- ++ + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, +- ("state = %x, event %x\n",state,event)); +- } while((int)(state & PCI_VPD_FLAG) == event); ++ ("state = %x, event %x\n", state, event)); ++ ++ } while ((int)(state & PCI_VPD_FLAG) == event); + + return(0); + } + +-#ifdef SKDIAG + ++#ifdef SK_DIAG + /* + * Read the dword at address 'addr' from the VPD EEPROM. + * +@@ -104,7 +112,7 @@ + * Returns the data read. + */ + SK_U32 VpdReadDWord( +-SK_AC *pAC, /* Adapters context */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC, /* IO Context */ + int addr) /* VPD address */ + { +@@ -112,7 +120,7 @@ + + /* start VPD read */ + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, +- ("VPD read dword at 0x%x\n",addr)); ++ ("VPD read dword at 0x%x\n", addr)); + addr &= ~VPD_WRITE; /* ensure the R/W bit is set to read */ + + VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)addr); +@@ -124,14 +132,73 @@ + Rtv = 0; + + VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv); +- ++ + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, +- ("VPD read dword data = 0x%x\n",Rtv)); ++ ("VPD read dword data = 0x%x\n", Rtv)); + return(Rtv); + } ++#endif /* SK_DIAG */ ++ ++ ++#ifdef XXX ++/* ++ Write the dword 'data' at address 'addr' into the VPD EEPROM, and ++ verify that the data is written. ++ ++ Needed Time: ++ ++. MIN MAX ++. ------------------------------------------------------------------- ++. write 1.8 ms 3.6 ms ++. internal write cyles 0.7 ms 7.0 ms ++. ------------------------------------------------------------------- ++. over all program time 2.5 ms 10.6 ms ++. read 1.3 ms 2.6 ms ++. ------------------------------------------------------------------- ++. over all 3.8 ms 13.2 ms ++. ++ ++ Returns 0: success ++ 1: error, I2C transfer does not terminate ++ 2: error, data verify error ++ ++ */ ++static int VpdWriteDWord( ++SK_AC *pAC, /* Adapters Context */ ++SK_IOC IoC, /* IO Context */ ++int addr, /* VPD address */ ++SK_U32 data) /* VPD data to write */ ++{ ++ /* start VPD write */ ++ /* Don't swap here, it's a data stream of bytes */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ++ ("VPD write dword at addr 0x%x, data = 0x%x\n", addr, data)); ++ VPD_OUT32(pAC, IoC, PCI_VPD_DAT_REG, (SK_U32)data); ++ /* But do it here */ ++ addr |= VPD_WRITE; ++ ++ VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE)); ++ ++ /* this may take up to 10,6 ms */ ++ if (VpdWait(pAC, IoC, VPD_WRITE)) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ++ ("Write Timed Out\n")); ++ return(1); ++ }; ++ ++ /* verify data */ ++ if (VpdReadDWord(pAC, IoC, addr) != data) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, ++ ("Data Verify Error\n")); ++ return(2); ++ } ++ return(0); ++} /* VpdWriteDWord */ + +-#endif /* SKDIAG */ ++#endif /* XXX */ + ++ ++#ifndef SK_SLIM + /* + * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from + * or to the I2C EEPROM. +@@ -139,7 +206,7 @@ + * Returns number of bytes read / written. + */ + static int VpdWriteStream( +-SK_AC *pAC, /* Adapters context */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC, /* IO Context */ + char *buf, /* data buffer */ + int Addr, /* VPD start address */ +@@ -156,7 +223,7 @@ + pComp = (SK_U8 *) buf; + + for (i = 0; i < Len; i++, buf++) { +- if ((i%sizeof(SK_U32)) == 0) { ++ if ((i % SZ_LONG) == 0) { + /* + * At the begin of each cycle read the Data Reg + * So it is initialized even if only a few bytes +@@ -174,14 +241,13 @@ + } + } + +- /* Write current Byte */ +- VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)), +- *(SK_U8*)buf); ++ /* Write current byte */ ++ VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i % SZ_LONG), *(SK_U8 *)buf); + +- if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) { ++ if (((i % SZ_LONG) == 3) || (i == (Len - 1))) { + /* New Address needs to be written to VPD_ADDR reg */ + AdrReg = (SK_U16) Addr; +- Addr += sizeof(SK_U32); ++ Addr += SZ_LONG; + AdrReg |= VPD_WRITE; /* WRITE operation */ + + VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); +@@ -191,7 +257,7 @@ + if (Rtv != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("Write Timed Out\n")); +- return(i - (i%sizeof(SK_U32))); ++ return(i - (i % SZ_LONG)); + } + + /* +@@ -206,18 +272,18 @@ + if (Rtv != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("Verify Timed Out\n")); +- return(i - (i%sizeof(SK_U32))); ++ return(i - (i % SZ_LONG)); + } + +- for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) { +- ++ for (j = 0; j <= (int)(i % SZ_LONG); j++, pComp++) { ++ + VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data); +- ++ + if (Data != *pComp) { + /* Verify Error */ + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("WriteStream Verify Error\n")); +- return(i - (i%sizeof(SK_U32)) + j); ++ return(i - (i % SZ_LONG) + j); + } + } + } +@@ -225,7 +291,7 @@ + + return(Len); + } +- ++#endif /* !SK_SLIM */ + + /* + * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from +@@ -234,7 +300,7 @@ + * Returns number of bytes read / written. + */ + static int VpdReadStream( +-SK_AC *pAC, /* Adapters context */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC, /* IO Context */ + char *buf, /* data buffer */ + int Addr, /* VPD start address */ +@@ -245,10 +311,10 @@ + int Rtv; + + for (i = 0; i < Len; i++, buf++) { +- if ((i%sizeof(SK_U32)) == 0) { ++ if ((i % SZ_LONG) == 0) { + /* New Address needs to be written to VPD_ADDR reg */ + AdrReg = (SK_U16) Addr; +- Addr += sizeof(SK_U32); ++ Addr += SZ_LONG; + AdrReg &= ~VPD_WRITE; /* READ operation */ + + VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); +@@ -259,13 +325,13 @@ + return(i); + } + } +- VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)), +- (SK_U8 *)buf); ++ VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i % SZ_LONG), (SK_U8 *)buf); + } + + return(Len); + } + ++ + /* + * Read ore writes 'len' bytes of VPD data, starting at 'addr' from + * or to the I2C EEPROM. +@@ -273,7 +339,7 @@ + * Returns number of bytes read / written. + */ + static int VpdTransferBlock( +-SK_AC *pAC, /* Adapters context */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC, /* IO Context */ + char *buf, /* data buffer */ + int addr, /* VPD start address */ +@@ -287,18 +353,19 @@ + ("VPD %s block, addr = 0x%x, len = %d\n", + dir ? "write" : "read", addr, len)); + +- if (len == 0) ++ if (len == 0) { + return(0); ++ } + + vpd_rom_size = pAC->vpd.rom_size; +- ++ + if (addr > vpd_rom_size - 4) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Address error: 0x%x, exp. < 0x%x\n", + addr, vpd_rom_size - 4)); + return(0); + } +- ++ + if (addr + len > vpd_rom_size) { + len = vpd_rom_size - addr; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, +@@ -308,22 +375,24 @@ + if (dir == VPD_READ) { + Rtv = VpdReadStream(pAC, IoC, buf, addr, len); + } ++#ifndef SK_SLIM + else { + Rtv = VpdWriteStream(pAC, IoC, buf, addr, len); + } ++#endif /* !SK_SLIM */ + + return(Rtv); + } + +-#ifdef SKDIAG + ++#if defined(SK_DIAG) || defined(SK_ASF) + /* + * Read 'len' bytes of VPD data, starting at 'addr'. + * + * Returns number of bytes read. + */ + int VpdReadBlock( +-SK_AC *pAC, /* pAC pointer */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC, /* IO Context */ + char *buf, /* buffer were the data should be stored */ + int addr, /* start reading at the VPD address */ +@@ -332,13 +401,14 @@ + return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ)); + } + ++ + /* + * Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'. + * + * Returns number of bytes writes. + */ + int VpdWriteBlock( +-SK_AC *pAC, /* pAC pointer */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC, /* IO Context */ + char *buf, /* buffer, holds the data to write */ + int addr, /* start writing at the VPD address */ +@@ -346,19 +416,28 @@ + { + return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE)); + } +-#endif /* SKDIAG */ ++#endif /* SK_DIAG || SK_ASF */ + +-/* +- * (re)initialize the VPD buffer ++ ++/****************************************************************************** + * +- * Reads the VPD data from the EEPROM into the VPD buffer. +- * Get the remaining read only and read / write space. ++ * VpdInit() - (re)initialize the VPD buffer + * +- * return 0: success +- * 1: fatal VPD error ++ * Description: ++ * Reads the VPD data from the EEPROM into the VPD buffer. ++ * Get the remaining read only and read / write space. ++ * ++ * Note: ++ * This is a local function and should be used locally only. ++ * However, the ASF module needs to use this function also. ++ * Therfore it has been published. ++ * ++ * Returns: ++ * 0: success ++ * 1: fatal VPD error + */ +-static int VpdInit( +-SK_AC *pAC, /* Adapters context */ ++int VpdInit( ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC) /* IO Context */ + { + SK_VPD_PARA *r, rp; /* RW or RV */ +@@ -368,14 +447,14 @@ + SK_U16 dev_id; + SK_U32 our_reg2; + +- SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. ")); +- ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit ... ")); ++ + VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id); +- ++ + VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2); +- ++ + pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14); +- ++ + /* + * this function might get used before the hardware is initialized + * therefore we cannot always trust in GIChipId +@@ -388,6 +467,7 @@ + /* for Yukon the VPD size is always 256 */ + vpd_size = VPD_SIZE_YUKON; + } ++#ifndef SK_SLIM + else { + /* Genesis uses the maximum ROM size up to 512 for VPD */ + if (pAC->vpd.rom_size > VPD_SIZE_GENESIS) { +@@ -397,6 +477,7 @@ + vpd_size = pAC->vpd.rom_size; + } + } ++#endif /* !SK_SLIM */ + + /* read the VPD data into the VPD buffer */ + if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf, 0, vpd_size, VPD_READ) +@@ -406,19 +487,17 @@ + ("Block Read Error\n")); + return(1); + } +- ++ + pAC->vpd.vpd_size = vpd_size; + ++#ifndef SK_SLIM + /* Asus K8V Se Deluxe bugfix. Correct VPD content */ +- /* MBo April 2004 */ +- if (((unsigned char)pAC->vpd.vpd_buf[0x3f] == 0x38) && +- ((unsigned char)pAC->vpd.vpd_buf[0x40] == 0x3c) && +- ((unsigned char)pAC->vpd.vpd_buf[0x41] == 0x45)) { +- printk("sk98lin: Asus mainboard with buggy VPD? " +- "Correcting data.\n"); +- pAC->vpd.vpd_buf[0x40] = 0x38; +- } ++ i = 62; ++ if (!SK_STRNCMP(pAC->vpd.vpd_buf + i, " 8vpd.vpd_buf[i + 2] = '8'; ++ } ++#endif /* !SK_SLIM */ + + /* find the end tag of the RO area */ + if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) { +@@ -426,9 +505,9 @@ + ("Encoding Error: RV Tag not found\n")); + return(1); + } +- ++ + if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) { +- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Encoding Error: Invalid VPD struct size\n")); + return(1); + } +@@ -438,7 +517,7 @@ + for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) { + x += pAC->vpd.vpd_buf[i]; + } +- ++ + if (x != 0) { + /* checksum error */ + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, +@@ -452,7 +531,7 @@ + ("Encoding Error: RV Tag not found\n")); + return(1); + } +- ++ + if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Encoding Error: Invalid VPD struct size\n")); +@@ -472,6 +551,7 @@ + return(0); + } + ++ + /* + * find the Keyword 'key' in the VPD buffer and fills the + * parameter struct 'p' with it's values +@@ -480,58 +560,63 @@ + * 0: parameter was not found or VPD encoding error + */ + static SK_VPD_PARA *vpd_find_para( +-SK_AC *pAC, /* common data base */ ++SK_AC *pAC, /* Adapters Context */ + const char *key, /* keyword to find (e.g. "MN") */ +-SK_VPD_PARA *p) /* parameter description struct */ ++SK_VPD_PARA *p) /* parameter description struct */ + { + char *v ; /* points to VPD buffer */ + int max; /* Maximum Number of Iterations */ ++ int len; + + v = pAC->vpd.vpd_buf; + max = 128; + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, +- ("VPD find para %s .. ",key)); ++ ("VPD find para %s .. ", key)); + + /* check mandatory resource type ID string (Product Name) */ + if (*v != (char)RES_ID) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Error: 0x%x missing\n", RES_ID)); +- return NULL; ++ return(0); + } + +- if (strcmp(key, VPD_NAME) == 0) { +- p->p_len = VPD_GET_RES_LEN(v); ++ len = VPD_GET_RES_LEN(v); ++ ++ if (SK_STRCMP(key, VPD_NAME) == 0) { ++ p->p_len = len; + p->p_val = VPD_GET_VAL(v); + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, +- ("found, len = %d\n", p->p_len)); ++ ("found, len = %d\n", len)); + return(p); + } + +- v += 3 + VPD_GET_RES_LEN(v) + 3; +- for (;; ) { +- if (SK_MEMCMP(key,v,2) == 0) { ++ v += 3 + len + 3; ++ ++ for ( ; ; ) { ++ if (SK_MEMCMP(key, v, 2) == 0) { + p->p_len = VPD_GET_VPD_LEN(v); + p->p_val = VPD_GET_VAL(v); + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, +- ("found, len = %d\n",p->p_len)); ++ ("found, len = %d\n", p->p_len)); + return(p); + } + + /* exit when reaching the "RW" Tag or the maximum of itera. */ + max--; +- if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) { ++ if (SK_MEMCMP(VPD_RW, v, 2) == 0 || max == 0) { + break; + } + +- if (SK_MEMCMP(VPD_RV,v,2) == 0) { +- v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */ +- } +- else { +- v += 3 + VPD_GET_VPD_LEN(v); ++ len = 3 + VPD_GET_VPD_LEN(v); ++ ++ if (SK_MEMCMP(VPD_RV, v, 2) == 0) { ++ len += 3; /* skip VPD-W */ + } ++ v += len; ++ + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, +- ("scanning '%c%c' len = %d\n",v[0],v[1],v[2])); ++ ("scanning '%c%c' len = %d\n", v[0], v[1], v[2])); + } + + #ifdef DEBUG +@@ -541,9 +626,10 @@ + ("Key/Len Encoding error\n")); + } + #endif /* DEBUG */ +- return NULL; ++ return(0); + } + ++ + /* + * Move 'n' bytes. Begin with the last byte if 'n' is > 0, + * Start with the last byte if n is < 0. +@@ -558,8 +644,9 @@ + char *p; + int i; /* number of byte copied */ + +- if (n == 0) ++ if (n == 0) { + return; ++ } + + i = (int) (end - start + 1); + if (n < 0) { +@@ -578,6 +665,7 @@ + } + } + ++ + /* + * setup the VPD keyword 'key' at 'ip'. + * +@@ -594,10 +682,11 @@ + p = (SK_VPD_KEY *) ip; + p->p_key[0] = key[0]; + p->p_key[1] = key[1]; +- p->p_len = (unsigned char) len; +- SK_MEMCPY(&p->p_val,buf,len); ++ p->p_len = (unsigned char)len; ++ SK_MEMCPY(&p->p_val, buf, len); + } + ++ + /* + * Setup the VPD end tag "RV" / "RW". + * Also correct the remaining space variables vpd_free_ro / vpd_free_rw. +@@ -606,7 +695,7 @@ + * 1: encoding error + */ + static int vpd_mod_endtag( +-SK_AC *pAC, /* common data base */ ++SK_AC *pAC, /* Adapters Context */ + char *etp) /* end pointer input position */ + { + SK_VPD_KEY *p; +@@ -615,7 +704,7 @@ + int vpd_size; + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, +- ("VPD modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1])); ++ ("VPD modify endtag at 0x%x = '%c%c'\n", etp, etp[0], etp[1])); + + vpd_size = pAC->vpd.vpd_size; + +@@ -623,7 +712,7 @@ + + if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) { + /* something wrong here, encoding error */ +- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Encoding Error: invalid end tag\n")); + return(1); + } +@@ -655,6 +744,7 @@ + return(0); + } + ++ + /* + * Insert a VPD keyword into the VPD buffer. + * +@@ -669,8 +759,8 @@ + * 6: fatal VPD error + * + */ +-static int VpdSetupPara( +-SK_AC *pAC, /* common data base */ ++int VpdSetupPara( ++SK_AC *pAC, /* Adapters Context */ + const char *key, /* keyword to insert */ + const char *buf, /* buffer with the keyword value */ + int len, /* length of the keyword value */ +@@ -687,12 +777,12 @@ + int vpd_size; + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, +- ("VPD setup para key = %s, val = %s\n",key,buf)); +- ++ ("VPD setup para key = %s, val = %s\n", key, buf)); ++ + vpd_size = pAC->vpd.vpd_size; + + rtv = 0; +- ip = NULL; ++ ip = 0; + if (type == VPD_RW_KEY) { + /* end tag is "RW" */ + free = pAC->vpd.v.vpd_free_rw; +@@ -743,7 +833,9 @@ + } + + vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head); ++ + vpd_insert_key(key, buf, len, ip); ++ + if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) { + pAC->vpd.v.vpd_status &= ~VPD_VALID; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, +@@ -754,7 +846,7 @@ + return(rtv); + } + +- ++#ifndef SK_SLIM + /* + * Read the contents of the VPD EEPROM and copy it to the + * VPD buffer if not already done. +@@ -763,7 +855,7 @@ + * this fields. + */ + SK_VPD_STATUS *VpdStat( +-SK_AC *pAC, /* Adapters context */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC) /* IO Context */ + { + if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { +@@ -780,13 +872,14 @@ + * keyword list by copying the keywords to 'buf', all after + * each other and terminated with a '\0'. + * +- * Exceptions: o The Resource Type ID String (product name) is called "Name" ++ * Exceptions: ++ * o The Resource Type ID String (product name) is called "Name" + * o The VPD end tags 'RV' and 'RW' are not listed + * + * The number of copied keywords is counted in 'elements'. + * + * returns 0: success +- * 2: buffer overfull, one or more keywords are missing ++ * 2: buffer overflow, one or more keywords are missing + * 6: fatal VPD error + * + * example values after returning: +@@ -796,7 +889,7 @@ + * *elements = 9 + */ + int VpdKeys( +-SK_AC *pAC, /* common data base */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC, /* IO Context */ + char *buf, /* buffer where to copy the keywords */ + int *len, /* buffer length */ +@@ -806,6 +899,7 @@ + int n; + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. ")); ++ + *elements = 0; + if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { + if (VpdInit(pAC, IoC) != 0) { +@@ -816,43 +910,44 @@ + } + } + +- if ((signed)strlen(VPD_NAME) + 1 <= *len) { ++ if ((signed)SK_STRLEN(VPD_NAME) + 1 <= *len) { + v = pAC->vpd.vpd_buf; +- strcpy(buf,VPD_NAME); +- n = strlen(VPD_NAME) + 1; ++ SK_STRCPY(buf, VPD_NAME); ++ n = SK_STRLEN(VPD_NAME) + 1; + buf += n; + *elements = 1; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, +- ("'%c%c' ",v[0],v[1])); ++ ("'%c%c' ", v[0], v[1])); + } + else { + *len = 0; +- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("buffer overflow\n")); + return(2); + } + + v += 3 + VPD_GET_RES_LEN(v) + 3; +- for (;; ) { ++ ++ for ( ; ; ) { + /* exit when reaching the "RW" Tag */ +- if (SK_MEMCMP(VPD_RW,v,2) == 0) { ++ if (SK_MEMCMP(VPD_RW, v, 2) == 0) { + break; + } + +- if (SK_MEMCMP(VPD_RV,v,2) == 0) { ++ if (SK_MEMCMP(VPD_RV, v, 2) == 0) { + v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */ + continue; + } + +- if (n+3 <= *len) { +- SK_MEMCPY(buf,v,2); ++ if (n + 3 <= *len) { ++ SK_MEMCPY(buf, v, 2); + buf += 2; + *buf++ = '\0'; + n += 3; + v += 3 + VPD_GET_VPD_LEN(v); + *elements += 1; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, +- ("'%c%c' ",v[0],v[1])); ++ ("'%c%c' ", v[0], v[1])); + } + else { + *len = n; +@@ -867,6 +962,7 @@ + return(0); + } + ++#endif /* !SK_SLIM */ + + /* + * Read the contents of the VPD EEPROM and copy it to the +@@ -882,7 +978,7 @@ + * 6: fatal VPD error + */ + int VpdRead( +-SK_AC *pAC, /* common data base */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC, /* IO Context */ + const char *key, /* keyword to read (e.g. "MN") */ + char *buf, /* buffer where to copy the keyword value */ +@@ -891,6 +987,7 @@ + SK_VPD_PARA *p, vp; + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key)); ++ + if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { + if (VpdInit(pAC, IoC) != 0) { + *len = 0; +@@ -901,7 +998,7 @@ + } + + if ((p = vpd_find_para(pAC, key, &vp)) != NULL) { +- if (p->p_len > (*(unsigned *)len)-1) { ++ if (p->p_len > (*(unsigned *)len) - 1) { + p->p_len = *len - 1; + } + SK_MEMCPY(buf, p->p_val, p->p_len); +@@ -909,7 +1006,7 @@ + *len = p->p_len; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, + ("%c%c%c%c.., len = %d\n", +- buf[0],buf[1],buf[2],buf[3],*len)); ++ buf[0], buf[1], buf[2], buf[3], *len)); + } + else { + *len = 0; +@@ -919,7 +1016,7 @@ + return(0); + } + +- ++#ifndef SK_SLIM + /* + * Check whether a given key may be written + * +@@ -932,12 +1029,13 @@ + { + if ((*key != 'Y' && *key != 'V') || + key[1] < '0' || key[1] > 'Z' || +- (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) { ++ (key[1] > '9' && key[1] < 'A') || SK_STRLEN(key) != 2) { + + return(SK_FALSE); + } + return(SK_TRUE); + } ++#endif /* !SK_SLIM */ + + /* + * Read the contents of the VPD EEPROM and copy it to the VPD +@@ -953,7 +1051,7 @@ + * 6: fatal VPD error + */ + int VpdWrite( +-SK_AC *pAC, /* common data base */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC, /* IO Context */ + const char *key, /* keyword to write (allowed values "Yx", "Vx") */ + const char *buf) /* buffer where the keyword value can be read from */ +@@ -963,11 +1061,11 @@ + int rtv2; + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, +- ("VPD write %s = %s\n",key,buf)); ++ ("VPD write %s = %s\n", key, buf)); + + if ((*key != 'Y' && *key != 'V') || + key[1] < '0' || key[1] > 'Z' || +- (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) { ++ (key[1] > '9' && key[1] < 'A') || SK_STRLEN(key) != 2) { + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("illegal key tag, keyword not written\n")); +@@ -983,13 +1081,13 @@ + } + + rtv = 0; +- len = strlen(buf); ++ len = SK_STRLEN(buf); + if (len > VPD_MAX_LEN) { + /* cut it */ + len = VPD_MAX_LEN; + rtv = 2; + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, +- ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN)); ++ ("keyword too long, cut after %d bytes\n", VPD_MAX_LEN)); + } + if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, +@@ -1000,6 +1098,7 @@ + return(rtv); + } + ++#ifndef SK_SLIM + /* + * Read the contents of the VPD EEPROM and copy it to the + * VPD buffer if not already done. Remove the VPD keyword +@@ -1013,7 +1112,7 @@ + * 6: fatal VPD error + */ + int VpdDelete( +-SK_AC *pAC, /* common data base */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC, /* IO Context */ + char *key) /* keyword to read (e.g. "MN") */ + { +@@ -1023,7 +1122,7 @@ + + vpd_size = pAC->vpd.vpd_size; + +- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key)); ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD delete key %s\n", key)); + if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { + if (VpdInit(pAC, IoC) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, +@@ -1042,7 +1141,7 @@ + + etp = pAC->vpd.vpd_buf + (vpd_size-pAC->vpd.v.vpd_free_rw-1-3); + +- vpd_move_para(vp.p_val+vp.p_len, etp+2, ++ vpd_move_para(vp.p_val + vp.p_len, etp + 2, + - ((int)(vp.p_len + 3))); + if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) { + pAC->vpd.v.vpd_status &= ~VPD_VALID; +@@ -1059,6 +1158,7 @@ + + return(0); + } ++#endif /* !SK_SLIM */ + + /* + * If the VPD buffer contains valid data write the VPD +@@ -1068,7 +1168,7 @@ + * 3: VPD transfer timeout + */ + int VpdUpdate( +-SK_AC *pAC, /* Adapters context */ ++SK_AC *pAC, /* Adapters Context */ + SK_IOC IoC) /* IO Context */ + { + int vpd_size; +@@ -1089,3 +1189,51 @@ + return(0); + } + ++#ifndef SK_SLIM ++/* ++ * Read the contents of the VPD EEPROM and copy it to the VPD buffer ++ * if not already done. If the keyword "VF" is not present it will be ++ * created and the error log message will be stored to this keyword. ++ * If "VF" is not present the error log message will be stored to the ++ * keyword "VL". "VL" will created or overwritten if "VF" is present. ++ * The VPD read/write area is saved to the VPD EEPROM. ++ * ++ * returns nothing, errors will be ignored. ++ */ ++void VpdErrLog( ++SK_AC *pAC, /* Adapters Context */ ++SK_IOC IoC, /* IO Context */ ++char *msg) /* error log message */ ++{ ++ SK_VPD_PARA *v, vf; /* VF */ ++ int len; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ++ ("VPD error log msg %s\n", msg)); ++ ++ if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { ++ if (VpdInit(pAC, IoC) != 0) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ++ ("VPD init error\n")); ++ return; ++ } ++ } ++ ++ len = SK_STRLEN(msg); ++ if (len > VPD_MAX_LEN) { ++ /* cut it */ ++ len = VPD_MAX_LEN; ++ } ++ if ((v = vpd_find_para(pAC, VPD_VF, &vf)) != NULL) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("overwrite VL\n")); ++ (void)VpdSetupPara(pAC, VPD_VL, msg, len, VPD_RW_KEY, OWR_KEY); ++ } ++ else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("write VF\n")); ++ (void)VpdSetupPara(pAC, VPD_VF, msg, len, VPD_RW_KEY, ADD_KEY); ++ } ++ ++ (void)VpdUpdate(pAC, IoC); ++} ++#endif /* !SK_SLIM */ ++ +diff -ruN linux/drivers/net/sk98lin/skxmac2.c linux-new/drivers/net/sk98lin/skxmac2.c +--- linux/drivers/net/sk98lin/skxmac2.c 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/skxmac2.c 2007-01-24 13:58:33.000000000 +0100 +@@ -2,23 +2,24 @@ + * + * Name: skxmac2.c + * Project: Gigabit Ethernet Adapters, Common Modules +- * Version: $Revision$ +- * Date: $Date$ ++ * Version: $Revision$ ++ * Date: $Date$ + * Purpose: Contains functions to initialize the MACs and PHYs + * + ******************************************************************************/ + + /****************************************************************************** + * ++ * LICENSE: + * (C)Copyright 1998-2002 SysKonnect. +- * (C)Copyright 2002-2003 Marvell. ++ * (C)Copyright 2002-2007 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. ++ * /LICENSE + * + ******************************************************************************/ + +@@ -29,7 +30,7 @@ + + /* BCOM PHY magic pattern list */ + typedef struct s_PhyHack { +- int PhyReg; /* Phy register */ ++ int PhyReg; /* PHY register */ + SK_U16 PhyVal; /* Value to write */ + } BCOM_HACK; + +@@ -37,17 +38,17 @@ + + #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) + static const char SysKonnectFileId[] = +- "@(#) $Id$ (C) Marvell."; ++ "@(#) $Id$ (C) Marvell."; + #endif + + #ifdef GENESIS +-static BCOM_HACK BcomRegA1Hack[] = { ++BCOM_HACK BcomRegA1Hack[] = { + { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 }, + { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 }, + { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 }, + { 0, 0 } + }; +-static BCOM_HACK BcomRegC0Hack[] = { ++BCOM_HACK BcomRegC0Hack[] = { + { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 }, + { 0x15, 0x0A04 }, { 0x18, 0x0420 }, + { 0, 0 } +@@ -83,7 +84,7 @@ + * Returns: + * nothing + */ +-void SkXmPhyRead( ++int SkXmPhyRead( + SK_AC *pAC, /* Adapter Context */ + SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ +@@ -94,13 +95,13 @@ + SK_GEPORT *pPrt; + + pPrt = &pAC->GIni.GP[Port]; +- ++ + /* write the PHY register's address */ + XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr); +- ++ + /* get the PHY register's value */ + XM_IN16(IoC, Port, XM_PHY_DATA, pVal); +- ++ + if (pPrt->PhyType != SK_PHY_XMAC) { + do { + XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); +@@ -110,6 +111,8 @@ + /* get the PHY register's value */ + XM_IN16(IoC, Port, XM_PHY_DATA, pVal); + } ++ ++ return(0); + } /* SkXmPhyRead */ + + +@@ -122,7 +125,7 @@ + * Returns: + * nothing + */ +-void SkXmPhyWrite( ++int SkXmPhyWrite( + SK_AC *pAC, /* Adapter Context */ + SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ +@@ -133,26 +136,28 @@ + SK_GEPORT *pPrt; + + pPrt = &pAC->GIni.GP[Port]; +- ++ + if (pPrt->PhyType != SK_PHY_XMAC) { + do { + XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); + /* wait until 'Busy' is cleared */ + } while ((Mmu & XM_MMU_PHY_BUSY) != 0); + } +- ++ + /* write the PHY register's address */ + XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr); +- ++ + /* write the PHY register's value */ + XM_OUT16(IoC, Port, XM_PHY_DATA, Val); +- ++ + if (pPrt->PhyType != SK_PHY_XMAC) { + do { + XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); + /* wait until 'Busy' is cleared */ + } while ((Mmu & XM_MMU_PHY_BUSY) != 0); + } ++ ++ return(0); + } /* SkXmPhyWrite */ + #endif /* GENESIS */ + +@@ -165,63 +170,110 @@ + * Description: reads a 16-bit word from GPHY through MDIO + * + * Returns: +- * nothing ++ * 0 o.k. ++ * 1 error during MDIO read ++ * 2 timeout + */ +-void SkGmPhyRead( ++int SkGmPhyRead( + SK_AC *pAC, /* Adapter Context */ + SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + int PhyReg, /* Register Address (Offset) */ + SK_U16 SK_FAR *pVal) /* Pointer to Value */ + { ++ SK_U16 Word; + SK_U16 Ctrl; + SK_GEPORT *pPrt; +-#ifdef VCPU +- u_long SimCyle; +- u_long SimLowTime; +- +- VCPUgetTime(&SimCyle, &SimLowTime); +- VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n", +- PhyReg, SimCyle, SimLowTime); +-#endif /* VCPU */ +- ++ SK_U32 StartTime; ++ SK_U32 CurrTime; ++ SK_U32 Delta; ++ SK_U32 TimeOut; ++ int Rtv; ++ ++ Rtv = 0; ++ ++ *pVal = 0xffff; ++ + pPrt = &pAC->GIni.GP[Port]; +- ++ ++ /* additional check for MDC/MDIO activity */ ++ GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); ++ ++ if ((Ctrl & GM_SMI_CT_BUSY) != 0) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("PHY access in progress on Port %d (Ctrl=0x%04x)\n", Port, Ctrl)); ++ ++ return(1); ++ } ++ + /* set PHY-Register offset and 'Read' OpCode (= 1) */ +- *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | ++ Word = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | + GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD); + +- GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal); ++ GM_OUT16(IoC, Port, GM_SMI_CTRL, Word); + +- GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); +- + /* additional check for MDC/MDIO activity */ +- if ((Ctrl & GM_SMI_CT_BUSY) == 0) { +- *pVal = 0; +- return; ++ GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); ++ ++ if (Ctrl == 0xffff || (Ctrl & GM_SMI_CT_OP_RD) == 0) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("PHY read impossible on Port %d (Ctrl=0x%04x)\n", Port, Ctrl)); ++ ++ return(1); + } + +- *pVal |= GM_SMI_CT_BUSY; +- +- do { ++ Word |= GM_SMI_CT_BUSY; ++ ++ /* get current value of timestamp timer */ ++ SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime); ++ ++ /* set timeout to 10 ms */ ++ TimeOut = HW_MS_TO_TICKS(pAC, 10); ++ ++ do { /* wait until 'Busy' is cleared and 'ReadValid' is set */ + #ifdef VCPU + VCPUwaitTime(1000); + #endif /* VCPU */ + ++ /* get current value of timestamp timer */ ++ SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); ++ ++ if (CurrTime >= StartTime) { ++ Delta = CurrTime - StartTime; ++ } ++ else { ++ Delta = CurrTime + ~StartTime + 1; ++ } ++ ++ if (Delta > TimeOut) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("PHY read timeout on Port %d (Ctrl=0x%04x)\n", Port, Ctrl)); ++ Rtv = 2; ++ break; ++ } ++ + GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); + +- /* wait until 'ReadValid' is set */ +- } while (Ctrl == *pVal); +- +- /* get the PHY register's value */ ++ /* Error on reading SMI Control Register */ ++ if (Ctrl == 0xffff) { ++ return(1); ++ } ++ ++ } while ((Ctrl ^ Word) != (GM_SMI_CT_RD_VAL | GM_SMI_CT_BUSY)); ++ + GM_IN16(IoC, Port, GM_SMI_DATA, pVal); + +-#ifdef VCPU +- VCPUgetTime(&SimCyle, &SimLowTime); +- VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n", +- SimCyle, SimLowTime); +-#endif /* VCPU */ ++ /* dummy read after GM_IN16() */ ++ SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); + ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("SkGmPhyRead, Port: %d, Reg: %2d, Val = 0x%04X\n", ++ Port, PhyReg, *pVal)); ++ ++ return(Rtv); + } /* SkGmPhyRead */ + + +@@ -232,9 +284,11 @@ + * Description: writes a 16-bit word to GPHY through MDIO + * + * Returns: +- * nothing ++ * 0 o.k. ++ * 1 error during MDIO read ++ * 2 timeout + */ +-void SkGmPhyWrite( ++int SkGmPhyWrite( + SK_AC *pAC, /* Adapter Context */ + SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ +@@ -243,54 +297,80 @@ + { + SK_U16 Ctrl; + SK_GEPORT *pPrt; +-#ifdef VCPU +- SK_U32 DWord; +- u_long SimCyle; +- u_long SimLowTime; +- +- VCPUgetTime(&SimCyle, &SimLowTime); +- VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n", +- PhyReg, Val, SimCyle, SimLowTime); +-#endif /* VCPU */ +- ++ SK_U32 StartTime; ++ SK_U32 CurrTime; ++ SK_U32 Delta; ++ SK_U32 TimeOut; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("SkGmPhyWrite, Port: %d, Reg: %2d, Val = 0x%04X\n", ++ Port, PhyReg, Val)); ++ + pPrt = &pAC->GIni.GP[Port]; +- ++ + /* write the PHY register's value */ + GM_OUT16(IoC, Port, GM_SMI_DATA, Val); +- +- /* set PHY-Register offset and 'Write' OpCode (= 0) */ +- Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg); + +- GM_OUT16(IoC, Port, GM_SMI_CTRL, Val); +- +- GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); +- ++#ifdef DEBUG + /* additional check for MDC/MDIO activity */ +- if ((Ctrl & GM_SMI_CT_BUSY) == 0) { +- return; ++ GM_IN16(IoC, Port, GM_SMI_DATA, &Ctrl); ++ ++ if (Ctrl != Val) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("PHY write impossible on Port %d (Val=0x%04x)\n", Port, Ctrl)); ++ ++ return(1); + } +- +- Val |= GM_SMI_CT_BUSY; ++#endif /* DEBUG */ + +- do { +-#ifdef VCPU +- /* read Timer value */ +- SK_IN32(IoC, B2_TI_VAL, &DWord); ++ /* set PHY-Register offset and 'Write' OpCode (= 0) */ ++ Ctrl = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | ++ GM_SMI_CT_REG_AD(PhyReg)); + ++ GM_OUT16(IoC, Port, GM_SMI_CTRL, Ctrl); ++ ++ /* get current value of timestamp timer */ ++ SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime); ++ ++ /* set timeout to 10 ms */ ++ TimeOut = HW_MS_TO_TICKS(pAC, 10); ++ ++ do { /* wait until 'Busy' is cleared */ ++#ifdef VCPU + VCPUwaitTime(1000); + #endif /* VCPU */ + ++ /* get current value of timestamp timer */ ++ SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); ++ ++ if (CurrTime >= StartTime) { ++ Delta = CurrTime - StartTime; ++ } ++ else { ++ Delta = CurrTime + ~StartTime + 1; ++ } ++ ++ if (Delta > TimeOut) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("PHY write timeout on Port %d (Ctrl=0x%04x)\n", Port, Ctrl)); ++ return(2); ++ } ++ + GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); + +- /* wait until 'Busy' is cleared */ +- } while (Ctrl == Val); +- +-#ifdef VCPU +- VCPUgetTime(&SimCyle, &SimLowTime); +- VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n", +- SimCyle, SimLowTime); +-#endif /* VCPU */ ++ /* Error on reading SMI Control Register */ ++ if (Ctrl == 0xffff) { ++ return(1); ++ } + ++ } while ((Ctrl & GM_SMI_CT_BUSY) != 0); ++ ++ /* dummy read after GM_IN16() */ ++ SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); ++ ++ return(0); + } /* SkGmPhyWrite */ + #endif /* YUKON */ + +@@ -312,16 +392,8 @@ + int PhyReg, /* Register Address (Offset) */ + SK_U16 *pVal) /* Pointer to Value */ + { +- void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal); + +- if (pAC->GIni.GIGenesis) { +- r_func = SkXmPhyRead; +- } +- else { +- r_func = SkGmPhyRead; +- } +- +- r_func(pAC, IoC, Port, PhyReg, pVal); ++ pAC->GIni.GIFunc.pFnMacPhyRead(pAC, IoC, Port, PhyReg, pVal); + } /* SkGePhyRead */ + + +@@ -341,16 +413,8 @@ + int PhyReg, /* Register Address (Offset) */ + SK_U16 Val) /* Value */ + { +- void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val); + +- if (pAC->GIni.GIGenesis) { +- w_func = SkXmPhyWrite; +- } +- else { +- w_func = SkGmPhyWrite; +- } +- +- w_func(pAC, IoC, Port, PhyReg, Val); ++ pAC->GIni.GIFunc.pFnMacPhyWrite(pAC, IoC, Port, PhyReg, Val); + } /* SkGePhyWrite */ + #endif /* SK_DIAG */ + +@@ -360,15 +424,15 @@ + * SkMacPromiscMode() - Enable / Disable Promiscuous Mode + * + * Description: +- * enables / disables promiscuous mode by setting Mode Register (XMAC) or +- * Receive Control Register (GMAC) dep. on board type ++ * enables / disables promiscuous mode by setting Mode Register (XMAC) or ++ * Receive Control Register (GMAC) dep. on board type + * + * Returns: + * nothing + */ + void SkMacPromiscMode( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + SK_BOOL Enable) /* Enable / Disable */ + { +@@ -376,12 +440,12 @@ + SK_U16 RcReg; + #endif + #ifdef GENESIS +- SK_U32 MdReg; +-#endif ++ SK_U32 SK_FAR MdReg; ++#endif + + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +- ++ + XM_IN32(IoC, Port, XM_MODE, &MdReg); + /* enable or disable promiscuous mode */ + if (Enable) { +@@ -394,12 +458,12 @@ + XM_OUT32(IoC, Port, XM_MODE, MdReg); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { +- ++ + GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg); +- ++ + /* enable or disable unicast and multicast filtering */ + if (Enable) { + RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); +@@ -420,28 +484,28 @@ + * SkMacHashing() - Enable / Disable Hashing + * + * Description: +- * enables / disables hashing by setting Mode Register (XMAC) or +- * Receive Control Register (GMAC) dep. on board type ++ * enables / disables hashing by setting Mode Register (XMAC) or ++ * Receive Control Register (GMAC) dep. on board type + * + * Returns: + * nothing + */ + void SkMacHashing( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + SK_BOOL Enable) /* Enable / Disable */ + { + #ifdef YUKON + SK_U16 RcReg; +-#endif ++#endif + #ifdef GENESIS +- SK_U32 MdReg; ++ SK_U32 SK_FAR MdReg; + #endif + + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +- ++ + XM_IN32(IoC, Port, XM_MODE, &MdReg); + /* enable or disable hashing */ + if (Enable) { +@@ -454,12 +518,12 @@ + XM_OUT32(IoC, Port, XM_MODE, MdReg); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { +- ++ + GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg); +- ++ + /* enable or disable multicast filtering */ + if (Enable) { + RcReg |= GM_RXCR_MCF_ENA; +@@ -487,8 +551,8 @@ + * - don't set XMR_FS_ERR in status SK_LENERR_OK_ON/OFF + * for inrange length error frames + * - don't set XMR_FS_ERR in status SK_BIG_PK_OK_ON/OFF +- * for frames > 1514 bytes +- * - enable Rx of own packets SK_SELF_RX_ON/OFF ++ * for frames > 1514 bytes ++ * - enable Rx of own packets SK_SELF_RX_ON/OFF + * + * for incoming packets may be enabled/disabled by this function. + * Additional modes may be added later. +@@ -499,11 +563,11 @@ + * nothing + */ + static void SkXmSetRxCmd( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF, +- SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ ++ SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ + { + SK_U16 OldRxCmd; + SK_U16 RxCmd; +@@ -511,7 +575,7 @@ + XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd); + + RxCmd = OldRxCmd; +- ++ + switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) { + case SK_STRIP_FCS_ON: + RxCmd |= XM_RX_STRIP_FCS; +@@ -572,8 +636,8 @@ + * The features + * - FCS (CRC) stripping, SK_STRIP_FCS_ON/OFF + * - don't set GMR_FS_LONG_ERR SK_BIG_PK_OK_ON/OFF +- * for frames > 1514 bytes +- * - enable Rx of own packets SK_SELF_RX_ON/OFF ++ * for frames > 1514 bytes ++ * - enable Rx of own packets SK_SELF_RX_ON/OFF + * + * for incoming packets may be enabled/disabled by this function. + * Additional modes may be added later. +@@ -584,20 +648,17 @@ + * nothing + */ + static void SkGmSetRxCmd( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF, +- SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ ++ SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ + { +- SK_U16 OldRxCmd; + SK_U16 RxCmd; + + if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) { +- +- GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd); + +- RxCmd = OldRxCmd; ++ GM_IN16(IoC, Port, GM_RX_CTRL, &RxCmd); + + if ((Mode & SK_STRIP_FCS_ON) != 0) { + RxCmd |= GM_RXCR_CRC_DIS; +@@ -605,17 +666,13 @@ + else { + RxCmd &= ~GM_RXCR_CRC_DIS; + } +- /* Write the new mode to the Rx control register if required */ +- if (OldRxCmd != RxCmd) { +- GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd); +- } ++ /* Write the new mode to the Rx Control register */ ++ GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd); + } + + if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) { +- +- GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd); + +- RxCmd = OldRxCmd; ++ GM_IN16(IoC, Port, GM_SERIAL_MODE, &RxCmd); + + if ((Mode & SK_BIG_PK_OK_ON) != 0) { + RxCmd |= GM_SMOD_JUMBO_ENA; +@@ -623,10 +680,8 @@ + else { + RxCmd &= ~GM_SMOD_JUMBO_ENA; + } +- /* Write the new mode to the Rx control register if required */ +- if (OldRxCmd != RxCmd) { +- GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd); +- } ++ /* Write the new mode to the Serial Mode register */ ++ GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd); + } + } /* SkGmSetRxCmd */ + +@@ -641,17 +696,17 @@ + * nothing + */ + void SkMacSetRxCmd( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + int Mode) /* Rx Mode */ + { + if (pAC->GIni.GIGenesis) { +- ++ + SkXmSetRxCmd(pAC, IoC, Port, Mode); + } + else { +- ++ + SkGmSetRxCmd(pAC, IoC, Port, Mode); + } + +@@ -668,15 +723,15 @@ + * nothing + */ + void SkMacCrcGener( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + SK_BOOL Enable) /* Enable / Disable */ + { + SK_U16 Word; + + if (pAC->GIni.GIGenesis) { +- ++ + XM_IN16(IoC, Port, XM_TX_CMD, &Word); + + if (Enable) { +@@ -689,9 +744,9 @@ + XM_OUT16(IoC, Port, XM_TX_CMD, Word); + } + else { +- ++ + GM_IN16(IoC, Port, GM_TX_CTRL, &Word); +- ++ + if (Enable) { + Word &= ~GM_TXCR_CRC_DIS; + } +@@ -721,14 +776,14 @@ + * nothing + */ + void SkXmClrExactAddr( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + int StartNum, /* Begin with this Address Register Index (0..15) */ + int StopNum) /* Stop after finished with this Register Idx (0..15) */ + { + int i; +- SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000}; ++ SK_U16 ZeroAddr[3] = {0, 0, 0}; + + if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 || + StartNum > StopNum) { +@@ -738,7 +793,7 @@ + } + + for (i = StartNum; i <= StopNum; i++) { +- XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]); ++ XM_OUTADDR(IoC, Port, XM_EXM(i), ZeroAddr); + } + } /* SkXmClrExactAddr */ + #endif /* GENESIS */ +@@ -755,21 +810,21 @@ + * nothing + */ + void SkMacFlushTxFifo( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + #ifdef GENESIS +- SK_U32 MdReg; ++ SK_U32 SK_FAR MdReg; + + if (pAC->GIni.GIGenesis) { +- ++ + XM_IN32(IoC, Port, XM_MODE, &MdReg); + + XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { + /* no way to flush the FIFO we have to issue a reset */ +@@ -790,13 +845,13 @@ + * Returns: + * nothing + */ +-static void SkMacFlushRxFifo( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++void SkMacFlushRxFifo( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + #ifdef GENESIS +- SK_U32 MdReg; ++ SK_U32 SK_FAR MdReg; + + if (pAC->GIni.GIGenesis) { + +@@ -805,7 +860,7 @@ + XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { + /* no way to flush the FIFO we have to issue a reset */ +@@ -853,23 +908,23 @@ + * nothing + */ + static void SkXmSoftRst( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { +- SK_U16 ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000}; +- ++ SK_U16 ZeroAddr[4] = {0, 0, 0, 0}; ++ + /* reset the statistics module */ + XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT); + + /* disable all XMAC IRQs */ + XM_OUT16(IoC, Port, XM_IMSK, 0xffff); +- ++ + XM_OUT32(IoC, Port, XM_MODE, 0); /* clear Mode Reg */ +- ++ + XM_OUT16(IoC, Port, XM_TX_CMD, 0); /* reset TX CMD Reg */ + XM_OUT16(IoC, Port, XM_RX_CMD, 0); /* reset RX CMD Reg */ +- ++ + /* disable all PHY IRQs */ + switch (pAC->GIni.GP[Port].PhyType) { + case SK_PHY_BCOM: +@@ -887,13 +942,13 @@ + } + + /* clear the Hash Register */ +- XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr); ++ XM_OUTHASH(IoC, Port, XM_HSM, ZeroAddr); + + /* clear the Exact Match Address registers */ + SkXmClrExactAddr(pAC, IoC, Port, 0, 15); +- ++ + /* clear the Source Check Address registers */ +- XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr); ++ XM_OUTHASH(IoC, Port, XM_SRC_CHK, ZeroAddr); + + } /* SkXmSoftRst */ + +@@ -916,8 +971,8 @@ + * nothing + */ + static void SkXmHardRst( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_U32 Reg; +@@ -940,19 +995,19 @@ + } + + SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST); +- ++ + SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word); +- ++ + } while ((Word & MFF_SET_MAC_RST) == 0); + } + + /* For external PHYs there must be special handling */ + if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) { +- ++ + SK_IN32(IoC, B2_GP_IO, &Reg); +- ++ + if (Port == 0) { +- Reg |= GP_DIR_0; /* set to output */ ++ Reg |= GP_DIR_0; /* set to output */ + Reg &= ~GP_IO_0; /* set PHY reset (active low) */ + } + else { +@@ -978,12 +1033,12 @@ + * nothing + */ + static void SkXmClearRst( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_U32 DWord; +- ++ + /* clear HW reset */ + SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); + +@@ -1000,7 +1055,7 @@ + /* Clear PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + +- /* Enable GMII interface */ ++ /* enable GMII interface */ + XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD); + } + } /* SkXmClearRst */ +@@ -1020,29 +1075,34 @@ + * nothing + */ + static void SkGmSoftRst( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { +- SK_U16 EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000}; +- SK_U16 RxCtrl; ++ SK_U16 EmptyHash[4] = { 0x0000, 0x0000, 0x0000, 0x0000 }; ++ SK_U16 RxCtrl; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("SkGmSoftRst: Port %d\n", Port)); + + /* reset the statistics module */ ++ (void)SkGmResetCounter(pAC, IoC, Port); + + /* disable all GMAC IRQs */ +- SK_OUT8(IoC, GMAC_IRQ_MSK, 0); +- +- /* disable all PHY IRQs */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); +- ++ SK_OUT8(IoC, MR_ADDR(Port, GMAC_IRQ_MSK), 0); ++ ++ if (pAC->GIni.GP[Port].PState != SK_PRT_RESET) { ++ /* disable all PHY IRQs */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); ++ } ++ + /* clear the Hash Register */ + GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash); + +- /* Enable Unicast and Multicast filtering */ ++ /* enable Unicast and Multicast filtering */ + GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl); +- +- GM_OUT16(IoC, Port, GM_RX_CTRL, +- (SK_U16)(RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)); ++ ++ GM_OUT16(IoC, Port, GM_RX_CTRL, RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); + + } /* SkGmSoftRst */ + +@@ -1057,16 +1117,19 @@ + * nothing + */ + static void SkGmHardRst( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_U32 DWord; +- ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("SkGmHardRst: Port %d\n", Port)); ++ + /* WA code for COMA mode */ + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { +- ++ + SK_IN32(IoC, B2_GP_IO, &DWord); + + DWord |= (GP_DIR_9 | GP_IO_9); +@@ -1076,10 +1139,10 @@ + } + + /* set GPHY Control reset */ +- SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET); ++ SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_SET); + + /* set GMAC Control reset */ +- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); ++ SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_SET); + + } /* SkGmHardRst */ + +@@ -1094,24 +1157,25 @@ + * nothing + */ + static void SkGmClearRst( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_U32 DWord; +- +-#ifdef XXX +- /* clear GMAC Control reset */ +- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR); ++#ifdef SK_DIAG ++ SK_U16 PhyId0; ++ SK_U16 PhyId1; ++#endif /* SK_DIAG */ + +- /* set GMAC Control reset */ +- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); +-#endif /* XXX */ ++#if defined(SK_DIAG) || defined(DEBUG) ++ SK_U8 Byte; ++ SK_U16 Word; ++#endif /* SK_DIAG || DEBUG */ + + /* WA code for COMA mode */ + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { +- ++ + SK_IN32(IoC, B2_GP_IO, &DWord); + + DWord |= GP_DIR_9; /* set to output */ +@@ -1121,30 +1185,89 @@ + SK_OUT32(IoC, B2_GP_IO, DWord); + } + +- /* set HWCFG_MODE */ +- DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | +- GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE | +- (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP : +- GPC_HWCFG_GMII_FIB); ++#ifdef VCPU ++ /* set MAC Reset before PHY reset is set */ ++ SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_SET); ++#endif /* VCPU */ + +- /* set GPHY Control reset */ +- SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET); ++ if (CHIP_ID_YUKON_2(pAC)) { ++ /* set GPHY Control reset */ ++ SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_SET); + +- /* release GPHY Control reset */ +- SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR); ++ /* release GPHY Control reset */ ++ SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_CLR); ++ ++#ifdef DEBUG ++ /* additional check for PEX */ ++ SK_IN8(IoC, GPHY_CTRL, &Byte); ++ ++ Byte &= GPC_RST_CLR | GPC_RST_SET; ++ ++ if (pAC->GIni.GIPciBus == SK_PEX_BUS && Byte != GPC_RST_CLR) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("Error on PEX-bus after GPHY reset (GPHY Ctrl=0x%02X)\n", ++ Byte)); ++ } ++#endif /* DEBUG */ ++ } ++ else { ++ /* set HWCFG_MODE */ ++ DWord = GPC_INT_POL | GPC_DIS_FC | GPC_DIS_SLEEP | ++ GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE | ++ (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP : ++ GPC_HWCFG_GMII_FIB); ++ ++ /* set GPHY Control reset */ ++ SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET); ++ ++ /* release GPHY Control reset */ ++ SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR); ++ } + + #ifdef VCPU +- VCpuWait(9000); ++ /* wait for internal initialization of GPHY */ ++ VCPUprintf(0, "Waiting until PHY %d is ready to initialize\n", Port); ++ VCpuWait(10000); + #endif /* VCPU */ + + /* clear GMAC Control reset */ +- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); ++ SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR); ++ ++#ifdef VCPU ++ /* wait for stable GMAC clock */ ++ VCpuWait(9000); ++#endif /* VCPU */ ++ ++#ifdef SK_DIAG ++ if (HW_FEATURE(pAC, HWF_WA_DEV_472) && Port == MAC_2) { ++ ++ /* clear GMAC 1 Control reset */ ++ SK_OUT8(IoC, MR_ADDR(MAC_1, GMAC_CTRL), (SK_U8)GMC_RST_CLR); ++ ++ do { ++ /* set GMAC 2 Control reset */ ++ SK_OUT8(IoC, MR_ADDR(MAC_2, GMAC_CTRL), (SK_U8)GMC_RST_SET); ++ ++ /* clear GMAC 2 Control reset */ ++ SK_OUT8(IoC, MR_ADDR(MAC_2, GMAC_CTRL), (SK_U8)GMC_RST_CLR); ++ ++ SkGmPhyRead(pAC, IoC, MAC_2, PHY_MARV_ID0, &PhyId0); ++ ++ SkGmPhyRead(pAC, IoC, MAC_2, PHY_MARV_ID1, &PhyId1); ++ ++ SkGmPhyRead(pAC, IoC, MAC_2, PHY_MARV_INT_MASK, &Word); ++ ++ } while (Word != 0 || PhyId0 != PHY_MARV_ID0_VAL || ++ PhyId1 != PHY_MARV_ID1_Y2); ++ } ++#endif /* SK_DIAG */ + + #ifdef VCPU + VCpuWait(2000); +- ++ + SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord); +- ++ + SK_IN32(IoC, B0_ISRC, &DWord); + #endif /* VCPU */ + +@@ -1162,37 +1285,33 @@ + * nothing + */ + void SkMacSoftRst( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { +- SK_GEPORT *pPrt; +- +- pPrt = &pAC->GIni.GP[Port]; +- + /* disable receiver and transmitter */ + SkMacRxTxDisable(pAC, IoC, Port); + + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +- ++ + SkXmSoftRst(pAC, IoC, Port); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { +- ++ + SkGmSoftRst(pAC, IoC, Port); + } + #endif /* YUKON */ + + /* flush the MAC's Rx and Tx FIFOs */ + SkMacFlushTxFifo(pAC, IoC, Port); +- ++ + SkMacFlushRxFifo(pAC, IoC, Port); + +- pPrt->PState = SK_PRT_STOP; ++ pAC->GIni.GP[Port].PState = SK_PRT_STOP; + + } /* SkMacSoftRst */ + +@@ -1207,29 +1326,63 @@ + * nothing + */ + void SkMacHardRst( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { +- ++ + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +- ++ + SkXmHardRst(pAC, IoC, Port); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { +- ++ + SkGmHardRst(pAC, IoC, Port); + } + #endif /* YUKON */ + ++ pAC->GIni.GP[Port].PHWLinkUp = SK_FALSE; ++ + pAC->GIni.GP[Port].PState = SK_PRT_RESET; + + } /* SkMacHardRst */ + ++#ifndef SK_SLIM ++/****************************************************************************** ++ * ++ * SkMacClearRst() - Clear the MAC reset ++ * ++ * Description: calls a clear MAC reset routine dep. on board type ++ * ++ * Returns: ++ * nothing ++ */ ++void SkMacClearRst( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port) /* Port Index (MAC_1 + n) */ ++{ ++ ++#ifdef GENESIS ++ if (pAC->GIni.GIGenesis) { ++ ++ SkXmClearRst(pAC, IoC, Port); ++ } ++#endif /* GENESIS */ ++ ++#ifdef YUKON ++ if (pAC->GIni.GIYukon) { ++ ++ SkGmClearRst(pAC, IoC, Port); ++ } ++#endif /* YUKON */ ++ ++} /* SkMacClearRst */ ++#endif /* !SK_SLIM */ + + #ifdef GENESIS + /****************************************************************************** +@@ -1247,8 +1400,8 @@ + * nothing + */ + void SkXmInitMac( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; +@@ -1258,13 +1411,13 @@ + pPrt = &pAC->GIni.GP[Port]; + + if (pPrt->PState == SK_PRT_STOP) { +- /* Port State: SK_PRT_STOP */ + /* Verify that the reset bit is cleared */ + SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord); + + if ((SWord & MFF_SET_MAC_RST) != 0) { + /* PState does not match HW state */ +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("SkXmInitMac: PState does not match HW state")); + /* Correct it */ + pPrt->PState = SK_PRT_RESET; + } +@@ -1283,7 +1436,7 @@ + * Must be done AFTER first access to BCOM chip. + */ + XM_IN16(IoC, Port, XM_MMU_CMD, &SWord); +- ++ + XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE); + + if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) { +@@ -1316,7 +1469,7 @@ + * Disable Power Management after reset. + */ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord); +- ++ + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, + (SK_U16)(SWord | PHY_B_AC_DIS_PM)); + +@@ -1325,19 +1478,13 @@ + + /* Dummy read the Interrupt source register */ + XM_IN16(IoC, Port, XM_ISRC, &SWord); +- ++ + /* + * The auto-negotiation process starts immediately after + * clearing the reset. The auto-negotiation process should be + * started by the SIRQ, therefore stop it here immediately. + */ + SkMacInitPhy(pAC, IoC, Port, SK_FALSE); +- +-#ifdef TEST_ONLY +- /* temp. code: enable signal detect */ +- /* WARNING: do not override GMII setting above */ +- XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_COM4SIG); +-#endif + } + + /* +@@ -1351,7 +1498,7 @@ + * independent. Remember this when changing. + */ + SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord); +- ++ + XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord); + } + +@@ -1369,7 +1516,7 @@ + SWord = SK_XM_THR_SL; /* for single port */ + + if (pAC->GIni.GIMacsFound > 1) { +- switch (pAC->GIni.GIPortUsage) { ++ switch (pPrt->PPortUsage) { + case SK_RED_LINK: + SWord = SK_XM_THR_REDL; /* redundant link */ + break; +@@ -1392,7 +1539,7 @@ + /* setup register defaults for the Rx Command Register */ + SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK; + +- if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { ++ if (pPrt->PPortUsage == SK_JUMBO_LINK) { + SWord |= XM_RX_BIG_PK_OK; + } + +@@ -1404,7 +1551,7 @@ + */ + SWord |= XM_RX_DIS_CEXT; + } +- ++ + XM_OUT16(IoC, Port, XM_RX_CMD, SWord); + + /* +@@ -1461,8 +1608,8 @@ + * nothing + */ + void SkGmInitMac( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; +@@ -1472,27 +1619,45 @@ + + pPrt = &pAC->GIni.GP[Port]; + +- if (pPrt->PState == SK_PRT_STOP) { +- /* Port State: SK_PRT_STOP */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("SkGmInitMac: Port %d\n", Port)); ++ ++ if (pPrt->PState == SK_PRT_STOP) { + /* Verify that the reset bit is cleared */ + SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord); +- ++ + if ((DWord & GMC_RST_SET) != 0) { + /* PState does not match HW state */ +- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG); ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("SkGmInitMac: PState does not match HW state")); + /* Correct it */ + pPrt->PState = SK_PRT_RESET; + } ++ else { ++ /* enable PHY interrupts */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, ++ (SK_U16)PHY_M_DEF_MSK); ++ } + } + + if (pPrt->PState == SK_PRT_RESET) { +- ++ + SkGmHardRst(pAC, IoC, Port); + + SkGmClearRst(pAC, IoC, Port); +- ++ ++#ifndef SK_SLIM ++ if (HW_FEATURE(pAC, HWF_FORCE_AUTO_NEG) && ++ pPrt->PLinkModeConf < SK_LMODE_AUTOHALF) { ++ /* Force Auto-Negotiation */ ++ pPrt->PLinkMode = (pPrt->PLinkModeConf == SK_LMODE_FULL) ? ++ SK_LMODE_AUTOBOTH : SK_LMODE_AUTOHALF; ++ } ++#endif /* !SK_SLIM */ ++ + /* Auto-negotiation ? */ +- if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { ++ if (pPrt->PLinkMode == SK_LMODE_HALF || ++ pPrt->PLinkMode == SK_LMODE_FULL) { + /* Auto-negotiation disabled */ + + /* get General Purpose Control */ +@@ -1500,10 +1665,10 @@ + + /* disable auto-update for speed, duplex and flow-control */ + SWord |= GM_GPCR_AU_ALL_DIS; +- ++ + /* setup General Purpose Control Register */ + GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); +- ++ + SWord = GM_GPCR_AU_ALL_DIS; + } + else { +@@ -1514,7 +1679,10 @@ + switch (pPrt->PLinkSpeed) { + case SK_LSPEED_AUTO: + case SK_LSPEED_1000MBPS: +- SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100; ++ if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { ++ ++ SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100; ++ } + break; + case SK_LSPEED_100MBPS: + SWord |= GM_GPCR_SPEED_100; +@@ -1532,8 +1700,6 @@ + /* flow-control settings */ + switch (pPrt->PFlowCtrlMode) { + case SK_FLOW_MODE_NONE: +- /* set Pause Off */ +- SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF); + /* disable Tx & Rx flow-control */ + SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; + break; +@@ -1551,24 +1717,24 @@ + GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); + + /* dummy read the Interrupt Source Register */ +- SK_IN16(IoC, GMAC_IRQ_SRC, &SWord); +- ++ SK_IN16(IoC, MR_ADDR(Port, GMAC_IRQ_SRC), &SWord); ++ + #ifndef VCPU +- /* read Id from PHY */ +- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1); +- + SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); +-#endif /* VCPU */ ++#endif /* !VCPU */ + } + ++#ifndef VCPU /* saves some time in co-sim */ + (void)SkGmResetCounter(pAC, IoC, Port); ++#endif + + /* setup Transmit Control Register */ +- GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres)); ++ GM_OUT16(IoC, Port, GM_TX_CTRL, (SK_U16)TX_COL_THR(pPrt->PMacColThres)); + + /* setup Receive Control Register */ +- GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA | +- GM_RXCR_CRC_DIS); ++ SWord = GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA | GM_RXCR_CRC_DIS; ++ ++ GM_OUT16(IoC, Port, GM_RX_CTRL, SWord); + + /* setup Transmit Flow Control Register */ + GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff); +@@ -1578,31 +1744,29 @@ + GM_IN16(IoC, Port, GM_TX_PARAM, &SWord); + #endif /* VCPU */ + +- SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) | +- TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) | +- TX_IPG_JAM_DATA(pPrt->PMacJamIpgData); +- ++ SWord = (SK_U16)(TX_JAM_LEN_VAL(pPrt->PMacJamLen) | ++ TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) | ++ TX_IPG_JAM_DATA(pPrt->PMacJamIpgData) | ++ TX_BACK_OFF_LIM(pPrt->PMacBackOffLim)); ++ + GM_OUT16(IoC, Port, GM_TX_PARAM, SWord); + + /* configure the Serial Mode Register */ +-#ifdef VCPU +- GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord); +-#endif /* VCPU */ +- +- SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData); ++ SWord = (SK_U16)(DATA_BLIND_VAL(pPrt->PMacDataBlind) | ++ GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData)); + + if (pPrt->PMacLimit4) { + /* reset of collision counter after 4 consecutive collisions */ + SWord |= GM_SMOD_LIMIT_4; + } + +- if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { ++ if (pPrt->PPortUsage == SK_JUMBO_LINK) { + /* enable jumbo mode (Max. Frame Length = 9018) */ + SWord |= GM_SMOD_JUMBO_ENA; + } +- ++ + GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord); +- ++ + /* + * configure the GMACs Station Addresses + * in PROM you can find our addresses at: +@@ -1631,17 +1795,17 @@ + else { + GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord); + } +-#else ++#else + GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord); + #endif /* WA_DEV_16 */ +- ++ + /* virtual address: will be used for data */ + SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord); + + GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord); +- ++ + /* reset Multicast filtering Hash registers 1-3 */ +- GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0); ++ GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + i * 4, 0); + } + + /* reset Multicast filtering Hash register 4 */ +@@ -1652,17 +1816,7 @@ + GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0); + GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0); + +-#if defined(SK_DIAG) || defined(DEBUG) +- /* read General Purpose Status */ +- GM_IN16(IoC, Port, GM_GP_STAT, &SWord); +- +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("MAC Stat Reg.=0x%04X\n", SWord)); +-#endif /* SK_DIAG || DEBUG */ +- +-#ifdef SK_DIAG +- c_print("MAC Stat Reg=0x%04X\n", SWord); +-#endif /* SK_DIAG */ ++ pPrt->PState = SK_PRT_STOP; + + } /* SkGmInitMac */ + #endif /* YUKON */ +@@ -1681,9 +1835,9 @@ + * Returns: + * nothing + */ +-static void SkXmInitDupMd( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++void SkXmInitDupMd( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + switch (pAC->GIni.GP[Port].PLinkModeStatus) { +@@ -1729,23 +1883,23 @@ + * Returns: + * nothing + */ +-static void SkXmInitPauseMd( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++void SkXmInitPauseMd( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; +- SK_U32 DWord; ++ SK_U32 SK_FAR DWord; + SK_U16 Word; + + pPrt = &pAC->GIni.GP[Port]; + + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); +- ++ + if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE || + pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) { + +- /* Disable Pause Frame Reception */ ++ /* disable Pause Frame Reception */ + Word |= XM_MMU_IGN_PF; + } + else { +@@ -1753,10 +1907,10 @@ + * enabling pause frame reception is required for 1000BT + * because the XMAC is not reset if the link is going down + */ +- /* Enable Pause Frame Reception */ ++ /* enable Pause Frame Reception */ + Word &= ~XM_MMU_IGN_PF; +- } +- ++ } ++ + XM_OUT16(IoC, Port, XM_MMU_CMD, Word); + + XM_IN32(IoC, Port, XM_MODE, &DWord); +@@ -1779,10 +1933,10 @@ + /* remember this value is defined in big endian (!) */ + XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff); + +- /* Set Pause Mode in Mode Register */ ++ /* set Pause Mode in Mode Register */ + DWord |= XM_PAUSE_MODE; + +- /* Set Pause Mode in MAC Rx FIFO */ ++ /* set Pause Mode in MAC Rx FIFO */ + SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE); + } + else { +@@ -1790,22 +1944,22 @@ + * disable pause frame generation is required for 1000BT + * because the XMAC is not reset if the link is going down + */ +- /* Disable Pause Mode in Mode Register */ ++ /* disable Pause Mode in Mode Register */ + DWord &= ~XM_PAUSE_MODE; + +- /* Disable Pause Mode in MAC Rx FIFO */ ++ /* disable Pause Mode in MAC Rx FIFO */ + SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE); + } +- ++ + XM_OUT32(IoC, Port, XM_MODE, DWord); + } /* SkXmInitPauseMd*/ + + + /****************************************************************************** + * +- * SkXmInitPhyXmac() - Initialize the XMAC Phy registers ++ * SkXmInitPhyXmac() - Initialize the XMAC PHY registers + * +- * Description: initializes all the XMACs Phy registers ++ * Description: initializes all the XMACs PHY registers + * + * Note: + * +@@ -1813,22 +1967,22 @@ + * nothing + */ + static void SkXmInitPhyXmac( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ +-SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ ++SK_BOOL DoLoop) /* Should a PHY LoopBack be set-up? */ + { + SK_GEPORT *pPrt; + SK_U16 Ctrl; + + pPrt = &pAC->GIni.GP[Port]; + Ctrl = 0; +- ++ + /* Auto-negotiation ? */ + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyXmac: no auto-negotiation Port %d\n", Port)); +- /* Set DuplexMode in Config register */ ++ /* set DuplexMode in Config register */ + if (pPrt->PLinkMode == SK_LMODE_FULL) { + Ctrl |= PHY_CT_DUP_MD; + } +@@ -1841,9 +1995,9 @@ + else { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyXmac: with auto-negotiation Port %d\n", Port)); +- /* Set Auto-negotiation advertisement */ ++ /* set Auto-negotiation advertisement */ + +- /* Set Full/half duplex capabilities */ ++ /* set Full/half duplex capabilities */ + switch (pPrt->PLinkMode) { + case SK_LMODE_AUTOHALF: + Ctrl |= PHY_X_AN_HD; +@@ -1859,7 +2013,7 @@ + SKERR_HWI_E015MSG); + } + +- /* Set Flow-control capabilities */ ++ /* set Flow-control capabilities */ + switch (pPrt->PFlowCtrlMode) { + case SK_FLOW_MODE_NONE: + Ctrl |= PHY_X_P_NO_PAUSE; +@@ -1886,20 +2040,20 @@ + } + + if (DoLoop) { +- /* Set the Phy Loopback bit, too */ ++ /* set the PHY Loopback bit, too */ + Ctrl |= PHY_CT_LOOP; + } + +- /* Write to the Phy control register */ ++ /* Write to the PHY control register */ + SkXmPhyWrite(pAC, IoC, Port, PHY_XMAC_CTRL, Ctrl); + } /* SkXmInitPhyXmac */ + + + /****************************************************************************** + * +- * SkXmInitPhyBcom() - Initialize the Broadcom Phy registers ++ * SkXmInitPhyBcom() - Initialize the Broadcom PHY registers + * +- * Description: initializes all the Broadcom Phy registers ++ * Description: initializes all the Broadcom PHY registers + * + * Note: + * +@@ -1907,10 +2061,10 @@ + * nothing + */ + static void SkXmInitPhyBcom( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ +-SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ ++SK_BOOL DoLoop) /* Should a PHY LoopBack be set-up? */ + { + SK_GEPORT *pPrt; + SK_U16 Ctrl1; +@@ -1930,16 +2084,17 @@ + /* manually Master/Slave ? */ + if (pPrt->PMSMode != SK_MS_MODE_AUTO) { + Ctrl2 |= PHY_B_1000C_MSE; +- ++ + if (pPrt->PMSMode == SK_MS_MODE_MASTER) { + Ctrl2 |= PHY_B_1000C_MSC; + } + } ++ + /* Auto-negotiation ? */ + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyBcom: no auto-negotiation Port %d\n", Port)); +- /* Set DuplexMode in Config register */ ++ /* set DuplexMode in Config register */ + if (pPrt->PLinkMode == SK_LMODE_FULL) { + Ctrl1 |= PHY_CT_DUP_MD; + } +@@ -1957,7 +2112,7 @@ + else { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyBcom: with auto-negotiation Port %d\n", Port)); +- /* Set Auto-negotiation advertisement */ ++ /* set Auto-negotiation advertisement */ + + /* + * Workaround BCOM Errata #1 for the C5 type. +@@ -1965,8 +2120,8 @@ + * Set Repeater/DTE bit 10 of the 1000Base-T Control Register + */ + Ctrl2 |= PHY_B_1000C_RD; +- +- /* Set Full/half duplex capabilities */ ++ ++ /* set Full/half duplex capabilities */ + switch (pPrt->PLinkMode) { + case SK_LMODE_AUTOHALF: + Ctrl2 |= PHY_B_1000C_AHD; +@@ -1982,7 +2137,7 @@ + SKERR_HWI_E015MSG); + } + +- /* Set Flow-control capabilities */ ++ /* set Flow-control capabilities */ + switch (pPrt->PFlowCtrlMode) { + case SK_FLOW_MODE_NONE: + Ctrl3 |= PHY_B_P_NO_PAUSE; +@@ -2004,27 +2159,27 @@ + /* Restart Auto-negotiation */ + Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; + } +- ++ + /* Initialize LED register here? */ + /* No. Please do it in SkDgXmitLed() (if required) and swap +- init order of LEDs and XMAC. (MAl) */ +- ++ init order of LEDs and XMAC. (MAl) */ ++ + /* Write 1000Base-T Control Register */ + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); +- ++ ("Set 1000B-T Ctrl Reg = 0x%04X\n", Ctrl2)); ++ + /* Write AutoNeg Advertisement Register */ + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); +- ++ ("Set Auto-Neg.Adv.Reg = 0x%04X\n", Ctrl3)); ++ + if (DoLoop) { +- /* Set the Phy Loopback bit, too */ ++ /* set the PHY Loopback bit, too */ + Ctrl1 |= PHY_CT_LOOP; + } + +- if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { ++ if (pPrt->PPortUsage == SK_JUMBO_LINK) { + /* configure FIFO to high latency for transmission of ext. packets */ + Ctrl4 |= PHY_B_PEC_HIGH_LA; + +@@ -2036,20 +2191,591 @@ + + /* Configure LED Traffic Mode and Jumbo Frame usage if specified */ + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4); +- +- /* Write to the Phy control register */ ++ ++ /* Write to the PHY control register */ + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("PHY Control Reg=0x%04X\n", Ctrl1)); ++ ("PHY Control Reg = 0x%04X\n", Ctrl1)); + } /* SkXmInitPhyBcom */ + #endif /* GENESIS */ + ++ + #ifdef YUKON ++#ifdef SK_PHY_LP_MODE ++/****************************************************************************** ++ * ++ * SkGmEnterLowPowerMode() ++ * ++ * Description: ++ * This function sets the Marvell Alaska PHY to the low power mode ++ * given by parameter mode. ++ * The following low power modes are available: ++ * ++ * - COMA Mode (Deep Sleep): ++ * The PHY cannot wake up on its own. ++ * ++ * - IEEE 22.2.4.1.5 compatible power down mode ++ * The PHY cannot wake up on its own. ++ * ++ * - energy detect mode ++ * The PHY can wake up on its own by detecting activity ++ * on the CAT 5 cable. ++ * ++ * - energy detect plus mode ++ * The PHY can wake up on its own by detecting activity ++ * on the CAT 5 cable. ++ * Connected devices can be woken up by sending normal link ++ * pulses every second. ++ * ++ * Note: ++ * ++ * Returns: ++ * 0: ok ++ * 1: error ++ */ ++int SkGmEnterLowPowerMode( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (e.g. MAC_1) */ ++SK_U8 Mode) /* low power mode */ ++{ ++ SK_U8 LastMode; ++ SK_U8 Byte; ++ SK_U16 Word; ++ SK_U16 ClkDiv; ++ SK_U32 DWord; ++ SK_U32 PowerDownBit; ++ int ChipId; ++ int Ret = 0; ++ ++ if (!(CHIP_ID_YUKON_2(pAC) || (pAC->GIni.GIYukonLite && ++ pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3))) { ++ ++ return(1); ++ } ++ ++ /* save current power mode */ ++ LastMode = pAC->GIni.GP[Port].PPhyPowerState; ++ pAC->GIni.GP[Port].PPhyPowerState = Mode; ++ ++ ChipId = pAC->GIni.GIChipId; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_POWM, SK_DBGCAT_CTRL, ++ ("SkGmEnterLowPowerMode: %u\n", Mode)); ++ ++ /* release GPHY Control reset */ ++ SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_CLR); ++ ++ /* release GMAC reset */ ++ SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR); ++ ++ if (ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX) { ++ /* select page 2 to access MAC control register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 2); ++ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); ++ /* allow GMII Power Down */ ++ Word &= ~PHY_M_MAC_GMIF_PUP; ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); ++ } ++ ++ switch (Mode) { ++ /* COMA mode (deep sleep) */ ++ case PHY_PM_DEEP_SLEEP: ++ /* setup General Purpose Control Register */ ++ GM_OUT16(IoC, Port, GM_GP_CTRL, GM_GPCR_FL_PASS | ++ GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS); ++ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ /* set power down bit */ ++ PowerDownBit = (Port == MAC_1) ? PCI_Y2_PHY1_POWD : ++ PCI_Y2_PHY2_POWD; ++ ++ if (ChipId != CHIP_ID_YUKON_EC) { ++ ++ if (ChipId == CHIP_ID_YUKON_EC_U) { ++ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); ++ /* enable Power Down */ ++ Word |= PHY_M_PC_POW_D_ENA; ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); ++ } ++ ++ /* set IEEE compatible Power Down Mode (dev. #4.99) */ ++ Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_PDOWN); ++ } ++ } ++ else { ++ /* apply COMA mode workaround for Yukon-Plus*/ ++ (void)SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 0x001f); ++ ++ Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xfff3); ++ ++ PowerDownBit = PCI_PHY_COMA; ++ } ++ ++ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); ++ ++ SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord); ++ ++ /* set PHY to PowerDown/COMA Mode */ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord | PowerDownBit); ++ ++ /* check if this routine was called from a for() loop */ ++ if (CHIP_ID_YUKON_2(pAC) && ++ (pAC->GIni.GIMacsFound == 1 || Port == MAC_2)) { ++ ++ /* ASF system clock stopped */ ++ SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, (SK_U8)Y2_ASF_CLK_HALT); ++ ++ if (ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX) { ++ /* set GPHY Control reset */ ++ SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_SET); ++ ++ /* additional power saving measurements */ ++ SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_4), &DWord); ++ ++ if (pAC->GIni.GIGotoD3Cold) { ++ /* set gating core clock for LTSSM in DETECT state */ ++ DWord |= (P_PEX_LTSSM_STAT(P_PEX_LTSSM_DET_STAT) | ++ /* enable Gate Root Core Clock */ ++ P_CLK_GATE_ROOT_COR_ENA); ++ ++ /* set Mask Register for Release/Gate Clock */ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5), ++ P_REL_MAIN_PWR_AVAIL | P_GAT_MAIN_PWR_N_AVAIL); ++ } ++ else { ++ /* set gating core clock for LTSSM in L1 state */ ++ DWord |= (P_PEX_LTSSM_STAT(P_PEX_LTSSM_L1_STAT) | ++ /* auto clock gated scheme controlled by CLKREQ */ ++ P_ASPM_A1_MODE_SELECT | ++ /* enable Gate Root Core Clock */ ++ P_CLK_GATE_ROOT_COR_ENA); ++ ++ if (HW_FEATURE(pAC, HWF_WA_DEV_4200)) { ++ /* enable Clock Power Management (CLKREQ) */ ++ SK_IN16(IoC, PCI_C(pAC, PEX_LNK_CTRL), &Word); ++ Word |= PEX_LC_CLK_PM_ENA; ++ SK_OUT16(IoC, PCI_C(pAC, PEX_LNK_CTRL), Word); ++ } ++ else { ++ /* force CLKREQ Enable in Our4 (A1b only) */ ++ DWord |= P_ASPM_FORCE_CLKREQ_ENA; ++ } ++ ++ /* set Mask Register for Release/Gate Clock */ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5), ++ P_REL_PCIE_EXIT_L1_ST | P_GAT_PCIE_ENTER_L1_ST | ++ P_REL_PCIE_RX_EX_IDLE | P_GAT_PCIE_RX_EL_IDLE | ++ P_REL_GPHY_LINK_UP | P_GAT_GPHY_LINK_DOWN); ++ } ++ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_4), DWord); ++ } ++ ++ if (HW_FEATURE(pAC, HWF_RED_CORE_CLK_SUP)) { ++ /* divide clock by 4 only for Yukon-EC */ ++ ClkDiv = (ChipId == CHIP_ID_YUKON_EC) ? 1 : 0; ++ ++ /* on Yukon-2 clock select value is 31 */ ++ DWord = (ChipId == CHIP_ID_YUKON_XL) ? ++ (Y2_CLK_DIV_VAL_2(0) | Y2_CLK_SEL_VAL_2(31)) : ++ Y2_CLK_DIV_VAL(ClkDiv); ++ ++ /* check for Yukon-2 dual port PCI-Express adapter */ ++ if (!(pAC->GIni.GIMacsFound == 2 && ++ pAC->GIni.GIPciBus == SK_PEX_BUS)) { ++ /* enable Core Clock Division */ ++ DWord |= Y2_CLK_DIV_ENA; ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Set Core Clock: 0x%08X\n", DWord)); ++ ++ /* reduce Core Clock Frequency */ ++ SK_OUT32(IoC, B2_Y2_CLK_CTRL, DWord); ++ } ++ ++ if (HW_FEATURE(pAC, HWF_CLK_GATING_ENABLE)) { ++ /* check for Yukon-2 Rev. A2 */ ++ if (ChipId == CHIP_ID_YUKON_XL && ++ pAC->GIni.GIChipRev > CHIP_REV_YU_XL_A1) { ++ /* enable bits are inverted */ ++ Byte = 0; ++ } ++ else { ++ Byte = (SK_U8)(Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | ++ Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS | ++ Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS); ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Set Clock Gating: 0x%02X\n", Byte)); ++ ++ /* disable MAC/PHY, PCI and Core Clock for both Links */ ++ SK_OUT8(IoC, B2_Y2_CLK_GATE, Byte); ++ } ++ ++ if (pAC->GIni.GIVauxAvail) { ++ /* switch power to VAUX */ ++ SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | ++ PC_VAUX_ON | PC_VCC_OFF)); ++ } ++#ifdef DEBUG ++ SK_IN32(IoC, B0_CTST, &DWord); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Ctrl/Stat & Switch: 0x%08x\n", DWord)); ++#endif /* DEBUG */ ++ ++ if (pAC->GIni.GILevel != SK_INIT_IO && ++ pAC->GIni.GIMacsFound == 1 && ++ pAC->GIni.GIPciBus == SK_PEX_BUS) { ++ ++ if (ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX) { ++ ++#ifdef PCI_E_L1_STATE ++ SK_IN16(IoC, PCI_C(pAC, PCI_OUR_REG_1), &Word); ++ /* force to PCIe L1 */ ++ Word |= (SK_U16)PCI_FORCE_PEX_L1; ++ SK_OUT16(IoC, PCI_C(pAC, PCI_OUR_REG_1), Word); ++#else /* !PCI_E_L1_STATE */ ++ ++#ifdef DEEP_SLEEP_D1 ++ SK_IN16(IoC, PCI_C(pAC, PEX_LNK_CTRL), &Word); ++ /* check if ASPM L1 enabled */ ++ if ((Word & PEX_LC_ASPM_LC_L1) != 0) { ++ break; ++ } ++#else ++ break; ++#endif /* !DEEP_SLEEP_D1 */ ++ ++#endif /* !PCI_E_L1_STATE */ ++ } ++ ++ /* switch to D1 state */ ++ SK_OUT8(IoC, PCI_C(pAC, PCI_PM_CTL_STS), PCI_PM_STATE_D1); ++ } ++ } ++ ++ break; ++ ++ /* IEEE 22.2.4.1.5 compatible power down mode */ ++ case PHY_PM_IEEE_POWER_DOWN: ++ ++ if (!CHIP_ID_YUKON_2(pAC) && !pAC->GIni.GIYukonLite) { ++ ++ Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); ++ ++ /* disable MAC 125 MHz clock */ ++ Word |= PHY_M_PC_DIS_125CLK; ++ Word &= ~PHY_M_PC_MAC_POW_UP; ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); ++ ++ /* these register changes must be followed by a software reset */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word | PHY_CT_RESET); ++ } ++ ++ /* switch IEEE compatible power down mode on */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_PDOWN); ++ ++ break; ++ ++ /* energy detect and energy detect plus mode */ ++ case PHY_PM_ENERGY_DETECT: ++ case PHY_PM_ENERGY_DETECT_PLUS: ++ ++ Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); ++ ++#ifdef XXX ++ /* disable Polarity Reversal */ ++ Word |= PHY_M_PC_POL_R_DIS; ++#endif /* XXX */ ++ ++ if (!CHIP_ID_YUKON_2(pAC)) { ++ /* disable MAC 125 MHz clock */ ++ Word |= PHY_M_PC_DIS_125CLK; ++ } ++ ++ if (ChipId == CHIP_ID_YUKON_FE) { ++ /* enable Energy Detect (sense & pulse) */ ++ Word |= PHY_M_PC_ENA_ENE_DT; ++ } ++ else { ++ /* clear energy detect mode bits */ ++ Word &= ~PHY_M_PC_EN_DET_MSK; ++ ++ Word |= (Mode == PHY_PM_ENERGY_DETECT) ? PHY_M_PC_EN_DET : ++ PHY_M_PC_EN_DET_PLUS; ++ } ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); ++ ++ /* these register changes must be followed by a software reset */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); ++ Word |= PHY_CT_RESET; ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); ++ ++ if (ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX) { ++ /* additional power saving measurements */ ++ SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_4), &DWord); ++ ++ if (pAC->GIni.GIGotoD3Cold) { ++ /* set gating core clock for LTSSM in DETECT state */ ++ DWord |= (P_PEX_LTSSM_STAT(P_PEX_LTSSM_DET_STAT) | ++ /* enable Gate Root Core Clock */ ++ P_CLK_GATE_ROOT_COR_ENA); ++ ++ /* set Mask Register for Release/Gate Clock */ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5), ++ P_REL_MAIN_PWR_AVAIL | P_GAT_MAIN_PWR_N_AVAIL); ++ } ++ else { ++ /* set gating core clock for LTSSM in L1 state */ ++ DWord |= (P_PEX_LTSSM_STAT(P_PEX_LTSSM_L1_STAT) | ++ /* auto clock gated scheme controlled by CLKREQ */ ++ P_ASPM_A1_MODE_SELECT | ++ /* enable Gate Root Core Clock */ ++ P_CLK_GATE_ROOT_COR_ENA); ++ ++ if (HW_FEATURE(pAC, HWF_WA_DEV_4200)) { ++ /* enable Clock Power Management (CLKREQ) */ ++ SK_IN16(IoC, PCI_C(pAC, PEX_LNK_CTRL), &Word); ++ Word |= PEX_LC_CLK_PM_ENA; ++ SK_OUT16(IoC, PCI_C(pAC, PEX_LNK_CTRL), Word); ++ } ++ else { ++ /* force CLKREQ Enable in Our4 (A1b only) */ ++ DWord |= P_ASPM_FORCE_CLKREQ_ENA; ++ } ++ ++ /* set Mask Register for Release/Gate Clock */ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5), ++ P_REL_PCIE_EXIT_L1_ST | P_GAT_PCIE_ENTER_L1_ST | ++ P_REL_PCIE_RX_EX_IDLE | P_GAT_PCIE_RX_EL_IDLE | ++ P_REL_GPHY_LINK_UP | P_GAT_GPHY_LINK_DOWN); ++ } ++ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_4), DWord); ++ ++#ifdef PCI_E_L1_STATE ++ SK_IN16(IoC, PCI_C(pAC, PCI_OUR_REG_1), &Word); ++ /* enable PCIe L1 on GPHY link down */ ++ Word |= (SK_U16)PCI_ENA_GPHY_LNK; ++ SK_OUT16(IoC, PCI_C(pAC, PCI_OUR_REG_1), Word); ++#endif /* PCI_E_L1_STATE */ ++ } ++ ++ pAC->GIni.GP[Port].PState = SK_PRT_STOP; ++ break; ++ ++ /* don't change current power mode */ ++ default: ++ pAC->GIni.GP[Port].PPhyPowerState = LastMode; ++ Ret = 1; ++ } ++ ++ return(Ret); ++ ++} /* SkGmEnterLowPowerMode */ ++ + /****************************************************************************** + * +- * SkGmInitPhyMarv() - Initialize the Marvell Phy registers ++ * SkGmLeaveLowPowerMode() + * +- * Description: initializes all the Marvell Phy registers ++ * Description: ++ * Leave the current low power mode and switch to normal mode ++ * ++ * Note: ++ * ++ * Returns: ++ * 0: ok ++ * 1: error ++ */ ++int SkGmLeaveLowPowerMode( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port) /* Port Index (e.g. MAC_1) */ ++{ ++ SK_U32 DWord; ++ SK_U32 PowerDownBit; ++ SK_U16 Word; ++ SK_U8 LastMode; ++ int ChipId; ++ int Ret = 0; ++ ++ if (!(CHIP_ID_YUKON_2(pAC) || (pAC->GIni.GIYukonLite && ++ pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3))) { ++ ++ return(1); ++ } ++ ++ /* save current power mode */ ++ LastMode = pAC->GIni.GP[Port].PPhyPowerState; ++ pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE; ++ ++ ChipId = pAC->GIni.GIChipId; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_POWM, SK_DBGCAT_CTRL, ++ ("SkGmLeaveLowPowerMode: %u\n", LastMode)); ++ ++ switch (LastMode) { ++ /* COMA mode (deep sleep) */ ++ case PHY_PM_DEEP_SLEEP: ++ ++ if (ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX) { ++#ifdef PCI_E_L1_STATE ++ SkPciReadCfgWord(pAC, PCI_OUR_REG_1, &Word); ++ ++ /* set the default value into bits 6 & 5 */ ++ Word &= ~(SK_U16)(PCI_ENA_GPHY_LNK | PCI_FORCE_PEX_L1); ++ ++ SkPciWriteCfgWord(pAC, PCI_OUR_REG_1, Word); ++#endif /* PCI_E_L1_STATE */ ++ ++ SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_4), &DWord); ++ ++ DWord &= P_ASPM_CONTROL_MSK; ++ /* set all bits to 0 except bits 15..12 */ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_4), DWord); ++ ++ /* set to default value */ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5), 0); ++ } ++ ++ SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &Word); ++ ++ if ((Word & PCI_PM_STATE_MSK) != 0) { ++ /* switch to D0 state */ ++ SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, Word & ~PCI_PM_STATE_MSK); ++ } ++ ++ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); ++ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ /* disable Core Clock Division */ ++ SK_OUT32(IoC, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS); ++ ++ /* set power down bit */ ++ PowerDownBit = (Port == MAC_1) ? PCI_Y2_PHY1_POWD : ++ PCI_Y2_PHY2_POWD; ++ } ++ else { ++ PowerDownBit = PCI_PHY_COMA; ++ } ++ ++ SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord); ++ ++ /* Release PHY from PowerDown/COMA Mode */ ++ SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord & ~PowerDownBit); ++ ++ SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); ++ ++ if (CHIP_ID_YUKON_2(pAC)) { ++ ++ if (ChipId == CHIP_ID_YUKON_FE) { ++ /* release IEEE compatible Power Down Mode */ ++ Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_ANE); ++ } ++ else if (ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX) { ++ /* release GPHY Control reset */ ++ SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_CLR); ++ } ++ } ++ else { ++ SK_IN32(IoC, B2_GP_IO, &DWord); ++ ++ /* set to output */ ++ DWord |= (GP_DIR_9 | GP_IO_9); ++ ++ /* set PHY reset */ ++ SK_OUT32(IoC, B2_GP_IO, DWord); ++ ++ DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ ++ ++ /* clear PHY reset */ ++ SK_OUT32(IoC, B2_GP_IO, DWord); ++ } ++ ++ break; ++ ++ /* IEEE 22.2.4.1.5 compatible power down mode */ ++ case PHY_PM_IEEE_POWER_DOWN: ++ ++ if (ChipId != CHIP_ID_YUKON_XL) { ++ ++ Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); ++ Word &= ~PHY_M_PC_DIS_125CLK; /* enable MAC 125 MHz clock */ ++ Word |= PHY_M_PC_MAC_POW_UP; /* set MAC power up */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); ++ ++ /* these register changes must be followed by a software reset */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); ++ Word |= PHY_CT_RESET; ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); ++ } ++ ++ /* switch IEEE compatible power down mode off */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); ++ Word &= ~PHY_CT_PDOWN; ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); ++ ++ break; ++ ++ /* energy detect and energy detect plus mode */ ++ case PHY_PM_ENERGY_DETECT: ++ case PHY_PM_ENERGY_DETECT_PLUS: ++ ++ if (ChipId != CHIP_ID_YUKON_XL) { ++ ++ Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); ++ ++ if (ChipId == CHIP_ID_YUKON_FE) { ++ /* disable Energy Detect */ ++ Word &= ~PHY_M_PC_ENA_ENE_DT; ++ } ++ else { ++ /* disable energy detect mode & enable MAC 125 MHz clock */ ++ Word &= ~(PHY_M_PC_EN_DET_MSK | PHY_M_PC_DIS_125CLK); ++ } ++ ++#ifdef XXX ++ /* enable Polarity Reversal */ ++ Word &= ~PHY_M_PC_POL_R_DIS; ++#endif /* XXX */ ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); ++ ++ /* these register changes must be followed by a software reset */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); ++ Word |= PHY_CT_RESET; ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); ++ } ++ break; ++ ++ /* don't change current power mode */ ++ default: ++ pAC->GIni.GP[Port].PPhyPowerState = LastMode; ++ Ret = 1; ++ } ++ ++ return(Ret); ++ ++} /* SkGmLeaveLowPowerMode */ ++#endif /* SK_PHY_LP_MODE */ ++ ++/****************************************************************************** ++ * ++ * SkGmInitPhyMarv() - Initialize the Marvell PHY registers ++ * ++ * Description: initializes all the Marvell PHY registers + * + * Note: + * +@@ -2057,107 +2783,248 @@ + * nothing + */ + static void SkGmInitPhyMarv( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ +-SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ ++SK_BOOL DoLoop) /* Should a PHY LoopBack be set-up? */ + { + SK_GEPORT *pPrt; ++ SK_BOOL AutoNeg; + SK_U16 PhyCtrl; + SK_U16 C1000BaseT; + SK_U16 AutoNegAdv; ++ SK_U8 PauseMode; ++ int ChipId; ++ int Mode; ++#ifndef VCPU ++ SK_U16 Word; ++ SK_U16 PageReg; ++#ifndef SK_SLIM ++ SK_U16 LoopSpeed; ++#endif /* !SK_SLIM */ + SK_U16 ExtPhyCtrl; ++ SK_U16 BlinkCtrl; + SK_U16 LedCtrl; +- SK_BOOL AutoNeg; ++ SK_U16 LedConf; ++ SK_U16 LedOver; ++#ifndef SK_DIAG ++ SK_EVPARA Para; ++#endif /* !SK_DIAG */ + #if defined(SK_DIAG) || defined(DEBUG) + SK_U16 PhyStat; + SK_U16 PhyStat1; + SK_U16 PhySpecStat; + #endif /* SK_DIAG || DEBUG */ ++#endif /* !VCPU */ ++ ++ /* set Pause On */ ++ PauseMode = (SK_U8)GMC_PAUSE_ON; + + pPrt = &pAC->GIni.GP[Port]; + ++ ChipId = pAC->GIni.GIChipId; ++ + /* Auto-negotiation ? */ +- if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { +- AutoNeg = SK_FALSE; ++ AutoNeg = pPrt->PLinkMode != SK_LMODE_HALF && ++ pPrt->PLinkMode != SK_LMODE_FULL; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("InitPhyMarv: Port %d, Auto-neg. %s, LMode %d, LSpeed %d, FlowC %d\n", ++ Port, AutoNeg ? "ON" : "OFF", ++ pPrt->PLinkMode, pPrt->PLinkSpeed, pPrt->PFlowCtrlMode)); ++ ++#ifndef VCPU ++ /* read Id from PHY */ ++ if (SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1) != 0) { ++ ++#ifndef SK_DIAG ++ Para.Para64 = Port; ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); ++#endif /* !SK_DIAG */ ++ ++ return; + } +- else { +- AutoNeg = SK_TRUE; ++ ++ if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { ++ ++#ifndef SK_SLIM ++ if (DoLoop) { ++ /* special setup for PHY 88E1112 */ ++ if (ChipId == CHIP_ID_YUKON_XL) { ++ ++ LoopSpeed = pPrt->PLinkSpeed; ++ ++ if (LoopSpeed == SK_LSPEED_AUTO) { ++ /* force 1000 Mbps */ ++ LoopSpeed = SK_LSPEED_1000MBPS; ++ } ++ LoopSpeed += 2; ++ ++ /* save page register */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_ADR, &PageReg); ++ ++ /* select page 2 to access MAC control register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 2); ++ ++ /* set MAC interface speed */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, LoopSpeed << 4); ++ ++ /* restore page register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, PageReg); ++ ++ /* disable link pulses */ ++ Word = PHY_M_PC_DIS_LINK_P; ++ } ++ else { ++ /* set 'MAC Power up'-bit, set Manual MDI configuration */ ++ Word = PHY_M_PC_MAC_POW_UP; ++ } ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); ++ } ++ else ++#endif /* !SK_SLIM */ ++ if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO && ++ !(ChipId == CHIP_ID_YUKON_XL || ++ ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX)) { ++ /* Read Ext. PHY Specific Control */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); ++ ++ ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | ++ PHY_M_EC_MAC_S_MSK); ++ ++ ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ); ++ ++ /* on PHY 88E1040 Rev.D0 (and newer) downshift control changed */ ++ if (pAC->GIni.GIYukonLite || ChipId == CHIP_ID_YUKON_EC) { ++ /* set downshift counter to 3x and enable downshift */ ++ ExtPhyCtrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA; ++ } ++ else { ++ /* set master & slave downshift counter to 1x */ ++ ExtPhyCtrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); ++ } ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl); ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Set Ext. PHY Ctrl = 0x%04X\n", ExtPhyCtrl)); ++ } + } +- +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("InitPhyMarv: Port %d, auto-negotiation %s\n", +- Port, AutoNeg ? "ON" : "OFF")); + +-#ifdef VCPU +- VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n", +- Port, DoLoop); +-#else /* VCPU */ +- if (DoLoop) { +- /* Set 'MAC Power up'-bit, set Manual MDI configuration */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, +- PHY_M_PC_MAC_POW_UP); ++ if (CHIP_ID_YUKON_2(pAC)) { ++ /* Read PHY Specific Control */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &PhyCtrl); ++ ++ if (!DoLoop && pAC->GIni.GICopperType) { ++ ++ if (ChipId == CHIP_ID_YUKON_FE) { ++ /* enable Automatic Crossover (!!! Bits 5..4) */ ++ PhyCtrl |= (SK_U16)(PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1); ++ } ++ else { ++ if (!pPrt->PEnDetMode) { ++ /* disable Energy Detect Mode */ ++ PhyCtrl &= ~PHY_M_PC_EN_DET_MSK; ++ } ++ ++ /* enable Automatic Crossover */ ++ PhyCtrl |= (SK_U16)PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); ++ ++ /* downshift on PHY 88E1112 and 88E1149 is changed */ ++ if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO && ++ (ChipId == CHIP_ID_YUKON_XL || ++ ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX)) { ++ /* set downshift counter to 3x and enable downshift */ ++ PhyCtrl &= ~PHY_M_PC_DSC_MSK; ++ PhyCtrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; ++ } ++ } ++ } ++ /* workaround for deviation #4.88 (CRC errors) */ ++ else { ++ /* disable Automatic Crossover */ ++ PhyCtrl &= ~PHY_M_PC_MDIX_MSK; ++ } ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PhyCtrl); + } +- else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) { +- /* Read Ext. PHY Specific Control */ +- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); +- +- ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | +- PHY_M_EC_MAC_S_MSK); +- +- ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) | +- PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); +- +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl); +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); ++ ++ /* special setup for PHY 88E1112 Fiber */ ++ if (ChipId == CHIP_ID_YUKON_XL && !pAC->GIni.GICopperType) { ++ /* select 1000BASE-X only mode in MAC Specific Ctrl Reg. */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 2); ++ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); ++ ++ Word &= ~PHY_M_MAC_MD_MSK; ++ Word |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX); ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); ++ ++ /* select page 1 to access Fiber registers */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 1); ++ ++ if (pAC->GIni.GIPmdTyp == 'P') { ++ /* for SFP-module set SIGDET polarity to low */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); ++ ++ Word |= PHY_M_FIB_SIGD_POL; ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); ++ } + } + + /* Read PHY Control */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); + ++ Word = PhyCtrl; ++ + if (!AutoNeg) { +- /* Disable Auto-negotiation */ +- PhyCtrl &= ~PHY_CT_ANE; ++ /* disable Auto-negotiation */ ++ Word &= ~PHY_CT_ANE; + } + +- PhyCtrl |= PHY_CT_RESET; +- /* Assert software reset */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); +-#endif /* VCPU */ ++ /* assert software reset */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word | PHY_CT_RESET); ++#endif /* !VCPU */ + + PhyCtrl = 0 /* PHY_CT_COL_TST */; + C1000BaseT = 0; + AutoNegAdv = PHY_SEL_TYPE; + ++#ifndef SK_SLIM + /* manually Master/Slave ? */ + if (pPrt->PMSMode != SK_MS_MODE_AUTO) { + /* enable Manual Master/Slave */ + C1000BaseT |= PHY_M_1000C_MSE; +- ++ + if (pPrt->PMSMode == SK_MS_MODE_MASTER) { + C1000BaseT |= PHY_M_1000C_MSC; /* set it to Master */ + } + } +- ++#endif /* !SK_SLIM */ ++ + /* Auto-negotiation ? */ + if (!AutoNeg) { +- ++ + if (pPrt->PLinkMode == SK_LMODE_FULL) { +- /* Set Full Duplex Mode */ ++ /* set Full Duplex Mode */ + PhyCtrl |= PHY_CT_DUP_MD; + } + +- /* Set Master/Slave manually if not already done */ ++#ifndef SK_SLIM ++ /* set Master/Slave manually if not already done */ + if (pPrt->PMSMode == SK_MS_MODE_AUTO) { + C1000BaseT |= PHY_M_1000C_MSE; /* set it to Slave */ + } ++#endif /* !SK_SLIM */ + +- /* Set Speed */ ++ /* set Speed */ + switch (pPrt->PLinkSpeed) { + case SK_LSPEED_AUTO: + case SK_LSPEED_1000MBPS: +- PhyCtrl |= PHY_CT_SP1000; ++ PhyCtrl |= (((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) ? ++ PHY_CT_SP1000 : PHY_CT_SP100); + break; + case SK_LSPEED_100MBPS: + PhyCtrl |= PHY_CT_SP100; +@@ -2169,38 +3036,66 @@ + SKERR_HWI_E019MSG); + } + ++ if ((pPrt->PFlowCtrlMode == SK_FLOW_STAT_NONE) || ++ /* disable Pause also for 10/100 Mbps in half duplex mode */ ++ (!(ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX) && ++ (pPrt->PLinkMode == SK_LMODE_HALF) && ++ ((pPrt->PLinkSpeed == SK_LSPEED_STAT_100MBPS) || ++ (pPrt->PLinkSpeed == SK_LSPEED_STAT_10MBPS)))) { ++ ++ /* set Pause Off */ ++ PauseMode = (SK_U8)GMC_PAUSE_OFF; ++ } ++ ++ SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), PauseMode); ++ + if (!DoLoop) { ++ /* assert software reset */ + PhyCtrl |= PHY_CT_RESET; + } + } + else { +- /* Set Auto-negotiation advertisement */ +- ++ /* set Auto-negotiation advertisement */ ++ + if (pAC->GIni.GICopperType) { +- /* Set Speed capabilities */ ++ /* set Speed capabilities */ + switch (pPrt->PLinkSpeed) { + case SK_LSPEED_AUTO: +- C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD; ++ if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { ++ C1000BaseT |= PHY_M_1000C_AFD; ++#ifdef xSK_DIAG ++ C1000BaseT |= PHY_M_1000C_AHD; ++#endif /* SK_DIAG */ ++ } + AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | + PHY_M_AN_10_FD | PHY_M_AN_10_HD; + break; + case SK_LSPEED_1000MBPS: +- C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD; ++ if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { ++ C1000BaseT |= PHY_M_1000C_AFD; ++#ifdef xSK_DIAG ++ C1000BaseT |= PHY_M_1000C_AHD; ++#endif /* SK_DIAG */ ++ } + break; + case SK_LSPEED_100MBPS: +- AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | +- /* advertise 10Base-T also */ +- PHY_M_AN_10_FD | PHY_M_AN_10_HD; ++ if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_100MBPS) != 0) { ++ AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | ++ /* advertise 10Base-T also */ ++ PHY_M_AN_10_FD | PHY_M_AN_10_HD; ++ } + break; + case SK_LSPEED_10MBPS: +- AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD; ++ if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_10MBPS) != 0) { ++ AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD; ++ } + break; + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019, + SKERR_HWI_E019MSG); + } + +- /* Set Full/half duplex capabilities */ ++ /* set Full/half duplex capabilities */ + switch (pPrt->PLinkMode) { + case SK_LMODE_AUTOHALF: + C1000BaseT &= ~PHY_M_1000C_AFD; +@@ -2216,8 +3111,8 @@ + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, + SKERR_HWI_E015MSG); + } +- +- /* Set Flow-control capabilities */ ++ ++ /* set Flow-control capabilities */ + switch (pPrt->PFlowCtrlMode) { + case SK_FLOW_MODE_NONE: + AutoNegAdv |= PHY_B_P_NO_PAUSE; +@@ -2236,9 +3131,9 @@ + SKERR_HWI_E016MSG); + } + } +- else { /* special defines for FIBER (88E1011S only) */ +- +- /* Set Full/half duplex capabilities */ ++ else { /* special defines for FIBER (88E1040S only) */ ++ ++ /* set Full/half duplex capabilities */ + switch (pPrt->PLinkMode) { + case SK_LMODE_AUTOHALF: + AutoNegAdv |= PHY_M_AN_1000X_AHD; +@@ -2253,8 +3148,8 @@ + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, + SKERR_HWI_E015MSG); + } +- +- /* Set Flow-control capabilities */ ++ ++ /* set Flow-control capabilities */ + switch (pPrt->PFlowCtrlMode) { + case SK_FLOW_MODE_NONE: + AutoNegAdv |= PHY_M_P_NO_PAUSE_X; +@@ -2279,138 +3174,262 @@ + PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG; + } + } +- ++ + #ifdef VCPU + /* + * E-mail from Gu Lin (08-03-2002): + */ +- ++ + /* Program PHY register 30 as 16'h0708 for simulation speed up */ + SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */); +- ++ + VCpuWait(2000); + +-#else /* VCPU */ +- +- /* Write 1000Base-T Control Register */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT); +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT)); +- ++#else /* !VCPU */ ++ ++ if (ChipId != CHIP_ID_YUKON_FE) { ++ /* Write 1000Base-T Control Register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT); ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Set 1000B-T Ctrl = 0x%04X\n", C1000BaseT)); ++ } ++ + /* Write AutoNeg Advertisement Register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); +-#endif /* VCPU */ +- ++ ("Set Auto-Neg.Adv. = 0x%04X\n", AutoNegAdv)); ++#endif /* !VCPU */ ++ ++#ifndef SK_SLIM + if (DoLoop) { +- /* Set the PHY Loopback bit */ ++ /* set the PHY Loopback bit */ + PhyCtrl |= PHY_CT_LOOP; +- +-#ifdef XXX +- /* Program PHY register 16 as 16'h0400 to force link good */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD); +-#endif /* XXX */ +- +-#ifndef VCPU +- if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) { +- /* Write Ext. PHY Specific Control */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, +- (SK_U16)((pPrt->PLinkSpeed + 2) << 4)); +- } +-#endif /* VCPU */ +- } +-#ifdef TEST_ONLY +- else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) { +- /* Write PHY Specific Control */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, +- PHY_M_PC_EN_DET_MSK); + } +-#endif ++#endif /* !SK_SLIM */ + + /* Write to the PHY Control register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl)); ++ ("Set PHY Ctrl Reg. = 0x%04X\n", PhyCtrl)); + + #ifdef VCPU + VCpuWait(2000); +-#else ++#else /* !VCPU */ ++ ++ LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS); ++ ++ LedOver = 0; ++ ++ BlinkCtrl = pAC->GIni.GILedBlinkCtrl; ++ ++ if ((BlinkCtrl & SK_ACT_LED_BLINK) != 0) { + +- LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS); ++ if (ChipId == CHIP_ID_YUKON_FE) { ++ /* on 88E3082 these bits are at 11..9 (shifted left) */ ++ LedCtrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1; + +- if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) { +- LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL; ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_FE_LED_PAR, &Word); ++ ++ /* delete LED1 (Activity) control bits */ ++ Word &= ~PHY_M_FELP_LED1_MSK; ++ /* change ACT LED control to blink mode */ ++ Word |= PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL); ++ ++ /* check for LINK_LED mux */ ++ if ((BlinkCtrl & SK_LED_LINK_MUX_P60) != 0) { ++ /* delete LED0 (Speed) control bits */ ++ Word &= ~PHY_M_FELP_LED0_MSK; ++ /* change Speed LED control to Link indication */ ++ Word |= PHY_M_FELP_LED0_CTRL(LED_PAR_CTRL_LINK); ++ } ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_FE_LED_PAR, Word); ++ } ++ else if (ChipId == CHIP_ID_YUKON_XL || ++ ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX) { ++ /* save page register */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_ADR, &PageReg); ++ ++ /* select page 3 to access LED control register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 3); ++ ++ LedConf = PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT (Yukon-2 only) */ ++ PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ ++ PHY_M_LEDC_STA0_CTRL(7); /* 1000 Mbps */ ++ ++ Mode = 7; /* 10 Mbps: On */ ++ ++ if (ChipId == CHIP_ID_YUKON_XL) { ++ /* set Polarity Control register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_STAT, (SK_U16) ++ (PHY_M_POLC_LS1_P_MIX(4) | PHY_M_POLC_IS0_P_MIX(4) | ++ PHY_M_POLC_LOS_CTRL(2) | PHY_M_POLC_INIT_CTRL(2) | ++ PHY_M_POLC_STA1_CTRL(2) | PHY_M_POLC_STA0_CTRL(2))); ++ } ++ else if (ChipId == CHIP_ID_YUKON_EC_U || ChipId == CHIP_ID_YUKON_EX) { ++ /* check for LINK_LED mux */ ++ if ((BlinkCtrl & SK_LED_LINK_MUX_P60) != 0) { ++ ++ SK_IN16(pAC, GPHY_CTRL, &Word); ++ ++ Word |= GPC_LED_CONF_VAL(4); ++ ++ /* set GPHY LED Config */ ++ SK_OUT16(pAC, GPHY_CTRL, Word); ++ } ++ else { ++ ++ SK_IN16(IoC, PCI_C(pAC, PCI_OUR_REG_4), &Word); ++ ++ if ((Word & P_PIN63_LINK_LED_ENA) == 0) { ++ Mode = 8; /* Forced Off */ ++ } ++ ++ /* set LED[5:4] Function Control and Polarity register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_STAT, (SK_U16) ++ (PHY_M_LEDC_STA1_CTRL(1) | /* LED_ACT to Link/Act. */ ++ PHY_M_LEDC_STA0_CTRL(6))); /* LED_DUP to Duplex */ ++ } ++ ++ /* set Blink Rate in LED Timer Control Register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, ++ LedCtrl | (SK_U16)PHY_M_LED_BLINK_RT(BLINK_84MS)); ++ } ++ ++ LedConf |= PHY_M_LEDC_INIT_CTRL(Mode); ++ ++ /* set LED Function Control register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, LedConf); ++ ++#if (defined(SK_DIAG) || (defined(DEBUG) && !defined(SK_SLIM))) ++ /* select page 6 to access Packet Generation register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 6); ++ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &PhyCtrl); ++ ++ PhyCtrl |= BIT_4S; /* enable CRC checker */ ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PhyCtrl); ++#endif /* SK_DIAG || (DEBUG && !SK_SLIM) */ ++ ++ /* restore page register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, PageReg); ++ } ++ else { ++ /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ ++ LedCtrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; ++ ++ /* on PHY 88E1111 there is a change for LED control */ ++ if (ChipId == CHIP_ID_YUKON_EC && ++ (BlinkCtrl & SK_DUAL_LED_ACT_LNK) != 0) { ++ /* Yukon-EC needs setting of 2 bits: 0,6=11) */ ++ LedCtrl |= PHY_M_LEDC_TX_C_LSB; ++ } ++ /* turn off the Rx LED (LED_RX) */ ++ LedOver |= PHY_M_LED_MO_RX(MO_LED_OFF); ++ } + } + +- if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) { ++ if ((BlinkCtrl & SK_DUP_LED_NORMAL) != 0) { ++ /* disable blink mode (LED_DUPLEX) on collisions */ + LedCtrl |= PHY_M_LEDC_DP_CTRL; + } +- +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl); + +- if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) { +- /* only in forced 100 Mbps mode */ +- if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) { ++ if (ChipId == CHIP_ID_YUKON_EC_U) { ++ if (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_A1) { ++ /* apply fixes in PHY AFE */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0x00ff); ++ ++ /* increase differential signal amplitude in 10BASE-T */ ++ SkGmPhyWrite(pAC, IoC, Port, 24, 0xaa99); ++ SkGmPhyWrite(pAC, IoC, Port, 23, 0x2011); ++ ++ /* fix for IEEE A/B Symmetry failure in 1000BASE-T */ ++ SkGmPhyWrite(pAC, IoC, Port, 24, 0xa204); ++ SkGmPhyWrite(pAC, IoC, Port, 23, 0x2002); ++ ++ /* set page register to 0 */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); ++ } ++ } ++ else if (ChipId != CHIP_ID_YUKON_EX) { ++ /* no effect on Yukon-XL */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl); ++ ++#ifndef SK_SLIM ++ if ((BlinkCtrl & SK_LED_LINK100_ON) != 0) { ++ /* only in forced 100 Mbps mode */ ++ if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) { ++ /* turn on 100 Mbps LED (LED_LINK100) */ ++ LedOver |= PHY_M_LED_MO_100(MO_LED_ON); ++ } ++ } ++#endif /* !SK_SLIM */ + +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER, +- PHY_M_LED_MO_100(MO_LED_ON)); ++ if (LedOver != 0) { ++ /* set Manual LED Override */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER, LedOver); + } + } + + #ifdef SK_DIAG +- c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl); +- c_print("Set 1000 B-T=0x%04X\n", C1000BaseT); +- c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv); +- c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl); ++ c_print("Set PHY Ctrl = 0x%04X\n", PhyCtrl); ++ c_print("Set 1000 B-T = 0x%04X\n", C1000BaseT); ++ c_print("Set Auto-Neg = 0x%04X\n", AutoNegAdv); ++ c_print("Set Ext Ctrl = 0x%04X\n", ExtPhyCtrl); + #endif /* SK_DIAG */ + +-#if defined(SK_DIAG) || defined(DEBUG) ++#if (defined(SK_DIAG) || (defined(DEBUG) && !defined(SK_SLIM))) + /* Read PHY Control */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl)); +- +- /* Read 1000Base-T Control Register */ +- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT); +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("1000B-T Ctrl =0x%04X\n", C1000BaseT)); +- ++ ("PHY Ctrl Reg. = 0x%04X\n", PhyCtrl)); ++ + /* Read AutoNeg Advertisement Register */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); +- +- /* Read Ext. PHY Specific Control */ +- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); +- ++ ("Auto-Neg.Adv. = 0x%04X\n", AutoNegAdv)); ++ ++ if (ChipId != CHIP_ID_YUKON_FE) { ++ /* Read 1000Base-T Control Register */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT); ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("1000B-T Ctrl = 0x%04X\n", C1000BaseT)); ++ ++ /* Read Ext. PHY Specific Control */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Ext. PHY Ctrl = 0x%04X\n", ExtPhyCtrl)); ++ } ++ + /* Read PHY Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("PHY Stat Reg.=0x%04X\n", PhyStat)); ++ ("PHY Stat Reg. = 0x%04X\n", PhyStat)); ++ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("PHY Stat Reg.=0x%04X\n", PhyStat1)); +- ++ ("PHY Stat Reg. = 0x%04X\n", PhyStat1)); ++ + /* Read PHY Specific Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("PHY Spec Stat=0x%04X\n", PhySpecStat)); +-#endif /* SK_DIAG || DEBUG */ ++ ("PHY Spec Stat = 0x%04X\n", PhySpecStat)); ++#endif /* SK_DIAG || (DEBUG && !SK_SLIM) */ + + #ifdef SK_DIAG +- c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl); +- c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT); +- c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv); +- c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl); +- c_print("PHY Stat Reg=0x%04X\n", PhyStat); +- c_print("PHY Stat Reg=0x%04X\n", PhyStat1); +- c_print("PHY Spec Reg=0x%04X\n", PhySpecStat); ++ c_print("PHY Ctrl Reg = 0x%04X\n", PhyCtrl); ++ c_print("PHY 1000 Reg = 0x%04X\n", C1000BaseT); ++ c_print("PHY AnAd Reg = 0x%04X\n", AutoNegAdv); ++ c_print("Ext Ctrl Reg = 0x%04X\n", ExtPhyCtrl); ++ c_print("PHY Stat Reg = 0x%04X\n", PhyStat); ++ c_print("PHY Stat Reg = 0x%04X\n", PhyStat1); ++ c_print("PHY Spec Reg = 0x%04X\n", PhySpecStat); + #endif /* SK_DIAG */ + +-#endif /* VCPU */ ++ /* enable PHY interrupts */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, (SK_U16)PHY_M_DEF_MSK); ++#endif /* !VCPU */ + + } /* SkGmInitPhyMarv */ + #endif /* YUKON */ +@@ -2419,9 +3438,9 @@ + #ifdef OTHER_PHY + /****************************************************************************** + * +- * SkXmInitPhyLone() - Initialize the Level One Phy registers ++ * SkXmInitPhyLone() - Initialize the Level One PHY registers + * +- * Description: initializes all the Level One Phy registers ++ * Description: initializes all the Level One PHY registers + * + * Note: + * +@@ -2429,10 +3448,10 @@ + * nothing + */ + static void SkXmInitPhyLone( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ +-SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ ++SK_BOOL DoLoop) /* Should a PHY LoopBack be set-up? */ + { + SK_GEPORT *pPrt; + SK_U16 Ctrl1; +@@ -2448,11 +3467,12 @@ + /* manually Master/Slave ? */ + if (pPrt->PMSMode != SK_MS_MODE_AUTO) { + Ctrl2 |= PHY_L_1000C_MSE; +- ++ + if (pPrt->PMSMode == SK_MS_MODE_MASTER) { + Ctrl2 |= PHY_L_1000C_MSC; + } + } ++ + /* Auto-negotiation ? */ + if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { + /* +@@ -2461,7 +3481,7 @@ + */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyLone: no auto-negotiation Port %d\n", Port)); +- /* Set DuplexMode in Config register */ ++ /* set DuplexMode in Config register */ + if (pPrt->PLinkMode == SK_LMODE_FULL) { + Ctrl1 |= PHY_CT_DUP_MD; + } +@@ -2470,7 +3490,6 @@ + if (pPrt->PMSMode == SK_MS_MODE_AUTO) { + Ctrl2 |= PHY_L_1000C_MSE; /* set it to Slave */ + } +- + /* + * Do NOT enable Auto-negotiation here. This would hold + * the link down because no IDLES are transmitted +@@ -2479,9 +3498,9 @@ + else { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyLone: with auto-negotiation Port %d\n", Port)); +- /* Set Auto-negotiation advertisement */ ++ /* set Auto-negotiation advertisement */ + +- /* Set Full/half duplex capabilities */ ++ /* set Full/half duplex capabilities */ + switch (pPrt->PLinkMode) { + case SK_LMODE_AUTOHALF: + Ctrl2 |= PHY_L_1000C_AHD; +@@ -2497,7 +3516,7 @@ + SKERR_HWI_E015MSG); + } + +- /* Set Flow-control capabilities */ ++ /* set Flow-control capabilities */ + switch (pPrt->PFlowCtrlMode) { + case SK_FLOW_MODE_NONE: + Ctrl3 |= PHY_L_P_NO_PAUSE; +@@ -2519,34 +3538,34 @@ + /* Restart Auto-negotiation */ + Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG; + } +- ++ + /* Write 1000Base-T Control Register */ + SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); +- ++ ("1000B-T Ctrl Reg = 0x%04X\n", Ctrl2)); ++ + /* Write AutoNeg Advertisement Register */ + SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); ++ ("Auto-Neg.Adv.Reg = 0x%04X\n", Ctrl3)); + + if (DoLoop) { +- /* Set the Phy Loopback bit, too */ ++ /* set the PHY Loopback bit, too */ + Ctrl1 |= PHY_CT_LOOP; + } + +- /* Write to the Phy control register */ ++ /* Write to the PHY control register */ + SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("PHY Control Reg=0x%04X\n", Ctrl1)); ++ ("PHY Control Reg = 0x%04X\n", Ctrl1)); + } /* SkXmInitPhyLone */ + + + /****************************************************************************** + * +- * SkXmInitPhyNat() - Initialize the National Phy registers ++ * SkXmInitPhyNat() - Initialize the National PHY registers + * +- * Description: initializes all the National Phy registers ++ * Description: initializes all the National PHY registers + * + * Note: + * +@@ -2554,10 +3573,10 @@ + * nothing + */ + static void SkXmInitPhyNat( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ +-SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ ++SK_BOOL DoLoop) /* Should a PHY LoopBack be set-up? */ + { + /* todo: National */ + } /* SkXmInitPhyNat */ +@@ -2576,10 +3595,10 @@ + * nothing + */ + void SkMacInitPhy( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ +-SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ ++SK_BOOL DoLoop) /* Should a PHY LoopBack be set-up? */ + { + SK_GEPORT *pPrt; + +@@ -2587,7 +3606,7 @@ + + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +- ++ + switch (pPrt->PhyType) { + case SK_PHY_XMAC: + SkXmInitPhyXmac(pAC, IoC, Port, DoLoop); +@@ -2606,10 +3625,10 @@ + } + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { +- ++ + SkGmInitPhyMarv(pAC, IoC, Port, DoLoop); + } + #endif /* YUKON */ +@@ -2627,17 +3646,17 @@ + * + * Returns: + * SK_AND_OK o.k. +- * SK_AND_DUP_CAP Duplex capability error happened +- * SK_AND_OTHER Other error happened ++ * SK_AND_DUP_CAP Duplex capability error happened ++ * SK_AND_OTHER Other error happened + */ + static int SkXmAutoNegDoneXmac( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; + SK_U16 ResAb; /* Resolved Ability */ +- SK_U16 LPAb; /* Link Partner Ability */ ++ SK_U16 LinkPartAb; /* Link Partner Ability */ + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegDoneXmac, Port %d\n", Port)); +@@ -2645,15 +3664,15 @@ + pPrt = &pAC->GIni.GP[Port]; + + /* Get PHY parameters */ +- SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb); ++ SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LinkPartAb); + SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb); + +- if ((LPAb & PHY_X_AN_RFB) != 0) { ++ if ((LinkPartAb & PHY_X_AN_RFB) != 0) { + /* At least one of the remote fault bit is set */ +- /* Error */ +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("AutoNegFail: Remote fault bit set Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; ++ + return(SK_AND_OTHER); + } + +@@ -2666,9 +3685,10 @@ + } + else { + /* Error */ +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("AutoNegFail: Duplex mode mismatch Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; ++ + return(SK_AND_DUP_CAP); + } + +@@ -2676,25 +3696,26 @@ + /* We are NOT using chapter 4.23 of the Xaqti manual */ + /* We are using IEEE 802.3z/D5.0 Table 37-4 */ + if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC || +- pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) && +- (LPAb & PHY_X_P_SYM_MD) != 0) { ++ pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) && ++ (LinkPartAb & PHY_X_P_SYM_MD) != 0) { + /* Symmetric PAUSE */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; + } + else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM && +- (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) { +- /* Enable PAUSE receive, disable PAUSE transmit */ ++ (LinkPartAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) { ++ /* enable PAUSE receive, disable PAUSE transmit */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; + } + else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND && +- (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) { +- /* Disable PAUSE receive, enable PAUSE transmit */ ++ (LinkPartAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) { ++ /* disable PAUSE receive, enable PAUSE transmit */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; + } + else { + /* PAUSE mismatch -> no PAUSE */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; + } ++ + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; + + return(SK_AND_OK); +@@ -2710,41 +3731,39 @@ + * + * Returns: + * SK_AND_OK o.k. +- * SK_AND_DUP_CAP Duplex capability error happened +- * SK_AND_OTHER Other error happened ++ * SK_AND_DUP_CAP Duplex capability error happened ++ * SK_AND_OTHER Other error happened + */ + static int SkXmAutoNegDoneBcom( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; +- SK_U16 LPAb; /* Link Partner Ability */ +- SK_U16 AuxStat; /* Auxiliary Status */ +- + #ifdef TEST_ONLY +-01-Sep-2000 RA;:;: + SK_U16 ResAb; /* Resolved Ability */ +-#endif /* 0 */ ++#endif ++ SK_U16 LinkPartAb; /* Link Partner Ability */ ++ SK_U16 AuxStat; /* Auxiliary Status */ + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegDoneBcom, Port %d\n", Port)); + pPrt = &pAC->GIni.GP[Port]; + + /* Get PHY parameters */ +- SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb); ++ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LinkPartAb); + #ifdef TEST_ONLY +-01-Sep-2000 RA;:;: + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); +-#endif /* 0 */ +- ++#endif ++ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat); + +- if ((LPAb & PHY_B_AN_RF) != 0) { ++ if ((LinkPartAb & PHY_B_AN_RF) != 0) { + /* Remote fault bit is set: Error */ +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("AutoNegFail: Remote fault bit set Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; ++ + return(SK_AND_OTHER); + } + +@@ -2757,26 +3776,26 @@ + } + else { + /* Error */ +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("AutoNegFail: Duplex mode mismatch Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; ++ + return(SK_AND_DUP_CAP); + } +- ++ + #ifdef TEST_ONLY +-01-Sep-2000 RA;:;: + /* Check Master/Slave resolution */ + if ((ResAb & PHY_B_1000S_MSF) != 0) { +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("Master/Slave Fault Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; + pPrt->PMSStatus = SK_MS_STAT_FAULT; + return(SK_AND_OTHER); + } +- ++ + pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? + SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; +-#endif /* 0 */ ++#endif + + /* Check PAUSE mismatch ??? */ + /* We are using IEEE 802.3z/D5.0 Table 37-4 */ +@@ -2785,17 +3804,18 @@ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; + } + else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) { +- /* Enable PAUSE receive, disable PAUSE transmit */ ++ /* enable PAUSE receive, disable PAUSE transmit */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; + } + else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) { +- /* Disable PAUSE receive, enable PAUSE transmit */ ++ /* disable PAUSE receive, enable PAUSE transmit */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; + } + else { + /* PAUSE mismatch -> no PAUSE */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; + } ++ + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; + + return(SK_AND_OK); +@@ -2813,99 +3833,196 @@ + * + * Returns: + * SK_AND_OK o.k. +- * SK_AND_DUP_CAP Duplex capability error happened +- * SK_AND_OTHER Other error happened ++ * SK_AND_DUP_CAP Duplex capability error happened ++ * SK_AND_OTHER Other error happened + */ + static int SkGmAutoNegDoneMarv( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; +- SK_U16 LPAb; /* Link Partner Ability */ + SK_U16 ResAb; /* Resolved Ability */ + SK_U16 AuxStat; /* Auxiliary Status */ ++ SK_U8 PauseMode; /* Pause Mode */ ++#ifndef SK_SLIM ++ SK_U16 LinkPartAb; /* Link Partner Ability */ ++#ifndef SK_DIAG ++ SK_EVPARA Para; ++#endif /* !SK_DIAG */ ++#endif /* !SK_SLIM */ ++ ++ /* set Pause On */ ++ PauseMode = (SK_U8)GMC_PAUSE_ON; + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNegDoneMarv, Port %d\n", Port)); ++ + pPrt = &pAC->GIni.GP[Port]; + ++#ifndef SK_SLIM + /* Get PHY parameters */ +- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb); ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LinkPartAb); ++ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Link P.Abil.=0x%04X\n", LPAb)); +- +- if ((LPAb & PHY_M_AN_RF) != 0) { +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Link P.Abil. = 0x%04X\n", LinkPartAb)); ++ ++ if ((LinkPartAb & PHY_M_AN_RF) != 0) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("AutoNegFail: Remote fault bit set Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; ++ + return(SK_AND_OTHER); + } + +- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); +- +- /* Check Master/Slave resolution */ +- if ((ResAb & PHY_B_1000S_MSF) != 0) { +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("Master/Slave Fault Port %d\n", Port)); +- pPrt->PAutoNegFail = SK_TRUE; +- pPrt->PMSStatus = SK_MS_STAT_FAULT; +- return(SK_AND_OTHER); ++ if (pAC->GIni.GICopperType) { ++ /* Read PHY Auto-Negotiation Expansion */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &LinkPartAb); ++ ++ if ((LinkPartAb & PHY_ANE_LP_CAP) == 0) { ++ ++ pPrt->PLipaAutoNeg = SK_LIPA_MANUAL; ++ ++#ifndef SK_DIAG ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("Link Partner not Auto-Neg. able, AN Exp.: 0x%04X\n", ++ LinkPartAb)); ++ ++#ifndef NDIS_MINIPORT_DRIVER ++ SK_ERR_LOG(pAC, SK_ERRCL_INFO, SKERR_HWI_E025, SKERR_HWI_E025MSG); ++#endif ++ ++ Para.Para64 = Port; ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_LIPA_NOT_AN_ABLE, Para); ++#else ++ c_print("Link Partner not Auto-Neg. able, AN Exp.: 0x%04X\n", ++ LinkPartAb); ++#endif /* !SK_DIAG */ ++ ++ if (HW_FEATURE(pAC, HWF_FORCE_AUTO_NEG) && ++ pPrt->PLinkModeConf < SK_LMODE_AUTOHALF) { ++ /* set used link speed */ ++ pPrt->PLinkSpeedUsed = pPrt->PLinkSpeed; ++ ++ /* Set Link Mode Status */ ++ pPrt->PLinkModeStatus = (SK_U8) ++ (pPrt->PLinkModeConf == SK_LMODE_FULL) ? ++ SK_LMODE_STAT_FULL : SK_LMODE_STAT_HALF; ++ ++ return(SK_AND_OK); ++ } ++ } ++ else { ++ pPrt->PLipaAutoNeg = SK_LIPA_AUTO; ++ } + } +- +- pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? +- (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE; +- ++#endif /* !SK_SLIM */ ++ ++ if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { ++ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); ++ ++ /* Check Master/Slave resolution */ ++ if ((ResAb & PHY_B_1000S_MSF) != 0) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("Master/Slave Fault Port %d\n", Port)); ++ pPrt->PAutoNegFail = SK_TRUE; ++ pPrt->PMSStatus = SK_MS_STAT_FAULT; ++ return(SK_AND_OTHER); ++ } ++ ++ pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? ++ (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE; ++ } ++ + /* Read PHY Specific Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat); +- ++ + /* Check Speed & Duplex resolved */ + if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) { +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; ++ + return(SK_AND_DUP_CAP); + } +- +- if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) { +- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; ++ ++ if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { ++ pPrt->PLinkModeStatus = (SK_U8)(((AuxStat & PHY_M_PS_FULL_DUP) != 0) ? ++ SK_LMODE_STAT_AUTOFULL : SK_LMODE_STAT_AUTOHALF); + } + else { +- pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; +- } +- +- /* Check PAUSE mismatch ??? */ +- /* We are using IEEE 802.3z/D5.0 Table 37-4 */ +- if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) { +- /* Symmetric PAUSE */ +- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; ++ pPrt->PLinkModeStatus = (SK_U8)(((AuxStat & PHY_M_PS_FULL_DUP) != 0) ? ++ SK_LMODE_STAT_FULL : SK_LMODE_STAT_HALF); + } +- else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) { +- /* Enable PAUSE receive, disable PAUSE transmit */ +- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; +- } +- else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) { +- /* Disable PAUSE receive, enable PAUSE transmit */ +- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) { ++ /* set used link speed */ ++ pPrt->PLinkSpeedUsed = (SK_U8)(((AuxStat & PHY_M_PS_SPEED_100) != 0) ? ++ SK_LSPEED_STAT_100MBPS : SK_LSPEED_STAT_10MBPS); + } + else { +- /* PAUSE mismatch -> no PAUSE */ +- pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; ++ /* set used link speed */ ++ switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) { ++ case (unsigned)PHY_M_PS_SPEED_1000: ++ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; ++ break; ++ case PHY_M_PS_SPEED_100: ++ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; ++ break; ++ default: ++ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS; ++ } ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_EX) { /* check it */ ++ /* Tx & Rx Pause Enabled bits are at 9..8 */ ++ AuxStat >>= 6; ++ ++ if (!pAC->GIni.GICopperType) { ++ /* always 1000 Mbps on fiber */ ++ pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; ++ } ++ } ++ ++ AuxStat &= PHY_M_PS_PAUSE_MSK; ++ /* We are using IEEE 802.3z/D5.0 Table 37-4 */ ++ if (AuxStat == PHY_M_PS_PAUSE_MSK) { ++ /* Symmetric PAUSE */ ++ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; ++ } ++ else if (AuxStat == PHY_M_PS_RX_P_EN) { ++ /* enable PAUSE receive, disable PAUSE transmit */ ++ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; ++ } ++ else if (AuxStat == PHY_M_PS_TX_P_EN) { ++ /* disable PAUSE receive, enable PAUSE transmit */ ++ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; ++ } ++ else { ++ /* PAUSE mismatch -> no PAUSE */ ++ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; ++ } + } +- +- /* set used link speed */ +- switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) { +- case (unsigned)PHY_M_PS_SPEED_1000: +- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; +- break; +- case PHY_M_PS_SPEED_100: +- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; +- break; +- default: +- pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("LinkSpeedUsed = %d\n", pPrt->PLinkSpeedUsed)); ++ ++ if ((pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE) || ++ /* disable Pause also for 10/100 Mbps in half duplex mode */ ++ (!(pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_EX) && ++ (pPrt->PLinkSpeedUsed < (SK_U8)SK_LSPEED_STAT_1000MBPS) && ++ pPrt->PLinkModeStatus == (SK_U8)SK_LMODE_STAT_AUTOHALF)) { ++ ++ /* set Pause Off */ ++ PauseMode = (SK_U8)GMC_PAUSE_OFF; + } + ++ SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), PauseMode); ++ + return(SK_AND_OK); + } /* SkGmAutoNegDoneMarv */ + #endif /* YUKON */ +@@ -2921,17 +4038,17 @@ + * + * Returns: + * SK_AND_OK o.k. +- * SK_AND_DUP_CAP Duplex capability error happened +- * SK_AND_OTHER Other error happened ++ * SK_AND_DUP_CAP Duplex capability error happened ++ * SK_AND_OTHER Other error happened + */ + static int SkXmAutoNegDoneLone( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; + SK_U16 ResAb; /* Resolved Ability */ +- SK_U16 LPAb; /* Link Partner Ability */ ++ SK_U16 LinkPartAb; /* Link Partner Ability */ + SK_U16 QuickStat; /* Auxiliary Status */ + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +@@ -2939,16 +4056,16 @@ + pPrt = &pAC->GIni.GP[Port]; + + /* Get PHY parameters */ +- SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb); ++ SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LinkPartAb); + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb); + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat); + +- if ((LPAb & PHY_L_AN_RF) != 0) { ++ if ((LinkPartAb & PHY_L_AN_RF) != 0) { + /* Remote fault bit is set */ +- /* Error */ +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("AutoNegFail: Remote fault bit set Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; ++ + return(SK_AND_OTHER); + } + +@@ -2959,28 +4076,25 @@ + else { + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; + } +- ++ + /* Check Master/Slave resolution */ + if ((ResAb & PHY_L_1000S_MSF) != 0) { + /* Error */ +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("Master/Slave Fault Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; + pPrt->PMSStatus = SK_MS_STAT_FAULT; + return(SK_AND_OTHER); + } +- else if (ResAb & PHY_L_1000S_MSR) { +- pPrt->PMSStatus = SK_MS_STAT_MASTER; +- } +- else { +- pPrt->PMSStatus = SK_MS_STAT_SLAVE; +- } ++ ++ pPrt->PMSStatus = ((ResAb & PHY_L_1000S_MSR) != 0) ? ++ (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE; + + /* Check PAUSE mismatch */ + /* We are using IEEE 802.3z/D5.0 Table 37-4 */ + /* we must manually resolve the abilities here */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; +- ++ + switch (pPrt->PFlowCtrlMode) { + case SK_FLOW_MODE_NONE: + /* default */ +@@ -2988,7 +4102,7 @@ + case SK_FLOW_MODE_LOC_SEND: + if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) == + (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) { +- /* Disable PAUSE receive, enable PAUSE transmit */ ++ /* disable PAUSE receive, enable PAUSE transmit */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; + } + break; +@@ -3001,7 +4115,7 @@ + case SK_FLOW_MODE_SYM_OR_REM: + if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) == + PHY_L_QS_AS_PAUSE) { +- /* Enable PAUSE receive, disable PAUSE transmit */ ++ /* enable PAUSE receive, disable PAUSE transmit */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; + } + else if ((QuickStat & PHY_L_QS_PAUSE) != 0) { +@@ -3013,7 +4127,7 @@ + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, + SKERR_HWI_E016MSG); + } +- ++ + return(SK_AND_OK); + } /* SkXmAutoNegDoneLone */ + +@@ -3027,12 +4141,12 @@ + * + * Returns: + * SK_AND_OK o.k. +- * SK_AND_DUP_CAP Duplex capability error happened +- * SK_AND_OTHER Other error happened ++ * SK_AND_DUP_CAP Duplex capability error happened ++ * SK_AND_OTHER Other error happened + */ + static int SkXmAutoNegDoneNat( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + /* todo: National */ +@@ -3049,12 +4163,12 @@ + * + * Returns: + * SK_AND_OK o.k. +- * SK_AND_DUP_CAP Duplex capability error happened +- * SK_AND_OTHER Other error happened ++ * SK_AND_DUP_CAP Duplex capability error happened ++ * SK_AND_OTHER Other error happened + */ +-int SkMacAutoNegDone( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++int SkMacAutoNegDone( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; +@@ -3066,9 +4180,9 @@ + + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +- ++ + switch (pPrt->PhyType) { +- ++ + case SK_PHY_XMAC: + Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port); + break; +@@ -3088,28 +4202,163 @@ + } + } + #endif /* GENESIS */ +- ++ ++#ifdef YUKON ++ if (pAC->GIni.GIYukon) { ++ ++ Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port); ++ } ++#endif /* YUKON */ ++ ++ if (Rtv != SK_AND_OK) { ++ return(Rtv); ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ("AutoNeg done Port %d\n", Port)); ++ ++ /* We checked everything and may now enable the link */ ++ pPrt->PAutoNegFail = SK_FALSE; ++ ++ SkMacRxTxEnable(pAC, IoC, Port); ++ ++ return(SK_AND_OK); ++} /* SkMacAutoNegDone */ ++ ++ ++#ifndef SK_SLIM ++#ifdef GENESIS ++/****************************************************************************** ++ * ++ * SkXmSetRxTxEn() - Special Set Rx/Tx Enable and some features in XMAC ++ * ++ * Description: ++ * sets MAC or PHY LoopBack and Duplex Mode in the MMU Command Reg. ++ * enables Rx/Tx ++ * ++ * Returns: N/A ++ */ ++static void SkXmSetRxTxEn( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (MAC_1 + n) */ ++int Para) /* Parameter to set: MAC or PHY LoopBack, Duplex Mode */ ++{ ++ SK_U16 Word; ++ ++ XM_IN16(IoC, Port, XM_MMU_CMD, &Word); ++ ++ switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) { ++ case SK_MAC_LOOPB_ON: ++ Word |= XM_MMU_MAC_LB; ++ break; ++ case SK_MAC_LOOPB_OFF: ++ Word &= ~XM_MMU_MAC_LB; ++ break; ++ } ++ ++ switch (Para & (SK_PHY_LOOPB_ON | SK_PHY_LOOPB_OFF)) { ++ case SK_PHY_LOOPB_ON: ++ Word |= XM_MMU_GMII_LOOP; ++ break; ++ case SK_PHY_LOOPB_OFF: ++ Word &= ~XM_MMU_GMII_LOOP; ++ break; ++ } ++ ++ switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) { ++ case SK_PHY_FULLD_ON: ++ Word |= XM_MMU_GMII_FD; ++ break; ++ case SK_PHY_FULLD_OFF: ++ Word &= ~XM_MMU_GMII_FD; ++ break; ++ } ++ ++ XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_ENA_RX | XM_MMU_ENA_TX); ++ ++ /* dummy read to ensure writing */ ++ XM_IN16(IoC, Port, XM_MMU_CMD, &Word); ++ ++} /* SkXmSetRxTxEn */ ++#endif /* GENESIS */ ++ ++ ++#ifdef YUKON ++/****************************************************************************** ++ * ++ * SkGmSetRxTxEn() - Special Set Rx/Tx Enable and some features in GMAC ++ * ++ * Description: ++ * sets MAC LoopBack and Duplex Mode in the General Purpose Control Reg. ++ * enables Rx/Tx ++ * ++ * Returns: N/A ++ */ ++static void SkGmSetRxTxEn( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (MAC_1 + n) */ ++int Para) /* Parameter to set: MAC LoopBack, Duplex Mode */ ++{ ++ SK_U16 Ctrl; ++ ++ GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl); ++ ++ switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) { ++ case SK_MAC_LOOPB_ON: ++ Ctrl |= GM_GPCR_LOOP_ENA; ++ break; ++ case SK_MAC_LOOPB_OFF: ++ Ctrl &= ~GM_GPCR_LOOP_ENA; ++ break; ++ } ++ ++ switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) { ++ case SK_PHY_FULLD_ON: ++ Ctrl |= GM_GPCR_DUP_FULL; ++ break; ++ case SK_PHY_FULLD_OFF: ++ Ctrl &= ~GM_GPCR_DUP_FULL; ++ break; ++ } ++ ++ GM_OUT16(IoC, Port, GM_GP_CTRL, Ctrl | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); ++ ++} /* SkGmSetRxTxEn */ ++#endif /* YUKON */ ++ ++ ++/****************************************************************************** ++ * ++ * SkMacSetRxTxEn() - Special Set Rx/Tx Enable and parameters ++ * ++ * Description: calls the Special Set Rx/Tx Enable routines dep. on board type ++ * ++ * Returns: N/A ++ */ ++void SkMacSetRxTxEn( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ ++int Port, /* Port Index (MAC_1 + n) */ ++int Para) ++{ ++#ifdef GENESIS ++ if (pAC->GIni.GIGenesis) { ++ ++ SkXmSetRxTxEn(pAC, IoC, Port, Para); ++ } ++#endif /* GENESIS */ ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { +- +- Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port); ++ ++ SkGmSetRxTxEn(pAC, IoC, Port, Para); + } + #endif /* YUKON */ +- +- if (Rtv != SK_AND_OK) { +- return(Rtv); +- } +- +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("AutoNeg done Port %d\n", Port)); +- +- /* We checked everything and may now enable the link */ +- pPrt->PAutoNegFail = SK_FALSE; + +- SkMacRxTxEnable(pAC, IoC, Port); +- +- return(SK_AND_OK); +-} /* SkMacAutoNegDone */ ++} /* SkMacSetRxTxEn */ ++#endif /* !SK_SLIM */ + + + /****************************************************************************** +@@ -3123,8 +4372,8 @@ + * != 0 Error happened + */ + int SkMacRxTxEnable( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; +@@ -3142,9 +4391,9 @@ + } + + if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF || +- pPrt->PLinkMode == SK_LMODE_AUTOFULL || +- pPrt->PLinkMode == SK_LMODE_AUTOBOTH) && +- pPrt->PAutoNegFail) { ++ pPrt->PLinkMode == SK_LMODE_AUTOFULL || ++ pPrt->PLinkMode == SK_LMODE_AUTOBOTH) && ++ pPrt->PAutoNegFail) { + /* Auto-negotiation is not done or failed */ + return(0); + } +@@ -3153,9 +4402,9 @@ + if (pAC->GIni.GIGenesis) { + /* set Duplex Mode and Pause Mode */ + SkXmInitDupMd(pAC, IoC, Port); +- ++ + SkXmInitPauseMd(pAC, IoC, Port); +- ++ + /* + * Initialize the Interrupt Mask Register. Default IRQs are... + * - Link Asynchronous Event +@@ -3171,23 +4420,24 @@ + /* add IRQ for Receive FIFO Overflow */ + IntMask &= ~XM_IS_RXF_OV; + #endif /* DEBUG */ +- ++ + if (pPrt->PhyType != SK_PHY_XMAC) { + /* disable GP0 interrupt bit */ + IntMask |= XM_IS_INP_ASS; + } ++ + XM_OUT16(IoC, Port, XM_IMSK, IntMask); +- ++ + /* get MMU Command Reg. */ + XM_IN16(IoC, Port, XM_MMU_CMD, &Reg); +- ++ + if (pPrt->PhyType != SK_PHY_XMAC && + (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || + pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) { + /* set to Full Duplex */ + Reg |= XM_MMU_GMII_FD; + } +- ++ + switch (pPrt->PhyType) { + case SK_PHY_BCOM: + /* +@@ -3197,7 +4447,7 @@ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord); + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, + (SK_U16)(SWord & ~PHY_B_AC_DIS_PM)); +- SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, ++ SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, + (SK_U16)PHY_B_DEF_MSK); + break; + #ifdef OTHER_PHY +@@ -3211,12 +4461,12 @@ + break; + #endif /* OTHER_PHY */ + } +- ++ + /* enable Rx/Tx */ + XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { + /* +@@ -3227,34 +4477,47 @@ + */ + IntMask = GMAC_DEF_MSK; + +-#ifdef DEBUG ++#if (defined(DEBUG) || defined(YUK2)) && (!defined(SK_SLIM)) + /* add IRQ for Receive FIFO Overrun */ + IntMask |= GM_IS_RX_FF_OR; +-#endif /* DEBUG */ +- +- SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask); +- ++#endif ++ ++ SK_OUT8(IoC, MR_ADDR(Port, GMAC_IRQ_MSK), (SK_U8)IntMask); ++ + /* get General Purpose Control */ + GM_IN16(IoC, Port, GM_GP_CTRL, &Reg); +- ++ + if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || + pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) { + /* set to Full Duplex */ + Reg |= GM_GPCR_DUP_FULL; ++ ++#ifndef SK_SLIM ++ if (HW_FEATURE(pAC, HWF_FORCE_AUTO_NEG) && ++ pPrt->PLinkModeConf < SK_LMODE_AUTOHALF) { ++ /* disable auto-update for speed, duplex and flow-control */ ++ Reg |= GM_GPCR_AU_ALL_DIS; ++ } ++#endif /* !SK_SLIM */ + } +- +- /* enable Rx/Tx */ +- GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA | +- GM_GPCR_TX_ENA)); + +-#ifndef VCPU +- /* Enable all PHY interrupts */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, +- (SK_U16)PHY_M_DEF_MSK); +-#endif /* VCPU */ ++ /* WA for dev. #4.209 */ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U && ++ (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_A1 || ++ pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_B0)) { ++ /* enable/disable Store & Forward mode for TX */ ++ SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), ++ pPrt->PLinkSpeedUsed != (SK_U8)SK_LSPEED_STAT_1000MBPS ? ++ TX_STFW_ENA : TX_STFW_DIS); ++ } ++ ++ /* enable Rx/Tx */ ++ GM_OUT16(IoC, Port, GM_GP_CTRL, Reg | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); + } + #endif /* YUKON */ +- ++ ++ pAC->GIni.GP[Port].PState = SK_PRT_RUN; ++ + return(0); + + } /* SkMacRxTxEnable */ +@@ -3270,33 +4533,33 @@ + */ + void SkMacRxTxDisable( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* IO context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_U16 Word; + + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +- ++ + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); +- +- XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); +- ++ ++ Word &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); ++ ++ XM_OUT16(IoC, Port, XM_MMU_CMD, Word); ++ + /* dummy read to ensure writing */ + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { +- ++ + GM_IN16(IoC, Port, GM_GP_CTRL, &Word); + +- GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA | +- GM_GPCR_TX_ENA))); ++ Word &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); + +- /* dummy read to ensure writing */ +- GM_IN16(IoC, Port, GM_GP_CTRL, &Word); ++ GM_OUT16(IoC, Port, GM_GP_CTRL, Word); + } + #endif /* YUKON */ + +@@ -3313,7 +4576,7 @@ + */ + void SkMacIrqDisable( + SK_AC *pAC, /* Adapter Context */ +-SK_IOC IoC, /* IO context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; +@@ -3325,18 +4588,18 @@ + + #ifdef GENESIS + if (pAC->GIni.GIGenesis) { +- ++ + /* disable all XMAC IRQs */ +- XM_OUT16(IoC, Port, XM_IMSK, 0xffff); +- +- /* Disable all PHY interrupts */ ++ XM_OUT16(IoC, Port, XM_IMSK, 0xffff); ++ ++ /* disable all PHY interrupts */ + switch (pPrt->PhyType) { + case SK_PHY_BCOM: + /* Make sure that PHY is initialized */ + if (pPrt->PState != SK_PRT_RESET) { + /* NOT allowed if BCOM is in RESET state */ + /* Workaround BCOM Errata (#10523) all BCom */ +- /* Disable Power Management if link is down */ ++ /* disable Power Management if link is down */ + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word); + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, + (SK_U16)(Word | PHY_B_AC_DIS_PM)); +@@ -3355,97 +4618,144 @@ + } + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { + /* disable all GMAC IRQs */ +- SK_OUT8(IoC, GMAC_IRQ_MSK, 0); +- ++ SK_OUT8(IoC, MR_ADDR(Port, GMAC_IRQ_MSK), 0); ++ + #ifndef VCPU +- /* Disable all PHY interrupts */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); +-#endif /* VCPU */ ++ if (pPrt->PState != SK_PRT_RESET) { ++ /* disable all PHY IRQs */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); ++ } ++#endif /* !VCPU */ + } + #endif /* YUKON */ + + } /* SkMacIrqDisable */ + + +-#ifdef SK_DIAG + /****************************************************************************** + * +- * SkXmSendCont() - Enable / Disable Send Continuous Mode ++ * SkMacTimeStamp() - Enable / Disable Time Stamp + * +- * Description: enable / disable Send Continuous Mode on XMAC ++ * Description: enable / disable Time Stamp generation for Rx packets + * + * Returns: + * nothing + */ +-void SkXmSendCont( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++void SkMacTimeStamp( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + SK_BOOL Enable) /* Enable / Disable */ + { +- SK_U32 MdReg; ++ SK_U32 SK_FAR MdReg; ++ SK_U8 TimeCtrl; + +- XM_IN32(IoC, Port, XM_MODE, &MdReg); ++ if (pAC->GIni.GIGenesis) { ++ ++ XM_IN32(IoC, Port, XM_MODE, &MdReg); + +- if (Enable) { +- MdReg |= XM_MD_TX_CONT; ++ if (Enable) { ++ MdReg |= XM_MD_ATS; ++ } ++ else { ++ MdReg &= ~XM_MD_ATS; ++ } ++ /* setup Mode Register */ ++ XM_OUT32(IoC, Port, XM_MODE, MdReg); + } + else { +- MdReg &= ~XM_MD_TX_CONT; ++ if (Enable) { ++ TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ; ++ } ++ else { ++ TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ; ++ } ++ /* Start/Stop Time Stamp Timer */ ++ SK_OUT8(IoC, GMAC_TI_ST_CTRL, TimeCtrl); + } +- /* setup Mode Register */ +- XM_OUT32(IoC, Port, XM_MODE, MdReg); +- +-} /* SkXmSendCont */ + ++} /* SkMacTimeStamp*/ + ++#ifdef SK_DIAG + /****************************************************************************** + * +- * SkMacTimeStamp() - Enable / Disable Time Stamp ++ * SkXmSendCont() - Enable / Disable Send Continuous Mode + * +- * Description: enable / disable Time Stamp generation for Rx packets ++ * Description: enable / disable Send Continuous Mode on XMAC resp. ++ * Packet Generation on GPHY + * + * Returns: + * nothing + */ +-void SkMacTimeStamp( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++void SkXmSendCont( ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + SK_BOOL Enable) /* Enable / Disable */ + { +- SK_U32 MdReg; +- SK_U8 TimeCtrl; ++ SK_U16 Reg; ++ SK_U16 Save; ++ SK_U32 SK_FAR MdReg; + + if (pAC->GIni.GIGenesis) { +- + XM_IN32(IoC, Port, XM_MODE, &MdReg); + + if (Enable) { +- MdReg |= XM_MD_ATS; ++ MdReg |= XM_MD_TX_CONT; + } + else { +- MdReg &= ~XM_MD_ATS; ++ MdReg &= ~XM_MD_TX_CONT; + } + /* setup Mode Register */ + XM_OUT32(IoC, Port, XM_MODE, MdReg); + } + else { +- if (Enable) { +- TimeCtrl = GMT_ST_START | GMT_ST_CLR_IRQ; ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) { ++ /* select page 18 */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 18); ++ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PAGE_DATA, &Reg); ++ ++ Reg &= ~0x003c; /* clear bits 5..2 */ ++ ++ if (Enable) { ++ /* enable packet generation, 1518 byte length */ ++ Reg |= (BIT_5S | BIT_3S); ++ } ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, Reg); + } +- else { +- TimeCtrl = GMT_ST_STOP | GMT_ST_CLR_IRQ; ++ ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U || ++ pAC->GIni.GIChipId == CHIP_ID_YUKON_EX) { ++ /* save page register */ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_ADR, &Save); ++ ++ /* select page 6 to access Packet Generation register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 6); ++ ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Reg); ++ ++ Reg &= ~0x003f; /* clear bits 5..0 */ ++ ++ if (Enable) { ++ /* enable packet generation, 1518 byte length */ ++ Reg |= (BIT_3S | BIT_1S); ++ } ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Reg); ++ ++ /* restore page register */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, Save); + } +- /* Start/Stop Time Stamp Timer */ +- SK_OUT8(IoC, GMAC_TI_ST_CTRL, TimeCtrl); + } + +-} /* SkMacTimeStamp*/ ++} /* SkXmSendCont */ + + #else /* !SK_DIAG */ + +@@ -3459,8 +4769,8 @@ + * is set true. + */ + void SkXmAutoNegLipaXmac( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + SK_U16 IStatus) /* Interrupt Status word to analyse */ + { +@@ -3472,8 +4782,9 @@ + (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) { + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04X\n", ++ ("AutoNegLipa: AutoNeg detected on Port %d, IStatus = 0x%04X\n", + Port, IStatus)); ++ + pPrt->PLipaAutoNeg = SK_LIPA_AUTO; + } + } /* SkXmAutoNegLipaXmac */ +@@ -3489,8 +4800,8 @@ + * is set true. + */ + void SkMacAutoNegLipaPhy( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + SK_U16 PhyStat) /* PHY Status word to analyse */ + { +@@ -3502,8 +4813,9 @@ + (PhyStat & PHY_ST_AN_OVER) != 0) { + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04X\n", ++ ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat = 0x%04X\n", + Port, PhyStat)); ++ + pPrt->PLipaAutoNeg = SK_LIPA_AUTO; + } + } /* SkMacAutoNegLipaPhy */ +@@ -3518,7 +4830,7 @@ + * + * Note: + * With an external PHY, some interrupt bits are not meaningfull any more: +- * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE ++ * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE + * - LinkPartnerReqConfig (bit #10) XM_IS_LIPA_RC + * - Page Received (bit #9) XM_IS_RX_PAGE + * - NextPageLoadedForXmt (bit #8) XM_IS_TX_PAGE +@@ -3530,23 +4842,24 @@ + * nothing + */ + static void SkXmIrq( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; +- SK_EVPARA Para; + SK_U16 IStatus; /* Interrupt status read from the XMAC */ + SK_U16 IStatus2; + #ifdef SK_SLIM +- SK_U64 OverflowStatus; +-#endif ++ SK_U64 OverflowStatus; ++#else ++ SK_EVPARA Para; ++#endif /* SK_SLIM */ + + pPrt = &pAC->GIni.GP[Port]; +- ++ + XM_IN16(IoC, Port, XM_ISRC, &IStatus); +- +- /* LinkPartner Auto-negable? */ ++ ++ /* Link Partner Auto-negable ? */ + if (pPrt->PhyType == SK_PHY_XMAC) { + SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus); + } +@@ -3556,7 +4869,7 @@ + XM_IS_RX_PAGE | XM_IS_TX_PAGE | + XM_IS_AND | XM_IS_INP_ASS); + } +- ++ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus)); + +@@ -3666,49 +4979,50 @@ + * nothing + */ + static void SkGmIrq( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; + SK_U8 IStatus; /* Interrupt status */ + #ifdef SK_SLIM +- SK_U64 OverflowStatus; ++ SK_U64 OverflowStatus; + #else + SK_EVPARA Para; +-#endif ++#endif /* SK_SLIM */ + + pPrt = &pAC->GIni.GP[Port]; +- +- SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus); +- +-#ifdef XXX +- /* LinkPartner Auto-negable? */ +- SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus); +-#endif /* XXX */ +- ++ ++ SK_IN8(IoC, MR_ADDR(Port, GMAC_IRQ_SRC), &IStatus); ++ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, +- ("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus)); ++ ("GmacIrq Port %d Isr 0x%02X\n", Port, IStatus)); + + /* Combined Tx & Rx Counter Overflow SIRQ Event */ + if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) { + /* these IRQs will be cleared by reading GMACs register */ + #ifdef SK_SLIM +- SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus); ++ SkGmOverflowStatus(pAC, IoC, Port, (SK_U16)IStatus, &OverflowStatus); + #else + Para.Para32[0] = (SK_U32)Port; + Para.Para32[1] = (SK_U32)IStatus; + SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para); +-#endif ++#endif /* SK_SLIM */ + } + ++#ifndef SK_SLIM + if (IStatus & GM_IS_RX_FF_OR) { + /* clear GMAC Rx FIFO Overrun IRQ */ + SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO); ++ ++ Para.Para64 = Port; ++ SkEventQueue(pAC, SKGE_DRV, SK_DRV_RX_OVERFLOW, Para); ++ + #ifdef DEBUG + pPrt->PRxOverCnt++; + #endif /* DEBUG */ + } ++#endif /* !SK_SLIM */ + + if (IStatus & GM_IS_TX_FF_UR) { + /* clear GMAC Tx FIFO Underrun IRQ */ +@@ -3738,8 +5052,8 @@ + * nothing + */ + void SkMacIrq( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port) /* Port Index (MAC_1 + n) */ + { + #ifdef GENESIS +@@ -3748,7 +5062,7 @@ + SkXmIrq(pAC, IoC, Port); + } + #endif /* GENESIS */ +- ++ + #ifdef YUKON + if (pAC->GIni.GIYukon) { + /* IRQ from GMAC */ +@@ -3775,8 +5089,8 @@ + * 1: something went wrong + */ + int SkXmUpdateStats( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + unsigned int Port) /* Port Index (MAC_1 + n) */ + { + SK_GEPORT *pPrt; +@@ -3798,7 +5112,7 @@ + do { + + XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg); +- ++ + if (++WaitIndex > 10) { + + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG); +@@ -3806,7 +5120,7 @@ + return(1); + } + } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0); +- ++ + return(0); + } /* SkXmUpdateStats */ + +@@ -3825,19 +5139,19 @@ + * 1: something went wrong + */ + int SkXmMacStatistic( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + unsigned int Port, /* Port Index (MAC_1 + n) */ + SK_U16 StatAddr, /* MIB counter base address */ +-SK_U32 SK_FAR *pVal) /* ptr to return statistic value */ ++SK_U32 SK_FAR *pVal) /* Pointer to return statistic value */ + { + if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) { +- ++ + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG); +- ++ + return(1); + } +- ++ + XM_IN32(IoC, Port, StatAddr, pVal); + + return(0); +@@ -3856,12 +5170,12 @@ + * 1: something went wrong + */ + int SkXmResetCounter( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + unsigned int Port) /* Port Index (MAC_1 + n) */ + { + XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); +- /* Clear two times according to Errata #3 */ ++ /* Clear two times according to XMAC Errata #3 */ + XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); + + return(0); +@@ -3888,14 +5202,14 @@ + * 1: something went wrong + */ + int SkXmOverflowStatus( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + unsigned int Port, /* Port Index (MAC_1 + n) */ +-SK_U16 IStatus, /* Interupt Status from MAC */ +-SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */ ++SK_U16 IStatus, /* Interrupt Status from MAC */ ++SK_U64 SK_FAR *pStatus) /* Pointer for return overflow status value */ + { + SK_U64 Status; /* Overflow status */ +- SK_U32 RegVal; ++ SK_U32 SK_FAR RegVal; + + Status = 0; + +@@ -3904,7 +5218,7 @@ + XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal); + Status |= (SK_U64)RegVal << 32; + } +- ++ + if ((IStatus & XM_IS_TXC_OV) != 0) { + + XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal); +@@ -3931,8 +5245,8 @@ + * 1: something went wrong + */ + int SkGmUpdateStats( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + unsigned int Port) /* Port Index (MAC_1 + n) */ + { + return(0); +@@ -3953,24 +5267,27 @@ + * 1: something went wrong + */ + int SkGmMacStatistic( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + unsigned int Port, /* Port Index (MAC_1 + n) */ + SK_U16 StatAddr, /* MIB counter base address */ +-SK_U32 SK_FAR *pVal) /* ptr to return statistic value */ ++SK_U32 SK_FAR *pVal) /* Pointer to return statistic value */ + { + + if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) { +- ++ + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG); +- +- SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr)); + return(1); + } +- ++ + GM_IN32(IoC, Port, StatAddr, pVal); + ++ /* dummy read after GM_IN32() */ ++ SK_IN16(IoC, B0_RAP, &StatAddr); ++ + return(0); + } /* SkGmMacStatistic */ + +@@ -3987,11 +5304,11 @@ + * 1: something went wrong + */ + int SkGmResetCounter( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + unsigned int Port) /* Port Index (MAC_1 + n) */ + { +- SK_U16 Reg; /* Phy Address Register */ ++ SK_U16 Reg; /* PHY Address Register */ + SK_U16 Word; + int i; + +@@ -3999,16 +5316,16 @@ + + /* set MIB Clear Counter Mode */ + GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR); +- ++ + /* read all MIB Counters with Clear Mode set */ + for (i = 0; i < GM_MIB_CNT_SIZE; i++) { + /* the reset is performed only when the lower 16 bits are read */ + GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word); + } +- ++ + /* clear MIB Clear Counter Mode */ + GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg); +- ++ + return(0); + } /* SkGmResetCounter */ + +@@ -4022,48 +5339,62 @@ + * resulting counter overflow status is written to , whereas the + * the following bit coding is used: + * 63:56 - unused +- * 55:48 - TxRx interrupt register bit7:0 +- * 32:47 - Rx interrupt register ++ * 55:48 - TxRx interrupt register bit 7:0 ++ * 47:32 - Rx interrupt register + * 31:24 - unused +- * 23:16 - TxRx interrupt register bit15:8 +- * 15:0 - Tx interrupt register ++ * 23:16 - TxRx interrupt register bit 15:8 ++ * 15: 0 - Tx interrupt register + * + * Returns: + * 0: success + * 1: something went wrong + */ + int SkGmOverflowStatus( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + unsigned int Port, /* Port Index (MAC_1 + n) */ +-SK_U16 IStatus, /* Interupt Status from MAC */ +-SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */ ++SK_U16 IStatus, /* Interrupt Status from MAC */ ++SK_U64 SK_FAR *pStatus) /* Pointer for return overflow status value */ + { +- SK_U64 Status; /* Overflow status */ + SK_U16 RegVal; ++#ifndef SK_SLIM ++ SK_U64 Status; /* Overflow status */ + + Status = 0; ++#endif /* !SK_SLIM */ + + if ((IStatus & GM_IS_RX_CO_OV) != 0) { + /* this register is self-clearing after read */ + GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal); ++ ++#ifndef SK_SLIM + Status |= (SK_U64)RegVal << 32; ++#endif /* !SK_SLIM */ + } +- ++ + if ((IStatus & GM_IS_TX_CO_OV) != 0) { + /* this register is self-clearing after read */ + GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal); ++ ++#ifndef SK_SLIM + Status |= (SK_U64)RegVal; ++#endif /* !SK_SLIM */ + } +- ++ + /* this register is self-clearing after read */ + GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal); +- /* Rx overflow interrupt register bits (LoByte)*/ ++ ++#ifndef SK_SLIM ++ /* Rx overflow interrupt register bits (LoByte) */ + Status |= (SK_U64)((SK_U8)RegVal) << 48; +- /* Tx overflow interrupt register bits (HiByte)*/ ++ /* Tx overflow interrupt register bits (HiByte) */ + Status |= (SK_U64)(RegVal >> 8) << 16; + + *pStatus = Status; ++#endif /* !SK_SLIM */ ++ ++ /* dummy read after GM_IN16() */ ++ SK_IN16(IoC, B0_RAP, &RegVal); + + return(0); + } /* SkGmOverflowStatus */ +@@ -4079,77 +5410,199 @@ + * gets the results if 'StartTest' is true + * + * NOTE: this test is meaningful only when link is down +- * ++ * + * Returns: + * 0: success +- * 1: no YUKON copper +- * 2: test in progress ++ * 1: no YUKON copper ++ * 2: test in progress ++ * 3: PHY read error + */ + int SkGmCableDiagStatus( +-SK_AC *pAC, /* adapter context */ +-SK_IOC IoC, /* IO context */ ++SK_AC *pAC, /* Adapter Context */ ++SK_IOC IoC, /* I/O Context */ + int Port, /* Port Index (MAC_1 + n) */ + SK_BOOL StartTest) /* flag for start / get result */ + { + int i; ++ int CableDiagOffs; ++ int MdiPairs; ++ int ChipId; ++ int Rtv; ++ SK_BOOL FastEthernet; ++ SK_BOOL Yukon2; ++ SK_U16 Ctrl; + SK_U16 RegVal; + SK_GEPORT *pPrt; + + pPrt = &pAC->GIni.GP[Port]; + + if (pPrt->PhyType != SK_PHY_MARV_COPPER) { +- ++ + return(1); + } + ++ ChipId = pAC->GIni.GIChipId; ++ ++ Yukon2 = ChipId == CHIP_ID_YUKON_XL || ++ ChipId == CHIP_ID_YUKON_EC_U || ++ ChipId == CHIP_ID_YUKON_EX; ++ ++ if (ChipId == CHIP_ID_YUKON_FE) { ++ ++ CableDiagOffs = PHY_MARV_FE_VCT_TX; ++ FastEthernet = SK_TRUE; ++ MdiPairs = 2; ++ } ++ else { ++ CableDiagOffs = Yukon2 ? PHY_MARV_PHY_CTRL : PHY_MARV_CABLE_DIAG; ++ ++ if (ChipId == CHIP_ID_YUKON_EX) { ++ ++ CableDiagOffs += 7; /* Advanced VCT Control Register */ ++ ++ /* apply TDR workaround */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 0x000d); ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0x4c32); ++ } ++ ++ FastEthernet = SK_FALSE; ++ MdiPairs = 4; ++ } ++ + if (StartTest) { ++ ++ /* set to RESET to avoid PortCheckUp */ ++ pPrt->PState = SK_PRT_RESET; ++ + /* only start the cable test */ +- if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) { +- /* apply TDR workaround from Marvell */ +- SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e); +- +- SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00); +- SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800); +- SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400); +- SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000); +- SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100); ++ if (!FastEthernet) { ++ ++ if ((((pPrt->PhyId1 & PHY_I1_MOD_NUM) >> 4) == 2) && ++ ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4)) { ++ /* apply TDR workaround for model 2, rev. < 4 */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 0x001e); ++ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xcc00); ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc800); ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc400); ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc000); ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc100); ++ } ++ ++#ifdef YUKON_DBG ++ if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) { ++ /* set address to 1 for page 1 */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 1); ++ ++ /* disable waiting period */ ++ SkGmPhyWrite(pAC, IoC, Port, CableDiagOffs, ++ PHY_M_CABD_DIS_WAIT); ++ } ++#endif ++ if (Yukon2) { ++ /* set address to 5 for page 5 */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 5); ++ ++#ifdef YUKON_DBG ++ /* disable waiting period */ ++ SkGmPhyWrite(pAC, IoC, Port, CableDiagOffs + 1, ++ PHY_M_CABD_DIS_WAIT); ++#endif ++ } ++ else { ++ /* set address to 0 for MDI[0] (Page 0) */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); ++ } + } ++ else { ++ RegVal = PHY_CT_RESET | PHY_CT_SP100; + +- /* set address to 0 for MDI[0] */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, RegVal); ++ ++#ifdef xYUKON_DBG ++ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_FE_SPEC_2, &RegVal); ++ /* disable waiting period */ ++ RegVal |= PHY_M_FESC_DIS_WAIT; + +- /* Read Cable Diagnostic Reg */ +- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_FE_SPEC_2, RegVal); ++#endif ++ } ++ ++ Rtv = SkGmPhyRead(pAC, IoC, Port, CableDiagOffs, &RegVal); ++ ++ if (Rtv != 0) { ++ /* PHY read error */ ++ return(3); ++ } + + /* start Cable Diagnostic Test */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, +- (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST)); +- ++ RegVal |= PHY_M_CABD_ENA_TEST; ++ ++ if (ChipId == CHIP_ID_YUKON_EX) { ++ /* select first peak above threshold */ ++ RegVal |= PHY_M_CABD_TEST_MODE(1); ++ ++ /* read Transmit Pulse Reg */ ++ SkGmPhyRead(pAC, IoC, Port, CableDiagOffs + 5, &Ctrl); ++ ++ /* select first 1/4 pulse width (32ns) */ ++ Ctrl |= PHY_M_CABD_PULS_WIDT(3); ++ ++ SkGmPhyWrite(pAC, IoC, Port, CableDiagOffs + 5, Ctrl); ++ } ++ ++ SkGmPhyWrite(pAC, IoC, Port, CableDiagOffs, RegVal); ++ + return(0); + } +- +- /* Read Cable Diagnostic Reg */ +- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); ++ ++ /* read Cable Diagnostic Reg */ ++ Rtv = SkGmPhyRead(pAC, IoC, Port, CableDiagOffs, &RegVal); ++ ++ if (Rtv != 0) { ++ /* PHY read error */ ++ return(3); ++ } + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, +- ("PHY Cable Diag.=0x%04X\n", RegVal)); ++ ("PHY Cable Diag. = 0x%04X\n", RegVal)); + + if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) { + /* test is running */ + return(2); + } + ++ if (ChipId == CHIP_ID_YUKON_EX) { ++ /* additional check */ ++ if ((RegVal & PHY_M_CABD_COMPLETE) == 0) { ++ /* test not completed */ ++ return(2); ++ } ++ ++ CableDiagOffs = PHY_MARV_PHY_CTRL; ++ } ++ + /* get the test results */ +- for (i = 0; i < 4; i++) { +- /* set address to i for MDI[i] */ +- SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i); ++ for (i = 0; i < MdiPairs; i++) { ++ ++ if (!FastEthernet && !Yukon2) { ++ /* set address to i for MDI[i] */ ++ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i); ++ } + + /* get Cable Diagnostic values */ +- SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); ++ SkGmPhyRead(pAC, IoC, Port, CableDiagOffs, &RegVal); + + pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK); + +- pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13); ++ pPrt->PMdiPairSts[i] = (SK_U8)((ChipId == CHIP_ID_YUKON_EX) ? ++ (RegVal >> 8) : ((RegVal & PHY_M_CABD_STAT_MSK) >> 13)); ++ ++ if (FastEthernet || Yukon2) { ++ /* get next register */ ++ CableDiagOffs++; ++ } + } + + return(0); +@@ -4158,3 +5611,4 @@ + #endif /* YUKON */ + + /* End of file */ ++ +diff -ruN linux/drivers/net/sk98lin/sky2.c linux-new/drivers/net/sk98lin/sky2.c +--- linux/drivers/net/sk98lin/sky2.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/sky2.c 2007-01-24 13:58:37.000000000 +0100 +@@ -0,0 +1,2768 @@ ++/****************************************************************************** ++ * ++ * Name: sky2.c ++ * Project: Yukon2 specific functions and implementations ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: The main driver source module ++ * ++ *****************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * (C)Copyright 1998-2002 SysKonnect GmbH. ++ * (C)Copyright 2002-2005 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 ++ * ++ * 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 ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,14) ++#include ++#endif ++/****************************************************************************** ++ * ++ * Local Function Prototypes ++ * ++ *****************************************************************************/ ++ ++static void InitPacketQueues(SK_AC *pAC,int Port); ++static void GiveTxBufferToHw(SK_AC *pAC,SK_IOC IoC,int Port); ++static void GiveRxBufferToHw(SK_AC *pAC,SK_IOC IoC,int Port,SK_PACKET *pPacket); ++static SK_BOOL HandleReceives(SK_AC *pAC,int Port,SK_U16 Len,SK_U32 FrameStatus,SK_U16 Tcp1,SK_U16 Tcp2,SK_U32 Tist,SK_U16 Vlan); ++static void CheckForSendComplete(SK_AC *pAC,SK_IOC IoC,int Port,SK_PKT_QUEUE *pPQ,SK_LE_TABLE *pLETab,unsigned int Done); ++static void UnmapAndFreeTxPktBuffer(SK_AC *pAC,SK_PACKET *pSkPacket,int TxPort); ++static SK_BOOL AllocateAndInitLETables(SK_AC *pAC); ++static SK_BOOL AllocatePacketBuffersYukon2(SK_AC *pAC); ++static void FreeLETables(SK_AC *pAC); ++static void FreePacketBuffers(SK_AC *pAC); ++static SK_BOOL AllocAndMapRxBuffer(SK_AC *pAC,SK_PACKET *pSkPacket,int Port); ++#ifdef CONFIG_SK98LIN_NAPI ++static SK_BOOL HandleStatusLEs(SK_AC *pAC,int *WorkDone,int WorkToDo); ++#else ++static SK_BOOL HandleStatusLEs(SK_AC *pAC); ++#endif ++ ++extern void SkGeCheckTimer (DEV_NET *pNet); ++extern void SkLocalEventQueue( SK_AC *pAC, ++ SK_U32 Class, ++ SK_U32 Event, ++ SK_U32 Param1, ++ SK_U32 Param2, ++ SK_BOOL Flag); ++extern void SkLocalEventQueue64( SK_AC *pAC, ++ SK_U32 Class, ++ SK_U32 Event, ++ SK_U64 Param, ++ SK_BOOL Flag); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) ++/* Need way to schedule device 0 even when it's offline. */ ++static inline int __netif_rx_schedule_prep(struct net_device *dev) ++{ ++ return !test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state); ++} ++#endif ++ ++ ++/****************************************************************************** ++ * ++ * Local Variables ++ * ++ *****************************************************************************/ ++ ++#define MAX_NBR_RX_BUFFERS_IN_HW 0x15 ++static SK_U8 NbrRxBuffersInHW; ++#define FLUSH_OPC(le) ++ ++/****************************************************************************** ++ * ++ * Global Functions ++ * ++ *****************************************************************************/ ++ ++int SkY2Xmit( struct sk_buff *skb, struct SK_NET_DEVICE *dev); ++void FillReceiveTableYukon2(SK_AC *pAC,SK_IOC IoC,int Port); ++ ++/***************************************************************************** ++ * ++ * SkY2RestartStatusUnit - restarts teh status unit ++ * ++ * Description: ++ * Reenables the status unit after any De-Init (e.g. when altering ++ * the sie of the MTU via 'ifconfig a.b.c.d mtu xxx') ++ * ++ * Returns: N/A ++ */ ++void SkY2RestartStatusUnit( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("==> SkY2RestartStatusUnit\n")); ++ ++ /* ++ ** It might be that the TX timer is not started. Therefore ++ ** it is initialized here -> to be more investigated! ++ */ ++ SK_OUT32(pAC->IoBase, STAT_TX_TIMER_INI, HW_MS_TO_TICKS(pAC,10)); ++ ++ pAC->StatusLETable.Done = 0; ++ pAC->StatusLETable.Put = 0; ++ pAC->StatusLETable.HwPut = 0; ++ SkGeY2InitStatBmu(pAC, pAC->IoBase, &pAC->StatusLETable); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("<== SkY2RestartStatusUnit\n")); ++} ++ ++/***************************************************************************** ++ * ++ * SkY2RlmtSend - sends out a single RLMT notification ++ * ++ * Description: ++ * This function sends out an RLMT frame ++ * ++ * 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) ++ */ ++int SkY2RlmtSend ( ++SK_AC *pAC, /* pointer to adapter control context */ ++int PortNr, /* index of port the packet(s) shall be send to */ ++struct sk_buff *pMessage) /* pointer to send-message */ ++{ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("=== SkY2RlmtSend\n")); ++#if 0 ++ return -1; // temporarily do not send out RLMT frames ++#endif ++ skb_shinfo(pMessage)->nr_frags = (2*MAX_SKB_FRAGS) + PortNr; ++ return(SkY2Xmit(pMessage, pAC->dev[PortNr])); // SkY2Xmit needs device ++} ++ ++/***************************************************************************** ++ * ++ * SkY2AllocateResources - Allocates all required resources for Yukon2 ++ * ++ * Description: ++ * This function allocates all memory needed for the Yukon2. ++ * It maps also RX buffers to the LETables and initializes the ++ * status list element table. ++ * ++ * Returns: ++ * SK_TRUE, if all resources could be allocated and setup succeeded ++ * SK_FALSE, if an error ++ */ ++SK_BOOL SkY2AllocateResources ( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ int CurrMac; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("==> SkY2AllocateResources\n")); ++ ++ /* ++ ** Initialize the packet queue variables first ++ */ ++ for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) { ++ InitPacketQueues(pAC, CurrMac); ++ } ++ ++ /* ++ ** Get sufficient memory for the LETables ++ */ ++ if (!AllocateAndInitLETables(pAC)) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR, ++ ("No memory for LETable.\n")); ++ return(SK_FALSE); ++ } ++ ++ /* ++ ** Allocate and intialize memory for both RX and TX ++ ** packet and fragment buffers. On an error, free ++ ** previously allocated LETable memory and quit. ++ */ ++ if (!AllocatePacketBuffersYukon2(pAC)) { ++ FreeLETables(pAC); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR, ++ ("No memory for Packetbuffers.\n")); ++ return(SK_FALSE); ++ } ++ ++ /* ++ ** Rx and Tx LE tables will be initialized in SkGeOpen() ++ ** ++ ** It might be that the TX timer is not started. Therefore ++ ** it is initialized here -> to be more investigated! ++ */ ++ SK_OUT32(pAC->IoBase, STAT_TX_TIMER_INI, HW_MS_TO_TICKS(pAC,10)); ++ SkGeY2InitStatBmu(pAC, pAC->IoBase, &pAC->StatusLETable); ++ ++ pAC->MaxUnusedRxLeWorking = MAX_UNUSED_RX_LE_WORKING; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("<== SkY2AllocateResources\n")); ++ ++ return (SK_TRUE); ++} ++ ++/***************************************************************************** ++ * ++ * SkY2FreeResources - Frees previously allocated resources of Yukon2 ++ * ++ * Description: ++ * This function frees all previously allocated memory of the Yukon2. ++ * ++ * Returns: N/A ++ */ ++void SkY2FreeResources ( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("==> SkY2FreeResources\n")); ++ ++ FreeLETables(pAC); ++ FreePacketBuffers(pAC); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("<== SkY2FreeResources\n")); ++} ++ ++/***************************************************************************** ++ * ++ * SkY2AllocateRxBuffers - Allocates the receive buffers for a port ++ * ++ * Description: ++ * This function allocated all the RX buffers of the Yukon2. ++ * ++ * Returns: N/A ++ */ ++void SkY2AllocateRxBuffers ( ++SK_AC *pAC, /* pointer to adapter control context */ ++SK_IOC IoC, /* I/O control context */ ++int Port) /* port index of RX */ ++{ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("==> SkY2AllocateRxBuffers (Port %c)\n", Port)); ++ ++ FillReceiveTableYukon2(pAC, IoC, Port); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("<== SkY2AllocateRxBuffers\n")); ++} ++ ++/***************************************************************************** ++ * ++ * SkY2FreeRxBuffers - Free's all allocates RX buffers of ++ * ++ * Description: ++ * This function frees all RX buffers of the Yukon2 for a single port ++ * ++ * Returns: N/A ++ */ ++void SkY2FreeRxBuffers ( ++SK_AC *pAC, /* pointer to adapter control context */ ++SK_IOC IoC, /* I/O control context */ ++int Port) /* port index of RX */ ++{ ++ SK_PACKET *pSkPacket; ++ unsigned long Flags; /* for POP/PUSH macros */ ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("==> SkY2FreeRxBuffers (Port %c)\n", Port)); ++ ++ if (pAC->RxPort[Port].ReceivePacketTable != NULL) { ++ POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket); ++ while (pSkPacket != NULL) { ++ if ((pSkPacket->pFrag) != NULL) { ++ pci_unmap_page(pAC->PciDev, ++ (dma_addr_t) pSkPacket->pFrag->pPhys, ++ pSkPacket->pFrag->FragLen - 2, ++ PCI_DMA_FROMDEVICE); ++ ++ /* wipe out any rubbish data that may interfere */ ++ skb_shinfo(pSkPacket->pMBuf)->nr_frags = 0; ++ skb_shinfo(pSkPacket->pMBuf)->frag_list = NULL; ++ DEV_KFREE_SKB_ANY(pSkPacket->pMBuf); ++ pSkPacket->pMBuf = NULL; ++ pSkPacket->pFrag->pPhys = (SK_U64) 0; ++ pSkPacket->pFrag->pVirt = NULL; ++ } ++ PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket); ++ POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket); ++ } ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("<== SkY2FreeRxBuffers\n")); ++} ++ ++/***************************************************************************** ++ * ++ * SkY2FreeTxBuffers - Free's any currently maintained Tx buffer ++ * ++ * Description: ++ * This function frees the TX buffers of the Yukon2 for a single port ++ * which might be in use by a transmit action ++ * ++ * Returns: N/A ++ */ ++void SkY2FreeTxBuffers ( ++SK_AC *pAC, /* pointer to adapter control context */ ++SK_IOC IoC, /* I/O control context */ ++int Port) /* port index of TX */ ++{ ++ SK_PACKET *pSkPacket; ++ SK_FRAG *pSkFrag; ++ unsigned long Flags; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("==> SkY2FreeTxBuffers (Port %c)\n", Port)); ++ ++ if (pAC->TxPort[Port][0].TransmitPacketTable != NULL) { ++ POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxAQ_working, pSkPacket); ++ while (pSkPacket != NULL) { ++ if ((pSkFrag = pSkPacket->pFrag) != NULL) { ++ UnmapAndFreeTxPktBuffer(pAC, pSkPacket, Port); ++ } ++ PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->TxPort[Port][0].TxQ_free, pSkPacket); ++ POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxAQ_working, pSkPacket); ++ } ++#ifdef USE_SYNC_TX_QUEUE ++ POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxSQ_working, pSkPacket); ++ while (pSkPacket != NULL) { ++ if ((pSkFrag = pSkPacket->pFrag) != NULL) { ++ UnmapAndFreeTxPktBuffer(pAC, pSkPacket, Port); ++ } ++ PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->TxPort[Port][0].TxQ_free, pSkPacket); ++ POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxSQ_working, pSkPacket); ++ } ++#endif ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("<== SkY2FreeTxBuffers\n")); ++} ++ ++/***************************************************************************** ++ * ++ * SkY2Isr - handle a receive IRQ for all yukon2 cards ++ * ++ * Description: ++ * This function is called when a receive IRQ is set. (only for yukon2) ++ * HandleReceives does the deferred processing of all outstanding ++ * interrupt operations. ++ * ++ * Returns: N/A ++ */ ++SkIsrRetVar SkY2Isr ( ++int irq, /* the irq we have received (might be shared!) */ ++void *dev_id, /* current device id */ ++struct pt_regs *ptregs) /* not used by our driver */ ++{ ++ struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ SK_U32 IntSrc; ++#ifdef CONFIG_SK98LIN_NAPI ++ SK_BOOL SetIntMask = SK_FALSE; ++#else ++ SK_BOOL handledStatLE = SK_FALSE; ++ unsigned long Flags; ++#endif ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("==> SkY2Isr\n")); ++ ++ SK_IN32(pAC->IoBase, B0_Y2_SP_ISRC2, &IntSrc); ++ ++ if ((IntSrc == 0) && (!pNet->NetConsoleMode)){ ++ SK_OUT32(pAC->IoBase, B0_Y2_SP_ICR, 2); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("No Interrupt\n ==> SkY2Isr\n")); ++ return SkIsrRetNone; ++ ++ } ++ ++#ifdef Y2_RECOVERY ++ if (pNet->InRecover) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("Already in recover\n ==> SkY2Isr\n")); ++ SK_OUT32(pAC->IoBase, B0_Y2_SP_ICR, 2); ++ return SkIsrRetNone; ++ } ++#endif ++ ++#ifdef CONFIG_SK98LIN_NAPI ++ /* Since both boards share one irq, they share one poll routine */ ++ if (__netif_rx_schedule_prep(pAC->dev[0])) { ++ pAC->GIni.GIValIrqMask &= ~(Y2_IS_STAT_BMU); ++ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); ++ SetIntMask = SK_TRUE; ++ __netif_rx_schedule(pAC->dev[0]); ++ } ++#else ++ handledStatLE = HandleStatusLEs(pAC); ++#endif ++ ++ /* ++ ** Check for Special Interrupts ++ */ ++ if ((IntSrc & ~Y2_IS_STAT_BMU) || pAC->CheckQueue || pNet->TimerExpired) { ++ pAC->CheckQueue = SK_FALSE; ++#ifdef CONFIG_SK98LIN_NAPI ++ spin_lock(&pAC->SlowPathLock); ++#else ++ spin_lock_irqsave(&pAC->SetPutIndexLock, Flags); ++#endif ++ SkGeSirqIsr(pAC, pAC->IoBase, IntSrc); ++ SkEventDispatcher(pAC, pAC->IoBase); ++#ifdef CONFIG_SK98LIN_NAPI ++ spin_unlock(&pAC->SlowPathLock); ++#else ++ spin_unlock_irqrestore(&pAC->SetPutIndexLock, Flags); ++#endif ++ } ++ ++ /* Speed enhancement for a2 chipsets */ ++ if (HW_FEATURE(pAC, HWF_WA_DEV_42)) { ++#ifdef CONFIG_SK98LIN_NAPI ++ spin_lock(&pAC->SlowPathLock); ++#else ++ spin_lock_irqsave(&pAC->SetPutIndexLock, Flags); ++#endif ++ SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_XA1,0), &pAC->TxPort[0][0].TxALET); ++ SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_R1,0), &pAC->RxPort[0].RxLET); ++#ifdef CONFIG_SK98LIN_NAPI ++ spin_unlock(&pAC->SlowPathLock); ++#else ++ spin_unlock_irqrestore(&pAC->SetPutIndexLock, Flags); ++#endif ++ } ++ ++ /* ++ ** Reenable interrupts and signal end of ISR ++ */ ++ SK_OUT32(pAC->IoBase, B0_Y2_SP_ICR, 2); ++ ++ /* ++ ** Stop and restart TX timer in case a Status LE was handled ++ */ ++#ifndef CONFIG_SK98LIN_NAPI ++ if ((HW_FEATURE(pAC, HWF_WA_DEV_43_418)) && (handledStatLE)) { ++ SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_STOP); ++ SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_START); ++ } ++#endif ++ ++ if (!(IS_Q_EMPTY(&(pAC->TxPort[0][TX_PRIO_LOW].TxAQ_waiting)))) { ++ GiveTxBufferToHw(pAC, pAC->IoBase, 0); ++ } ++ if (!(IS_Q_EMPTY(&(pAC->TxPort[1][TX_PRIO_LOW].TxAQ_waiting)))) { ++ GiveTxBufferToHw(pAC, pAC->IoBase, 1); ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("<== SkY2Isr\n")); ++ ++ return SkIsrRetHandled; ++} /* SkY2Isr */ ++ ++/***************************************************************************** ++ * ++ * SkY2Xmit - Linux frame transmit function for Yukon2 ++ * ++ * 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) !!! ++ */ ++int SkY2Xmit( ++struct sk_buff *skb, /* socket buffer to be sent */ ++struct SK_NET_DEVICE *dev) /* via which device? */ ++{ ++ DEV_NET *pNet = (DEV_NET*) dev->priv; ++ SK_AC *pAC = pNet->pAC; ++ SK_U8 FragIdx = 0; ++ SK_PACKET *pSkPacket; ++ SK_FRAG *PrevFrag; ++ SK_FRAG *CurrFrag; ++ SK_PKT_QUEUE *pWorkQueue; /* corresponding TX queue */ ++ SK_PKT_QUEUE *pWaitQueue; ++ SK_PKT_QUEUE *pFreeQueue; ++ SK_LE_TABLE *pLETab; /* corresponding LETable */ ++ skb_frag_t *sk_frag; ++ SK_U64 PhysAddr; ++ unsigned long Flags; ++ unsigned int Port; ++ int CurrFragCtr; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("==> SkY2Xmit\n")); ++ ++ /* ++ ** Get port and return if no free packet is available ++ */ ++ if (skb_shinfo(skb)->nr_frags > MAX_SKB_FRAGS) { ++ Port = skb_shinfo(skb)->nr_frags - (2*MAX_SKB_FRAGS); ++ skb_shinfo(skb)->nr_frags = 0; ++ } else { ++ Port = (pAC->RlmtNets == 2) ? pNet->PortNr : pAC->ActivePort; ++ } ++ ++ if (IS_Q_EMPTY(&(pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free))) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR, ++ ("Not free packets available for send\n")); ++ return 1; /* zero bytes sent! */ ++ } ++ ++ /* ++ ** Put any new packet to be sent in the waiting queue and ++ ** handle also any possible fragment of that packet. ++ */ ++ pWorkQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working); ++ pWaitQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting); ++ pFreeQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free); ++ pLETab = &(pAC->TxPort[Port][TX_PRIO_LOW].TxALET); ++ ++ /* ++ ** Normal send operations require only one fragment, because ++ ** only one sk_buff data area is passed. ++ ** In contradiction to this, scatter-gather (zerocopy) send ++ ** operations might pass one or more additional fragments ++ ** where each fragment needs a separate fragment info packet. ++ */ ++ if (((skb_shinfo(skb)->nr_frags + 1) * MAX_FRAG_OVERHEAD) > ++ NUM_FREE_LE_IN_TABLE(pLETab)) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR, ++ ("Not enough LE available for send\n")); ++ return 1; /* zero bytes sent! */ ++ } ++ ++ if ((skb_shinfo(skb)->nr_frags + 1) > MAX_NUM_FRAGS) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR, ++ ("Not even one fragment available for send\n")); ++ return 1; /* zero bytes sent! */ ++ } ++ ++ /* ++ ** Get first packet from free packet queue ++ */ ++ POP_FIRST_PKT_FROM_QUEUE(pFreeQueue, pSkPacket); ++ if(pSkPacket == NULL) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR, ++ ("Could not obtain free packet used for xmit\n")); ++ return 1; /* zero bytes sent! */ ++ } ++ ++ pSkPacket->pFrag = &(pSkPacket->FragArray[FragIdx]); ++ ++ /* ++ ** map the sk_buff to be available for the adapter ++ */ ++ PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, ++ virt_to_page(skb->data), ++ ((unsigned long) skb->data & ~PAGE_MASK), ++ skb_headlen(skb), ++ PCI_DMA_TODEVICE); ++ pSkPacket->pMBuf = skb; ++ pSkPacket->pFrag->pPhys = PhysAddr; ++ pSkPacket->pFrag->FragLen = skb_headlen(skb); ++ pSkPacket->pFrag->pNext = NULL; /* initial has no next default */ ++ pSkPacket->NumFrags = skb_shinfo(skb)->nr_frags + 1; ++ ++ PrevFrag = pSkPacket->pFrag; ++ ++ /* ++ ** Each scatter-gather fragment need to be mapped... ++ */ ++ for ( CurrFragCtr = 0; ++ CurrFragCtr < skb_shinfo(skb)->nr_frags; ++ CurrFragCtr++) { ++ FragIdx++; ++ sk_frag = &skb_shinfo(skb)->frags[CurrFragCtr]; ++ CurrFrag = &(pSkPacket->FragArray[FragIdx]); ++ ++ /* ++ ** map the sk_buff to be available for the adapter ++ */ ++ PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, ++ sk_frag->page, ++ sk_frag->page_offset, ++ sk_frag->size, ++ PCI_DMA_TODEVICE); ++ ++ CurrFrag->pPhys = PhysAddr; ++ CurrFrag->FragLen = sk_frag->size; ++ CurrFrag->pNext = NULL; ++ ++ /* ++ ** Add the new fragment to the list of fragments ++ */ ++ PrevFrag->pNext = CurrFrag; ++ PrevFrag = CurrFrag; ++ } ++ ++ /* ++ ** Add packet to waiting packets queue ++ */ ++ PUSH_PKT_AS_LAST_IN_QUEUE(pWaitQueue, pSkPacket); ++ GiveTxBufferToHw(pAC, pAC->IoBase, Port); ++ dev->trans_start = jiffies; ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("<== SkY2Xmit(return 0)\n")); ++ return (0); ++} /* SkY2Xmit */ ++ ++#ifdef CONFIG_SK98LIN_NAPI ++/***************************************************************************** ++ * ++ * SkY2Poll - NAPI Rx polling callback for Yukon2 chipsets ++ * ++ * Description: ++ * Called by the Linux system in case NAPI polling is activated ++ * ++ * Returns ++ * The number of work data still to be handled ++ * ++ * Notes ++ * The slowpath lock needs to be set because HW accesses may ++ * interfere with slowpath events (e.g. TWSI) ++ */ ++int SkY2Poll( ++struct net_device *dev, /* device that needs to be polled */ ++int *budget) /* how many budget do we have? */ ++{ ++ SK_AC *pAC = ((DEV_NET*)(dev->priv))->pAC; ++ int WorkToDo = min(*budget, dev->quota); ++ int WorkDone = 0; ++ SK_BOOL handledStatLE = SK_FALSE; ++ ++ handledStatLE = HandleStatusLEs(pAC, &WorkDone, WorkToDo); ++ ++ *budget -= WorkDone; ++ dev->quota -= WorkDone; ++ ++ if(WorkDone < WorkToDo) { ++ netif_rx_complete(dev); ++ pAC->GIni.GIValIrqMask |= (Y2_IS_STAT_BMU); ++ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); ++ if ((HW_FEATURE(pAC, HWF_WA_DEV_43_418)) && (handledStatLE)) { ++ SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_STOP); ++ SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_START); ++ } ++ } ++ return (WorkDone >= WorkToDo); ++} /* SkY2Poll */ ++#endif ++ ++/****************************************************************************** ++ * ++ * SkY2PortStop - stop a port on Yukon2 ++ * ++ * Description: ++ * This function stops a port of the Yukon2 chip. This stop ++ * stop needs to be performed in a specific order: ++ * ++ * a) Stop the Prefetch unit ++ * b) Stop the Port (MAC, PHY etc.) ++ * ++ * Returns: N/A ++ */ ++void SkY2PortStop( ++SK_AC *pAC, /* adapter control context */ ++SK_IOC IoC, /* I/O control context (address of adapter registers) */ ++int Port, /* port to stop (MAC_1 + n) */ ++int Dir, /* StopDirection (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */ ++int RstMode) /* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */ ++{ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("==> SkY2PortStop (Port %c)\n", 'A' + Port)); ++ ++ /* ++ ** Stop the HW ++ */ ++ SkGeStopPort(pAC, IoC, Port, Dir, RstMode); ++ ++ /* ++ ** Move any TX packet from work queues into the free queue again ++ ** and initialize the TX LETable variables ++ */ ++ SkY2FreeTxBuffers(pAC, pAC->IoBase, Port); ++ pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Bmu.RxTx.TcpWp = 0; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Bmu.RxTx.MssValue = 0; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxALET.BufHighAddr = 0; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Done = 0; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Put = 0; ++ // pAC->GIni.GP[Port].PState = SK_PRT_STOP; ++ ++ /* ++ ** Move any RX packet from work queue into the waiting queue ++ ** and initialize the RX LETable variables ++ */ ++ SkY2FreeRxBuffers(pAC, pAC->IoBase, Port); ++ pAC->RxPort[Port].RxLET.BufHighAddr = 0; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("<== SkY2PortStop()\n")); ++} ++ ++/****************************************************************************** ++ * ++ * SkY2PortStart - start a port on Yukon2 ++ * ++ * Description: ++ * This function starts a port of the Yukon2 chip. This start ++ * action needs to be performed in a specific order: ++ * ++ * a) Initialize the LET indices (PUT/GET to 0) ++ * b) Initialize the LET in HW (enables also prefetch unit) ++ * c) Move all RX buffers from waiting queue to working queue ++ * which involves also setting up of RX list elements ++ * d) Initialize the FIFO settings of Yukon2 (Watermark etc.) ++ * e) Initialize the Port (MAC, PHY etc.) ++ * f) Initialize the MC addresses ++ * ++ * Returns: N/A ++ */ ++void SkY2PortStart( ++SK_AC *pAC, /* adapter control context */ ++SK_IOC IoC, /* I/O control context (address of adapter registers) */ ++int Port) /* port to start */ ++{ ++ // SK_GEPORT *pPrt = &pAC->GIni.GP[Port]; ++ SK_HWLE *pLE; ++ SK_U32 DWord; ++ SK_U32 PrefetchReg; /* register for Put index */ ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("==> SkY2PortStart (Port %c)\n", 'A' + Port)); ++ ++ /* ++ ** Initialize the LET indices ++ */ ++ pAC->RxPort[Port].RxLET.Done = 0; ++ pAC->RxPort[Port].RxLET.Put = 0; ++ pAC->RxPort[Port].RxLET.HwPut = 0; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Done = 0; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Put = 0; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxALET.HwPut = 0; ++ if (HW_SYNC_TX_SUPPORTED(pAC)) { ++ pAC->TxPort[Port][TX_PRIO_LOW].TxSLET.Done = 0; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxSLET.Put = 0; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxSLET.HwPut = 0; ++ } ++ ++ if (HW_FEATURE(pAC, HWF_WA_DEV_420)) { ++ /* ++ ** It might be that we have to limit the RX buffers ++ ** effectively passed to HW. Initialize the start ++ ** value in that case... ++ */ ++ NbrRxBuffersInHW = 0; ++ } ++ ++ /* ++ ** TODO on dual net adapters we need to check if ++ ** StatusLETable need to be set... ++ ** ++ ** pAC->StatusLETable.Done = 0; ++ ** pAC->StatusLETable.Put = 0; ++ ** pAC->StatusLETable.HwPut = 0; ++ ** SkGeY2InitPrefetchUnit(pAC, pAC->IoBase, Q_ST, &pAC->StatusLETable); ++ */ ++ ++ /* ++ ** Initialize the LET in HW (enables also prefetch unit) ++ */ ++ SkGeY2InitPrefetchUnit(pAC, IoC,(Port == 0) ? Q_R1 : Q_R2, ++ &pAC->RxPort[Port].RxLET); ++ SkGeY2InitPrefetchUnit( pAC, IoC,(Port == 0) ? Q_XA1 : Q_XA2, ++ &pAC->TxPort[Port][TX_PRIO_LOW].TxALET); ++ if (HW_SYNC_TX_SUPPORTED(pAC)) { ++ SkGeY2InitPrefetchUnit( pAC, IoC, (Port == 0) ? Q_XS1 : Q_XS2, ++ &pAC->TxPort[Port][TX_PRIO_HIGH].TxSLET); ++ } ++ ++ ++ /* ++ ** Using new values for the watermarks and the timer for ++ ** low latency optimization ++ */ ++ if (pAC->LowLatency) { ++ SK_OUT8(IoC, STAT_FIFO_WM, 1); ++ SK_OUT8(IoC, STAT_FIFO_ISR_WM, 1); ++ SK_OUT32(IoC, STAT_LEV_TIMER_INI, 50); ++ SK_OUT32(IoC, STAT_ISR_TIMER_INI, 10); ++ } ++ ++ ++ /* ++ ** Initialize the Port (MAC, PHY etc.) ++ */ ++ if (SkGeInitPort(pAC, IoC, Port)) { ++ if (Port == 0) { ++ printk("%s: SkGeInitPort A failed.\n",pAC->dev[0]->name); ++ } else { ++ printk("%s: SkGeInitPort B failed.\n",pAC->dev[1]->name); ++ } ++ } ++ ++ if (IS_GMAC(pAC)) { ++ /* disable Rx GMAC FIFO Flush Mode */ ++ SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8) GMF_RX_F_FL_OFF); ++ } ++ ++ /* ++ ** Initialize the MC addresses ++ */ ++ SkAddrMcUpdate(pAC,IoC, Port); ++ ++ SkMacRxTxEnable(pAC, IoC,Port); ++ ++ SkGeRxCsum(pAC, IoC, Port, SK_TRUE); ++ ++ GET_RX_LE(pLE, &pAC->RxPort[Port].RxLET); ++ RXLE_SET_STACS1(pLE, pAC->CsOfs1); ++ RXLE_SET_STACS2(pLE, pAC->CsOfs2); ++ RXLE_SET_CTRL(pLE, 0); ++ ++ RXLE_SET_OPC(pLE, OP_TCPSTART | HW_OWNER); ++ FLUSH_OPC(pLE); ++ if (Port == 0) { ++ PrefetchReg=Y2_PREF_Q_ADDR(Q_R1,PREF_UNIT_PUT_IDX_REG); ++ } else { ++ PrefetchReg=Y2_PREF_Q_ADDR(Q_R2,PREF_UNIT_PUT_IDX_REG); ++ } ++ DWord = GET_PUT_IDX(&pAC->RxPort[Port].RxLET); ++ SK_OUT32(IoC, PrefetchReg, DWord); ++ UPDATE_HWPUT_IDX(&pAC->RxPort[Port].RxLET); ++ ++ pAC->GIni.GP[Port].PState = SK_PRT_RUN; ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("<== SkY2PortStart()\n")); ++} ++ ++/****************************************************************************** ++ * ++ * Local Functions ++ * ++ *****************************************************************************/ ++ ++/***************************************************************************** ++ * ++ * InitPacketQueues - initialize SW settings of packet queues ++ * ++ * Description: ++ * This function will initialize the packet queues for a port. ++ * ++ * Returns: N/A ++ */ ++static void InitPacketQueues( ++SK_AC *pAC, /* pointer to adapter control context */ ++int Port) /* index of port to be initialized */ ++{ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("==> InitPacketQueues(Port %c)\n", 'A' + Port)); ++ ++ pAC->RxPort[Port].RxQ_working.pHead = NULL; ++ pAC->RxPort[Port].RxQ_working.pTail = NULL; ++ spin_lock_init(&pAC->RxPort[Port].RxQ_working.QueueLock); ++ ++ pAC->RxPort[Port].RxQ_waiting.pHead = NULL; ++ pAC->RxPort[Port].RxQ_waiting.pTail = NULL; ++ spin_lock_init(&pAC->RxPort[Port].RxQ_waiting.QueueLock); ++ ++ pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free.pHead = NULL; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free.pTail = NULL; ++ spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free.QueueLock); ++ ++ pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working.pHead = NULL; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working.pTail = NULL; ++ spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working.QueueLock); ++ ++ pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.pHead = NULL; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.pTail = NULL; ++ spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.QueueLock); ++ ++#ifdef USE_SYNC_TX_QUEUE ++ pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.pHead = NULL; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.pTail = NULL; ++ spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.QueueLock); ++ ++ pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_waiting.pHead = NULL; ++ pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_waiting.pTail = NULL; ++ spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_waiting.QueueLock); ++#endif ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("<== InitPacketQueues(Port %c)\n", 'A' + Port)); ++} /* InitPacketQueues */ ++ ++/***************************************************************************** ++ * ++ * GiveTxBufferToHw - commits a previously allocated DMA area to HW ++ * ++ * Description: ++ * This functions gives transmit buffers to HW. If no list elements ++ * are available the buffers will be queued. ++ * ++ * Notes: ++ * This function can run only once in a system at one time. ++ * ++ * Returns: N/A ++ */ ++static void GiveTxBufferToHw( ++SK_AC *pAC, /* pointer to adapter control context */ ++SK_IOC IoC, /* I/O control context (address of registers) */ ++int Port) /* port index for which the buffer is used */ ++{ ++ SK_HWLE *pLE; ++ SK_PACKET *pSkPacket; ++ SK_FRAG *pFrag; ++ SK_PKT_QUEUE *pWorkQueue; /* corresponding TX queue */ ++ SK_PKT_QUEUE *pWaitQueue; ++ SK_LE_TABLE *pLETab; /* corresponding LETable */ ++ SK_BOOL SetOpcodePacketFlag; ++ SK_U32 HighAddress; ++ SK_U32 LowAddress; ++ SK_U16 TcpSumStart = 0; ++ SK_U16 TcpSumWrite = 0; ++ SK_U8 OpCode; ++ SK_U8 Ctrl; ++ unsigned long Flags; ++ unsigned long LockFlag; ++ int Protocol; ++#ifdef NETIF_F_TSO ++ SK_U16 Mss; ++ int TcpOptLen; ++ int IpTcpLen; ++#endif ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("==> GiveTxBufferToHw\n")); ++ ++ if (IS_Q_EMPTY(&(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting))) { ++ return; ++ } ++ ++ spin_lock_irqsave(&pAC->TxQueueLock, LockFlag); ++ ++ /* ++ ** Initialize queue settings ++ */ ++ pWorkQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working); ++ pWaitQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting); ++ pLETab = &(pAC->TxPort[Port][TX_PRIO_LOW].TxALET); ++ ++ POP_FIRST_PKT_FROM_QUEUE(pWaitQueue, pSkPacket); ++ while (pSkPacket != NULL) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("\tWe have a packet to send %p\n", pSkPacket)); ++ ++ /* ++ ** the first frag of a packet gets opcode OP_PACKET ++ */ ++ SetOpcodePacketFlag = SK_TRUE; ++ pFrag = pSkPacket->pFrag; ++ ++ /* ++ ** fill list elements with data from fragments ++ */ ++ while (pFrag != NULL) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("\tGet LE\n")); ++#ifdef NETIF_F_TSO ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17) ++ Mss = skb_shinfo(pSkPacket->pMBuf)->gso_size; ++#else ++ Mss = skb_shinfo(pSkPacket->pMBuf)->tso_size; ++#endif ++ ++ if (Mss) { ++#ifdef SK_EXTREME ++ if (!HW_IS_EXT_LE_FORMAT(pAC)) { ++#endif ++ TcpOptLen = ((pSkPacket->pMBuf->h.th->doff - 5) * 4); ++ IpTcpLen = ((pSkPacket->pMBuf->nh.iph->ihl * 4) + ++ sizeof(struct tcphdr)); ++ Mss += (TcpOptLen + IpTcpLen + C_LEN_ETHERMAC_HEADER); ++#ifdef SK_EXTREME ++ } ++#endif ++ } ++ if (pLETab->Bmu.RxTx.MssValue != Mss) { ++ pLETab->Bmu.RxTx.MssValue = Mss; ++ /* Take a new LE for TSO from the table */ ++ GET_TX_LE(pLE, pLETab); ++ ++#ifdef SK_EXTREME ++ if (HW_IS_EXT_LE_FORMAT(pAC)) { ++ TXLE_SET_OPC(pLE, OP_MSS | HW_OWNER); ++ } else { ++#endif ++ TXLE_SET_OPC(pLE, OP_LRGLEN | HW_OWNER); ++#ifdef SK_EXTREME ++ } ++#endif ++ ++ /* set maximum segment size for new packet */ ++ TXLE_SET_LSLEN(pLE, pLETab->Bmu.RxTx.MssValue); ++ FLUSH_OPC(pLE) ; ++ } ++#endif ++ GET_TX_LE(pLE, pLETab); ++ Ctrl = 0; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("\tGot empty LE %p idx %d\n", pLE, GET_PUT_IDX(pLETab))); ++ ++ SK_DBG_DUMP_TX_LE(pLE); ++ ++ LowAddress = (SK_U32) (pFrag->pPhys & 0xffffffff); ++ HighAddress = (SK_U32) (pFrag->pPhys >> 32); ++ ++ if (HighAddress != pLETab->BufHighAddr) { ++ /* set opcode high part of the address in one LE */ ++ OpCode = OP_ADDR64 | HW_OWNER; ++ ++ /* Set now the 32 high bits of the address */ ++ TXLE_SET_ADDR( pLE, HighAddress); ++ ++ /* Set the opcode into the LE */ ++ TXLE_SET_OPC(pLE, OpCode); ++ ++ /* Flush the LE to memory */ ++ FLUSH_OPC(pLE); ++ ++ /* remember the HighAddress we gave to the Hardware */ ++ pLETab->BufHighAddr = HighAddress; ++ ++ /* get a new LE because we filled one with high address */ ++ GET_TX_LE(pLE, pLETab); ++ } ++ ++ /* ++ ** TCP checksum offload ++ */ ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) ++ if ((pSkPacket->pMBuf->ip_summed == CHECKSUM_PARTIAL) && ++#else ++ if ((pSkPacket->pMBuf->ip_summed == CHECKSUM_HW) && ++#endif ++ (SetOpcodePacketFlag == SK_TRUE)) { ++ Protocol = ((SK_U8)pSkPacket->pMBuf->data[C_OFFSET_IPPROTO] & 0xff); ++ ++ /* if (Protocol & C_PROTO_ID_IP) { Ctrl = 0; } */ ++ if (Protocol & C_PROTO_ID_TCP) { ++#ifdef SK_EXTREME ++ if (!HW_IS_EXT_LE_FORMAT(pAC)) { ++#endif ++ Ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; ++ /* TCP Checksum Calculation Start Position */ ++ TcpSumStart = C_LEN_ETHERMAC_HEADER + IP_HDR_LEN; ++ /* TCP Checksum Write Position */ ++ TcpSumWrite = TcpSumStart + TCP_CSUM_OFFS; ++#ifdef SK_EXTREME ++ } else { ++ Ctrl = CALSUM; ++ } ++#endif ++ } else { ++#ifdef SK_EXTREME ++ if (!HW_IS_EXT_LE_FORMAT(pAC)) { ++#endif ++ Ctrl = UDPTCP | CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; ++ /* TCP Checksum Calculation Start Position */ ++ TcpSumStart = ETHER_MAC_HDR_LEN + IP_HDR_LEN; ++ /* UDP Checksum Write Position */ ++ TcpSumWrite = TcpSumStart + UDP_CSUM_OFFS; ++#ifdef SK_EXTREME ++ } else { ++ Ctrl = CALSUM; ++ } ++#endif ++ } ++ ++ if ((Ctrl) && (pLETab->Bmu.RxTx.TcpWp != TcpSumWrite)) { ++ /* Update the last value of the write position */ ++ pLETab->Bmu.RxTx.TcpWp = TcpSumWrite; ++ ++ /* Set the Lock field for this LE: */ ++ /* Checksum calculation for one packet only */ ++ TXLE_SET_LCKCS(pLE, 1); ++ ++ /* Set the start position for checksum. */ ++ TXLE_SET_STACS(pLE, TcpSumStart); ++ ++ /* Set the position where the checksum will be writen */ ++ TXLE_SET_WRICS(pLE, TcpSumWrite); ++ ++ /* Set the initial value for checksum */ ++ /* PseudoHeader CS passed from Linux -> 0! */ ++ TXLE_SET_INICS(pLE, 0); ++ ++ /* Set the opcode for tcp checksum */ ++ TXLE_SET_OPC(pLE, OP_TCPLISW | HW_OWNER); ++ ++ /* Flush the LE to memory */ ++ FLUSH_OPC(pLE); ++ ++ /* get a new LE because we filled one with data for checksum */ ++ GET_TX_LE(pLE, pLETab); ++ } ++ } /* end TCP offload handling */ ++ ++ TXLE_SET_ADDR(pLE, LowAddress); ++ TXLE_SET_LEN(pLE, pFrag->FragLen); ++ ++ if (SetOpcodePacketFlag){ ++#ifdef NETIF_F_TSO ++ if (Mss) { ++ OpCode = OP_LARGESEND | HW_OWNER; ++ } else { ++#endif ++ OpCode = OP_PACKET| HW_OWNER; ++#ifdef NETIF_F_TSO ++ } ++#endif ++ SetOpcodePacketFlag = SK_FALSE; ++ } else { ++ /* Follow packet in a sequence has always OP_BUFFER */ ++ OpCode = OP_BUFFER | HW_OWNER; ++ } ++ ++ /* Check if the low address is near the upper limit. */ ++ CHECK_LOW_ADDRESS(pLETab->BufHighAddr, LowAddress, pFrag->FragLen); ++ ++ pFrag = pFrag->pNext; ++ if (pFrag == NULL) { ++ /* mark last fragment */ ++ Ctrl |= EOP; ++ } ++ TXLE_SET_CTRL(pLE, Ctrl); ++ TXLE_SET_OPC(pLE, OpCode); ++ FLUSH_OPC(pLE); ++ ++ SK_DBG_DUMP_TX_LE(pLE); ++ } ++ ++ /* ++ ** Remember next LE for tx complete ++ */ ++ pSkPacket->NextLE = GET_PUT_IDX(pLETab); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("\tNext LE for pkt %p is %d\n", pSkPacket, pSkPacket->NextLE)); ++ ++ /* ++ ** Add packet to working packets queue ++ */ ++ PUSH_PKT_AS_LAST_IN_QUEUE(pWorkQueue, pSkPacket); ++ ++ /* ++ ** give transmit start command ++ */ ++ if (HW_FEATURE(pAC, HWF_WA_DEV_42)) { ++ spin_lock(&pAC->SetPutIndexLock); ++ SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_XA1,0), &pAC->TxPort[0][0].TxALET); ++ spin_unlock(&pAC->SetPutIndexLock); ++ } else { ++ /* write put index */ ++ if (Port == 0) { ++ SK_OUT32(pAC->IoBase, ++ Y2_PREF_Q_ADDR(Q_XA1,PREF_UNIT_PUT_IDX_REG), ++ GET_PUT_IDX(&pAC->TxPort[0][0].TxALET)); ++ UPDATE_HWPUT_IDX(&pAC->TxPort[0][0].TxALET); ++ } else { ++ SK_OUT32(pAC->IoBase, ++ Y2_PREF_Q_ADDR(Q_XA2, PREF_UNIT_PUT_IDX_REG), ++ GET_PUT_IDX(&pAC->TxPort[1][0].TxALET)); ++ UPDATE_HWPUT_IDX(&pAC->TxPort[1][0].TxALET); ++ } ++ } ++ ++ if (IS_Q_EMPTY(&(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting))) { ++ break; /* get out of while */ ++ } ++ POP_FIRST_PKT_FROM_QUEUE(pWaitQueue, pSkPacket); ++ } /* while (pSkPacket != NULL) */ ++ ++ spin_unlock_irqrestore(&pAC->TxQueueLock, LockFlag); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("<== GiveTxBufferToHw\n")); ++ return; ++} /* GiveTxBufferToHw */ ++ ++/*********************************************************************** ++ * ++ * GiveRxBufferToHw - commits a previously allocated DMA area to HW ++ * ++ * Description: ++ * This functions gives receive buffers to HW. If no list elements ++ * are available the buffers will be queued. ++ * ++ * Notes: ++ * This function can run only once in a system at one time. ++ * ++ * Returns: N/A ++ */ ++static void GiveRxBufferToHw( ++SK_AC *pAC, /* pointer to adapter control context */ ++SK_IOC IoC, /* I/O control context (address of registers) */ ++int Port, /* port index for which the buffer is used */ ++SK_PACKET *pPacket) /* receive buffer(s) */ ++{ ++ SK_HWLE *pLE; ++ SK_LE_TABLE *pLETab; ++ SK_BOOL Done = SK_FALSE; /* at least on LE changed? */ ++ SK_U32 LowAddress; ++ SK_U32 HighAddress; ++ SK_U32 PrefetchReg; /* register for Put index */ ++ unsigned NumFree; ++ unsigned Required; ++ unsigned long Flags; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("==> GiveRxBufferToHw(Port %c, Packet %p)\n", 'A' + Port, pPacket)); ++ ++ pLETab = &pAC->RxPort[Port].RxLET; ++ ++ if (Port == 0) { ++ PrefetchReg = Y2_PREF_Q_ADDR(Q_R1, PREF_UNIT_PUT_IDX_REG); ++ } else { ++ PrefetchReg = Y2_PREF_Q_ADDR(Q_R2, PREF_UNIT_PUT_IDX_REG); ++ } ++ ++ if (pPacket != NULL) { ++ /* ++ ** For the time being, we have only one packet passed ++ ** to this function which might be changed in future! ++ */ ++ PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket); ++ } ++ ++ /* ++ ** now pPacket contains the very first waiting packet ++ */ ++ POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket); ++ while (pPacket != NULL) { ++ if (HW_FEATURE(pAC, HWF_WA_DEV_420)) { ++ if (NbrRxBuffersInHW >= MAX_NBR_RX_BUFFERS_IN_HW) { ++ PUSH_PKT_AS_FIRST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("<== GiveRxBufferToHw()\n")); ++ return; ++ } ++ NbrRxBuffersInHW++; ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("Try to add packet %p\n", pPacket)); ++ ++ /* ++ ** Check whether we have enough listelements: ++ ** ++ ** we have to take into account that each fragment ++ ** may need an additional list element for the high ++ ** part of the address here I simplified it by ++ ** using MAX_FRAG_OVERHEAD maybe it's worth to split ++ ** this constant for Rx and Tx or to calculate the ++ ** real number of needed LE's ++ */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("\tNum %d Put %d Done %d Free %d %d\n", ++ pLETab->Num, pLETab->Put, pLETab->Done, ++ NUM_FREE_LE_IN_TABLE(pLETab), ++ (NUM_FREE_LE_IN_TABLE(pLETab)))); ++ ++ Required = pPacket->NumFrags + MAX_FRAG_OVERHEAD; ++ NumFree = NUM_FREE_LE_IN_TABLE(pLETab); ++ if (NumFree) { ++ NumFree--; ++ } ++ ++ if (Required > NumFree ) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR, ++ ("\tOut of LEs have %d need %d\n", ++ NumFree, Required)); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("\tWaitQueue starts with packet %p\n", pPacket)); ++ PUSH_PKT_AS_FIRST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket); ++ if (Done) { ++ /* ++ ** write Put index to BMU or Polling Unit and make the LE's ++ ** available for the hardware ++ */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("\tWrite new Put Idx\n")); ++ ++ SK_OUT32(IoC, PrefetchReg, GET_PUT_IDX(pLETab)); ++ UPDATE_HWPUT_IDX(pLETab); ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("<== GiveRxBufferToHw()\n")); ++ return; ++ } else { ++ if (!AllocAndMapRxBuffer(pAC, pPacket, Port)) { ++ /* ++ ** Failure while allocating sk_buff might ++ ** be due to temporary short of resources ++ ** Maybe next time buffers are available. ++ ** Until this, the packet remains in the ++ ** RX waiting queue... ++ */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR, ++ ("Failed to allocate Rx buffer\n")); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("WaitQueue starts with packet %p\n", pPacket)); ++ PUSH_PKT_AS_FIRST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket); ++ if (Done) { ++ /* ++ ** write Put index to BMU or Polling ++ ** Unit and make the LE's ++ ** available for the hardware ++ */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("\tWrite new Put Idx\n")); ++ ++ SK_OUT32(IoC, PrefetchReg, GET_PUT_IDX(pLETab)); ++ UPDATE_HWPUT_IDX(pLETab); ++ } ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("<== GiveRxBufferToHw()\n")); ++ return; ++ } ++ } ++ Done = SK_TRUE; ++ ++ LowAddress = (SK_U32) (pPacket->pFrag->pPhys & 0xffffffff); ++ HighAddress = (SK_U32) (pPacket->pFrag->pPhys >> 32); ++ if (HighAddress != pLETab->BufHighAddr) { ++ /* get a new LE for high address */ ++ GET_RX_LE(pLE, pLETab); ++ ++ /* Set now the 32 high bits of the address */ ++ RXLE_SET_ADDR(pLE, HighAddress); ++ ++ /* Set the control bits of the address */ ++ RXLE_SET_CTRL(pLE, 0); ++ ++ /* Set the opcode into the LE */ ++ RXLE_SET_OPC(pLE, (OP_ADDR64 | HW_OWNER)); ++ ++ /* Flush the LE to memory */ ++ FLUSH_OPC(pLE); ++ ++ /* remember the HighAddress we gave to the Hardware */ ++ pLETab->BufHighAddr = HighAddress; ++ } ++ ++ /* ++ ** Fill data into listelement ++ */ ++ GET_RX_LE(pLE, pLETab); ++ RXLE_SET_ADDR(pLE, LowAddress); ++ RXLE_SET_LEN(pLE, pPacket->pFrag->FragLen); ++ RXLE_SET_CTRL(pLE, 0); ++ RXLE_SET_OPC(pLE, (OP_PACKET | HW_OWNER)); ++ FLUSH_OPC(pLE); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("=== LE filled\n")); ++ ++ SK_DBG_DUMP_RX_LE(pLE); ++ ++ /* ++ ** Remember next LE for rx complete ++ */ ++ pPacket->NextLE = GET_PUT_IDX(pLETab); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("\tPackets Next LE is %d\n", pPacket->NextLE)); ++ ++ /* ++ ** Add packet to working receive buffer queue and get ++ ** any next packet out of the waiting queue ++ */ ++ PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_working, pPacket); ++ if (IS_Q_EMPTY(&(pAC->RxPort[Port].RxQ_waiting))) { ++ break; /* get out of while processing */ ++ } ++ POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket); ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("\tWaitQueue is empty\n")); ++ ++ if (Done) { ++ /* ++ ** write Put index to BMU or Polling Unit and make the LE's ++ ** available for the hardware ++ */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("\tWrite new Put Idx\n")); ++ ++ /* Speed enhancement for a2 chipsets */ ++ if (HW_FEATURE(pAC, HWF_WA_DEV_42)) { ++ spin_lock_irqsave(&pAC->SetPutIndexLock, Flags); ++ SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_R1,0), pLETab); ++ spin_unlock_irqrestore(&pAC->SetPutIndexLock, Flags); ++ } else { ++ /* write put index */ ++ if (Port == 0) { ++ SK_OUT32(IoC, ++ Y2_PREF_Q_ADDR(Q_R1, PREF_UNIT_PUT_IDX_REG), ++ GET_PUT_IDX(pLETab)); ++ } else { ++ SK_OUT32(IoC, ++ Y2_PREF_Q_ADDR(Q_R2, PREF_UNIT_PUT_IDX_REG), ++ GET_PUT_IDX(pLETab)); ++ } ++ ++ /* Update put index */ ++ UPDATE_HWPUT_IDX(pLETab); ++ } ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("<== GiveRxBufferToHw()\n")); ++} /* GiveRxBufferToHw */ ++ ++/*********************************************************************** ++ * ++ * FillReceiveTableYukon2 - map any waiting RX buffers to HW ++ * ++ * Description: ++ * If the list element table contains more empty elements than ++ * specified this function tries to refill them. ++ * ++ * Notes: ++ * This function can run only once per port in a system at one time. ++ * ++ * Returns: N/A ++ */ ++void FillReceiveTableYukon2( ++SK_AC *pAC, /* pointer to adapter control context */ ++SK_IOC IoC, /* I/O control context */ ++int Port) /* port index of RX */ ++{ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("==> FillReceiveTableYukon2 (Port %c)\n", 'A' + Port)); ++ ++ if (NUM_FREE_LE_IN_TABLE(&pAC->RxPort[Port].RxLET) > ++ pAC->MaxUnusedRxLeWorking) { ++ ++ /* ++ ** Give alle waiting receive buffers down ++ ** The queue holds all RX packets that ++ ** need a fresh allocation of the sk_buff. ++ */ ++ if (pAC->RxPort[Port].RxQ_waiting.pHead != NULL) { ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("Waiting queue is not empty -> give it to HW")); ++ GiveRxBufferToHw(pAC, IoC, Port, NULL); ++ } ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("<== FillReceiveTableYukon2 ()\n")); ++} /* FillReceiveTableYukon2 */ ++ ++/****************************************************************************** ++ * ++ * ++ * HandleReceives - will pass any ready RX packet to kernel ++ * ++ * Description: ++ * This functions handles a received packet. It checks wether it is ++ * valid, updates the receive list element table and gives the receive ++ * buffer to Linux ++ * ++ * Notes: ++ * This function can run only once per port at one time in the system. ++ * ++ * Returns: N/A ++ */ ++static SK_BOOL HandleReceives( ++SK_AC *pAC, /* adapter control context */ ++int Port, /* port on which a packet has been received */ ++SK_U16 Len, /* number of bytes which was actually received */ ++SK_U32 FrameStatus, /* MAC frame status word */ ++SK_U16 Tcp1, /* first hw checksum */ ++SK_U16 Tcp2, /* second hw checksum */ ++SK_U32 Tist, /* timestamp */ ++SK_U16 Vlan) /* Vlan Id */ ++{ ++ ++ SK_PACKET *pSkPacket; ++ SK_LE_TABLE *pLETab; ++ SK_MBUF *pRlmtMbuf; /* buffer for giving RLMT frame */ ++ struct sk_buff *pMsg; /* ptr to message holding frame */ ++#ifdef __ia64__ ++ struct sk_buff *pNewMsg; /* used when IP aligning */ ++#endif ++ ++ SK_BOOL IsGoodPkt; ++ SK_BOOL IsBc; ++ SK_BOOL IsMc; ++ SK_EVPARA EvPara; /* an event parameter union */ ++ SK_I16 LenToFree; /* must be signed integer */ ++ ++ unsigned long Flags; /* for spin lock */ ++ unsigned int RlmtNotifier; ++ unsigned short Type; ++ int IpFrameLength; ++ int FrameLength; /* total length of recvd frame */ ++ int HeaderLength; ++ int NumBytes; ++ int Result; ++ int Offset = 0; ++ ++#ifdef Y2_SYNC_CHECK ++ SK_U16 MyTcp; ++#endif ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("==> HandleReceives (Port %c)\n", 'A' + Port)); ++ ++ /* ++ ** initialize vars for selected port ++ */ ++ pLETab = &pAC->RxPort[Port].RxLET; ++ ++ /* ++ ** check whether we want to receive this packet ++ */ ++ SK_Y2_RXSTAT_CHECK_PKT(Len, FrameStatus, IsGoodPkt); ++ ++ /* ++ ** Remember length to free (in case of RxBuffer overruns; ++ ** unlikely, but might happen once in a while) ++ */ ++ LenToFree = (SK_I16) Len; ++ ++ /* ++ ** maybe we put these two checks into the SK_RXDESC_CHECK_PKT macro too ++ */ ++ if (Len > pAC->RxPort[Port].RxBufSize) { ++ IsGoodPkt = SK_FALSE; ++ } ++ ++ /* ++ ** take first receive buffer out of working queue ++ */ ++ POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket); ++ if (pSkPacket == NULL) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_ERROR, ++ ("Packet not available. NULL pointer.\n")); ++ return(SK_TRUE); ++ } ++ ++ if (HW_FEATURE(pAC, HWF_WA_DEV_420)) { ++ NbrRxBuffersInHW--; ++ } ++ ++ /* ++ ** Verify the received length of the frame! Note that having ++ ** multiple RxBuffers being aware of one single receive packet ++ ** (one packet spread over multiple RxBuffers) is not supported ++ ** by this driver! ++ */ ++ if ((Len > pAC->RxPort[Port].RxBufSize) || ++ (Len > (SK_U16) pSkPacket->PacketLen)) { ++ IsGoodPkt = SK_FALSE; ++ } ++ ++ /* ++ ** Reset own bit in LE's between old and new Done index ++ ** This is not really necessary but makes debugging easier ++ */ ++ CLEAR_LE_OWN_FROM_DONE_TO(pLETab, pSkPacket->NextLE); ++ ++ /* ++ ** Free the list elements for new Rx buffers ++ */ ++ SET_DONE_INDEX(pLETab, pSkPacket->NextLE); ++ pMsg = pSkPacket->pMBuf; ++ FrameLength = Len; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("Received frame of length %d on port %d\n",FrameLength, Port)); ++ ++ if (!IsGoodPkt) { ++ /* ++ ** release the DMA mapping ++ */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ++ pci_dma_sync_single(pAC->PciDev, ++ (dma_addr_t) pSkPacket->pFrag->pPhys, ++ pSkPacket->pFrag->FragLen, ++ PCI_DMA_FROMDEVICE); ++ ++#else ++ pci_dma_sync_single_for_cpu(pAC->PciDev, ++ (dma_addr_t) pSkPacket->pFrag->pPhys, ++ pSkPacket->pFrag->FragLen, ++ PCI_DMA_FROMDEVICE); ++#endif ++ ++ DEV_KFREE_SKB_ANY(pSkPacket->pMBuf); ++ PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("<== HandleReceives (Port %c)\n", 'A' + Port)); ++ ++ /* ++ ** Sanity check for RxBuffer overruns... ++ */ ++ LenToFree = LenToFree - (pSkPacket->pFrag->FragLen); ++ while (LenToFree > 0) { ++ POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket); ++ if (HW_FEATURE(pAC, HWF_WA_DEV_420)) { ++ NbrRxBuffersInHW--; ++ } ++ CLEAR_LE_OWN_FROM_DONE_TO(pLETab, pSkPacket->NextLE); ++ SET_DONE_INDEX(pLETab, pSkPacket->NextLE); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ++ pci_dma_sync_single(pAC->PciDev, ++ (dma_addr_t) pSkPacket->pFrag->pPhys, ++ pSkPacket->pFrag->FragLen, ++ PCI_DMA_FROMDEVICE); ++#else ++ pci_dma_sync_single_for_device(pAC->PciDev, ++ (dma_addr_t) pSkPacket->pFrag->pPhys, ++ pSkPacket->pFrag->FragLen, ++ PCI_DMA_FROMDEVICE); ++#endif ++ ++ DEV_KFREE_SKB_ANY(pSkPacket->pMBuf); ++ PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket); ++ LenToFree = LenToFree - ((SK_I16)(pSkPacket->pFrag->FragLen)); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR, ++ ("<==HandleReceives (Port %c) drop faulty len pkt(2)\n",'A'+Port)); ++ } ++ return(SK_TRUE); ++ } else { ++ /* ++ ** Release the DMA mapping ++ */ ++ pci_unmap_single(pAC->PciDev, ++ pSkPacket->pFrag->pPhys, ++ pAC->RxPort[Port].RxBufSize, ++ PCI_DMA_FROMDEVICE); ++ ++ skb_put(pMsg, FrameLength); /* set message len */ ++ pMsg->ip_summed = CHECKSUM_NONE; /* initial default */ ++ ++#ifdef Y2_SYNC_CHECK ++ pAC->FramesWithoutSyncCheck++; ++ if (pAC->FramesWithoutSyncCheck > Y2_RESYNC_WATERMARK) { ++ if ((Tcp1 != 1) || (Tcp2 != 0)) { ++ pAC->FramesWithoutSyncCheck = 0; ++ MyTcp = (SK_U16) SkCsCalculateChecksum( ++ &pMsg->data[14], ++ FrameLength - 14); ++ if (MyTcp != Tcp1) { ++ /* Queue port reset event */ ++ SkLocalEventQueue(pAC, SKGE_DRV, ++ SK_DRV_RECOVER,Port,-1,SK_FALSE); ++ } ++ } ++ } ++#endif ++ ++ if (pAC->RxPort[Port].UseRxCsum) { ++ Type = ntohs(*((short*)&pMsg->data[12])); ++ if (Type == 0x800) { ++ *((char *)&(IpFrameLength)) = pMsg->data[16]; ++ *(((char *)&(IpFrameLength))+1) = pMsg->data[17]; ++ IpFrameLength = ntohs(IpFrameLength); ++ HeaderLength = FrameLength - IpFrameLength; ++ if (HeaderLength == 0xe) { ++ Result = ++ SkCsGetReceiveInfo(pAC,&pMsg->data[14],Tcp1,Tcp2, Port); ++ if ((Result == SKCS_STATUS_IP_FRAGMENT) || ++ (Result == SKCS_STATUS_IP_CSUM_OK) || ++ (Result == SKCS_STATUS_TCP_CSUM_OK) || ++ (Result == SKCS_STATUS_UDP_CSUM_OK)) { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) ++ pMsg->ip_summed = CHECKSUM_COMPLETE; ++ pMsg->csum = Tcp1 & 0xffff; ++#else ++ pMsg->ip_summed = CHECKSUM_UNNECESSARY; ++#endif ++ } 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)) { ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR, ++ ("skge: CRC error. Frame dropped!\n")); ++ DEV_KFREE_SKB_ANY(pMsg); ++ PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket); ++ SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_RX_PROGRESS, ++ ("<==HandleReceives(Port %c)\n",'A'+Port)); ++ return(SK_TRUE); ++ } else { ++ pMsg->ip_summed = CHECKSUM_NONE; ++ } ++ } /* end if (HeaderLength == valid) */ ++ } /* end if (Type == 0x800) -> IP frame */ ++ } /* end if (pRxPort->UseRxCsum) */ ++ ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_RX_PROGRESS,("V")); ++ RlmtNotifier = SK_RLMT_RX_PROTOCOL; ++ ++ IsBc = (FrameStatus & GMR_FS_BC) ? SK_TRUE : SK_FALSE; ++ SK_RLMT_PRE_LOOKAHEAD(pAC,Port,FrameLength, ++ IsBc,&Offset,&NumBytes); ++ if (NumBytes != 0) { ++ IsMc = (FrameStatus & GMR_FS_MC) ? SK_TRUE : SK_FALSE; ++ SK_RLMT_LOOKAHEAD(pAC,Port,&pMsg->data[Offset], ++ IsBc,IsMc,&RlmtNotifier); ++ } ++ ++ if (RlmtNotifier == SK_RLMT_RX_PROTOCOL) { ++ SK_DBG_MSG(NULL,SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_RX_PROGRESS,("W")); ++ if ((Port == pAC->ActivePort)||(pAC->RlmtNets == 2)) { ++ /* send up only frames from active port */ ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_RX_PROGRESS,("U")); ++#ifdef xDEBUG ++ DumpMsg(pMsg, "Rx"); ++#endif ++ SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC, ++ FrameLength, Port); ++#ifdef __ia64__ ++ pNewMsg = alloc_skb(pMsg->len, GFP_ATOMIC); ++ skb_reserve(pNewMsg, 2); /* to align IP */ ++ SK_MEMCPY(pNewMsg->data,pMsg->data,pMsg->len); ++ pNewMsg->ip_summed = pMsg->ip_summed; ++ skb_put(pNewMsg, pMsg->len); ++ DEV_KFREE_SKB_ANY(pMsg); ++ pMsg = pNewMsg; ++#endif ++ pMsg->dev = pAC->dev[Port]; ++ pMsg->protocol = eth_type_trans(pMsg, ++ pAC->dev[Port]); ++#ifdef CONFIG_SK98LIN_NAPI ++ netif_receive_skb(pMsg); ++#else ++ netif_rx(pMsg); ++#endif ++ pAC->dev[Port]->last_rx = jiffies; ++ } else { /* drop frame */ ++ SK_DBG_MSG(NULL,SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_RX_PROGRESS,("D")); ++ DEV_KFREE_SKB_ANY(pMsg); ++ } ++ } else { /* This is an RLMT-packet! */ ++ 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 = Port; ++ EvPara.pParaPtr = pRlmtMbuf; ++ SK_MEMCPY((char*)(pRlmtMbuf->pData), ++ (char*)(pMsg->data),FrameLength); ++ ++#ifdef CONFIG_SK98LIN_NAPI ++ spin_lock_irqsave(&pAC->SlowPathLock, Flags); ++#endif ++ SkEventQueue(pAC, SKGE_RLMT, ++ SK_RLMT_PACKET_RECEIVED, ++ EvPara); ++ pAC->CheckQueue = SK_TRUE; ++#ifdef CONFIG_SK98LIN_NAPI ++ spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); ++#endif ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_RX_PROGRESS,("Q")); ++ } ++ if (pAC->dev[Port]->flags & (IFF_PROMISC | IFF_ALLMULTI)) { ++#ifdef __ia64__ ++ pNewMsg = alloc_skb(pMsg->len, GFP_ATOMIC); ++ skb_reserve(pNewMsg, 2); /* to align IP */ ++ SK_MEMCPY(pNewMsg->data,pMsg->data,pMsg->len); ++ pNewMsg->ip_summed = pMsg->ip_summed; ++ pNewMsg->len = pMsg->len; ++ DEV_KFREE_SKB_ANY(pMsg); ++ pMsg = pNewMsg; ++#endif ++ pMsg->dev = pAC->dev[Port]; ++ pMsg->protocol = eth_type_trans(pMsg,pAC->dev[Port]); ++ netif_rx(pMsg); ++ pAC->dev[Port]->last_rx = jiffies; ++ } else { ++ DEV_KFREE_SKB_ANY(pMsg); ++ } ++ } /* if packet for rlmt */ ++ PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket); ++ } /* end if-else (IsGoodPkt) */ ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("<== HandleReceives (Port %c)\n", 'A' + Port)); ++ return(SK_TRUE); ++ ++} /* HandleReceives */ ++ ++/*********************************************************************** ++ * ++ * CheckForSendComplete - Frees any freeable Tx bufffer ++ * ++ * Description: ++ * This function checks the queues of a port for completed send ++ * packets and returns these packets back to the OS. ++ * ++ * Notes: ++ * This function can run simultaneously for both ports if ++ * the OS function OSReturnPacket() can handle this, ++ * ++ * Such a send complete does not mean, that the packet is really ++ * out on the wire. We just know that the adapter has copied it ++ * into its internal memory and the buffer in the systems memory ++ * is no longer needed. ++ * ++ * Returns: N/A ++ */ ++static void CheckForSendComplete( ++SK_AC *pAC, /* pointer to adapter control context */ ++SK_IOC IoC, /* I/O control context */ ++int Port, /* port index */ ++SK_PKT_QUEUE *pPQ, /* tx working packet queue to check */ ++SK_LE_TABLE *pLETab, /* corresponding list element table */ ++unsigned int Done) /* done index reported for this LET */ ++{ ++ SK_PACKET *pSkPacket; ++ SK_PKT_QUEUE SendCmplPktQ = { NULL, NULL, SPIN_LOCK_UNLOCKED }; ++ SK_BOOL DoWakeQueue = SK_FALSE; ++ unsigned long Flags; ++ unsigned Put; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("==> CheckForSendComplete(Port %c)\n", 'A' + Port)); ++ ++ /* ++ ** Reset own bit in LE's between old and new Done index ++ ** This is not really necessairy but makes debugging easier ++ */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("Clear Own Bits in TxTable from %d to %d\n", ++ pLETab->Done, (Done == 0) ? ++ NUM_LE_IN_TABLE(pLETab) : ++ (Done - 1))); ++ ++ spin_lock_irqsave(&(pPQ->QueueLock), Flags); ++ ++ CLEAR_LE_OWN_FROM_DONE_TO(pLETab, Done); ++ ++ Put = GET_PUT_IDX(pLETab); ++ ++ /* ++ ** Check whether some packets have been completed ++ */ ++ PLAIN_POP_FIRST_PKT_FROM_QUEUE(pPQ, pSkPacket); ++ while (pSkPacket != NULL) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("Check Completion of Tx packet %p\n", pSkPacket)); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("Put %d NewDone %d NextLe of Packet %d\n", Put, Done, ++ pSkPacket->NextLE)); ++ ++ if ((Put > Done) && ++ ((pSkPacket->NextLE > Put) || (pSkPacket->NextLE <= Done))) { ++ PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("Packet finished (a)\n")); ++ } else if ((Done > Put) && ++ (pSkPacket->NextLE > Put) && (pSkPacket->NextLE <= Done)) { ++ PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("Packet finished (b)\n")); ++ } else if ((Done == NUMBER_OF_TX_LE-1) && (Put == 0) && (pSkPacket->NextLE == 0)) { ++ PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("Packet finished (b)\n")); ++ DoWakeQueue = SK_TRUE; ++ } else if (Done == Put) { ++ /* all packets have been sent */ ++ PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("Packet finished (c)\n")); ++ } else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("Packet not yet finished\n")); ++ PLAIN_PUSH_PKT_AS_FIRST_IN_QUEUE(pPQ, pSkPacket); ++ break; ++ } ++ PLAIN_POP_FIRST_PKT_FROM_QUEUE(pPQ, pSkPacket); ++ } ++ spin_unlock_irqrestore(&(pPQ->QueueLock), Flags); ++ ++ /* ++ ** Set new done index in list element table ++ */ ++ SET_DONE_INDEX(pLETab, Done); ++ ++ /* ++ ** All TX packets that are send complete should be added to ++ ** the free queue again for new sents to come ++ */ ++ pSkPacket = SendCmplPktQ.pHead; ++ while (pSkPacket != NULL) { ++ while (pSkPacket->pFrag != NULL) { ++ pci_unmap_page(pAC->PciDev, ++ (dma_addr_t) pSkPacket->pFrag->pPhys, ++ pSkPacket->pFrag->FragLen, ++ PCI_DMA_FROMDEVICE); ++ pSkPacket->pFrag = pSkPacket->pFrag->pNext; ++ } ++ ++ DEV_KFREE_SKB_ANY(pSkPacket->pMBuf); ++ pSkPacket->pMBuf = NULL; ++ pSkPacket = pSkPacket->pNext; /* get next packet */ ++ } ++ ++ /* ++ ** Append the available TX packets back to free queue ++ */ ++ if (SendCmplPktQ.pHead != NULL) { ++ spin_lock_irqsave(&(pAC->TxPort[Port][0].TxQ_free.QueueLock), Flags); ++ if (pAC->TxPort[Port][0].TxQ_free.pTail != NULL) { ++ pAC->TxPort[Port][0].TxQ_free.pTail->pNext = SendCmplPktQ.pHead; ++ pAC->TxPort[Port][0].TxQ_free.pTail = SendCmplPktQ.pTail; ++ if (pAC->TxPort[Port][0].TxQ_free.pHead->pNext == NULL) { ++ netif_wake_queue(pAC->dev[Port]); ++ } ++ } else { ++ pAC->TxPort[Port][0].TxQ_free.pHead = SendCmplPktQ.pHead; ++ pAC->TxPort[Port][0].TxQ_free.pTail = SendCmplPktQ.pTail; ++ netif_wake_queue(pAC->dev[Port]); ++ } ++ if (Done == Put) { ++ netif_wake_queue(pAC->dev[Port]); ++ } ++ if (DoWakeQueue) { ++ netif_wake_queue(pAC->dev[Port]); ++ DoWakeQueue = SK_FALSE; ++ } ++ spin_unlock_irqrestore(&pAC->TxPort[Port][0].TxQ_free.QueueLock, Flags); ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("<== CheckForSendComplete()\n")); ++ ++ return; ++} /* CheckForSendComplete */ ++ ++/***************************************************************************** ++ * ++ * UnmapAndFreeTxPktBuffer ++ * ++ * Description: ++ * This function free any allocated space of receive buffers ++ * ++ * Arguments: ++ * pAC - A pointer to the adapter context struct. ++ * ++ */ ++static void UnmapAndFreeTxPktBuffer( ++SK_AC *pAC, /* pointer to adapter context */ ++SK_PACKET *pSkPacket, /* pointer to port struct of ring to fill */ ++int TxPort) /* TX port index */ ++{ ++ SK_FRAG *pFrag = pSkPacket->pFrag; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("--> UnmapAndFreeTxPktBuffer\n")); ++ ++ while (pFrag != NULL) { ++ pci_unmap_page(pAC->PciDev, ++ (dma_addr_t) pFrag->pPhys, ++ pFrag->FragLen, ++ PCI_DMA_FROMDEVICE); ++ pFrag = pFrag->pNext; ++ } ++ ++ DEV_KFREE_SKB_ANY(pSkPacket->pMBuf); ++ pSkPacket->pMBuf = NULL; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ++ ("<-- UnmapAndFreeTxPktBuffer\n")); ++} ++ ++/***************************************************************************** ++ * ++ * HandleStatusLEs ++ * ++ * Description: ++ * This function checks for any new status LEs that may have been ++ * received. Those status LEs may either be Rx or Tx ones. ++ * ++ * Returns: N/A ++ */ ++static SK_BOOL HandleStatusLEs( ++#ifdef CONFIG_SK98LIN_NAPI ++SK_AC *pAC, /* pointer to adapter context */ ++int *WorkDone, /* Done counter needed for NAPI */ ++int WorkToDo) /* ToDo counter for NAPI */ ++#else ++SK_AC *pAC) /* pointer to adapter context */ ++#endif ++{ ++ int DoneTxA[SK_MAX_MACS]; ++ int DoneTxS[SK_MAX_MACS]; ++ int Port; ++ SK_BOOL handledStatLE = SK_FALSE; ++ SK_BOOL NewDone = SK_FALSE; ++ SK_HWLE *pLE; ++ SK_U16 HighVal; ++ SK_U32 LowVal; ++ SK_U8 OpCode; ++ int i; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("==> HandleStatusLEs\n")); ++ ++ do { ++ if (OWN_OF_FIRST_LE(&pAC->StatusLETable) != HW_OWNER) ++ break; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("Check next Own Bit of ST-LE[%d]: 0x%li \n", ++ (pAC->StatusLETable.Done + 1) % NUM_LE_IN_TABLE(&pAC->StatusLETable), ++ OWN_OF_FIRST_LE(&pAC->StatusLETable))); ++ ++ while (OWN_OF_FIRST_LE(&pAC->StatusLETable) == HW_OWNER) { ++ GET_ST_LE(pLE, &pAC->StatusLETable); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("Working on finished status LE[%d]:\n", ++ GET_DONE_INDEX(&pAC->StatusLETable))); ++ SK_DBG_DUMP_ST_LE(pLE); ++ handledStatLE = SK_TRUE; ++ OpCode = STLE_GET_OPC(pLE) & ~HW_OWNER; ++ Port = STLE_GET_LINK(pLE); ++ ++#ifdef USE_TIST_FOR_RESET ++ if (!HW_IS_EXT_LE_FORMAT(pAC) && SK_ADAPTER_WAITING_FOR_TIST(pAC)) { ++ /* do we just have a tist LE ? */ ++ if ((OpCode & OP_RXTIMESTAMP) == OP_RXTIMESTAMP) { ++ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { ++ if (SK_PORT_WAITING_FOR_ANY_TIST(pAC, i)) { ++ /* if a port is waiting for any tist it is done */ ++ SK_CLR_STATE_FOR_PORT(pAC, i); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, ++ ("Got any Tist on port %c (now 0x%X!!!)\n", ++ 'A' + i, pAC->AdapterResetState)); ++ } ++ if (SK_PORT_WAITING_FOR_SPECIFIC_TIST(pAC, i)) { ++ Y2_GET_TIST_LOW_VAL(pAC->IoBase, &LowVal); ++ if ((pAC->MinTistHi != pAC->GIni.GITimeStampCnt) || ++ (pAC->MinTistLo < LowVal)) { ++ /* time is up now */ ++ SK_CLR_STATE_FOR_PORT(pAC, i); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, ++ ("Got expected Tist on Port %c (now 0x%X)!!!\n", ++ 'A' + i, pAC->AdapterResetState)); ++#ifdef Y2_SYNC_CHECK ++ pAC->FramesWithoutSyncCheck = ++ Y2_RESYNC_WATERMARK; ++#endif ++ } else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, ++ ("Got Tist %l:%l on Port %c but still waiting\n", ++ pAC->GIni.GITimeStampCnt, pAC->MinTistLo, ++ 'A' + i)); ++ } ++ } ++ } ++#ifndef Y2_RECOVERY ++ if (!SK_ADAPTER_WAITING_FOR_TIST(pAC)) { ++ /* nobody needs tist anymore - turn it off */ ++ Y2_DISABLE_TIST(pAC->IoBase); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, ++ ("Turn off Tist !!!\n")); ++ } ++#endif ++ } else if (OpCode == OP_TXINDEXLE) { ++ /* ++ * change OpCode to notify the folowing code ++ * to ignore the done index from this LE ++ * unfortunately tist LEs will be generated only ++ * for RxStat LEs ++ * so in order to get a safe Done index for a ++ * port currently waiting for a tist we have to ++ * get the done index directly from the BMU ++ */ ++ OpCode = OP_MOD_TXINDEX; ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, ++ ("Mark unusable TX_INDEX LE!!!\n")); ++ } else { ++ if (SK_PORT_WAITING_FOR_TIST(pAC, Port)) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, ++ ("Ignore LE 0x%X on Port %c!!!\n", ++ OpCode, 'A' + Port)); ++ OpCode = OP_MOD_LE; ++#ifdef Y2_LE_CHECK ++ /* mark entries invalid */ ++ pAC->LastOpc = 0xFF; ++ pAC->LastPort = 3; ++#endif ++ } ++ } ++ } /* if (SK_ADAPTER_WAITING_FOR_TIST(pAC)) */ ++#endif ++ ++ ++ ++ ++ ++#ifdef Y2_LE_CHECK ++ if (!HW_IS_EXT_LE_FORMAT(pAC) && pAC->LastOpc != 0xFF) { ++ /* last opc is valid ++ * check if current opcode follows last opcode ++ */ ++ if ((((OpCode & OP_RXTIMESTAMP) == OP_RXTIMESTAMP) && (pAC->LastOpc != OP_RXSTAT)) || ++ (((OpCode & OP_RXCHKS) == OP_RXCHKS) && (pAC->LastOpc != OP_RXTIMESTAMP)) || ++ ((OpCode == OP_RXSTAT) && (pAC->LastOpc != OP_RXCHKS))) { ++ ++ /* opcode sequence broken ++ * current LE is invalid ++ */ ++ ++ if (pAC->LastOpc == OP_RXTIMESTAMP) { ++ /* force invalid checksum */ ++ pLE->St.StUn.StRxTCPCSum.RxTCPSum1 = 1; ++ pLE->St.StUn.StRxTCPCSum.RxTCPSum2 = 0; ++ OpCode = pAC->LastOpc = OP_RXCHKS; ++ Port = pAC->LastPort; ++ } else if (pAC->LastOpc == OP_RXCHKS) { ++ /* force invalid frame */ ++ Port = pAC->LastPort; ++ pLE->St.Stat.BufLen = 64; ++ pLE->St.StUn.StRxStatWord = GMR_FS_CRC_ERR; ++ OpCode = pAC->LastOpc = OP_RXSTAT; ++#ifdef Y2_SYNC_CHECK ++ /* force rx sync check */ ++ pAC->FramesWithoutSyncCheck = Y2_RESYNC_WATERMARK; ++#endif ++ } else if (pAC->LastOpc == OP_RXSTAT) { ++ /* create dont care tist */ ++ pLE->St.StUn.StRxTimeStamp = 0; ++ OpCode = pAC->LastOpc = OP_RXTIMESTAMP; ++ /* dont know the port yet */ ++ } else { ++#ifdef DEBUG ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("Unknown LastOpc %X for Timestamp on port %c.\n", ++ pAC->LastOpc, Port)); ++#endif ++ } ++ } ++ } ++#endif ++ ++ switch (OpCode) { ++ case OP_RXSTAT: ++#ifdef Y2_RECOVERY ++ pAC->LastOpc = OP_RXSTAT; ++#endif ++ /* ++ ** This is always the last Status LE belonging ++ ** to a received packet -> handle it... ++ */ ++ ++ HandleReceives( ++ pAC, ++#ifdef SK_EXTREME ++ CSS_GET_PORT(Port), ++#else ++ Port, ++#endif ++ STLE_GET_LEN(pLE), ++ STLE_GET_FRSTATUS(pLE), ++ pAC->StatusLETable.Bmu.Stat.TcpSum1, ++ pAC->StatusLETable.Bmu.Stat.TcpSum2, ++ pAC->StatusLETable.Bmu.Stat.RxTimeStamp, ++ pAC->StatusLETable.Bmu.Stat.VlanId); ++#ifdef CONFIG_SK98LIN_NAPI ++ if (*WorkDone >= WorkToDo) { ++ break; ++ } ++ (*WorkDone)++; ++#endif ++ break; ++ case OP_RXVLAN: ++ /* this value will be used for next RXSTAT */ ++ pAC->StatusLETable.Bmu.Stat.VlanId = STLE_GET_VLAN(pLE); ++ break; ++ case OP_RXTIMEVLAN: ++ /* this value will be used for next RXSTAT */ ++ pAC->StatusLETable.Bmu.Stat.VlanId = STLE_GET_VLAN(pLE); ++ /* fall through */ ++ case OP_RXTIMESTAMP: ++ /* this value will be used for next RXSTAT */ ++ pAC->StatusLETable.Bmu.Stat.RxTimeStamp = STLE_GET_TIST(pLE); ++#ifdef Y2_RECOVERY ++ pAC->LastOpc = OP_RXTIMESTAMP; ++ pAC->LastPort = Port; ++#endif ++ break; ++ case OP_RXCHKSVLAN: ++ /* this value will be used for next RXSTAT */ ++ pAC->StatusLETable.Bmu.Stat.VlanId = STLE_GET_VLAN(pLE); ++ /* fall through */ ++ case OP_RXCHKS: ++ /* this value will be used for next RXSTAT */ ++ pAC->StatusLETable.Bmu.Stat.TcpSum1 = STLE_GET_TCP1(pLE); ++ pAC->StatusLETable.Bmu.Stat.TcpSum2 = STLE_GET_TCP2(pLE); ++#ifdef Y2_RECOVERY ++ pAC->LastPort = Port; ++ pAC->LastOpc = OP_RXCHKS; ++#endif ++ break; ++ case OP_RSS_HASH: ++ /* this value will be used for next RXSTAT */ ++#if 0 ++ pAC->StatusLETable.Bmu.Stat.RssHashValue = STLE_GET_RSS(pLE); ++#endif ++ break; ++ case OP_TXINDEXLE: ++ /* ++ ** :;:; TODO ++ ** it would be possible to check for which queues ++ ** the index has been changed and call ++ ** CheckForSendComplete() only for such queues ++ */ ++ STLE_GET_DONE_IDX(pLE,LowVal,HighVal); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("LowVal: 0x%x HighVal: 0x%x\n", LowVal, HighVal)); ++ ++ /* ++ ** It would be possible to check whether we really ++ ** need the values for second port or sync queue, ++ ** but I think checking whether we need them is ++ ** more expensive than the calculation ++ */ ++ DoneTxA[0] = STLE_GET_DONE_IDX_TXA1(LowVal,HighVal); ++ DoneTxS[0] = STLE_GET_DONE_IDX_TXS1(LowVal,HighVal); ++ DoneTxA[1] = STLE_GET_DONE_IDX_TXA2(LowVal,HighVal); ++ DoneTxS[1] = STLE_GET_DONE_IDX_TXS2(LowVal,HighVal); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("DoneTxa1 0x%x DoneTxS1: 0x%x DoneTxa2 0x%x DoneTxS2: 0x%x\n", ++ DoneTxA[0], DoneTxS[0], DoneTxA[1], DoneTxS[1])); ++ ++ NewDone = SK_TRUE; ++ break; ++#ifdef USE_TIST_FOR_RESET ++ case OP_MOD_TXINDEX: ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, ++ ("OP_MOD_TXINDEX\n")); ++ SK_IN16(pAC->IoBase, Q_ADDR(Q_XA1, Q_DONE), &DoneTxA[0]); ++ if (pAC->GIni.GIMacsFound > 1) { ++ SK_IN16(pAC->IoBase, Q_ADDR(Q_XA2, Q_DONE), &DoneTxA[1]); ++ } ++ NewDone = SK_TRUE; ++ break; ++ case OP_MOD_LE: ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, ++ ("Ignore marked LE on port in Reset\n")); ++ break; ++#endif ++ ++ default: ++ /* ++ ** Have to handle the illegal Opcode in Status LE ++ */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("Unexpected OpCode\n")); ++ break; ++ } ++ ++#ifdef Y2_RECOVERY ++ OpCode = STLE_GET_OPC(pLE) & ~HW_OWNER; ++ STLE_SET_OPC(pLE, OpCode); ++#else ++ /* ++ ** Reset own bit we have to do this in order to detect a overflow ++ */ ++ STLE_SET_OPC(pLE, SW_OWNER); ++#endif ++ } /* while (OWN_OF_FIRST_LE(&pAC->StatusLETable) == HW_OWNER) */ ++ ++ /* ++ ** Now handle any new transmit complete ++ */ ++ if (NewDone) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("Done Index for Tx BMU has been changed\n")); ++ for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) { ++ /* ++ ** Do we have a new Done idx ? ++ */ ++ if (DoneTxA[Port] != GET_DONE_INDEX(&pAC->TxPort[Port][0].TxALET)) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("Check TxA%d\n", Port + 1)); ++ CheckForSendComplete(pAC, pAC->IoBase, Port, ++ &(pAC->TxPort[Port][0].TxAQ_working), ++ &pAC->TxPort[Port][0].TxALET, ++ DoneTxA[Port]); ++ } else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("No changes for TxA%d\n", Port + 1)); ++ } ++#ifdef USE_SYNC_TX_QUEUE ++ if (HW_SYNC_TX_SUPPORTED(pAC)) { ++ /* ++ ** Do we have a new Done idx ? ++ */ ++ if (DoneTxS[Port] != ++ GET_DONE_INDEX(&pAC->TxPort[Port][0].TxSLET)) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_INT_SRC, ++ ("Check TxS%d\n", Port)); ++ CheckForSendComplete(pAC, pAC->IoBase, Port, ++ &(pAC->TxPort[Port][0].TxSQ_working), ++ &pAC->TxPort[Port][0].TxSLET, ++ DoneTxS[Port]); ++ } else { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_INT_SRC, ++ ("No changes for TxS%d\n", Port)); ++ } ++ } ++#endif ++ } ++ } ++ NewDone = SK_FALSE; ++ ++ /* ++ ** Check whether we have to refill our RX table ++ */ ++ if (HW_FEATURE(pAC, HWF_WA_DEV_420)) { ++ if (NbrRxBuffersInHW < MAX_NBR_RX_BUFFERS_IN_HW) { ++ for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("Check for refill of RxBuffers on Port %c\n", 'A' + Port)); ++ FillReceiveTableYukon2(pAC, pAC->IoBase, Port); ++ } ++ } ++ } else { ++ for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ++ ("Check for refill of RxBuffers on Port %c\n", 'A' + Port)); ++ if (NUM_FREE_LE_IN_TABLE(&pAC->RxPort[Port].RxLET) >= 64) { ++ FillReceiveTableYukon2(pAC, pAC->IoBase, Port); ++ } ++ } ++ } ++#ifdef CONFIG_SK98LIN_NAPI ++ if (*WorkDone >= WorkToDo) { ++ break; ++ } ++#endif ++ } while (OWN_OF_FIRST_LE(&pAC->StatusLETable) == HW_OWNER); ++ ++ /* ++ ** Clear status BMU ++ */ ++ if (handledStatLE) ++ SK_OUT32(pAC->IoBase, STAT_CTRL, SC_STAT_CLR_IRQ); ++ ++ return(handledStatLE); ++} /* HandleStatusLEs */ ++ ++/***************************************************************************** ++ * ++ * AllocateAndInitLETables - allocate memory for the LETable and init ++ * ++ * Description: ++ * This function will allocate space for the LETable and will also ++ * initialize them. The size of the tables must have been specified ++ * before. ++ * ++ * Arguments: ++ * pAC - A pointer to the adapter context struct. ++ * ++ * Returns: ++ * SK_TRUE - all LETables initialized ++ * SK_FALSE - failed ++ */ ++static SK_BOOL AllocateAndInitLETables( ++SK_AC *pAC) /* pointer to adapter context */ ++{ ++ char *pVirtMemAddr; ++ dma_addr_t pPhysMemAddr = 0; ++ SK_U32 CurrMac; ++ unsigned Size; ++ unsigned Aligned; ++ unsigned Alignment; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("==> AllocateAndInitLETables()\n")); ++ ++ /* ++ ** Determine how much memory we need with respect to alignment ++ */ ++ Alignment = (SK_U32) LE_TAB_SIZE(NUMBER_OF_ST_LE); ++ ++ Size = 0; ++ for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) { ++ SK_ALIGN_SIZE(LE_TAB_SIZE(NUMBER_OF_RX_LE), Alignment, Aligned); ++ Size += Aligned; ++ SK_ALIGN_SIZE(LE_TAB_SIZE(NUMBER_OF_TX_LE), Alignment, Aligned); ++ Size += Aligned; ++ SK_ALIGN_SIZE(LE_TAB_SIZE(TXS_MAX_LE), Alignment, Aligned); ++ Size += Aligned; ++ } ++ SK_ALIGN_SIZE(LE_TAB_SIZE(NUMBER_OF_ST_LE), Alignment, Aligned); ++ Size += Aligned; ++ Size += Alignment; ++ pAC->SizeOfAlignedLETables = Size; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("Need %08x bytes in total\n", Size)); ++ ++ /* ++ ** Allocate the memory ++ */ ++ pVirtMemAddr = pci_alloc_consistent(pAC->PciDev, Size, &pPhysMemAddr); ++ if (pVirtMemAddr == NULL) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, ++ SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR, ++ ("AllocateAndInitLETables: kernel malloc failed!\n")); ++ return (SK_FALSE); ++ } ++ ++ /* ++ ** Initialize the memory ++ */ ++ SK_MEMSET(pVirtMemAddr, 0, Size); ++ ALIGN_ADDR(pVirtMemAddr, Alignment); /* Macro defined in skgew.h */ ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("Virtual address of LETab is %8p!\n", pVirtMemAddr)); ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("Phys address of LETab is %8p!\n", (void *) pPhysMemAddr)); ++ ++ for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("RxLeTable for Port %c", 'A' + CurrMac)); ++ SkGeY2InitSingleLETable( ++ pAC, ++ &pAC->RxPort[CurrMac].RxLET, ++ NUMBER_OF_RX_LE, ++ pVirtMemAddr, ++ (SK_U32) (pPhysMemAddr & 0xffffffff), ++ (SK_U32) (((SK_U64) pPhysMemAddr) >> 32)); ++ ++ SK_ALIGN_SIZE(LE_TAB_SIZE(NUMBER_OF_RX_LE), Alignment, Aligned); ++ pVirtMemAddr += Aligned; ++ pPhysMemAddr += Aligned; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("TxALeTable for Port %c", 'A' + CurrMac)); ++ SkGeY2InitSingleLETable( ++ pAC, ++ &pAC->TxPort[CurrMac][0].TxALET, ++ NUMBER_OF_TX_LE, ++ pVirtMemAddr, ++ (SK_U32) (pPhysMemAddr & 0xffffffff), ++ (SK_U32) (((SK_U64) pPhysMemAddr) >> 32)); ++ ++ SK_ALIGN_SIZE(LE_TAB_SIZE(NUMBER_OF_TX_LE), Alignment, Aligned); ++ pVirtMemAddr += Aligned; ++ pPhysMemAddr += Aligned; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("TxSLeTable for Port %c", 'A' + CurrMac)); ++ SkGeY2InitSingleLETable( ++ pAC, ++ &pAC->TxPort[CurrMac][0].TxSLET, ++ TXS_MAX_LE, ++ pVirtMemAddr, ++ (SK_U32) (pPhysMemAddr & 0xffffffff), ++ (SK_U32) (((SK_U64) pPhysMemAddr) >> 32)); ++ ++ SK_ALIGN_SIZE(LE_TAB_SIZE(TXS_MAX_LE), Alignment, Aligned); ++ pVirtMemAddr += Aligned; ++ pPhysMemAddr += Aligned; ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,("StLeTable")); ++ ++ SkGeY2InitSingleLETable( ++ pAC, ++ &pAC->StatusLETable, ++ NUMBER_OF_ST_LE, ++ pVirtMemAddr, ++ (SK_U32) (pPhysMemAddr & 0xffffffff), ++ (SK_U32) (((SK_U64) pPhysMemAddr) >> 32)); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("<== AllocateAndInitLETables(OK)\n")); ++ return(SK_TRUE); ++} /* AllocateAndInitLETables */ ++ ++/***************************************************************************** ++ * ++ * AllocatePacketBuffersYukon2 - allocate packet and fragment buffers ++ * ++ * Description: ++ * This function will allocate space for the packets and fragments ++ * ++ * Arguments: ++ * pAC - A pointer to the adapter context struct. ++ * ++ * Returns: ++ * SK_TRUE - Memory was allocated correctly ++ * SK_FALSE - An error occured ++ */ ++static SK_BOOL AllocatePacketBuffersYukon2( ++SK_AC *pAC) /* pointer to adapter context */ ++{ ++ SK_PACKET *pRxPacket; ++ SK_PACKET *pTxPacket; ++ SK_U32 CurrBuff; ++ SK_U32 CurrMac; ++ unsigned long Flags; /* needed for POP/PUSH functions */ ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("==> AllocatePacketBuffersYukon2()")); ++ ++ for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) { ++ /* ++ ** Allocate RX packet space, initialize the packets and ++ ** add them to the RX waiting queue. Waiting queue means ++ ** that packet and fragment are initialized, but no sk_buff ++ ** has been assigned to it yet. ++ */ ++ pAC->RxPort[CurrMac].ReceivePacketTable = ++ kmalloc((RX_MAX_NBR_BUFFERS * sizeof(SK_PACKET)), GFP_KERNEL); ++ ++ if (pAC->RxPort[CurrMac].ReceivePacketTable == NULL) { ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR, ++ ("AllocatePacketBuffersYukon2: no mem RxPkts (port %i)",CurrMac)); ++ break; ++ } else { ++ SK_MEMSET(pAC->RxPort[CurrMac].ReceivePacketTable, 0, ++ (RX_MAX_NBR_BUFFERS * sizeof(SK_PACKET))); ++ ++ pRxPacket = pAC->RxPort[CurrMac].ReceivePacketTable; ++ ++ for (CurrBuff=0;CurrBuffpFrag = &(pRxPacket->FragArray[0]); ++ pRxPacket->NumFrags = 1; ++ PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[CurrMac].RxQ_waiting, pRxPacket); ++ pRxPacket++; ++ } ++ } ++ ++ /* ++ ** Allocate TX packet space, initialize the packets and ++ ** add them to the TX free queue. Free queue means that ++ ** packet is available and initialized, but no fragment ++ ** has been assigned to it. (Must be done at TX side) ++ */ ++ pAC->TxPort[CurrMac][0].TransmitPacketTable = ++ kmalloc((TX_MAX_NBR_BUFFERS * sizeof(SK_PACKET)), GFP_KERNEL); ++ ++ if (pAC->TxPort[CurrMac][0].TransmitPacketTable == NULL) { ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR, ++ ("AllocatePacketBuffersYukon2: no mem TxPkts (port %i)",CurrMac)); ++ kfree(pAC->RxPort[CurrMac].ReceivePacketTable); ++ return(SK_FALSE); ++ } else { ++ SK_MEMSET(pAC->TxPort[CurrMac][0].TransmitPacketTable, 0, ++ (TX_MAX_NBR_BUFFERS * sizeof(SK_PACKET))); ++ ++ pTxPacket = pAC->TxPort[CurrMac][0].TransmitPacketTable; ++ ++ for (CurrBuff=0;CurrBuffTxPort[CurrMac][0].TxQ_free, pTxPacket); ++ pTxPacket++; ++ } ++ } ++ } /* end for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) */ ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, ++ ("<== AllocatePacketBuffersYukon2 (OK)\n")); ++ return(SK_TRUE); ++ ++} /* AllocatePacketBuffersYukon2 */ ++ ++/***************************************************************************** ++ * ++ * FreeLETables - release allocated memory of LETables ++ * ++ * Description: ++ * This function will free all resources of the LETables ++ * ++ * Arguments: ++ * pAC - A pointer to the adapter context struct. ++ * ++ * Returns: N/A ++ */ ++static void FreeLETables( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ dma_addr_t pPhysMemAddr; ++ char *pVirtMemAddr; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("==> FreeLETables()\n")); ++ ++ /* ++ ** The RxLETable is the first of all LET. ++ ** Therefore we can use its address for the input ++ ** of the free function. ++ */ ++ pVirtMemAddr = (char *) pAC->RxPort[0].RxLET.pLETab; ++ pPhysMemAddr = (((SK_U64) pAC->RxPort[0].RxLET.pPhyLETABHigh << (SK_U64) 32) | ++ ((SK_U64) pAC->RxPort[0].RxLET.pPhyLETABLow)); ++ ++ /* free continuous memory */ ++ pci_free_consistent(pAC->PciDev, pAC->SizeOfAlignedLETables, ++ pVirtMemAddr, pPhysMemAddr); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("<== FreeLETables()\n")); ++} /* FreeLETables */ ++ ++/***************************************************************************** ++ * ++ * FreePacketBuffers - free's all packet buffers of an adapter ++ * ++ * Description: ++ * This function will free all previously allocated memory of the ++ * packet buffers. ++ * ++ * Arguments: ++ * pAC - A pointer to the adapter context struct. ++ * ++ * Returns: N/A ++ */ ++static void FreePacketBuffers( ++SK_AC *pAC) /* pointer to adapter control context */ ++{ ++ int Port; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("==> FreePacketBuffers()\n")); ++ ++ for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) { ++ kfree(pAC->RxPort[Port].ReceivePacketTable); ++ kfree(pAC->TxPort[Port][0].TransmitPacketTable); ++ } ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ++ ("<== FreePacketBuffers()\n")); ++} /* FreePacketBuffers */ ++ ++/***************************************************************************** ++ * ++ * AllocAndMapRxBuffer - fill one buffer into the receive packet/fragment ++ * ++ * Description: ++ * The function allocates a new receive buffer and assigns it to the ++ * the passsed receive packet/fragment ++ * ++ * Returns: ++ * SK_TRUE - a buffer was allocated and assigned ++ * SK_FALSE - a buffer could not be added ++ */ ++static SK_BOOL AllocAndMapRxBuffer( ++SK_AC *pAC, /* pointer to the adapter control context */ ++SK_PACKET *pSkPacket, /* pointer to packet that is to fill */ ++int Port) /* port the packet belongs to */ ++{ ++ struct sk_buff *pMsgBlock; /* pointer to a new message block */ ++ SK_U64 PhysAddr; /* physical address of a rx buffer */ ++ ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("--> AllocAndMapRxBuffer (Port: %i)\n", Port)); ++ ++ pMsgBlock = alloc_skb(pAC->RxPort[Port].RxBufSize, GFP_ATOMIC); ++ if (pMsgBlock == NULL) { ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, ++ SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR, ++ ("%s: Allocation of rx buffer failed !\n", ++ pAC->dev[Port]->name)); ++ SK_PNMI_CNT_NO_RX_BUF(pAC, pAC->RxPort[Port].PortIndex); ++ return(SK_FALSE); ++ } ++ skb_reserve(pMsgBlock, 8); ++ ++ PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, ++ virt_to_page(pMsgBlock->data), ++ ((unsigned long) pMsgBlock->data & ++ ~PAGE_MASK), ++ pAC->RxPort[Port].RxBufSize, ++ PCI_DMA_FROMDEVICE); ++ ++ pSkPacket->pFrag->pVirt = pMsgBlock->data; ++ pSkPacket->pFrag->pPhys = PhysAddr; ++ pSkPacket->pFrag->FragLen = pAC->RxPort[Port].RxBufSize; /* for correct unmap */ ++ pSkPacket->pMBuf = pMsgBlock; ++ pSkPacket->PacketLen = pAC->RxPort[Port].RxBufSize; ++ ++ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, ++ ("<-- AllocAndMapRxBuffer\n")); ++ ++ return (SK_TRUE); ++} /* AllocAndMapRxBuffer */ ++ ++/******************************************************************************* ++ * ++ * End of file ++ * ++ ******************************************************************************/ +diff -ruN linux/drivers/net/sk98lin/sky2le.c linux-new/drivers/net/sk98lin/sky2le.c +--- linux/drivers/net/sk98lin/sky2le.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-new/drivers/net/sk98lin/sky2le.c 2007-01-24 14:03:40.000000000 +0100 +@@ -0,0 +1,507 @@ ++/***************************************************************************** ++ * ++ * Name: sky2le.c ++ * Project: Gigabit Ethernet Adapters, Common Modules ++ * Version: $Revision$ ++ * Date: $Date$ ++ * Purpose: Functions for handling List Element Tables ++ * ++ *****************************************************************************/ ++ ++/****************************************************************************** ++ * ++ * LICENSE: ++ * (C)Copyright 2002-2006 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. ++ * /LICENSE ++ * ++ ******************************************************************************/ ++ ++/***************************************************************************** ++ * ++ * Description: ++ * ++ * This module contains the code necessary for handling List Elements. ++ * ++ * Supported Gigabit Ethernet Chipsets: ++ * Yukon-2 (PCI, PCI-X, PCI-Express) ++ * ++ * Include File Hierarchy: ++ * ++ * ++ *****************************************************************************/ ++#include "h/skdrv1st.h" ++#include "h/skdrv2nd.h" ++ ++/* defines *******************************************************************/ ++/* typedefs ******************************************************************/ ++/* global variables **********************************************************/ ++/* local variables ***********************************************************/ ++ ++#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) ++static const char SysKonnectFileId[] = ++ "@(#) $Id$ (C) Marvell."; ++#endif /* DEBUG || (!LINT && !SK_SLIM) */ ++ ++/* function prototypes *******************************************************/ ++ ++/***************************************************************************** ++ * ++ * SkGeY2InitSingleLETable() - initializes a list element table ++ * ++ * Description: ++ * This function will initialize the selected list element table. ++ * Should be called once during DriverInit. No InitLevel required. ++ * ++ * Arguments: ++ * pAC - pointer to the adapter context struct. ++ * pLETab - pointer to list element table structure ++ * NumLE - number of list elements in this table ++ * pVMem - virtual address of memory allocated for this LE table ++ * PMemLowAddr - physical address of memory to be used for the LE table ++ * PMemHighAddr ++ * ++ * Returns: ++ * nothing ++ */ ++void SkGeY2InitSingleLETable( ++SK_AC *pAC, /* pointer to adapter context */ ++SK_LE_TABLE *pLETab, /* pointer to list element table to be initialized */ ++unsigned int NumLE, /* number of list elements to be filled in tab */ ++void *pVMem, /* virtual address of memory used for list elements */ ++SK_U32 PMemLowAddr, /* physical addr of mem used for LE */ ++SK_U32 PMemHighAddr) ++{ ++ unsigned int i; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("==> SkGeY2InitSingleLETable()\n")); ++ ++#ifdef DEBUG ++ if (NumLE != 2) { /* not table for polling unit */ ++ if ((NumLE % MIN_LEN_OF_LE_TAB) != 0 || NumLE > MAX_LEN_OF_LE_TAB) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("ERROR: Illegal number of list elements %d\n", NumLE)); ++ } ++ } ++#endif /* DEBUG */ ++ ++ /* special case: unused list element table */ ++ if (NumLE == 0) { ++ PMemLowAddr = 0; ++ PMemHighAddr = 0; ++ pVMem = 0; ++ } ++ ++ /* ++ * in order to get the best possible performance the macros to access ++ * list elements use & instead of % ++ * this requires the length of LE tables to be a power of 2 ++ */ ++ ++ /* ++ * this code guarantees that we use the next power of 2 below the ++ * value specified for NumLe - this way some LEs in the table may ++ * not be used but the macros work correctly ++ * this code does not check for bad values below 128 because in such a ++ * case we cannot do anything here ++ */ ++ ++ if ((NumLE != 2) && (NumLE != 0)) { ++ /* no check for polling unit and unused sync Tx */ ++ i = MIN_LEN_OF_LE_TAB; ++ while (NumLE > i) { ++ i *= 2; ++ if (i > MAX_LEN_OF_LE_TAB) { ++ break; ++ } ++ } ++ if (NumLE != i) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("ERROR: Illegal number of list elements %d adjusted to %d\n", ++ NumLE, (i / 2))); ++ NumLE = i / 2; ++ } ++ } ++ ++ /* set addresses */ ++ pLETab->pPhyLETABLow = PMemLowAddr; ++ pLETab->pPhyLETABHigh = PMemHighAddr; ++ pLETab->pLETab = pVMem; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("contains %d LEs", NumLE)); ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ (" and starts at virt %08lx and phys %08lx:%08lx\n", ++ pVMem, PMemHighAddr, PMemLowAddr)); ++ ++ /* initialize indexes */ ++ pLETab->Done = 0; ++ pLETab->Put = 0; ++ pLETab->HwPut = 0; ++ /* initialize size */ ++ pLETab->Num = NumLE; ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("<== SkGeY2InitSingleLETable()\n")); ++} /* SkGeY2InitSingleLETable */ ++ ++/***************************************************************************** ++ * ++ * SkGeY2InitPrefetchUnit() - Initialize a Prefetch Unit ++ * ++ * Description: ++ * Calling this function requires an already configured list element ++ * table. The prefetch unit to be configured is specified in the parameter ++ * 'Queue'. The function is able to initialze the prefetch units of ++ * the following queues: Q_R1, Q_R2, Q_XS1, Q_XS2, Q_XA1, Q_XA2. ++ * The funcution should be called before SkGeInitPort(). ++ * ++ * Arguments: ++ * pAC - pointer to the adapter context struct. ++ * IoC - I/O context. ++ * Queue - I/O offset of queue e.g. Q_XA1. ++ * pLETab - pointer to list element table to be initialized ++ * ++ * Returns: N/A ++ */ ++void SkGeY2InitPrefetchUnit( ++SK_AC *pAC, /* pointer to adapter context */ ++SK_IOC IoC, /* I/O context */ ++unsigned int Queue, /* Queue offset for finding the right registers */ ++SK_LE_TABLE *pLETab) /* pointer to list element table to be initialized */ ++{ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("==> SkGeY2InitPrefetchUnit()\n")); ++ ++#ifdef DEBUG ++ if (Queue != Q_R1 && Queue != Q_R2 && Queue != Q_XS1 && ++ Queue != Q_XS2 && Queue != Q_XA1 && Queue != Q_XA2) { ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ++ ("ERROR: Illegal queue identifier %x\n", Queue)); ++ } ++#endif /* DEBUG */ ++ ++ /* disable the prefetch unit */ ++ SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_CTRL_REG), PREF_UNIT_RST_SET); ++ SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_CTRL_REG), PREF_UNIT_RST_CLR); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("Base address: %08lx:%08lx\n", pLETab->pPhyLETABHigh, ++ pLETab->pPhyLETABLow)); ++ ++ /* Set the list base address high part*/ ++ SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_ADDR_HI_REG), ++ pLETab->pPhyLETABHigh); ++ ++ /* Set the list base address low part */ ++ SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_ADDR_LOW_REG), ++ pLETab->pPhyLETABLow); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("Last index: %d\n", pLETab->Num-1)); ++ ++ /* Set the list last index */ ++ SK_OUT16(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_LAST_IDX_REG), ++ (SK_U16)(pLETab->Num - 1)); ++ ++ /* turn on prefetch unit */ ++ SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_CTRL_REG), PREF_UNIT_OP_ON); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("<== SkGeY2InitPrefetchUnit()\n")); ++} /* SkGeY2InitPrefetchUnit */ ++ ++ ++/***************************************************************************** ++ * ++ * SkGeY2InitStatBmu() - Initialize the Status BMU ++ * ++ * Description: ++ * Calling this function requires an already configured list element ++ * table. Ensure the status BMU is only initialized once during ++ * DriverInit - InitLevel2 required. ++ * ++ * Arguments: ++ * pAC - pointer to the adapter context struct. ++ * IoC - I/O context. ++ * pLETab - pointer to status LE table to be initialized ++ * ++ * Returns: N/A ++ */ ++void SkGeY2InitStatBmu( ++SK_AC *pAC, /* pointer to adapter context */ ++SK_IOC IoC, /* I/O context */ ++SK_LE_TABLE *pLETab) /* pointer to status LE table */ ++{ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("==> SkGeY2InitStatBmu()\n")); ++ ++ /* disable the prefetch unit */ ++ SK_OUT32(IoC, STAT_CTRL, SC_STAT_RST_SET); ++ SK_OUT32(IoC, STAT_CTRL, SC_STAT_RST_CLR); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("Base address Low: %08lX\n", pLETab->pPhyLETABLow)); ++ ++ /* Set the list base address */ ++ SK_OUT32(IoC, STAT_LIST_ADDR_LO, pLETab->pPhyLETABLow); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("Base address High: %08lX\n", pLETab->pPhyLETABHigh)); ++ ++ SK_OUT32(IoC, STAT_LIST_ADDR_HI, pLETab->pPhyLETABHigh); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("Last index: %d\n", pLETab->Num - 1)); ++ ++ /* Set the list last index */ ++ SK_OUT16(IoC, STAT_LAST_IDX, (SK_U16)(pLETab->Num - 1)); ++ ++ if (HW_FEATURE(pAC, HWF_WA_DEV_43_418)) { ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("Set Tx index threshold\n")); ++ /* WA for dev. #4.3 */ ++ SK_OUT16(IoC, STAT_TX_IDX_TH, ST_TXTH_IDX_MASK); ++ ++ /* set Status-FIFO watermark */ ++ SK_OUT8(IoC, STAT_FIFO_WM, 0x21); /* WA for dev. #4.18 */ ++ ++ /* set Status-FIFO ISR watermark */ ++ SK_OUT8(IoC, STAT_FIFO_ISR_WM, 0x07); /* WA for dev. #4.18 */ ++ ++ /* WA for dev. #4.3 and #4.18 */ ++ /* set Status-FIFO Tx timer init value */ ++ SK_OUT32(IoC, STAT_TX_TIMER_INI, HW_MS_TO_TICKS(pAC, 10)); ++ } ++ else { ++ /* ++ * Further settings may be added if required... ++ * 1) Status-FIFO watermark (STAT_FIFO_WM, STAT_FIFO_ISR_WM) ++ * 2) Status-FIFO timer values (STAT_TX_TIMER_INI, ++ * STAT_LEV_TIMER_INI and STAT_ISR_TIMER_INI) ++ * but tests shows that the default values give the best results, ++ * therefore the defaults are used. ++ */ ++ ++ /* ++ * Theses settings should avoid the temporary hang of the status BMU. ++ * May be not all required... still under investigation... ++ */ ++ SK_OUT16(IoC, STAT_TX_IDX_TH, 0x000a); ++ ++ /* set Status-FIFO watermark */ ++ SK_OUT8(IoC, STAT_FIFO_WM, 0x10); ++ ++ /* set Status-FIFO ISR watermark */ ++ SK_OUT8(IoC, STAT_FIFO_ISR_WM, ++ HW_FEATURE(pAC, HWF_WA_DEV_4109) ? 0x10 : 0x04); ++ ++ /* set ISR Timer Init Value to 400 (3.2 us on Yukon-EC) */ ++ SK_OUT32(IoC, STAT_ISR_TIMER_INI, 0x0190); ++ } ++ ++ /* start Status-FIFO timer */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("Start Status FiFo timer\n")); ++ ++ /* enable the prefetch unit */ ++ /* operational bit not functional for Yukon-EC, but fixed in Yukon-2 */ ++ SK_OUT32(IoC, STAT_CTRL, SC_STAT_OP_ON); ++ ++ /* start Status-FIFO timer */ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("Start Status FiFo timer\n")); ++ ++ SK_OUT8(IoC, STAT_TX_TIMER_CTRL, TIM_START); ++ SK_OUT8(IoC, STAT_LEV_TIMER_CTRL, TIM_START); ++ SK_OUT8(IoC, STAT_ISR_TIMER_CTRL, TIM_START); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("<== SkGeY2InitStatBmu()\n")); ++} /* SkGeY2InitStatBmu */ ++ ++#ifdef USE_POLLING_UNIT ++/***************************************************************************** ++ * ++ * SkGeY2InitPollUnit() - Initialize the Polling Unit ++ * ++ * Description: ++ * This function will write the data of one polling LE table into the ++ * adapter. ++ * ++ * Arguments: ++ * pAC - pointer to the adapter context struct. ++ * IoC - I/O context. ++ * pLETab - pointer to polling LE table to be initialized ++ * ++ * Returns: N/A ++ */ ++void SkGeY2InitPollUnit( ++SK_AC *pAC, /* pointer to adapter context */ ++SK_IOC IoC, /* I/O context */ ++SK_LE_TABLE *pLETab) /* pointer to polling LE table */ ++{ ++ SK_HWLE *pLE; ++ int i; ++#ifdef VCPU ++ VCPU_VARS(); ++#endif /* VCPU */ ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("==> SkGeY2InitPollUnit()\n")); ++ ++#ifdef VCPU ++ for (i = 0; i < SK_MAX_MACS; i++) { ++ GET_PO_LE(pLE, pLETab, i); ++ VCPU_START_AND_COPY_LE(); ++ /* initialize polling LE but leave indexes invalid */ ++ POLE_SET_OPC(pLE, OP_PUTIDX | HW_OWNER); ++ POLE_SET_LINK(pLE, i); ++ POLE_SET_RXIDX(pLE, 0); ++ POLE_SET_TXAIDX(pLE, 0); ++ POLE_SET_TXSIDX(pLE, 0); ++ VCPU_WRITE_LE(); ++ SK_DBG_DUMP_PO_LE(pLE); ++ } ++#endif /* VCPU */ ++ ++ /* disable the polling unit */ ++ SK_OUT32(IoC, POLL_CTRL, PC_POLL_RST_SET); ++ SK_OUT32(IoC, POLL_CTRL, PC_POLL_RST_CLR); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("Base address Low: %08lX\n", pLETab->pPhyLETABLow)); ++ ++ /* Set the list base address */ ++ SK_OUT32(IoC, POLL_LIST_ADDR_LO, pLETab->pPhyLETABLow); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("Base address High: %08lX\n", pLETab->pPhyLETABHigh)); ++ ++ SK_OUT32(IoC, POLL_LIST_ADDR_HI, pLETab->pPhyLETABHigh); ++ ++ /* we don't need to write the last index - it is hardwired to 1 */ ++ ++ /* enable the prefetch unit */ ++ SK_OUT32(IoC, POLL_CTRL, PC_POLL_OP_ON); ++ ++ /* ++ * now we have to start the descriptor poll timer because it triggers ++ * the polling unit ++ */ ++ ++ /* ++ * still playing with the value (timer runs at 125 MHz) ++ * descriptor poll timer is enabled by GeInit ++ */ ++ SK_OUT32(IoC, B28_DPT_INI, ++ (SK_DPOLL_DEF_Y2 * (SK_U32)pAC->GIni.GIHstClkFact / 100)); ++ ++ SK_OUT8(IoC, B28_DPT_CTRL, TIM_START); ++ ++ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ++ ("<== SkGeY2InitPollUnit()\n")); ++} /* SkGeY2InitPollUnit */ ++#endif /* USE_POLLING_UNIT */ ++ ++ ++/****************************************************************************** ++ * ++ * SkGeY2SetPutIndex ++ * ++ * Description: ++ * This function is writing the Done index of a transmit ++ * list element table. ++ * ++ * Notes: ++ * Dev. Issue 4.2 ++ * ++ * Returns: N/A ++ */ ++void SkGeY2SetPutIndex( ++SK_AC *pAC, /* pointer to adapter context */ ++SK_IOC IoC, /* pointer to the IO context */ ++SK_U32 StartAddrPrefetchUnit, /* start address of the prefetch unit */ ++SK_LE_TABLE *pLETab) /* list element table to work with */ ++{ ++ unsigned int Put; ++ SK_U16 EndOfListIndex; ++ SK_U16 HwGetIndex; ++ SK_U16 HwPutIndex; ++ ++ /* set put index we would like to write */ ++ Put = GET_PUT_IDX(pLETab); ++ ++ /* ++ * in this case we wrap around ++ * new put is lower than last put given to HW ++ */ ++ if (Put < pLETab->HwPut) { ++ ++ /* set put index = last index of list */ ++ EndOfListIndex = (NUM_LE_IN_TABLE(pLETab)-1); ++ ++ /* read get index of hw prefetch unit */ ++ SK_IN16(IoC, (StartAddrPrefetchUnit + PREF_UNIT_GET_IDX_REG), ++ &HwGetIndex); ++ ++ /* read put index of hw prefetch unit */ ++ SK_IN16(IoC, (StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG), ++ &HwPutIndex); ++ ++ /* prefetch unit reached end of list */ ++ /* prefetch unit reached first list element */ ++ if (HwGetIndex == 0) { ++ /* restore watermark */ ++ SK_OUT8(IoC, StartAddrPrefetchUnit + PREF_UNIT_FIFO_WM_REG, 0xe0U); ++ /* write put index */ ++ SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG, ++ (SK_U16)Put); ++ ++ /* remember put index we wrote to hw */ ++ pLETab->HwPut = Put; ++ } ++ else if (HwGetIndex == EndOfListIndex) { ++ /* set watermark to one list element */ ++ SK_OUT8(IoC, StartAddrPrefetchUnit + PREF_UNIT_FIFO_WM_REG, 8); ++ /* set put index to first list element */ ++ SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG, 0); ++ } ++ /* prefetch unit did not reach end of list yet */ ++ /* and we did not write put index to end of list yet */ ++ else if ((HwPutIndex != EndOfListIndex) && ++ (HwGetIndex != EndOfListIndex)) { ++ /* write put index */ ++ SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG, ++ EndOfListIndex); ++ } ++ else { ++ /* do nothing */ ++ } ++ } ++ else { ++#ifdef XXX /* leads in to problems in the Windows Driver */ ++ if (Put != pLETab->HwPut) { ++ /* write put index */ ++ SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG, ++ (SK_U16)Put); ++ /* update put index */ ++ UPDATE_HWPUT_IDX(pLETab); ++ } ++#else ++ /* write put index */ ++ SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG, ++ (SK_U16)Put); ++ /* update put index */ ++ UPDATE_HWPUT_IDX(pLETab); ++#endif ++ } ++} /* SkGeY2SetPutIndex */ ++ +diff -ruN linux/Documentation/networking/sk98lin.txt linux-new/Documentation/networking/sk98lin.txt +--- linux/Documentation/networking/sk98lin.txt 2007-07-09 01:32:17.000000000 +0200 ++++ linux-new/drivers/net/sk98lin/sk98lin.txt 2007-01-24 14:03:40.000000000 +0100 +@@ -1,38 +1,56 @@ +-(C)Copyright 1999-2004 Marvell(R). +-All rights reserved +-=========================================================================== ++(C)Copyright 1999-2007 Marvell(R). ++All rights reserved. ++================================================================================ + +-sk98lin.txt created 13-Feb-2004 ++sk98lin.txt created 24-Jan-2007 + +-Readme File for sk98lin v6.23 +-Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX ++Readme File for sk98lin v10.0.4.3 ++Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter driver for LINUX + + This file contains + 1 Overview +- 2 Required Files +- 3 Installation +- 3.1 Driver Installation +- 3.2 Inclusion of adapter at system start +- 4 Driver Parameters +- 4.1 Per-Port Parameters +- 4.2 Adapter Parameters +- 5 Large Frame Support +- 6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) +- 7 Troubleshooting ++ 2 Supported Functions ++ 3 Required Files ++ 4 Installation ++ 4.1 Driver Installation ++ 4.2 Inclusion of adapter at system start ++ 5 Driver Parameters ++ 5.1 Per-Port Parameters ++ 5.2 Adapter Parameters ++ 6 Ethtool Support ++ 7 Large Frame Support ++ 8 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) ++ 9 Wake on Lan support ++10 Troubleshooting + +-=========================================================================== ++================================================================================ + + + 1 Overview + =========== + +-The sk98lin driver supports the Marvell Yukon and SysKonnect +-SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. It has +-been tested with Linux on Intel/x86 machines. ++The sk98lin driver supports the Marvell Yukon, Yukon EC/FE, Yukon 2 ++and SysKonnect SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. ++It has been tested with Linux on Intel/x86, x86_64 and IA64 machines. + *** + ++2 Supported Functions ++====================== ++ ++The following functions are supported by the driver: + +-2 Required Files ++ NOTE 1: The hardware support depends on the used card ++ ++ - RX/TX HW Checksum ++ - Hardware interrupt moderation (static/dynamic) ++ - Transmit poll ++ - Zerocopy/Scatter-Gather ++ - Ethtool support ++ - Wake on Lan (Magic Packet only) ++ - DualNet ++ ++ ++3 Required Files + ================= + + The linux kernel source. +@@ -40,16 +58,14 @@ + *** + + +-3 Installation ++4 Installation + =============== + + It is recommended to download the latest version of the driver from the +-SysKonnect web site www.syskonnect.com. If you have downloaded the latest +-driver, the Linux kernel has to be patched before the driver can be +-installed. For details on how to patch a Linux kernel, refer to the +-patch.txt file. ++SysKonnect web site www.syskonnect.com. For details on Installation ++Instructions for sk98lin Driver, please refer to the README.txt file. + +-3.1 Driver Installation ++4.1 Driver Installation + ------------------------ + + The following steps describe the actions that are required to install +@@ -91,7 +107,7 @@ + with (M) + 5. Execute the command "make modules". + 6. Execute the command "make modules_install". +- The appropriate modules will be installed. ++ The appropiate modules will be installed. + 7. Reboot your system. + + +@@ -110,13 +126,13 @@ + + NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx + adapter installed, the adapters will be listed as 'eth0', +- 'eth1', 'eth2', etc. +- For each adapter, repeat steps 3 and 4 below. ++ 'eth1', 'eth2', etc. ++ For each adapter, repeat steps 3 and 4 below. + + NOTE 2: If you have other Ethernet adapters installed, your Marvell + Yukon or SysKonnect SK-98xx adapter will be mapped to the +- next available number, e.g. 'eth1'. The mapping is executed +- automatically. ++ next available number, e.g. 'eth1'. The mapping is executed ++ automatically. + The module installation message (displayed either in a system + log file or on the console) prints a line for each adapter + found containing the corresponding 'ethX'. +@@ -153,7 +169,7 @@ + 1. Execute the command "ifconfig eth0 down". + 2. Execute the command "rmmod sk98lin". + +-3.2 Inclusion of adapter at system start ++4.2 Inclusion of adapter at system start + ----------------------------------------- + + Since a large number of different Linux distributions are +@@ -165,7 +181,8 @@ + + *** + +-4 Driver Parameters ++ ++5 Driver Parameters + ==================== + + Parameters can be set at the command line after the module has been +@@ -174,13 +191,13 @@ + to the driver module. + + If you use the kernel module loader, you can set driver parameters +-in the file /etc/modprobe.conf (or /etc/modules.conf in 2.4 or earlier). ++in the file /etc/modules.conf (or old name: /etc/conf.modules). + To set the driver parameters in this file, proceed as follows: + + 1. Insert a line of the form : + options sk98lin ... + For "...", the same syntax is required as described for the command +- line parameters of modprobe below. ++ line paramaters of modprobe below. + 2. To activate the new parameters, either reboot your computer + or + unload and reload the driver. +@@ -208,7 +225,7 @@ + more adapters, adjust this and recompile. + + +-4.1 Per-Port Parameters ++5.1 Per-Port Parameters + ------------------------ + + These settings are available for each port on the adapter. +@@ -245,7 +262,7 @@ + This parameters is only relevant if auto-negotiation for this port is + not set to "Sense". If auto-negotiation is set to "On", all three values + are possible. If it is set to "Off", only "Full" and "Half" are allowed. +-This parameter is useful if your link partner does not support all ++This parameter is usefull if your link partner does not support all + possible combinations. + + Flow Control +@@ -268,6 +285,18 @@ + + NOTE: This parameter is ignored if auto-negotiation is set to "Off". + ++Broadcast Priority ++------------------- ++Parameter: BroadcastPrio ++Values: On, Off ++Default: Off ++ ++This parameter specifies whether received broadcast packets have the ++highest priority for the port switch decision ("Off") or not ("On"). ++ ++NOTE: This parameter is only valid for dual port adapters. ++ ++ + Role in Master-Slave-Negotiation (1000Base-T only) + -------------------------------------------------- + Parameter: Role_? +@@ -282,13 +311,13 @@ + with this parameter. + + +-4.2 Adapter Parameters ++5.2 Adapter Parameters + ----------------------- + +-Connection Type (SK-98xx V2.0 copper adapters only) ++Connection Type (for copper adapters only) + --------------- + Parameter: ConType +-Values: Auto, 100FD, 100HD, 10FD, 10HD ++Values: Auto, 1000FD, 100FD, 100HD, 10FD, 10HD + Default: Auto + + The parameter 'ConType' is a combination of all five per-port parameters +@@ -302,6 +331,7 @@ + ConType | DupCap AutoNeg FlowCtrl Role Speed + ----------+------------------------------------------------------ + Auto | Both On SymOrRem Auto Auto ++ 1000FD | Full Off None Auto (ignored) 1000 + 100FD | Full Off None Auto (ignored) 100 + 100HD | Half Off None Auto (ignored) 100 + 10FD | Full Off None Auto (ignored) 10 +@@ -320,7 +350,7 @@ + Values: None, Static, Dynamic + Default: None + +-Interrupt moderation is employed to limit the maximum number of interrupts ++Interrupt moderation is employed to limit the maxmimum number of interrupts + the driver has to serve. That is, one or more interrupts (which indicate any + transmit or receive packet to be processed) are queued until the driver + processes them. When queued interrupts are to be served, is determined by the +@@ -346,7 +376,7 @@ + depending on the load of the system. If the driver detects that the + system load is too high, the driver tries to shield the system against + too much network load by enabling interrupt moderation. If - at a later +- time - the CPU utilization decreases again (or if the network load is ++ time - the CPU utilizaton decreases again (or if the network load is + negligible) the interrupt moderation will automatically be disabled. + + Interrupt moderation should be used when the driver has to handle one or more +@@ -364,9 +394,9 @@ + Values: 30...40000 (interrupts per second) + Default: 2000 + +-This parameter is only used if either static or dynamic interrupt moderation +-is used on a network adapter card. Using this parameter if no moderation is +-applied will lead to no action performed. ++This parameter is only used, if either static or dynamic interrupt moderation ++is used on a network adapter card. Using this paramter if no moderation is ++applied, will lead to no action performed. + + This parameter determines the length of any interrupt moderation interval. + Assuming that static interrupt moderation is to be used, an 'IntsPerSec' +@@ -379,7 +409,6 @@ + is tremendous. On the other hand, selecting a very short moderation time might + compensate the use of any moderation being applied. + +- + Preferred Port + -------------- + Parameter: PrefPort +@@ -394,7 +423,7 @@ + ------------------------------------------------ + Parameter: RlmtMode + Values: CheckLinkState,CheckLocalPort, CheckSeg, DualNet +-Default: CheckLinkState ++Default: CheckLinkState (DualNet on dual port adapters) + + RLMT monitors the status of the port. If the link of the active port + fails, RLMT switches immediately to the standby link. The virtual link is +@@ -429,10 +458,100 @@ + where a network path between the ports on one adapter exists. + Moreover, they are not designed to work where adapters are connected + back-to-back. ++ ++LowLatency ++---------- ++Parameter: LowLatency ++Values: On, Off ++Default: Off ++ ++This is used to reduce the packet latency time of the adapter. Setting the ++LowLatency parameter to 'On' forces the adapter to pass any received packet ++immediately to upper network layers and to send out any transmit packet as ++fast as possible. ++ ++NOTE 1: The system load increases if LowLatency is set to 'On' and a lot ++ of data packets are transmitted and received. ++ ++NOTE 2: This parameter is only used on adapters which are based on ++ PCI Express compatible chipsets. ++*** ++ ++ ++6 Ethtool Support ++================== ++ ++The sk98lin driver provides built-in ethtool support. The ethtool ++can be used to display or modify interface specific configurations. ++ ++Ethtool commands are invoked using a single parameter which reflects ++the requested ethtool command plus an optional number of parameters ++which belong to the desired command. ++ ++It is not the intention of this section to explain the ethtool command ++line tool and all its options. For further information refer to the ++manpage of the ethtool. This sections describes only the sk98lin ++driver supported ethtool commands. ++ ++Pause Parameters ++---------------- ++Query command: -a ++Set command: -A [autoneg on|off] [rx on|off] [tx on|off] ++Sample: ethtool -A eth0 rx off tx off ++ ++Coalescing Parameters ++--------------------- ++Query command: -c ++Set command: -C [sample-interval I] ++ [rx-usecs N] [tx-usecs N] ++ [rx-usecs-low N] [tx-usecs-low N] ++ [rx-usecs-high N] [tx-usecs-high N] ++Parameter: I = Length of sample interval, in seconds ++ (supported values range from 1...10) ++ N = Length of coalescing interval, in microseconds ++ (supported values range from 25...33,333) ++Sample: ethtool -C eth2 rx-usecs 500 tx-usecs 500 ++ ++NOTE: The sk98lin driver does not support different settings ++ for the rx and tx interrupt coalescing parameters. ++ ++Driver Information ++------------------ ++Query command: -i ++Sample: ethtool -i eth1 ++ ++Checksumming Parameters ++----------------------- ++Query command: -k ++Set command: -K [rx on|off] [tx on|off] [sg on|off] ++Sample: ethtool -K eth0 sg off ++ ++Locate NIC Command ++------------------ ++Query command: -p [N] ++Parameter: N = Amount of time to perform locate NIC command, in seconds ++Sample: ethtool -p 10 eth1 ++ ++Driver-specific Statistics ++-------------------------- ++Query command: -S ++Sample: ethtool -S eth0 ++ ++Setting Parameters ++------------------ ++Set command: -s [speed 10|100|1000] [duplex half|full] ++ [autoneg on|off] [wol gd] ++Sample: ethtool -s eth2 wol d ++ ++NOTE: If cable is disconnected, please set the speed and duplex mode ++ if you disable/enable autonegotiation ++ ++NOTE: To set back to the default values use the "autoneg on" command. ++ Sample: ethtool -s eth2 autoneg on + *** + + +-5 Large Frame Support ++7 Large Frame Support + ====================== + + The driver supports large frames (also called jumbo frames). Using large +@@ -444,10 +563,10 @@ + ifconfig eth0 mtu 9000 + This will only work if you have two adapters connected back-to-back + or if you use a switch that supports large frames. When using a switch, +-it should be configured to allow large frames and auto-negotiation should +-be set to OFF. The setting must be configured on all adapters that can be +-reached by the large frames. If one adapter is not set to receive large +-frames, it will simply drop them. ++it should be configured to allow large frames. The setting must be ++configured on all adapters that can be reached by the large frames. ++If one adapter is not set to receive large frames, it will simply drop ++them. + + You can switch back to the standard ethernet frame size by executing the + following command: +@@ -459,7 +578,7 @@ + *** + + +-6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) ++8 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) + ================================================================== + + The Marvell Yukon/SysKonnect Linux drivers are able to support VLAN and +@@ -477,14 +596,27 @@ + cause problems when unloading the driver. + + +-7 Troubleshooting +-================== ++9 Wake on Lan support ++====================== ++ ++The sk98lin driver supports wake up from suspend mode with MagicPacket ++on APM systems. Wake on Lan support is enabled by default. To disable it ++please use the ethtool. ++ ++NOTE 1: APM support has to be enabled in BIOS and in the kernel. ++ ++NOTE 2: Refer to the kernel documentation for additional requirements ++ regarding APM support. ++ ++ ++10 Troubleshooting ++=================== + + If any problems occur during the installation process, check the + following list: + + +-Problem: The SK-98xx adapter cannot be found by the driver. ++Problem: The SK-98xx adapter can not be found by the driver. + Solution: In /proc/pci search for the following entry: + 'Ethernet controller: SysKonnect SK-98xx ...' + If this entry exists, the SK-98xx or SK-98xx V2.0 adapter has +@@ -497,12 +629,12 @@ + www.syskonnect.com + + Some COMPAQ machines have problems dealing with PCI under Linux. +- This problem is described in the 'PCI howto' document ++ Linux. This problem is described in the 'PCI howto' document + (included in some distributions or available from the + web, e.g. at 'www.linux.org'). + + +-Problem: Programs such as 'ifconfig' or 'route' cannot be found or the ++Problem: Programs such as 'ifconfig' or 'route' can not be found or the + error message 'Operation not permitted' is displayed. + Reason: You are not logged in as user 'root'. + Solution: Logout and login as 'root' or change to 'root' via 'su'. +diff -ruN linux/drivers/net/Kconfig linux-new/drivers/net/Kconfig +--- linux/drivers/net/Kconfig 2007-08-07 19:40:14.025085874 +0200 ++++ linux-new/drivers/net/Kconfig 2007-08-07 20:15:44.595494870 +0200 +@@ -2252,92 +2252,35 @@ + To compile this driver as a module, choose M here: the module + will be called sky2. This is recommended. + ++ + config SK98LIN +- tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)" ++ tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support" + depends on PCI + ---help--- + Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx + compliant Gigabit Ethernet Adapter. +- +- This driver supports the original Yukon chipset. This driver is +- deprecated and will be removed from the kernel in the near future, +- it has been replaced by the skge driver. skge is cleaner and +- seems to work better. +- +- This driver does not support the newer Yukon2 chipset. A separate +- driver, sky2, is provided to support Yukon2-based adapters. +- +- The following adapters are supported by this driver: +- - 3Com 3C940 Gigabit LOM Ethernet Adapter +- - 3Com 3C941 Gigabit LOM Ethernet Adapter +- - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter +- - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter +- - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter +- - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter +- - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter +- - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter +- - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter +- - Allied Telesyn AT-2971T Gigabit Ethernet Adapter +- - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45 +- - EG1032 v2 Instant Gigabit Network Adapter +- - EG1064 v2 Instant Gigabit Network Adapter +- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) +- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron) +- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus) +- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS) +- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox) +- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn) +- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte) +- - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill) +- - Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel) +- - Marvell RDK-8001 Adapter +- - Marvell RDK-8002 Adapter +- - Marvell RDK-8003 Adapter +- - Marvell RDK-8004 Adapter +- - Marvell RDK-8006 Adapter +- - Marvell RDK-8007 Adapter +- - Marvell RDK-8008 Adapter +- - Marvell RDK-8009 Adapter +- - Marvell RDK-8010 Adapter +- - Marvell RDK-8011 Adapter +- - Marvell RDK-8012 Adapter +- - Marvell RDK-8052 Adapter +- - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit) +- - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit) +- - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L) +- - SK-9521 10/100/1000Base-T Adapter +- - SK-9521 V2.0 10/100/1000Base-T Adapter +- - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T) +- - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter +- - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link) +- - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX) +- - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter +- - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link) +- - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX) +- - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter +- - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link) +- - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter +- - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition) +- - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter +- - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link) +- - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX) +- - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter +- - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) +- - SMC EZ Card 1000 (SMC9452TXV.2) + + The adapters support Jumbo Frames. + The dual link adapters support link-failover and dual port features. + Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support + the scatter-gather functionality with sendfile(). Please refer to +- for more information about ++ Documentation/networking/sk98lin.txt for more information about + optional driver parameters. + Questions concerning this driver may be addressed to: +- ++ linux@syskonnect.de + + If you want to compile this driver as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), +- say M here and read . The module will +- be called sk98lin. This is recommended. ++ say M here and read Documentation/modules.txt. This is recommended. ++ The module will be called sk98lin. This is recommended. ++ ++config SK98LIN_NAPI ++ bool "Use Rx polling (NAPI)" ++ depends on SK98LIN ++ help ++ NAPI is a new driver API designed to reduce CPU and interrupt load ++ when the driver is receiving lots of packets from the card. ++ + + config VIA_VELOCITY + tristate "VIA Velocity support" -- 2.44.0