diff options
-rw-r--r-- | package/ar7-net/Makefile | 51 | ||||
-rw-r--r-- | target/linux/ar7-2.4/Makefile | 5 | ||||
-rw-r--r-- | target/linux/ar7-2.4/config | 7 | ||||
-rw-r--r-- | target/linux/ar7-2.4/patches/003-net_driver_cpmac.patch | 13341 |
4 files changed, 51 insertions, 13353 deletions
diff --git a/package/ar7-net/Makefile b/package/ar7-net/Makefile new file mode 100644 index 0000000..89ce239 --- /dev/null +++ b/package/ar7-net/Makefile @@ -0,0 +1,51 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +# $Id:$ + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=avalanche-cpmac +PKG_VERSION:=0.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=http://downloads.openwrt.org/sources +PKG_MD5SUM:=ce46849a8f1055cef09c59c6bdb7f86a +PKG_CAT:=bzcat + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define Package/kmod-avalanche-cpmac + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@LINUX_2_4_AR7 +kmod-atm + DEFAULT:=y + TITLE:=AR7 ADSL driver (Annex A) + DESCRIPTION:=The AR7 ADSL driver for Annex A + VERSION:=$(PKG_VERSION)+$(LINUX_VERSION)-$(BOARD)-$(PKG_RELEASE) +endef + +define Build/Compile + $(MAKE) -C "$(LINUX_DIR)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + SUBDIRS="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="-DCONFIG_AVALANCHE_CPMAC_AUTO -DCONFIG_MIPS_CPMAC_INIT_BUF_MALLOC" \ + modules +endef + +define Package/kmod-avalanche-cpmac/install + install -m0755 -d $(1)/lib/modules/$(LINUX_VERSION) + $(CP) $(PKG_BUILD_DIR)/avalanche_cpmac.$(LINUX_KMOD_SUFFIX) \ + $(1)/lib/modules/$(LINUX_VERSION) +endef + +$(eval $(call BuildPackage,kmod-avalanche-cpmac)) diff --git a/target/linux/ar7-2.4/Makefile b/target/linux/ar7-2.4/Makefile index aececf8..92e49d2 100644 --- a/target/linux/ar7-2.4/Makefile +++ b/target/linux/ar7-2.4/Makefile @@ -12,11 +12,6 @@ LINUX_KERNEL_MD5SUM:=38f4d0830e95a20f4bfed17622d5557c include ./config include $(INCLUDE_DIR)/kernel.mk - -$(eval $(call KMOD_template,CPMAC,cpmac,\ - $(MODULES_DIR)/kernel/drivers/net/avalanche_cpmac/avalanche_cpmac.o \ -,CONFIG_MIPS_AVALANCHE_CPMAC,,10,avalanche_cpmac)) - include $(INCLUDE_DIR)/kernel-build.mk $(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked diff --git a/target/linux/ar7-2.4/config b/target/linux/ar7-2.4/config index 5f7a151..47e57a9 100644 --- a/target/linux/ar7-2.4/config +++ b/target/linux/ar7-2.4/config @@ -640,12 +640,6 @@ CONFIG_NET_RANDOM=y # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MIPS_AVALANCHE_CPMAC=m -CONFIG_MIPS_CPMAC_INIT_BUF_MALLOC=y -CONFIG_MIPS_CPMAC_PORTS=1 -CONFIG_AVALANCHE_CPMAC_AUTO=y -# CONFIG_AVALANCHE_LOW_CPMAC is not set -# CONFIG_AVALANCHE_HIGH_CPMAC is not set # CONFIG_SUNLANCE is not set # CONFIG_SUNBMAC is not set # CONFIG_SUNQE is not set @@ -721,7 +715,6 @@ CONFIG_SHAPER=m # ATM drivers # # CONFIG_ATM_TCP is not set -CONFIG_MIPS_SANGAM_ATM=m # # Amateur Radio support diff --git a/target/linux/ar7-2.4/patches/003-net_driver_cpmac.patch b/target/linux/ar7-2.4/patches/003-net_driver_cpmac.patch deleted file mode 100644 index 3d6d1e5..0000000 --- a/target/linux/ar7-2.4/patches/003-net_driver_cpmac.patch +++ /dev/null @@ -1,13341 +0,0 @@ -diff -urN linux.old/drivers/net/avalanche_cpmac/cpcommon_cpmac.c linux.dev/drivers/net/avalanche_cpmac/cpcommon_cpmac.c ---- linux.old/drivers/net/avalanche_cpmac/cpcommon_cpmac.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/cpcommon_cpmac.c 2005-07-12 02:48:41.996601000 +0200 -@@ -0,0 +1,728 @@ -+#ifndef _INC_CPCOMMON_C -+#define _INC_CPCOMMON_C -+ -+#ifdef _CPHAL_CPMAC -+#include "cpremap_cpmac.c" -+#endif -+ -+#ifdef _CPHAL_AAL5 -+#include "cpremap_cpaal5.c" -+#endif -+ -+#ifdef _CPHAL_CPSAR -+#include "cpremap_cpsar.c" -+#endif -+ -+#ifdef _CPHAL_AAL2 -+#include "cpremap_cpaal2.c" -+#endif -+ -+/** -+@defgroup Common_Config_Params Common Configuration Parameters -+ -+This section documents the configuration parameters that are valid across -+all CPHAL devices. -+@{ -+*/ -+/** This is the debug level. The field is bit defined, such that the user -+should set to 1 all the bits corresponding to desired debug outputs. The following -+are the meanings for each debug bit: -+- bit0 (LSB): CPHAL Function Trace -+- b1 : OS Function call trace -+- b2 : Critical section entry/exit -+- b3 : Memory allocation/destruction -+- b4 : Detailed information in Rx path -+- b5 : Detailed information in Tx path -+- b6 : Extended error information -+- b7 : General info -+*/ -+static const char pszDebug[] = "debug"; -+/** CPU Frequency. */ -+/*static const char pszCpuFreq[] = "CpuFreq";*/ /*MJH-030403*/ -+/** Base address for the module. */ -+static const char pszBase[] = "base"; -+/** Reset bit for the module. */ -+static const char pszResetBit[] = "reset_bit"; -+/** Reset base address for the module. */ -+static const char pszResetBase[] = "ResetBase"; -+/** Interrupt line for the module. */ -+static const char pszIntLine[] = "int_line"; -+/** VLYNQ offset for the module. Disregard if not using VLYNQ. */ -+static const char pszOffset[] = "offset"; -+/** The OS may "Get" this parameter, which is a pointer -+ to a character string that indicates the version of CPHAL. */ -+static const char pszVer[] = "Version"; -+/*@}*/ -+ -+/** -+@defgroup Common_Control_Params Common Keys for [os]Control() -+ -+This section documents the keys used with the OS @c Control() interface that -+are required by CPHAL devices. -+ -+@{ -+*/ -+/** Used to wait for an integer number of clock ticks, given as an integer -+ pointer in the @p Value parameter. No actions are defined. */ -+static const char pszSleep[] = "Sleep"; -+/** Requests the OS to flush it's IO buffers. No actions are defined. */ -+static const char pszSioFlush[] = "SioFlush"; -+/*@}*/ -+ -+static const char pszStateChange[] = "StateChange"; -+static const char pszStatus[] = "Status"; -+ -+static const char pszGET[] = "Get"; -+static const char pszSET[] = "Set"; -+static const char pszCLEAR[] = "Clear"; -+static const char pszNULL[] = ""; -+static const char pszLocator[] = "Locator"; -+static const char pszOff[] = "Off"; -+static const char pszOn[] = "On"; -+static const char hcMaxFrags[] = "MaxFrags"; -+ -+#ifdef _CPHAL_CPMAC -+ -+/* New method for string constants */ -+const char hcClear[] = "Clear"; -+const char hcGet[] = "Get"; -+const char hcSet[] = "Set"; -+ -+const char hcTick[] = "Tick"; -+ -+static const CONTROL_KEY KeyCommon[] = -+ { -+ {"" , enCommonStart}, -+ {pszStatus , enStatus}, -+ {pszOff , enOff}, -+ {pszOn , enOn}, -+ {pszDebug , enDebug}, -+ {hcCpuFrequency , enCpuFreq}, /*MJH~030403*/ -+ {"" , enCommonEnd} -+ }; -+#endif -+ -+/** -+@defgroup Common_Statistics Statistics -+ -+A broad array of module statistics is available. Statistics values are accessed -+through the @c Control() interface of the CPHAL. There are 5 different levels -+of statistics, each of which correspond to a unique set of data. Furthermore, -+certain statistics data is indexed by using a channel number and Tx queue number. -+The following is a brief description of each statistics level, along with the -+indexes used for the level: -+ -+- Level 0: Hardware Statistics (index with channel) -+- Level 1: CPHAL Software Statistics (channel, queue) -+- Level 2: CPHAL Flags (channel, queue) -+- Level 3: CPHAL Channel Configuration (channel) -+- Level 4: CPHAL General Configuration (no index) -+ -+The caller requests statistics information by providing a Key string to the -+@c Control() API in the following format: "Stats;[Level #];[Ch #];[Queue #]". -+The only valid Action parameter for statistics usage is "Get". -+ -+Code Examples: -+@code -+unsigned int *StatsData; -+ -+# Get Level 0 stats for Channel 1 -+HalFunc->Control(OsDev->HalDev, "Stats;0;1", "Get", &StatsData); -+ -+# Get Level 2 stats for Channel 0, Queue 0 -+HalFunc->Control(OsDev->HalDev, "Stats;2;0;0", "Get", &StatsData); -+ -+# Get Level 4 stats -+HalFunc->Control(OsDev->HalDev, "Stats;4", "Get", &StatsData); -+@endcode -+ -+The information returned in the Value parameter of @c Control() is an -+array of pointers to strings. The pointers are arranged in pairs. -+The first pointer is a pointer to a name string for a particular statistic. -+The next pointer is a pointer to a string containing the representation of -+the integer statistic value corresponding to the first pointer. This is followed -+by another pair of pointers, and so on, until a NULL pointer is encountered. The -+following is example code for processing the statistics data. Note that the OS -+is responsible for freeing the memory passed back through the Value parameter of -+@c Control(). -+ -+@code -+unsigned int *StatsData; -+ -+# Get Level 0 stats for Channel 1 -+HalFunc->Control(OsDev->HalDev, "Stats;0;1", "Get", &StatsData); -+ -+# output Statistics data -+PrintStats(StatsData); -+ -+# the upper layer is responsible for freeing stats info -+free(&StatsPtr); -+ -+... -+ -+void PrintStats(unsigned int *StatsPtr) -+ { -+ while(*StatsPtr) -+ { -+ printf("%20s:", (char *)*StatsPtr); -+ StatsPtr++; -+ printf("%11s\n", (char *)*StatsPtr); -+ StatsPtr++; -+ } -+ MySioFlush(); -+ } -+@endcode -+ -+Within each statistics level, there are several statistics defined. The statistics that -+are common to every CPPI module are listed below. In addition, each module may define -+extra statistics in each level, which will be documented within the module-specific -+documentation appendices. -+ -+- Level 0 Statistics -+ - All level 0 statistics are module-specific. -+- Level 1 Statistics (CPHAL Software Statistics) -+ - DmaLenErrors: Incremented when the port DMA's more data than expected (per channel). (AAL5 Only) -+ - TxMisQCnt: Incremented when host queues a packet for transmission as the port finishes -+transmitting the previous last packet in the queue (per channel and queue). -+ - RxMisQCnt: Incremented when host queues adds buffers to a queue as the port finished the -+reception of the previous last packet in the queue (per channel). -+ - TxEOQCnt: Number of times the port has reached the end of the transmit queue (per channel and queue). -+ - RxEOQCnt: Number of times the port has reached the end of the receive queue (per channel). -+ - RxPacketsServiced: Number of received packets (per channel). -+ - TxPacketsServiced: Number of transmitted packets (per channel and queue). -+ - RxMaxServiced: Maximum number of packets that the CPHAL receive interrupt has serviced at a time (per channel). -+ - TxMaxServiced: Maximum number of packets that the CPHAL transmit interrupt has serviced at a time (per channel and queue). -+ - RxTotal: Total number of received packets, all channels. -+ - TxTotal: Total number of transmitted packets, all channels and queues. -+- Level 2 Statistics (CPHAL Flags) -+ - RcbPool: Pointer to receive descriptor pool (per channel). -+ - RxActQueueCount: Number of buffers currently available for receive (per channel). -+ - RxActQueueHead: Pointer to first buffer in receive queue (per channel). -+ - RxActQueueTail: Pointer to last buffer in receive queue (per channel). -+ - RxActive: 0 if inactive (no buffers available), or 1 if active (buffers available). -+ - RcbStart: Pointer to block of receive descriptors. -+ - RxTeardownPending: 1 if Rx teardown is pending but incomplete, 0 otherwise. -+ - TcbPool: Pointer to transmit descriptor pool (per channel and queue). -+ - TxActQueueCount: Number of buffers currently queued to be transmitted (per channel and queue). -+ - TxActQueueHead: Pointer to first buffer in transmit queue (per channel and queue). -+ - TxActQueueTail: Pointer to last buffer in transmit queue (per channel and queue). -+ - TxActive: 0 if inactive (no buffers to send), or 1 if active (buffers queued to send). -+ - TcbStart: Pointer to block of transmit descriptors. -+ - TxTeardownPending: 1 if Tx teardown is pending but incomplete, 0 otherwise. -+- Level 3 Statistics (CPHAL Channel Configuration) -+ - RxBufSize: Rx buffer size. -+ - RxBufferOffset: Rx buffer offset. -+ - RxNumBuffers: Number of Rx buffers. -+ - RxServiceMax: Maximum number of receive packets to service at a time. -+ - TxNumBuffers: Number of Tx buffer descriptors. -+ - TxNumQueues: Number of Tx queues to use. -+ - TxServiceMax: Maximum number of transmit packets to service at a time. -+- Level 4 Statistics (CPHAL General Configuration) -+ - Base Address: Base address of the module. -+ - Offset (VLYNQ): VLYNQ relative module offset. -+ - Interrupt Line: Interrupt number. -+ - Debug: Debug flag, 1 to enable debug. -+ - Inst: Instance number. -+*/ -+ -+/* -+ Data Type 0 = int display -+ Data Type 1 = hex display -+ Data Type 2 = channel structure, int display -+ Data Type 3 = queue index and int display -+ Data Type 4 = queue index and hex display -+*/ -+#if (defined(_CPHAL_AAL5) || defined(_CPHAL_CPMAC)) /* +GSG 030307 */ -+static STATS_TABLE StatsTable0[] = -+ { -+#ifdef _CPHAL_AAL5 -+ /* Name , Data Ptr, Data Type */ -+ {"Crc Errors", 0, 0}, -+ {"Len Errors", 0, 0}, -+ {"Abort Errors", 0, 0}, -+ {"Starv Errors", 0, 0} -+#endif -+#ifdef _CPHAL_CPMAC -+ {"Rx Good Frames", 0, 0} -+#endif -+ }; -+ -+static STATS_TABLE StatsTable1[] = -+ { -+ /* Name , Data Ptr, Data Type */ -+ {"DmaLenErrors", 0, 0}, -+ {"TxMisQCnt", 0, 3}, -+ {"RxMisQCnt", 0, 0}, -+ {"TxEOQCnt", 0, 3}, -+ {"RxEOQCnt", 0, 0}, -+ {"RxPacketsServiced", 0, 0}, -+ {"TxPacketsServiced", 0, 3}, -+ {"RxMaxServiced", 0, 0}, -+ {"TxMaxServiced", 0, 3}, -+ {"RxTotal", 0, 0}, -+ {"TxTotal", 0, 0}, -+ }; -+ -+static STATS_TABLE StatsTable2[] = -+ { -+ /* Name , Data Ptr, Data Type */ -+ {"RcbPool", 0, 1}, -+ {"RxActQueueCount", 0, 0}, -+ {"RxActQueueHead", 0, 1}, -+ {"RxActQueueTail", 0, 1}, -+ {"RxActive", 0, 0}, -+ {"RcbStart", 0, 1}, -+ {"RxTeardownPending", 0, 0}, -+ {"TcbPool", 0, 4}, -+ {"TxActQueueCount", 0, 3}, -+ {"TxActQueueHead", 0, 4}, -+ {"TxActQueueTail", 0, 4}, -+ {"TxActive", 0, 3}, -+ {"TcbStart", 0, 4}, -+ {"TxTeardownPending", 0, 0} -+ }; -+ -+static STATS_TABLE StatsTable3[] = -+ { -+ /* Name , Data Ptr, Data Type */ -+ {"RxBufSize", 0, 2}, -+ {"RxBufferOffset", 0, 2}, -+ {"RxNumBuffers", 0, 2}, -+ {"RxServiceMax", 0, 2}, -+ {"TxNumBuffers", 0, 2}, -+ {"TxNumQueues", 0, 2}, -+ {"TxServiceMax", 0, 2}, -+#ifdef _CPHAL_AAL5 -+ {"CpcsUU", 0, 2}, -+ {"Gfc", 0, 2}, -+ {"Clp", 0, 2}, -+ {"Pti", 0, 2}, -+ {"DaMask", 0, 2}, -+ {"Priority", 0, 2}, -+ {"PktType", 0, 2}, -+ {"Vci", 0, 2}, -+ {"Vpi", 0, 2}, -+ {"CellRate", 0, 2}, -+ {"QosType", 0, 2}, -+ {"Mbs", 0, 2}, -+ {"Pcr", 0, 2} -+#endif -+ }; -+ -+static STATS_TABLE StatsTable4[] = -+ { -+ {"Base Address", 0, 1}, -+ {"Offset (VLYNQ)", 0, 0}, -+ {"Interrupt Line", 0, 0}, -+ {"Debug", 0, 0}, -+ {"Instance", 0, 0}, -+#ifdef _CPHAL_AAL5 -+ {"UniNni", 0, 0} -+#endif -+ }; -+ -+static STATS_DB StatsDb[] = -+ { -+ {(sizeof(StatsTable0)/sizeof(STATS_TABLE)), StatsTable0}, -+ {(sizeof(StatsTable1)/sizeof(STATS_TABLE)), StatsTable1}, -+ {(sizeof(StatsTable2)/sizeof(STATS_TABLE)), StatsTable2}, -+ {(sizeof(StatsTable3)/sizeof(STATS_TABLE)), StatsTable3}, -+ {(sizeof(StatsTable4)/sizeof(STATS_TABLE)), StatsTable4} -+ }; -+#endif /* +GSG 030307 */ -+ -+#ifdef _CPHAL_CPMAC /* +RC 3.02 */ -+static void resetWait(HAL_DEVICE *HalDev) -+ { /*+RC3.02*/ -+ const int TickReset=64; -+ osfuncSleep((int*)&TickReset); -+ } /*+RC3.02*/ -+#endif /* +RC 3.02 */ -+ -+/* I only define the reset base function for the modules -+ that can perform a reset. The AAL5 and AAL2 modules -+ do not perform a reset, that is done by the shared module -+ CPSAR */ -+#if defined(_CPHAL_CPSAR) || defined(_CPHAL_CPMAC) || defined(_CPHAL_VDMAVT) -+/* -+ * Determines the reset register address to be used for a particular device. -+ * It will search the current device entry for Locator information. If the -+ * device is a root device, there will be no Locator information, and the -+ * function will find and return the root reset register. If a Locator value -+ * is found, the function will search each VLYNQ device entry in the system -+ * looking for a matching Locator. Once it finds a VLYNQ device entry with -+ * a matching Locator, it will extract the "ResetBase" parameter from that -+ * VLYNQ device entry (thus every VLYNQ entry must have the ResetBase parameter). -+ * -+ * @param HalDev CPHAL module instance. (set by xxxInitModule()) -+ * @param ResetBase Pointer to integer address of reset register. -+ * -+ * @return 0 OK, Non-zero not OK -+ */ -+static int ResetBaseGet(HAL_DEVICE *HalDev, bit32u *ResetBase) -+ { -+ char *DeviceInfo = HalDev->DeviceInfo; -+ char *MyLocator, *NextLocator; -+ int Inst=1; -+ bit32u error_code; -+ -+#ifdef __CPHAL_DEBUG -+ if (DBG(0)) -+ { -+ dbgPrintf("[cpcommon]ResetBaseGet(HalDev:%08x, ResetBase:%08x)\n", (bit32u)HalDev, ResetBase); -+ osfuncSioFlush(); -+ } -+#endif -+ -+ error_code = HalDev->OsFunc->DeviceFindParmValue(DeviceInfo, "Locator", &MyLocator); -+ if (error_code) -+ { -+ /* if no Locator value, device is on the root, so get the "reset" device */ -+ error_code = HalDev->OsFunc->DeviceFindInfo(0, "reset", &DeviceInfo); -+ if (error_code) -+ { -+ return(EC_VAL_DEVICE_NOT_FOUND); -+ } -+ -+ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, "base", ResetBase); -+ if (error_code) -+ { -+ return(EC_VAL_BASE_ADDR_NOT_FOUND); -+ } -+ -+ *ResetBase = ((bit32u)PhysToVirtNoCache(*ResetBase)); -+ -+ /* found base address for root device, so we're done */ -+ return (EC_NO_ERRORS); -+ } -+ else -+ { -+ /* we have a Locator value, so the device is remote */ -+ -+ /* Find a vlynq device with a matching locator value */ -+ while ((HalDev->OsFunc->DeviceFindInfo(Inst, "vlynq", &DeviceInfo)) == EC_NO_ERRORS) -+ { -+ error_code = HalDev->OsFunc->DeviceFindParmValue(DeviceInfo, "Locator", &NextLocator); -+ if (error_code) -+ { -+ /* no Locator value for this VLYNQ, so move on */ -+ continue; -+ } -+ if (HalDev->OsFunc->Strcmpi(MyLocator, NextLocator)==0) -+ { -+ /* we have found a VLYNQ with a matching Locator, so extract the ResetBase */ -+ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, "ResetBase", ResetBase); -+ if (error_code) -+ { -+ return(EC_VAL_BASE_ADDR_NOT_FOUND); -+ } -+ *ResetBase = ((bit32u)PhysToVirtNoCache(*ResetBase)); -+ -+ /* found base address for root device, so we're done */ -+ return (EC_NO_ERRORS); -+ } -+ Inst++; -+ } /* while */ -+ } /* else */ -+ -+ return (EC_NO_ERRORS); -+ } -+#endif -+ -+#ifndef _CPHAL_AAL2 /* + RC 3.02 */ -+static bit32u ConfigGetCommon(HAL_DEVICE *HalDev) -+ { -+ bit32u ParmValue; -+ bit32 error_code; -+ char *DeviceInfo = HalDev->DeviceInfo; -+ -+#ifdef __CPHAL_DEBUG -+ if (DBG(0)) -+ { -+ dbgPrintf("[cpcommon]ConfigGetCommon(HalDev:%08x)\n", (bit32u)HalDev); -+ osfuncSioFlush(); -+ } -+#endif -+ -+ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszBase, &ParmValue); -+ if (error_code) -+ { -+ return(EC_FUNC_HAL_INIT|EC_VAL_BASE_ADDR_NOT_FOUND); -+ } -+ HalDev->dev_base = ((bit32u)PhysToVirtNoCache(ParmValue)); -+ -+#ifndef _CPHAL_AAL5 -+#ifndef _CPHAL_AAL2 -+ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszResetBit, &ParmValue); -+ if(error_code) -+ { -+ return(EC_FUNC_HAL_INIT|EC_VAL_RESET_BIT_NOT_FOUND); -+ } -+ HalDev->ResetBit = ParmValue; -+ -+ /* Get reset base address */ -+ error_code = ResetBaseGet(HalDev, &ParmValue); -+ if (error_code) -+ return(EC_FUNC_HAL_INIT|EC_VAL_RESET_BASE_NOT_FOUND); -+ HalDev->ResetBase = ParmValue; -+#endif -+#endif -+ -+#ifndef _CPHAL_CPSAR -+ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszIntLine,&ParmValue); -+ if (error_code) -+ { -+ return(EC_FUNC_HAL_INIT|EC_VAL_INTERRUPT_NOT_FOUND); -+ } -+ HalDev->interrupt = ParmValue; -+#endif -+ -+ /* only look for the offset if there is a Locator field, which indicates that -+ the module is a VLYNQ module */ -+ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszLocator,&ParmValue); -+ if (!error_code) -+ { -+ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszOffset,&ParmValue); -+ if (error_code) -+ { -+ return(EC_FUNC_HAL_INIT|EC_VAL_OFFSET_NOT_FOUND); -+ } -+ HalDev->offset = ParmValue; -+ } -+ else -+ HalDev->offset = 0; -+ -+ error_code = HalDev->OsFunc->DeviceFindParmUint(DeviceInfo, pszDebug, &ParmValue); -+ if (!error_code) HalDev->debug = ParmValue; -+ -+ return (EC_NO_ERRORS); -+ } -+#endif /* +RC 3.02 */ -+ -+#ifdef _CPHAL_CPMAC /* +RC 3.02 */ -+static void StatsInit(HAL_DEVICE *HalDev) /* +() RC3.02 */ -+ { -+ /* even though these statistics may be for multiple channels and -+ queues, i need only configure the pointer to the beginning -+ of the array, and I can index from there if necessary */ -+ -+#ifdef _CPHAL_AAL5 -+ StatsTable0[0].StatPtr = &HalDev->Stats.CrcErrors[0]; -+ StatsTable0[1].StatPtr = &HalDev->Stats.LenErrors[0]; -+ StatsTable0[2].StatPtr = &HalDev->Stats.AbortErrors[0]; -+ StatsTable0[3].StatPtr = &HalDev->Stats.StarvErrors[0]; -+ -+ StatsTable1[0].StatPtr = &HalDev->Stats.DmaLenErrors[0]; -+ StatsTable1[1].StatPtr = &HalDev->Stats.TxMisQCnt[0][0]; -+ StatsTable1[2].StatPtr = &HalDev->Stats.RxMisQCnt[0]; -+ StatsTable1[3].StatPtr = &HalDev->Stats.TxEOQCnt[0][0]; -+ StatsTable1[4].StatPtr = &HalDev->Stats.RxEOQCnt[0]; -+ StatsTable1[5].StatPtr = &HalDev->Stats.RxPacketsServiced[0]; -+ StatsTable1[6].StatPtr = &HalDev->Stats.TxPacketsServiced[0][0]; -+ StatsTable1[7].StatPtr = &HalDev->Stats.RxMaxServiced; -+ StatsTable1[8].StatPtr = &HalDev->Stats.TxMaxServiced[0][0]; -+ StatsTable1[9].StatPtr = &HalDev->Stats.RxTotal; -+ StatsTable1[10].StatPtr = &HalDev->Stats.TxTotal; -+#endif -+ -+#if (defined(_CPHAL_AAL5) || defined(_CPHAL_CPMAC)) -+ StatsTable2[0].StatPtr = (bit32u *)&HalDev->RcbPool[0]; -+ StatsTable2[1].StatPtr = &HalDev->RxActQueueCount[0]; -+ StatsTable2[2].StatPtr = (bit32u *)&HalDev->RxActQueueHead[0]; -+ StatsTable2[3].StatPtr = (bit32u *)&HalDev->RxActQueueTail[0]; -+ StatsTable2[4].StatPtr = &HalDev->RxActive[0]; -+ StatsTable2[5].StatPtr = (bit32u *)&HalDev->RcbStart[0]; -+ StatsTable2[6].StatPtr = &HalDev->RxTeardownPending[0]; -+ StatsTable2[7].StatPtr = (bit32u *)&HalDev->TcbPool[0][0]; -+ StatsTable2[8].StatPtr = &HalDev->TxActQueueCount[0][0]; -+ StatsTable2[9].StatPtr = (bit32u *)&HalDev->TxActQueueHead[0][0]; -+ StatsTable2[10].StatPtr = (bit32u *)&HalDev->TxActQueueTail[0][0]; -+ StatsTable2[11].StatPtr = &HalDev->TxActive[0][0]; -+ StatsTable2[12].StatPtr = (bit32u *)&HalDev->TcbStart[0][0]; -+ StatsTable2[13].StatPtr = &HalDev->TxTeardownPending[0]; -+ -+ StatsTable3[0].StatPtr = &HalDev->ChData[0].RxBufSize; -+ StatsTable3[1].StatPtr = &HalDev->ChData[0].RxBufferOffset; -+ StatsTable3[2].StatPtr = &HalDev->ChData[0].RxNumBuffers; -+ StatsTable3[3].StatPtr = &HalDev->ChData[0].RxServiceMax; -+ StatsTable3[4].StatPtr = &HalDev->ChData[0].TxNumBuffers; -+ StatsTable3[5].StatPtr = &HalDev->ChData[0].TxNumQueues; -+ StatsTable3[6].StatPtr = &HalDev->ChData[0].TxServiceMax; -+#ifdef _CPHAL_AAL5 -+ StatsTable3[7].StatPtr = &HalDev->ChData[0].CpcsUU; -+ StatsTable3[8].StatPtr = &HalDev->ChData[0].Gfc; -+ StatsTable3[9].StatPtr = &HalDev->ChData[0].Clp; -+ StatsTable3[10].StatPtr = &HalDev->ChData[0].Pti; -+ StatsTable3[11].StatPtr = &HalDev->ChData[0].DaMask; -+ StatsTable3[12].StatPtr = &HalDev->ChData[0].Priority; -+ StatsTable3[13].StatPtr = &HalDev->ChData[0].PktType; -+ StatsTable3[14].StatPtr = &HalDev->ChData[0].Vci; -+ StatsTable3[15].StatPtr = &HalDev->ChData[0].Vpi; -+ StatsTable3[16].StatPtr = &HalDev->ChData[0].TxVc_CellRate; -+ StatsTable3[17].StatPtr = &HalDev->ChData[0].TxVc_QosType; -+ StatsTable3[18].StatPtr = &HalDev->ChData[0].TxVc_Mbs; -+ StatsTable3[19].StatPtr = &HalDev->ChData[0].TxVc_Pcr; -+#endif -+#endif -+ -+ StatsTable4[0].StatPtr = &HalDev->dev_base; -+ StatsTable4[1].StatPtr = &HalDev->offset; -+ StatsTable4[2].StatPtr = &HalDev->interrupt; -+ StatsTable4[3].StatPtr = &HalDev->debug; -+ StatsTable4[4].StatPtr = &HalDev->Inst; -+ } -+#endif /* +RC 3.02 */ -+ -+#ifndef _CPHAL_CPSAR /* +RC 3.02 */ -+#ifndef _CPHAL_AAL2 /* +RC 3.02 */ -+/* -+ * Returns statistics information. -+ * -+ * @param HalDev CPHAL module instance. (set by xxxInitModule()) -+ * -+ * @return 0 -+ */ -+static int StatsGet(HAL_DEVICE *HalDev, void **StatPtr, int Index, int Ch, int Queue) -+ { -+ int Size; -+ bit32u *AddrPtr; -+ char *DataPtr; -+ STATS_TABLE *StatsTable; -+ int i, NumberOfStats; -+ -+#ifdef __CPHAL_DEBUG -+ if (DBG(0)) -+ { -+ dbgPrintf("[cpcommon]StatsGet(HalDev:%08x, StatPtr:%08x)\n", -+ (bit32u)HalDev, (bit32u)StatPtr); -+ osfuncSioFlush(); -+ } -+#endif -+ -+ StatsTable = StatsDb[Index].StatTable; -+ NumberOfStats = StatsDb[Index].NumberOfStats; -+ -+ Size = sizeof(bit32u)*((NumberOfStats*2)+1); -+ Size += (NumberOfStats*11); -+ *StatPtr = (bit32u *)HalDev->OsFunc->Malloc(Size); -+ -+ AddrPtr = (bit32u *) *StatPtr; -+ DataPtr = (char *)AddrPtr; -+ DataPtr += sizeof(bit32u)*((NumberOfStats*2)+1); -+ -+ for (i=0; i<NumberOfStats; i++) -+ { -+ *AddrPtr++ = (bit32u)StatsTable[i].StatName; -+ *AddrPtr++ = (bit32u)DataPtr; -+ if (&StatsTable[i].StatPtr[Ch] != 0) -+ { -+ switch(StatsTable[i].DataType) -+ { -+ case 0: -+ HalDev->OsFunc->Sprintf(DataPtr, "%d", (bit32u *)StatsTable[i].StatPtr[Ch]); -+ break; -+ case 1: -+ HalDev->OsFunc->Sprintf(DataPtr, "0x%x", (bit32u *)StatsTable[i].StatPtr[Ch]); -+ break; -+ case 2: -+ HalDev->OsFunc->Sprintf(DataPtr, "%d", *((bit32u *)StatsTable[i].StatPtr + (Ch * (sizeof(CHANNEL_INFO)/4)))); -+ break; -+ case 3: -+ HalDev->OsFunc->Sprintf(DataPtr, "%d", *((bit32u *)StatsTable[i].StatPtr + (Ch*MAX_QUEUE)+Queue)); -+ break; -+ case 4: -+ HalDev->OsFunc->Sprintf(DataPtr, "0x%x", *((bit32u *)StatsTable[i].StatPtr + (Ch*MAX_QUEUE)+Queue)); -+ break; -+ default: -+ /* invalid data type, due to CPHAL programming error */ -+ break; -+ } -+ } -+ else -+ { -+ /* invalid statistics pointer, probably was not initialized */ -+ } -+ DataPtr += HalDev->OsFunc->Strlen(DataPtr) + 1; -+ } -+ -+ *AddrPtr = (bit32u) 0; -+ -+ return (EC_NO_ERRORS); -+ } -+#endif /* +RC 3.02 */ -+#endif /* +RC 3.02 */ -+ -+#ifdef _CPHAL_CPMAC -+static void gpioFunctional(int base, int bit) -+ { /*+RC3.02*/ -+ bit32u GpioEnr = base + 0xC; -+ /* To make functional, set to zero */ -+ *(volatile bit32u *)(GpioEnr) &= ~(1 << bit); /*+RC3.02*/ -+ } /*+RC3.02*/ -+ -+ -+/*+RC3.02*/ -+/* Common function, Checks to see if GPIO should be in functional mode */ -+static void gpioCheck(HAL_DEVICE *HalDev, void *moduleDeviceInfo) -+ { /*+RC3.02*/ -+ int rc; -+ void *DeviceInfo; -+ char *pszMuxBits; -+ char pszMuxBit[20]; -+ char *pszTmp; -+ char szMuxBit[20]; -+ char *ptr; -+ int base; -+ int reset_bit; -+ int bit; -+ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; -+ -+ rc = OsFunc->DeviceFindParmValue(moduleDeviceInfo, "gpio_mux",&pszTmp); -+ if(rc) return; -+ /* gpio entry found, get GPIO register info and make functional */ -+ -+ /* temp copy until FinParmValue fixed */ -+ ptr = &szMuxBit[0]; -+ while ((*ptr++ = *pszTmp++)); -+ -+ pszMuxBits = &szMuxBit[0]; -+ -+ rc = OsFunc->DeviceFindInfo(0,"gpio",&DeviceInfo); -+ if(rc) return; -+ -+ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "base",&base); -+ if(rc) return; -+ -+ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "reset_bit",&reset_bit); -+ if(rc) return; -+ -+ /* If GPIO still in reset, then exit */ -+ if((VOLATILE32(HalDev->ResetBase) & (1 << reset_bit)) == 0) -+ return; -+ /* format for gpio_mux is gpio_mux = <int>;<int>;<int>...*/ -+ while (*pszMuxBits) -+ { -+ pszTmp = &pszMuxBit[0]; -+ if(*pszMuxBits == ';') pszMuxBits++; -+ while ((*pszMuxBits != ';') && (*pszMuxBits != '\0')) -+ { -+ osfuncSioFlush(); -+ /*If value not a number, skip */ -+ if((*pszMuxBits < '0') || (*pszMuxBits > '9')) -+ pszMuxBits++; -+ else -+ *pszTmp++ = *pszMuxBits++; -+ } -+ *pszTmp = '\0'; -+ bit = OsFunc->Strtoul(pszMuxBit, &pszTmp, 10); -+ gpioFunctional(base, bit); -+ resetWait(HalDev); /* not sure if this is needed */ -+ } -+ } /*+RC3.02*/ -+#endif /* CPMAC */ -+ -+#ifdef _CPHAL_AAL5 -+const char hcSarFrequency[] = "SarFreq"; -+#endif -+ -+#endif /* _INC */ -diff -urN linux.old/drivers/net/avalanche_cpmac/cpcommon_cpmac.h linux.dev/drivers/net/avalanche_cpmac/cpcommon_cpmac.h ---- linux.old/drivers/net/avalanche_cpmac/cpcommon_cpmac.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/cpcommon_cpmac.h 2005-07-12 02:48:41.996601000 +0200 -@@ -0,0 +1,79 @@ -+#ifndef _INC_CPCOMMON_H -+#define _INC_CPCOMMON_H -+ -+#define VOLATILE32(addr) (*(volatile bit32u *)(addr)) -+#ifndef dbgPrintf -+#define dbgPrintf HalDev->OsFunc->Printf -+#endif -+ -+#define ChannelUpdate(Field) if(HalChn->Field != 0xFFFFFFFF) HalDev->ChData[Ch].Field = HalChn->Field -+ -+#define DBG(level) (HalDev->debug & (1<<(level))) -+/* -+#define DBG0() DBG(0) -+#define DBG1() DBG(1) -+#define DBG2() DBG(2) -+#define DBG3() DBG(3) -+#define DBG4() DBG(4) -+#define DBG5() DBG(5) -+#define DBG6() DBG(6) -+#define DBG7() DBG(7) -+*/ -+ -+/* -+ * List of defined actions for use with Control(). -+ */ -+typedef enum -+ { -+ enGET=0, /**< Get the value associated with a key */ -+ enSET, /**< Set the value associates with a key */ -+ enCLEAR, /**<Clear the value */ -+ enNULL /**< No data action, used to initiate a service or send a message */ -+ }ACTION; -+ -+/* -+ * Enumerated hardware states. -+ */ -+typedef enum -+ { -+ enConnected=1, enDevFound, enInitialized, enOpened -+ }DEVICE_STATE; -+ -+typedef enum -+ { -+ enCommonStart=0, -+ /* General */ -+ enOff, enOn, enDebug, -+ /* Module General */ -+ enCpuFreq, -+ enStatus, -+ enCommonEnd -+ }COMMON_KEY; -+ -+typedef struct -+ { -+ const char *strKey; -+ int enKey; -+ }CONTROL_KEY; -+ -+typedef struct -+ { -+ char *StatName; -+ unsigned int *StatPtr; -+ int DataType; /* 0: int, 1: hex int, 2:channel data */ -+ }STATS_TABLE; -+ -+typedef struct -+ { -+ int NumberOfStats; -+ STATS_TABLE *StatTable; -+ }STATS_DB; -+ -+#define osfuncSioFlush() HalDev->OsFunc->Control(HalDev->OsDev,"SioFlush",pszNULL,0) -+#define osfuncSleep(Ticks) HalDev->OsFunc->Control(HalDev->OsDev,pszSleep,pszNULL,Ticks) -+#define osfuncStateChange() HalDev->OsFunc->Control(HalDev->OsDev,pszStateChange,pszNULL,0) -+ -+#define CHANNEL_NAMES {"Ch0","Ch1","Ch2","Ch3","Ch4","Ch5","Ch6","Ch7","Ch8","Ch9","Ch10","Ch11","Ch12","Ch13","Ch14","Ch15"} -+ -+#endif -+ -diff -urN linux.old/drivers/net/avalanche_cpmac/cpmac.c linux.dev/drivers/net/avalanche_cpmac/cpmac.c ---- linux.old/drivers/net/avalanche_cpmac/cpmac.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/cpmac.c 2005-07-22 01:03:12.609318544 +0200 -@@ -0,0 +1,2504 @@ -+/****************************************************************************** -+ * FILE PURPOSE: CPMAC Linux Network Device Driver Source -+ ****************************************************************************** -+ * FILE NAME: cpmac.c -+ * -+ * DESCRIPTION: CPMAC Network Device Driver Source -+ * -+ * REVISION HISTORY: -+ * -+ * Date Description Author -+ *----------------------------------------------------------------------------- -+ * 27 Nov 2002 Initial Creation Suraj S Iyer -+ * 09 Jun 2003 Updates for GA Suraj S Iyer -+ * 30 Sep 2003 Updates for LED, Reset stats Suraj S Iyer -+ * -+ * (C) Copyright 2003, Texas Instruments, Inc -+ *******************************************************************************/ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/delay.h> -+#include <linux/spinlock.h> -+#include <linux/proc_fs.h> -+#include <linux/ioport.h> -+#include <asm/io.h> -+ -+#include <linux/skbuff.h> -+ -+#include <asm/mips-boards/prom.h> -+#include <linux/string.h> -+#include <asm/uaccess.h> -+#include <linux/config.h> -+#include <asm/ar7/if_port.h> -+ -+extern void build_psp_config(void); -+extern void psp_config_cleanup(void); -+ -+#include "cpmacHalLx.h" -+#include "cpmac.h" -+ -+static struct net_device *last_cpmac_device = NULL; -+static int cpmac_devices_installed = 0; -+ -+void xdump( u_char* cp, int length, char* prefix ); -+ -+unsigned int cpmac_cpu_freq = 0; -+ -+char cpmac_version[] = "1.5"; -+ -+char l3_align_array[] = {0x02, 0x01, 0x00, 0x03}; -+#define L3_ALIGN(i) l3_align_array[i] -+ -+char add_for_4byte_align[] = {0x04, 0x03, 0x02, 0x05}; -+#define ADD_FOR_4BYTE_ALIGN(i) add_for_4byte_align[i] -+ -+ -+#define TPID 0x8100 -+#define IS_802_1Q_FRAME(byte_ptr) (*(unsigned short*)byte_ptr == TPID) -+#define TPID_START_OFFSET 12 -+#define TCI_START_OFFSET 14 -+#define TCI_LENGTH 2 -+#define TPID_LENGTH 2 -+#define TPID_END_OFFSET (TPID_START_OFFSET + TPID_LENGTH) -+#define TCI_END_OFFSET (TCI_START_OFFSET + TCI_LENGTH) -+#define IS_VALID_VLAN_ID(byte_ptr) ((*(unsigned short*)byte_ptr) && 0xfff != 0) -+#define MAX_CLASSES 8 -+#define MAX_USER_PRIORITY 8 -+#define CONTROL_802_1Q_SIZE (TCI_LENGTH + TPID_LENGTH) -+ -+unsigned char user_priority_to_traffic_class_map[MAX_CLASSES][MAX_USER_PRIORITY] = -+{ -+ {0, 0, 0, 1, 1, 1, 1, 2}, -+ {0, 0, 0, 0, 0, 0, 0, 0}, -+ {0, 0, 0, 0, 0, 0, 0, 1}, -+ {0, 0, 0, 1, 1, 2, 2, 3}, -+ {0, 1, 1, 2, 2, 3, 3, 4}, -+ {0, 1, 1, 2, 3, 4, 4, 5}, -+ {0, 1, 2, 3, 4, 5, 5, 6}, -+ {0, 1, 2, 3, 4, 5, 6, 7} -+}; -+ -+#define GET_802_1P_CHAN(x,y) user_priority_to_traffic_class_map[x][(y & 0xe0)] -+ -+#if defined(CONFIG_MIPS_SEAD2) -+unsigned long temp_base_address[2] = {0xa8610000, 0xa8612800}; -+unsigned long temp_reset_value[2] = { 1<< 17,1<<21}; -+#define RESET_REG_PRCR (*(volatile unsigned int *)((0xa8611600 + 0x0))) -+#define VERSION(base) (*(volatile unsigned int *)(((base)|0xa0000000) + 0x0)) -+#endif -+ -+MODULE_AUTHOR("Maintainer: Suraj S Iyer <ssiyer@ti.com>"); -+MODULE_DESCRIPTION("Driver for TI CPMAC"); -+ -+static int cfg_link_speed = 0; -+MODULE_PARM(cfg_link_speed, "i"); -+MODULE_PARM_DESC(cfg_link_speed, "Fixed speed of the Link: <100/10>"); -+ -+static char *cfg_link_mode = NULL; -+MODULE_PARM(cfg_link_mode, "1-3s"); -+MODULE_PARM_DESC(cfg_link_mode, "Fixed mode of the Link: <fd/hd>"); -+ -+int cpmac_debug_mode = 0; -+MODULE_PARM(debug_mode, "i"); -+MODULE_PARM_DESC(debug_mode, "Turn on the debug info: <0/1>. Default is 0 (off)"); -+ -+#define dbgPrint if (cpmac_debug_mode) printk -+#define errPrint printk -+ -+static int g_cfg_start_link_params = CFG_START_LINK_SPEED; -+static int g_init_enable_flag = 0; -+static int cfg_start_link_speed; -+static int cpmac_max_frame_size; -+ -+static struct net_device *g_dev_array[2]; -+static struct proc_dir_entry *gp_stats_file = NULL; -+ -+//----------------------------------------------------------------------------- -+// Statistics related private functions. -+//----------------------------------------------------------------------------- -+static int cpmac_p_update_statistics(struct net_device *p_dev, char *buf, int limit, int *len); -+static int cpmac_p_read_rfc2665_stats(char *buf, char **start, off_t offset, int count, int *eof, void *data); -+static int cpmac_p_read_link(char *buf, char **start, off_t offset, int count, int *eof, void *data); -+static int cpmac_p_read_stats(char* buf, char **start, off_t offset, int count, int *eof, void *data); -+static int cpmac_p_write_stats (struct file *fp, const char * buf, unsigned long count, void * data); -+static int cpmac_p_reset_statistics (struct net_device *p_dev); -+static int cpmac_p_get_version(char *buf, char **start, off_t offset, int count, int *eof, void *data); -+ -+static int cpmac_p_detect_manual_cfg(int, char*, int); -+static int cpmac_p_process_status_ind(CPMAC_PRIVATE_INFO_T *p_cpmac_priv); -+ -+//----------------------------------------------------------------------------- -+// Timer related private functions. -+//----------------------------------------------------------------------------- -+static int cpmac_p_timer_init(CPMAC_PRIVATE_INFO_T *p_cpmac_priv); -+// static int cpmac_timer_cleanup(CPMAC_PRIVATE_INFO_T *p_cpmac_priv); -+static void cpmac_p_tick_timer_expiry(unsigned long p_cb_param); -+inline static int cpmac_p_start_timer(struct timer_list *p_timer, unsigned int delay_ticks); -+static int cpmac_p_stop_timer(struct timer_list *p_timer); -+ -+//------------------------------------------------------------------------------ -+// Device configuration and setup related private functions. -+//------------------------------------------------------------------------------ -+static int cpmac_p_probe_and_setup_device(CPMAC_PRIVATE_INFO_T *p_cpmac_priv, unsigned long *p_dev_flags); -+static int cpmac_p_setup_driver_params(CPMAC_PRIVATE_INFO_T *p_cpmac_priv); -+inline static int cpmac_p_rx_buf_setup(CPMAC_RX_CHAN_INFO_T *p_rx_chan); -+ -+//----------------------------------------------------------------------------- -+// Net device related private functions. -+//----------------------------------------------------------------------------- -+static int cpmac_dev_init(struct net_device *p_dev); -+static int cpmac_dev_open( struct net_device *dev ); -+static int cpmac_dev_close(struct net_device *p_dev); -+static void cpmac_dev_mcast_set(struct net_device *p_dev); -+static int cpmac_dev_set_mac_addr(struct net_device *p_dev,void * addr); -+static int cpmac_dev_tx( struct sk_buff *skb, struct net_device *p_dev); -+static struct net_device_stats *cpmac_dev_get_net_stats (struct net_device *dev); -+ -+static int cpmac_p_dev_enable( struct net_device *p_dev); -+ -+ -+ -+/* Max. Reserved headroom in front of each packet so that the headers can be added to -+ * a packet. Worst case scenario would be PPPoE + 2684 LLC Encapsulation + Ethernet -+ * header. */ -+#define MAX_RESERVED_HEADROOM 20 -+ -+/* This is the MAX size of the static buffer for pure data. */ -+#define MAX_SIZE_STATIC_BUFFER 1600 -+ -+typedef struct DRIVER_BUFFER -+{ -+ /* Pointer to the allocated data buffer. This is the static data buffer -+ * allocated for the TI-Cache. 60 bytes out of the below buffer are required -+ * by the SKB shared info. We always reserve at least MAX_RESERVED_HEADROOM bytes -+ * so that the packets always have sufficient headroom. */ -+ char ptr_buffer[MAX_SIZE_STATIC_BUFFER + MAX_RESERVED_HEADROOM + 60]; -+ -+ /* List of the driver buffers. */ -+ struct DRIVER_BUFFER* ptr_next; -+}DRIVER_BUFFER; -+ -+typedef struct DRIVER_BUFFER_MCB -+{ -+ /* List of the driver buffers. */ -+ DRIVER_BUFFER* ptr_available_driver_buffers; -+ -+ /* The number of available buffers. */ -+ int num_available_buffers; -+}DRIVER_BUFFER_MCB; -+ -+DRIVER_BUFFER_MCB driver_mcb; -+int hybrid_mode = 0; -+ -+static union { -+ struct sk_buff_head list; -+ char pad[SMP_CACHE_BYTES]; -+} skb_head_pool[NR_CPUS]; -+ -+/************************************************************************** -+ * FUNCTION NAME : ti_release_skb -+ ************************************************************************** -+ * DESCRIPTION : -+ * This function is called from the ti_alloc_skb when there were no more -+ * data buffers available. The allocated SKB had to released back to the -+ * data pool. The reason why this function was moved from the fast path -+ * below was because '__skb_queue_head' is an inline function which adds -+ * a large code chunk on the fast path. -+ * -+ * NOTES : -+ * This function is called with interrupts disabled. -+ **************************************************************************/ -+static void ti_release_skb (struct sk_buff_head* list, struct sk_buff* skb) -+{ -+ __skb_queue_head(list, skb); -+ return; -+} -+ -+/************************************************************************** -+ * FUNCTION NAME : ti_alloc_skb -+ ************************************************************************** -+ * DESCRIPTION : -+ * The function is called to allocate memory from the static allocated -+ * TI-Cached memory pool. -+ * -+ * RETURNS : -+ * Allocated static memory buffer - Success -+ * NULL - Error. -+ **************************************************************************/ -+struct sk_buff *ti_alloc_skb(unsigned int size,int gfp_mask) -+{ -+ register struct sk_buff* skb; -+ unsigned long flags; -+ struct sk_buff_head* list; -+ DRIVER_BUFFER* ptr_node = NULL; -+ -+ /* Critical Section Begin: Lock out interrupts. */ -+ local_irq_save(flags); -+ -+ /* Get the SKB Pool list associated with the processor and dequeue the head. */ -+ list = &skb_head_pool[smp_processor_id()].list; -+ skb = __skb_dequeue(list); -+ -+ /* Align the data size. */ -+ size = SKB_DATA_ALIGN(size); -+ -+ /* Did we get one. */ -+ if (skb != NULL) -+ { -+ /* YES. Now get a data block from the head of statically allocated block. */ -+ ptr_node = driver_mcb.ptr_available_driver_buffers; -+ if (ptr_node != NULL) -+ { -+ /* YES. Got a data block. Advance the free list pointer to the next available buffer. */ -+ driver_mcb.ptr_available_driver_buffers = ptr_node->ptr_next; -+ ptr_node->ptr_next = NULL; -+ -+ /* Decrement the number of available data buffers. */ -+ driver_mcb.num_available_buffers = driver_mcb.num_available_buffers - 1; -+ } -+ else -+ { -+ /* NO. Was unable to get a data block. So put the SKB back on the free list. -+ * This is slow path. */ -+#ifdef DEBUG_SKB -+ printk ("DEBUG: No Buffer memory available: Number of free buffer:%d.\n", -+ driver_mcb.num_available_buffers); -+#endif -+ ti_release_skb (list, skb); -+ } -+ } -+ -+ /* Critical Section End: Unlock interrupts. */ -+ local_irq_restore(flags); -+ -+ /* Did we get an SKB and data buffer. Proceed only if we were succesful in getting both else drop */ -+ if (skb != NULL && ptr_node != NULL) -+ { -+ /* XXX: does not include slab overhead */ -+ skb->truesize = size + sizeof(struct sk_buff); -+ -+ /* Load the data pointers. */ -+ skb->head = ptr_node->ptr_buffer; -+ skb->data = ptr_node->ptr_buffer + MAX_RESERVED_HEADROOM; -+ skb->tail = ptr_node->ptr_buffer + MAX_RESERVED_HEADROOM; -+ skb->end = ptr_node->ptr_buffer + size + MAX_RESERVED_HEADROOM; -+ -+ /* Set up other state */ -+ skb->len = 0; -+ skb->cloned = 0; -+ skb->data_len = 0; -+ -+ /* Mark the SKB indicating that the SKB is from the TI cache. */ -+ skb->cb[45] = 1; -+ -+ atomic_set(&skb->users, 1); -+ atomic_set(&(skb_shinfo(skb)->dataref), 1); -+ skb_shinfo(skb)->nr_frags = 0; -+ skb_shinfo(skb)->frag_list = NULL; -+ return skb; -+ } -+ else -+ { -+ /* Control comes here only when there is no statically allocated data buffers -+ * available. This case is handled using the mode selected -+ * -+ * 1. Hybrid Mode. -+ * In that case lets jump to the old allocation code. This way we -+ * can allocate a small number of data buffers upfront and the rest will hit -+ * this portion of the code, which is slow path. Note the number of hits here -+ * should be kept as low as possible to satisfy performance requirements. -+ * -+ * 2. Pure Static Mode. -+ * Return NULL the user should have tuned the number of static buffers for -+ * worst case scenario. So return NULL and let the drivers handle the error. */ -+ if (hybrid_mode == 1) -+ { -+ /* Hybrid Mode: Old allocation. */ -+ return dev_alloc_skb(size); -+ } -+ else -+ { -+ /* Pure Static Mode: No buffers available. */ -+ return NULL; -+ } -+ } -+} -+ -+/************************************************************************** -+ * FUNCTION NAME : ti_skb_release_fragment -+ ************************************************************************** -+ * DESCRIPTION : -+ * This function is called to release fragmented packets. This is NOT in -+ * the fast path and this function requires some work. -+ **************************************************************************/ -+static void ti_skb_release_fragment(struct sk_buff *skb) -+{ -+ if (skb_shinfo(skb)->nr_frags) -+ { -+ /* PANKAJ TODO: This portion has not been tested. */ -+ int i; -+#ifdef DEBUG_SKB -+ printk ("DEBUG: Releasing fragments in TI-Cached code.\n"); -+#endif -+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -+ printk ("DEBUG: Fragmented Page = 0x%p.\n", skb_shinfo(skb)->frags[i].page); -+ } -+ -+ /* Check if there were any fragments present and if so clean all the SKB's. -+ * This is required to recursivly clean the SKB's. */ -+ if (skb_shinfo(skb)->frag_list) -+ skb_drop_fraglist(skb); -+ -+ return; -+} -+ -+/************************************************************************** -+ * FUNCTION NAME : ti_skb_release_data -+ ************************************************************************** -+ * DESCRIPTION : -+ * The function is called to release the SKB back into the TI-Cached static -+ * memory pool. -+ **************************************************************************/ -+static void ti_skb_release_data(struct sk_buff *skb) -+{ -+ DRIVER_BUFFER* ptr_node; -+ unsigned long flags; -+ -+ /* The SKB data can be cleaned only if the packet has not been cloned and we -+ * are the only one holding a reference to the data. */ -+ if (!skb->cloned || atomic_dec_and_test(&(skb_shinfo(skb)->dataref))) -+ { -+ /* Are there any fragments associated with the SKB ?*/ -+ if ((skb_shinfo(skb)->nr_frags != 0) || (skb_shinfo(skb)->frag_list != NULL)) -+ { -+ /* Slow Path: Try and clean up the fragments. */ -+ ti_skb_release_fragment (skb); -+ } -+ -+ /* Cleanup the SKB data memory. This is fast path. */ -+ ptr_node = (DRIVER_BUFFER *)skb->head; -+ -+ /* Critical Section: Lock out interrupts. */ -+ local_irq_save(flags); -+ -+ /* Add the data buffer to the list of available buffers. */ -+ ptr_node->ptr_next = driver_mcb.ptr_available_driver_buffers; -+ driver_mcb.ptr_available_driver_buffers = ptr_node; -+ -+ /* Increment the number of available data buffers. */ -+ driver_mcb.num_available_buffers = driver_mcb.num_available_buffers + 1; -+ -+ /* Criticial Section: Unlock interrupts. */ -+ local_irq_restore(flags); -+ } -+ return; -+} -+ -+ -+ -+ -+static unsigned char str2hexnum(unsigned char c) -+{ -+ if(c >= '0' && c <= '9') -+ return c - '0'; -+ if(c >= 'a' && c <= 'f') -+ return c - 'a' + 10; -+ if(c >= 'A' && c <= 'F') -+ return c - 'A' + 10; -+ return 0; -+} -+ -+static void str2eaddr(unsigned char *ea, unsigned char *str) -+{ -+ int i; -+ unsigned char num; -+ for(i = 0; i < 6; i++) { -+ if((*str == '.') || (*str == ':')) -+ str++; -+ num = str2hexnum(*str++) << 4; -+ num |= (str2hexnum(*str++)); -+ ea[i] = num; -+ } -+} -+ -+//----------------------------------------------------------------------------- -+// Statistics related private functions. -+//----------------------------------------------------------------------------- -+static int cpmac_p_update_statistics(struct net_device *p_dev, char *buf, int limit, int *p_len) -+{ -+ int ret_val = -1; -+ unsigned long rx_hal_errors = 0; -+ unsigned long rx_hal_discards = 0; -+ unsigned long tx_hal_errors = 0; -+ unsigned long ifOutDiscards = 0; -+ unsigned long ifInDiscards = 0; -+ unsigned long ifOutErrors = 0; -+ unsigned long ifInErrors = 0; -+ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ CPMAC_DEVICE_MIB_T *p_device_mib = p_cpmac_priv->device_mib; -+ CPMAC_DRV_STATS_T *p_stats = p_cpmac_priv->stats; -+ CPMAC_DEVICE_MIB_T local_mib; -+ CPMAC_DEVICE_MIB_T *p_local_mib = &local_mib; -+ -+ struct net_device_stats *p_net_dev_stats = &p_cpmac_priv->net_dev_stats; -+ -+ int len = 0; -+ int dev_mib_elem_count = 0; -+ -+ /* do not access the hardware if it is in the reset state. */ -+ if(!test_bit(0, &p_cpmac_priv->set_to_close)) -+ { -+ if(p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "StatsDump", "Get", -+ p_local_mib) != 0) -+ { -+ errPrint("The stats dump for %s is failing.\n", p_dev->name); -+ return(ret_val); -+ } -+ -+ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "StatsClear", "Set", NULL); -+ -+ dev_mib_elem_count = sizeof(CPMAC_DEVICE_MIB_T)/sizeof(unsigned long); -+ -+ /* Update the history of the stats. This takes care of any reset of the -+ * device and stats that might have taken place during the life time of -+ * the driver. -+ */ -+ while(dev_mib_elem_count--) -+ { -+ *((unsigned long*) p_device_mib + dev_mib_elem_count) += -+ *((unsigned long*) p_local_mib + dev_mib_elem_count); -+ } -+ } -+ -+ /* RFC2665, section 3.2.7, page 9 */ -+ rx_hal_errors = p_device_mib->ifInFragments + -+ p_device_mib->ifInCRCErrors + -+ p_device_mib->ifInAlignCodeErrors + -+ p_device_mib->ifInJabberFrames; -+ -+ /* RFC2233 */ -+ rx_hal_discards = p_device_mib->ifRxDMAOverruns; -+ -+ /* RFC2665, section 3.2.7, page 9 */ -+ tx_hal_errors = p_device_mib->ifExcessiveCollisionFrames + -+ p_device_mib->ifLateCollisions + -+ p_device_mib->ifCarrierSenseErrors + -+ p_device_mib->ifOutUnderrun; -+ -+ /* if not set, the short frames (< 64 bytes) are considered as errors */ -+ if(!p_cpmac_priv->flags & IFF_PRIV_SHORT_FRAMES) -+ rx_hal_errors += p_device_mib->ifInUndersizedFrames; -+ -+ /* if not set, the long frames ( > 1518) are considered as errors -+ * RFC2665, section 3.2.7, page 9. */ -+ if(!p_cpmac_priv->flags & IFF_PRIV_JUMBO_FRAMES) -+ rx_hal_errors += p_device_mib->ifInOversizedFrames; -+ -+ /* if not in promiscous, then non addr matching frames are discarded */ -+ /* CPMAC 2.0 Manual Section 2.8.1.14 */ -+ if(!p_dev->flags & IFF_PROMISC) -+ { -+ ifInDiscards += p_device_mib->ifInFilteredFrames; -+ } -+ -+ /* total rx discards = hal discards + driver discards. */ -+ ifInDiscards = rx_hal_discards + p_net_dev_stats->rx_dropped; -+ ifInErrors = rx_hal_errors; -+ -+ ifOutErrors = tx_hal_errors; -+ ifOutDiscards = p_net_dev_stats->tx_dropped; -+ -+ /* Let us update the net device stats struct. To be updated in the later releases.*/ -+ p_cpmac_priv->net_dev_stats.rx_errors = ifInErrors; -+ p_cpmac_priv->net_dev_stats.collisions = p_device_mib->ifCollisionFrames; -+ -+ if(buf == NULL || limit == 0) -+ { -+ return(0); -+ } -+ -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %ld\n", "ifSpeed", (long)p_cpmac_priv->link_speed); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "dot3StatsDuplexStatus", (long)p_cpmac_priv->link_mode); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifAdminStatus", (long)(p_dev->flags & IFF_UP ? 1:2)); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOperStatus", (long)(((p_dev->flags & IFF_UP) && netif_carrier_ok(p_dev)) ? 1:2)); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifLastChange", p_stats->start_tick); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInDiscards", ifInDiscards); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInErrors", ifInErrors); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutDiscards", ifOutDiscards); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutErrors", ifOutErrors); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInGoodFrames", p_device_mib->ifInGoodFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInBroadcasts", p_device_mib->ifInBroadcasts); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInMulticasts", p_device_mib->ifInMulticasts); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInPauseFrames", p_device_mib->ifInPauseFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInCRCErrors", p_device_mib->ifInCRCErrors); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInAlignCodeErrors", p_device_mib->ifInAlignCodeErrors); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInOversizedFrames", p_device_mib->ifInOversizedFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInJabberFrames", p_device_mib->ifInJabberFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInUndersizedFrames", p_device_mib->ifInUndersizedFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInFragments", p_device_mib->ifInFragments); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInFilteredFrames", p_device_mib->ifInFilteredFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInQosFilteredFrames", p_device_mib->ifInQosFilteredFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifInOctets", p_device_mib->ifInOctets); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutGoodFrames", p_device_mib->ifOutGoodFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutBroadcasts", p_device_mib->ifOutBroadcasts); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutMulticasts", p_device_mib->ifOutMulticasts); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutPauseFrames", p_device_mib->ifOutPauseFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifDeferredTransmissions", p_device_mib->ifDeferredTransmissions); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifCollisionFrames", p_device_mib->ifCollisionFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifSingleCollisionFrames", p_device_mib->ifSingleCollisionFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifMultipleCollisionFrames", p_device_mib->ifMultipleCollisionFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifExcessiveCollisionFrames", p_device_mib->ifExcessiveCollisionFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifLateCollisions", p_device_mib->ifLateCollisions); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutUnderrun", p_device_mib->ifOutUnderrun); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifCarrierSenseErrors", p_device_mib->ifCarrierSenseErrors); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifOutOctets", p_device_mib->ifOutOctets); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "if64OctetFrames", p_device_mib->if64OctetFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "if65To127POctetFrames", p_device_mib->if65To127OctetFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "if128To255OctetFrames", p_device_mib->if128To255OctetFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "if256To511OctetFrames", p_device_mib->if256To511OctetFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "if512To1023OctetFrames", p_device_mib->if512To1023OctetFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "if1024ToUpOctetFrames", p_device_mib->if1024ToUPOctetFrames); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifNetOctets", p_device_mib->ifNetOctets); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifRxSofOverruns", p_device_mib->ifRxSofOverruns); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifRxMofOverruns", p_device_mib->ifRxMofOverruns); -+ if(len <= limit) -+ len+= sprintf(buf + len, "%-35s: %lu\n", "ifRxDMAOverruns", p_device_mib->ifRxDMAOverruns); -+ -+ *p_len = len; -+ -+ return(0); -+} -+ -+ -+static int cpmac_p_read_rfc2665_stats(char* buf, char **start, off_t offset, -+ int count, int *eof, void *data) -+{ -+ int limit = count - 80; -+ int len = 0; -+ struct net_device *p_dev = (struct net_device*)data; -+ -+ cpmac_p_update_statistics(p_dev, buf, limit, &len); -+ -+ *eof = 1; -+ -+ return len; -+} -+ -+static int cpmac_p_read_link(char *buf, char **start, off_t offset, int count, -+ int *eof, void *data) -+{ -+ int len = 0; -+ -+ struct net_device *p_dev; -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv; -+ struct net_device *cpmac_dev_list[cpmac_devices_installed]; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal; -+ -+ int i; -+ int phy; /* what phy are we using? */ -+ -+ len += sprintf(buf+len, "CPMAC devices = %d\n",cpmac_devices_installed); -+ -+ p_dev = last_cpmac_device; -+ -+ /* Reverse the the device link list to list eth0,eth1...in correct order */ -+ for(i=0; i< cpmac_devices_installed; i++) -+ { -+ cpmac_dev_list[cpmac_devices_installed -(i+1)] = p_dev; -+ p_cpmac_priv = p_dev->priv; -+ p_dev = p_cpmac_priv->next_device; -+ } -+ -+ for(i=0; i< cpmac_devices_installed; i++) -+ { -+ p_dev = cpmac_dev_list[i]; -+ p_cpmac_priv = p_dev->priv; -+ p_drv_hal = p_cpmac_priv->drv_hal; -+ -+ /* This prints them out from high to low because of how the devices are linked */ -+ if(netif_carrier_ok(p_dev)) -+ { -+ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "PhyNum", "Get", &phy); -+ -+ -+ len += sprintf(buf+len,"eth%d: Link State: %s Phy:0x%x, Speed = %s, Duplex = %s\n", -+ p_cpmac_priv->instance_num, "UP", phy, -+ (p_cpmac_priv->link_speed == 100000000) ? "100":"10", -+ (p_cpmac_priv->link_mode == 2) ? "Half":"Full"); -+ -+ } -+ else -+ len += sprintf(buf+len,"eth%d: Link State: DOWN\n",p_cpmac_priv->instance_num); -+ -+ p_dev = p_cpmac_priv->next_device; -+ } -+ -+ return len; -+ -+} -+ -+static int cpmac_p_read_stats(char* buf, char **start, off_t offset, int count, -+ int *eof, void *data) -+{ -+ struct net_device *p_dev = last_cpmac_device; -+ int len = 0; -+ int limit = count - 80; -+ int i; -+ struct net_device *cpmac_dev_list[cpmac_devices_installed]; -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv; -+ CPMAC_DEVICE_MIB_T *p_device_mib; -+ -+ /* Reverse the the device link list to list eth0,eth1...in correct order */ -+ for(i=0; i< cpmac_devices_installed; i++) -+ { -+ cpmac_dev_list[cpmac_devices_installed - (i+1)] = p_dev; -+ p_cpmac_priv = p_dev->priv; -+ p_dev = p_cpmac_priv->next_device; -+ } -+ -+ for(i=0; i< cpmac_devices_installed; i++) -+ { -+ p_dev = cpmac_dev_list[i]; -+ -+ if(!p_dev) -+ goto proc_error; -+ -+ /* Get Stats */ -+ cpmac_p_update_statistics(p_dev, NULL, 0, NULL); -+ -+ p_cpmac_priv = p_dev->priv; -+ p_device_mib = p_cpmac_priv->device_mib; -+ -+ /* Transmit stats */ -+ if(len<=limit) -+ len+= sprintf(buf+len, "\nCpmac %d, Address %lx\n",i+1, p_dev->base_addr); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Transmit Stats\n"); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Tx Valid Bytes Sent :%lu\n",p_device_mib->ifOutOctets); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Good Tx Frames (Hardware) :%lu\n",p_device_mib->ifOutGoodFrames); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Good Tx Frames (Software) :%lu\n",p_cpmac_priv->net_dev_stats.tx_packets); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Good Tx Broadcast Frames :%lu\n",p_device_mib->ifOutBroadcasts); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Good Tx Multicast Frames :%lu\n",p_device_mib->ifOutMulticasts); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Pause Frames Sent :%lu\n",p_device_mib->ifOutPauseFrames); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Collisions :%lu\n",p_device_mib->ifCollisionFrames); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Tx Error Frames :%lu\n",p_cpmac_priv->net_dev_stats.tx_errors); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Carrier Sense Errors :%lu\n",p_device_mib->ifCarrierSenseErrors); -+ if(len<=limit) -+ len+= sprintf(buf+len, "\n"); -+ -+ -+ /* Receive Stats */ -+ if(len<=limit) -+ len+= sprintf(buf+len, "\nCpmac %d, Address %lx\n",i+1,p_dev->base_addr); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Receive Stats\n"); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Rx Valid Bytes Received :%lu\n",p_device_mib->ifInOctets); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Good Rx Frames (Hardware) :%lu\n",p_device_mib->ifInGoodFrames); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Good Rx Frames (Software) :%lu\n",p_cpmac_priv->net_dev_stats.rx_packets); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Good Rx Broadcast Frames :%lu\n",p_device_mib->ifInBroadcasts); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Good Rx Multicast Frames :%lu\n",p_device_mib->ifInMulticasts); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Pause Frames Received :%lu\n",p_device_mib->ifInPauseFrames); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Rx CRC Errors :%lu\n",p_device_mib->ifInCRCErrors); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Rx Align/Code Errors :%lu\n",p_device_mib->ifInAlignCodeErrors); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Rx Jabbers :%lu\n",p_device_mib->ifInOversizedFrames); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Rx Filtered Frames :%lu\n",p_device_mib->ifInFilteredFrames); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Rx Fragments :%lu\n",p_device_mib->ifInFragments); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Rx Undersized Frames :%lu\n",p_device_mib->ifInUndersizedFrames); -+ if(len<=limit) -+ len+= sprintf(buf+len, " Rx Overruns :%lu\n",p_device_mib->ifRxDMAOverruns); -+ } -+ -+ -+ return len; -+ -+ proc_error: -+ *eof=1; -+ return len; -+} -+ -+static int cpmac_p_write_stats (struct file *fp, const char * buf, unsigned long count, void * data) -+{ -+ char local_buf[31]; -+ int ret_val = 0; -+ -+ if(count > 30) -+ { -+ printk("Error : Buffer Overflow\n"); -+ printk("Use \"echo 0 > cpmac_stat\" to reset the statistics\n"); -+ return -EFAULT; -+ } -+ -+ copy_from_user(local_buf,buf,count); -+ local_buf[count-1]='\0'; /* Ignoring last \n char */ -+ ret_val = count; -+ -+ if(strcmp("0",local_buf)==0) -+ { -+ struct net_device *p_dev = last_cpmac_device; -+ int i; -+ struct net_device *cpmac_dev_list[cpmac_devices_installed]; -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv; -+ -+ /* Valid command */ -+ printk("Resetting statistics for CPMAC interface.\n"); -+ -+ /* Reverse the the device link list to list eth0,eth1...in correct order */ -+ for(i=0; i< cpmac_devices_installed; i++) -+ { -+ cpmac_dev_list[cpmac_devices_installed - (i+1)] = p_dev; -+ p_cpmac_priv = p_dev->priv; -+ p_dev = p_cpmac_priv->next_device; -+ } -+ -+ for(i=0; i< cpmac_devices_installed; i++) -+ { -+ p_dev = cpmac_dev_list[i]; -+ if(!p_dev) -+ { -+ ret_val = -EFAULT; -+ break; -+ } -+ -+ cpmac_p_reset_statistics(p_dev); -+ } -+ } -+ else -+ { -+ printk("Error: Unknown operation on cpmac statistics\n"); -+ printk("Use \"echo 0 > cpmac_stats\" to reset the statistics\n"); -+ return -EFAULT; -+ } -+ -+ return ret_val; -+} -+ -+static int cpmac_p_reset_statistics(struct net_device *p_dev) -+{ -+ int ret_val = 0; -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ -+ memset(p_cpmac_priv->device_mib, 0, sizeof(CPMAC_DEVICE_MIB_T)); -+ memset(p_cpmac_priv->stats, 0, sizeof(CPMAC_DRV_STATS_T)); -+ memset(&p_cpmac_priv->net_dev_stats, 0, sizeof(struct net_device_stats)); -+ -+ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "StatsClear", "Set", NULL); -+ -+ return(ret_val); -+} -+ -+static int cpmac_p_get_version(char* buf, char **start, off_t offset, int count,int *eof, void *data) -+{ -+ int len = 0; -+ int limit = count - 80; -+ char *hal_version = NULL; -+ struct net_device *p_dev = last_cpmac_device; -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ -+ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "Version", "Get", &hal_version); -+ -+ len += sprintf(buf+len, "Texas Instruments CPMAC driver version: %s\n", cpmac_version); -+ -+ if(len <= limit && hal_version) -+ len += sprintf(buf+len, "Texas Instruments CPMAC HAL version: %s\n", hal_version); -+ -+ return len; -+} -+ -+static struct net_device_stats *cpmac_dev_get_net_stats (struct net_device *p_dev) -+{ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = (CPMAC_PRIVATE_INFO_T *) p_dev->priv; -+ -+ cpmac_p_update_statistics(p_dev, NULL, 0, NULL); -+ -+ return &p_cpmac_priv->net_dev_stats; -+} -+ -+static int cpmac_p_detect_manual_cfg(int link_speed, char* link_mode, int debug) -+{ -+ char *pSpeed = NULL; -+ -+ if(debug == 1) -+ { -+ cpmac_debug_mode = 1; -+ dbgPrint("Enabled the debug print.\n"); -+ } -+ -+ if(!link_speed && !link_mode) -+ { -+ dbgPrint("No manual link params, defaulting to auto negotiation.\n"); -+ return (0); -+ } -+ -+ if(!link_speed || (link_speed != 10 && link_speed != 100)) -+ { -+ dbgPrint("Invalid or No value of link speed specified, defaulting to auto speed.\n"); -+ pSpeed = "auto"; -+ } -+ else if(link_speed == 10) -+ { -+ g_cfg_start_link_params &= ~(_CPMDIO_100); -+ pSpeed = "10 Mbps"; -+ } -+ else -+ { -+ g_cfg_start_link_params &= ~(_CPMDIO_10); -+ pSpeed = "100 Mbps"; -+ } -+ -+ if(!link_mode || (!strcmp(link_mode, "fd") && !strcmp(link_mode, "hd"))) -+ { -+ dbgPrint("Invalid or No value of link mode specified, defaulting to auto mode.\n"); -+ } -+ else if(!strcmp(link_mode, "hd")) -+ { -+ g_cfg_start_link_params &= ~(_CPMDIO_FD); -+ } -+ else -+ { -+ g_cfg_start_link_params &= ~(_CPMDIO_HD); -+ } -+ -+ dbgPrint("Link is manually set to the speed of %s speed and %s mode.\n", -+ pSpeed, link_mode ? link_mode : "auto"); -+ -+ return(0); -+} -+ -+//------------------------------------------------------------------------------ -+// Call back from the HAL. -+//------------------------------------------------------------------------------ -+static int cpmac_p_process_status_ind(CPMAC_PRIVATE_INFO_T *p_cpmac_priv) -+{ -+ struct net_device *p_dev = p_cpmac_priv->owner; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ int status; -+ -+ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "Status", "Get", &status); -+ -+ /* We do not reflect the real link status if in loopback. -+ * After all, we want the packets to reach the hardware so -+ * that Send() should work. */ -+ if(p_dev->flags & IFF_LOOPBACK) -+ { -+ dbgPrint("Maintaining the link up loopback for %s.\n", p_dev->name); -+ netif_carrier_on(p_dev); -+ -+//#if defined (CONFIG_MIPS_AVALANCHE_LED) -+// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_ON); -+//#endif -+ -+ return(0); -+ } -+ -+ if(status & CPMAC_STATUS_ADAPTER_CHECK) /* ???? */ -+ { -+ ; /* what to do ? */ -+ } -+ else if(status) -+ { -+ if(!netif_carrier_ok(p_dev)) -+ { -+ netif_carrier_on(p_cpmac_priv->owner); -+ -+//#if defined (CONFIG_MIPS_AVALANCHE_LED) -+// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_ON); -+//#endif -+ dbgPrint("Found the Link for the CPMAC instance %s.\n", p_dev->name); -+ } -+ -+ if(netif_running(p_dev) & netif_queue_stopped(p_dev)) -+ { -+ netif_wake_queue(p_dev); -+ } -+ -+ p_cpmac_priv->link_speed = status & CPMAC_STATUS_LINK_SPEED ? 100000000:10000000; -+ p_cpmac_priv->link_mode = status & CPMAC_STATUS_LINK_DUPLEX? 3:2; -+ -+ } -+ else -+ { -+ if(netif_carrier_ok(p_dev)) -+ { -+ /* do we need to register synchronization issues with stats here. */ -+ p_cpmac_priv->link_speed = 100000000; -+ p_cpmac_priv->link_mode = 1; -+ -+ netif_carrier_off(p_dev); -+ -+//#if defined (CONFIG_MIPS_AVALANCHE_LED) -+// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_OFF); -+//#endif -+ -+ dbgPrint("Lost the Link for the CPMAC for %s.\n", p_dev->name); -+ } -+ -+ if(!netif_queue_stopped(p_dev)) -+ { -+ netif_stop_queue(p_dev); /* So that kernel does not keep on xmiting pkts. */ -+ } -+ } -+ -+ return(0); -+} -+ -+//----------------------------------------------------------------------------- -+// Timer related private functions. -+//----------------------------------------------------------------------------- -+static int cpmac_p_timer_init(CPMAC_PRIVATE_INFO_T *p_cpmac_priv) -+{ -+ struct timer_list *p_timer = p_cpmac_priv->timer; -+ -+ init_timer(p_timer); -+ -+ p_timer = p_cpmac_priv->timer + TICK_TIMER; -+ p_timer->expires = 0; -+ p_timer->data = (unsigned long)p_cpmac_priv; -+ p_timer->function = cpmac_p_tick_timer_expiry; -+ -+ return(0); -+} -+ -+#if 0 -+static int cpmac_timer_cleanup(CPMAC_PRIVATE_INFO_T *p_cpmac_priv) -+{ -+ struct timer_list *p_timer; -+ -+ p_timer = p_cpmac_priv->timer + TICK_TIMER; -+ -+ /* use spin lock to establish synchronization with the dispatch */ -+ if(p_timer->function) del_timer_sync(p_timer); -+ p_timer->function = NULL; -+ -+ return (0); -+} -+#endif -+ -+static int cpmac_p_start_timer(struct timer_list *p_timer, unsigned int delay_ticks) -+{ -+ p_timer->expires = jiffies + delay_ticks; -+ -+ if(p_timer->function) -+ { -+ add_timer(p_timer); -+ } -+ -+ return(0); -+} -+ -+static void cpmac_p_tick_timer_expiry(unsigned long p_cb_param) -+{ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = (CPMAC_PRIVATE_INFO_T*) p_cb_param; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ struct timer_list *p_timer = p_cpmac_priv->timer + TICK_TIMER; -+ -+ if(test_bit(0, &p_cpmac_priv->set_to_close)) -+ { -+ return; -+ } -+ -+ p_drv_hal->hal_funcs->Tick(p_drv_hal->hal_dev); -+ -+ cpmac_p_start_timer(p_timer, p_cpmac_priv->delay_ticks); -+} -+ -+static int cpmac_p_stop_timer(struct timer_list *p_timer) -+{ -+ /* Ideally we need to a set flag indicating not to start the timer again -+ before del_timer_sync() is called up. But here we assume that the -+ caller has set the p_cpmac_priv->set_to_close (ok for now). */ -+ del_timer_sync(p_timer); -+ -+ return(0); -+} -+ -+//------------------------------------------------------------------------------ -+// Device configuration and setup related private functions. -+//------------------------------------------------------------------------------ -+static int cpmac_p_probe_and_setup_device(CPMAC_PRIVATE_INFO_T *p_cpmac_priv, -+ unsigned long *p_dev_flags) -+{ -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; -+ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; -+ CPMAC_ABILITY_INFO_T *p_capability= p_cpmac_priv->ability_info; -+ unsigned int val = 0; -+ int channel = 0; -+ -+ p_cpmac_priv->flags = 0; -+ -+ p_capability->promiscous = CFG_PROMISCOUS; -+ p_capability->broadcast = CFG_BROADCAST; -+ p_capability->multicast = CFG_MULTICAST; -+ p_capability->all_multi = CFG_ALL_MULTI; -+ p_capability->jumbo_frames = CFG_JUMBO_FRAMES; -+ p_capability->short_frames = CFG_SHORT_FRAMES; -+ p_capability->auto_negotiation = CFG_AUTO_NEGOTIATION; -+ p_capability->link_speed = cfg_start_link_speed; -+ p_capability->loop_back = CFG_LOOP_BACK; -+ p_capability->tx_flow_control = CFG_TX_FLOW_CNTL; -+ p_capability->rx_flow_control = CFG_RX_FLOW_CNTL; -+ p_capability->tx_pacing = CFG_TX_PACING; -+ p_capability->rx_pass_crc = CFG_RX_PASS_CRC; -+ p_capability->qos_802_1q = CFG_QOS_802_1Q; -+ p_capability->tx_num_chan = CFG_TX_NUM_CHAN; -+ -+ /* Lets probe the device for the configured capabilities (netdev specific).*/ -+ -+ /* Following are set in the set_multi_list, when indicated by the kernel -+ * Promiscous and all multi. -+ */ -+ -+ if(p_capability->broadcast) -+ { -+ channel = 0; -+ val = 1; -+ if((p_hal_funcs->Control(p_hal_dev, pszRX_BROAD_EN, pszSet, &val) == 0) && -+ (p_hal_funcs->Control(p_hal_dev, pszRX_BROAD_CH, pszSet, &channel) == 0)) -+ *p_dev_flags |= IFF_BROADCAST; -+ else -+ p_capability->broadcast = 0; /* no broadcast capabilities */ -+ } -+ -+ if(p_capability->multicast) -+ { -+ val = 1; -+ channel = 0; -+ if((p_hal_funcs->Control(p_hal_dev, pszRX_MULT_EN, pszSet, &val) == 0) && -+ (p_hal_funcs->Control(p_hal_dev, pszRX_MULT_CH, pszSet, &channel) == 0)) -+ *p_dev_flags |= IFF_MULTICAST; -+ else -+ { -+ p_capability->multicast = 0; -+ p_capability->all_multi = 0; /* no multicast, no all-multi. */ -+ } -+ } -+ -+ if(p_capability->loop_back) -+ { -+ ; /* We do not put the device in loopback, if required use ioctl */ -+ } -+ -+ /* Lets probe the device for the configured capabilities (Non net device specific).*/ -+ -+ if(p_capability->jumbo_frames) -+ { -+ val = 0; -+ if(p_hal_funcs->Control(p_hal_dev, pszRX_NO_CHAIN, pszSet, &val) == 0) -+ p_cpmac_priv->flags |= IFF_PRIV_JUMBO_FRAMES; -+ else -+ p_capability->jumbo_frames = 0; -+ } -+ -+ if(p_capability->short_frames) -+ { -+ val = 1; -+ if(p_hal_funcs->Control(p_hal_dev, pszRX_CSF_EN, pszSet, &val) == 0) -+ p_cpmac_priv->flags |= IFF_PRIV_SHORT_FRAMES; -+ else -+ p_capability->short_frames = 0; -+ } -+ -+ val = g_cfg_start_link_params; -+ -+#ifdef CONFIG_AR7_MDIX -+ if( avalanche_is_mdix_on_chip() ) -+ { -+ val |= _CPMDIO_AUTOMDIX; -+ } -+#endif -+ -+ if(p_hal_funcs->Control(p_hal_dev,pszMdioConnect,pszSet, &val) !=0) -+ { -+ p_capability->link_speed = 0; -+ } -+ else -+ { -+ if(g_cfg_start_link_params & (_CPMDIO_100 | _CPMDIO_HD | _CPMDIO_FD | _CPMDIO_10)) -+ p_cpmac_priv->flags |= IFF_PRIV_AUTOSPEED; -+ else if(g_cfg_start_link_params & (_CPMDIO_100 | _CPMDIO_HD)) -+ p_cpmac_priv->flags |= IFF_PRIV_LINK100_HD; -+ else if(g_cfg_start_link_params & (_CPMDIO_100 | _CPMDIO_FD)) -+ p_cpmac_priv->flags |= IFF_PRIV_LINK100_FD; -+ else if(g_cfg_start_link_params & (_CPMDIO_10 | _CPMDIO_HD)) -+ p_cpmac_priv->flags |= IFF_PRIV_LINK10_HD; -+ else if(g_cfg_start_link_params & (_CPMDIO_10 | _CPMDIO_FD)) -+ p_cpmac_priv->flags |= IFF_PRIV_LINK10_FD; -+ else -+ ; -+ } -+ -+ if(p_capability->tx_flow_control) -+ { -+ val = 1; -+ if(p_hal_funcs->Control(p_hal_dev,pszTX_FLOW_EN, pszSet, &val) ==0) -+ p_cpmac_priv->flags |= IFF_PRIV_TX_FLOW_CNTL; -+ else -+ p_capability->tx_flow_control = 0; -+ } -+ -+ if(p_capability->rx_flow_control) -+ { -+ val = 1; -+ if(p_hal_funcs->Control(p_hal_dev, pszRX_FLOW_EN, pszSet, &val) ==0) -+ p_cpmac_priv->flags |= IFF_PRIV_RX_FLOW_CNTL; -+ else -+ p_capability->rx_flow_control = 0; -+ } -+ -+ if(p_capability->tx_pacing) -+ { -+ val = 1; -+ if(p_hal_funcs->Control(p_hal_dev, pszTX_PACE, pszSet, &val) ==0) -+ p_cpmac_priv->flags |= IFF_PRIV_TX_PACING; -+ else -+ p_capability->tx_pacing = 0; -+ } -+ -+ if(p_capability->rx_pass_crc) -+ { -+ val = 1; -+ if(p_hal_funcs->Control(p_hal_dev, pszRX_PASS_CRC, pszSet, &val) == 0) -+ p_cpmac_priv->flags |= IFF_PRIV_RX_PASS_CRC; -+ else -+ p_capability->rx_pass_crc = 0; -+ } -+ -+ if(p_capability->qos_802_1q) -+ { -+ val = 1; -+ if(p_hal_funcs->Control(p_hal_dev, pszRX_QOS_EN, pszSet, &val) == 0) -+ p_cpmac_priv->flags |= IFF_PRIV_8021Q_EN; -+ else -+ { -+ p_capability->qos_802_1q = 0; -+ p_capability->tx_num_chan= 1; -+ } -+ } -+ -+ if(p_capability->tx_num_chan > 1) -+ { -+ int cfg_tx_num_chan = p_capability->tx_num_chan; -+ val = 0; -+#ifdef TEST -+ if(p_hal_funcs->Control(p_hal_dev, pszTX_NUM_CH, pszGet, &val) == 0) -+ cfg_tx_num_chan = cfg_tx_num_chan > val ? val : cfg_tx_num_chan; -+ else -+ cfg_tx_num_chan = 1; -+#endif -+ p_capability->tx_num_chan = cfg_tx_num_chan; -+ } -+ -+ return(0); -+} -+ -+static int cpmac_p_setup_driver_params(CPMAC_PRIVATE_INFO_T *p_cpmac_priv) -+{ -+ int i=0; -+ int threshold = CFG_TX_NUM_BUF_SERVICE; -+ -+ char *tx_threshold_ptr = prom_getenv("threshold"); -+ -+ CPMAC_TX_CHAN_INFO_T *p_tx_chan_info = p_cpmac_priv->tx_chan_info; -+ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info = p_cpmac_priv->rx_chan_info; -+ CPMAC_ABILITY_INFO_T *p_capability = p_cpmac_priv->ability_info; -+ -+ /* Timer stuff */ -+ p_cpmac_priv->timer_count = 1; /* should be < or = the MAX TIMER */ -+ p_cpmac_priv->timer_created = 0; -+ p_cpmac_priv->timer_access_hal = 1; -+ -+ for(i=0; i < MAX_TIMER; i++) -+ p_cpmac_priv->timer[i].function = NULL; -+ -+ p_cpmac_priv->enable_802_1q = p_capability->qos_802_1q; -+ -+ /* Tx channel related.*/ -+ p_tx_chan_info->cfg_chan = p_capability->tx_num_chan; -+ p_tx_chan_info->opened_chan = 0; -+ -+ if(tx_threshold_ptr) -+ threshold = simple_strtol(tx_threshold_ptr, (char **)NULL, 10); -+ -+ if((threshold <= 0) && tx_threshold_ptr) /* If threshold set to 0 then Enable the TX interrupt */ -+ { -+ threshold = CFG_TX_NUM_BUF_SERVICE; -+ p_tx_chan_info->tx_int_disable = 0; -+ -+ } -+ else -+ { -+ p_tx_chan_info->tx_int_disable = CFG_TX_INT_DISABLE; -+ } -+ -+ for(i=0; i < MAX_TX_CHAN; i++) -+ { -+ -+ -+ -+ p_tx_chan_info->chan[i].state = CHAN_CLOSE; -+ p_tx_chan_info->chan[i].num_BD = CFG_TX_NUM_BUF_DESC; -+ p_tx_chan_info->chan[i].buffer_size = cpmac_max_frame_size; -+ p_tx_chan_info->chan[i].buffer_offset = CFG_TX_BUF_OFFSET; -+ -+ -+ -+ p_tx_chan_info->chan[i].service_max = threshold; -+ } -+ -+ if (p_tx_chan_info->tx_int_disable) -+ printk("Cpmac driver Disable TX complete interrupt setting threshold to %d.\n",threshold); -+ else -+ printk("Cpmac driver Enable TX complete interrupt\n"); -+ -+ -+ /* Assuming just one rx channel for now */ -+ p_rx_chan_info->cfg_chan = 1; -+ p_rx_chan_info->opened_chan = 0; -+ p_rx_chan_info->chan->state = CHAN_CLOSE; -+ p_rx_chan_info->chan->num_BD = CFG_RX_NUM_BUF_DESC; -+ p_rx_chan_info->chan->buffer_size = cpmac_max_frame_size; -+ p_rx_chan_info->chan->buffer_offset = CFG_RX_BUF_OFFSET; -+ p_rx_chan_info->chan->service_max = CFG_RX_NUM_BUF_SERVICE; -+ -+ /* Set as per RFC 2665 */ -+ p_cpmac_priv->link_speed = 100000000; -+ p_cpmac_priv->link_mode = 1; -+ -+ p_cpmac_priv->loop_back = 0; -+ -+ return(0); -+} -+ -+inline static int cpmac_p_rx_buf_setup(CPMAC_RX_CHAN_INFO_T *p_rx_chan) -+{ -+ /* Number of ethernet packets & max pkt length */ -+ p_rx_chan->chan->tot_buf_size = p_rx_chan->chan->buffer_size + -+ 2*(CONTROL_802_1Q_SIZE) + -+ p_rx_chan->chan->buffer_offset + -+ ADD_FOR_4BYTE_ALIGN(p_rx_chan->chan->buffer_offset & 0x3); -+ -+ p_rx_chan->chan->tot_reserve_bytes = CONTROL_802_1Q_SIZE + -+ p_rx_chan->chan->buffer_offset + -+ L3_ALIGN(p_rx_chan->chan->buffer_offset & 0x3); -+ -+ return(0); -+} -+ -+//----------------------------------------------------------------------------- -+// Net device related private functions. -+//----------------------------------------------------------------------------- -+ -+/*************************************************************** -+ * cpmac_dev_init -+ * -+ * Returns: -+ * 0 on success, error code otherwise. -+ * Parms: -+ * dev The structure of the device to be -+ * init'ed. -+ * -+ * This function completes the initialization of the -+ * device structure and driver. It reserves the IO -+ * addresses and assignes the device's methods. -+ * -+ * -+ **************************************************************/ -+ -+static int cpmac_dev_init(struct net_device *p_dev) -+{ -+ int retVal = -1; -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ int instance_num = p_cpmac_priv->instance_num; -+ unsigned long net_flags = 0; -+ char *mac_name = NULL; -+ char *mac_string = NULL; -+ -+ CPMAC_TX_CHAN_INFO_T *p_tx_chan_info; -+ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal; -+ int i; -+ -+ int mem_size = sizeof(CPMAC_DRV_HAL_INFO_T) -+ + sizeof(CPMAC_TX_CHAN_INFO_T) -+ + sizeof(CPMAC_RX_CHAN_INFO_T) -+ + sizeof(CPMAC_ABILITY_INFO_T) -+ + sizeof(CPMAC_DEVICE_MIB_T) -+ + sizeof(CPMAC_DRV_STATS_T); -+ -+ -+#if defined(CONFIG_MIPS_SEAD2) -+ int prev_reset_val = RESET_REG_PRCR; -+ /* Bring the module out of reset */ -+ RESET_REG_PRCR |= temp_reset_value[p_cpmac_priv->instance_num]; -+ -+ /* Read the version id of the device to check if the device really exists */ -+ if( VERSION(temp_base_address[p_cpmac_priv->instance_num]) == 0) -+ { -+ printk(" CPMAC:Device not found\n"); -+ RESET_REG_PRCR = prev_reset_val; -+ return -ENODEV; -+ } -+ -+ RESET_REG_PRCR = prev_reset_val; -+#endif -+ -+ -+ if((p_drv_hal = kmalloc(mem_size, GFP_KERNEL)) == NULL) -+ { -+ errPrint("Failed to allocate memory; rewinding.\n"); -+ return(-1); -+ } -+ -+ memset(p_drv_hal, 0, mem_size); -+ -+ /* build the cpmac private object */ -+ p_cpmac_priv->drv_hal = p_drv_hal; -+ p_cpmac_priv->tx_chan_info = p_tx_chan_info -+ = (CPMAC_TX_CHAN_INFO_T*)((char*)p_drv_hal -+ + sizeof(CPMAC_DRV_HAL_INFO_T)); -+ p_cpmac_priv->rx_chan_info = p_rx_chan_info -+ = (CPMAC_RX_CHAN_INFO_T*)((char *)p_tx_chan_info -+ + sizeof(CPMAC_TX_CHAN_INFO_T)); -+ p_cpmac_priv->ability_info = (CPMAC_ABILITY_INFO_T *)((char *)p_rx_chan_info -+ + sizeof(CPMAC_RX_CHAN_INFO_T)); -+ p_cpmac_priv->device_mib = (CPMAC_DEVICE_MIB_T *)((char *)p_cpmac_priv->ability_info -+ + sizeof(CPMAC_ABILITY_INFO_T)); -+ p_cpmac_priv->stats = (CPMAC_DRV_STATS_T *)((char *)p_cpmac_priv->device_mib -+ + sizeof(CPMAC_DEVICE_MIB_T)); -+ -+ p_drv_hal->owner = p_cpmac_priv; -+ -+ -+ switch(instance_num) -+ { -+ -+ case 0: -+ mac_name="maca"; -+ -+ /* Also setting port information */ -+ p_dev->if_port = AVALANCHE_CPMAC_LOW_PORT_ID; -+ -+ break; -+ -+ case 1: -+ mac_name="macb"; -+ -+ /* Also setting port information */ -+ p_dev->if_port = AVALANCHE_CPMAC_HIGH_PORT_ID; -+ -+ break; -+ } -+ -+ if(mac_name) -+ mac_string=prom_getenv(mac_name); -+ -+ if(!mac_string) -+ { -+ mac_string="08.00.28.32.06.02"; -+ printk("Error getting mac from Boot enviroment for %s\n",p_dev->name); -+ printk("Using default mac address: %s\n",mac_string); -+ if(mac_name) -+ { -+ printk("Use Bootloader command:\n"); -+ printk(" setenv %s xx.xx.xx.xx.xx.xx\n","<env_name>"); -+ printk("to set mac address\n"); -+ } -+ } -+ -+ str2eaddr(p_cpmac_priv->mac_addr,mac_string); -+ -+ for (i=0; i <= ETH_ALEN; i++) -+ { -+ /* This sets the hardware address */ -+ p_dev->dev_addr[i] = p_cpmac_priv->mac_addr[i]; -+ } -+ -+ p_cpmac_priv->set_to_close = 1; -+ p_cpmac_priv->non_data_irq_expected = 0; -+ -+//#if defined (CONFIG_MIPS_AVALANCHE_LED) -+// if((p_cpmac_priv->led_handle = avalanche_led_register("cpmac", instance_num)) == NULL) -+// { -+// errPrint("Could not allocate handle for CPMAC[%d] LED.\n", instance_num); -+// goto cpmac_init_mod_error; -+// } -+//#endif -+ -+ if(cpmac_drv_init_module(p_drv_hal, p_dev, instance_num) != 0) -+ { -+ errPrint("Could not initialize the HAL for %s.\n", p_dev->name); -+ goto cpmac_init_mod_error; -+ } -+ -+ /* initialize the CPMAC device */ -+ if (cpmac_drv_init(p_drv_hal) == -1) -+ { -+ errPrint("HAL init failed for %s.\n", p_dev->name); -+ goto cpmac_init_device_error; -+ } -+ -+ if(cpmac_p_probe_and_setup_device(p_cpmac_priv, &net_flags) == -1) -+ { -+ errPrint("Failed to configure up %s.\n", p_dev->name); -+ goto cpmac_init_device_error; -+ } -+ -+ if(cpmac_p_setup_driver_params(p_cpmac_priv) == -1) -+ { -+ errPrint("Failed to set driver parameters for %s.\n", p_dev->name); -+ goto cpmac_init_device_error; -+ } -+ -+ cpmac_p_rx_buf_setup(p_rx_chan_info); -+ -+ /* initialize the timers for the net device */ -+ if(cpmac_p_timer_init(p_cpmac_priv) == -1) -+ { -+ errPrint("Failed to set timer(s) for %s.\n", p_dev->name); -+ goto cpmac_timer_init_error; -+ } -+ -+ p_dev->addr_len = 6; -+ -+ p_dev->open = &cpmac_dev_open; /* i.e. Start Device */ -+ p_dev->hard_start_xmit = &cpmac_dev_tx; -+ p_dev->stop = &cpmac_dev_close; -+ p_dev->get_stats = &cpmac_dev_get_net_stats; -+ -+ p_dev->set_multicast_list = &cpmac_dev_mcast_set; -+ p_dev->set_mac_address = cpmac_dev_set_mac_addr; -+ /* Knocking off the default broadcast and multicast flags. Allowing the -+ device configuration to control the flags. */ -+ p_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); -+ p_dev->flags |= net_flags; -+ -+ netif_carrier_off(p_dev); -+ -+//#if defined (CONFIG_MIPS_AVALANCHE_LED) -+// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_OFF); -+//#endif -+ -+ /* Tasklet is initialized at the isr registeration time. */ -+ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "CpmacBase", "Get", &p_dev->base_addr); -+ p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "CpmacSize", "Get", &p_cpmac_priv->dev_size); -+ -+ request_mem_region(p_dev->base_addr, p_cpmac_priv->dev_size, p_dev->name); -+ -+ retVal = 0; -+ -+ if(g_init_enable_flag) -+ cpmac_p_dev_enable(p_dev); -+ -+ return(retVal); -+ -+cpmac_timer_init_error: -+cpmac_init_device_error : -+ cpmac_drv_cleanup(p_drv_hal); -+ -+cpmac_init_mod_error: -+ kfree(p_drv_hal); -+ -+ return (retVal); -+ -+} /* cpmac_dev_init */ -+ -+ -+/*************************************************************** -+ * cpmac_p_dev_enable -+ * -+ * Returns: -+ * 0 on success, error code otherwise. -+ * Parms: -+ * dev Structure of device to be opened. -+ * -+ * This routine puts the driver and CPMAC adapter in a -+ * state where it is ready to send and receive packets. -+ * -+ * -+ **************************************************************/ -+int cpmac_p_dev_enable( struct net_device *p_dev) -+{ -+ int ret_val = 0; -+ int channel = 0; -+ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info = p_cpmac_priv->rx_chan_info; -+ int max_length = p_rx_chan_info->chan->tot_buf_size; -+ -+ p_cpmac_priv->set_to_close = 0; -+ -+ if((ret_val = cpmac_drv_start(p_drv_hal, p_cpmac_priv->tx_chan_info, -+ p_cpmac_priv->rx_chan_info, CHAN_SETUP))==-1) -+ { -+ errPrint("%s error: failed to start the device.\n", p_dev->name); -+ ret_val = -1; -+ } -+ else if(p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev,"RX_UNICAST_SET", -+ "Set", &channel)!=0) -+ { -+ errPrint("%s error: device chan 0 could not be enabled.\n", p_dev->name); -+ ret_val = -1; -+ } -+ else if(p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, pszRX_MAXLEN, pszSet, &max_length) != 0) -+ { -+ errPrint(" CPMAC registers can't be written \n"); -+ ret_val = -1; -+ } -+ else if(p_drv_hal->hal_funcs->Control(p_drv_hal->hal_dev, "TxIntDisable", "Set", -+ &p_cpmac_priv->tx_chan_info->tx_int_disable) != 0) -+ { -+ errPrint(" CPMAC registers can't be written \n"); -+ ret_val = -1; -+ } -+ else -+ { -+ ; // Every thing went OK. -+ } -+ -+ return(ret_val); -+} /* cpmac_dev_enable */ -+ -+ -+static int cpmac_dev_open(struct net_device *p_dev) -+{ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_ISR_INFO_T *p_isr_cb_param = &p_cpmac_priv->cpmac_isr; -+ -+ if(!g_init_enable_flag) -+ cpmac_p_dev_enable(p_dev); -+ -+ if(request_irq(p_isr_cb_param->intr, cpmac_hal_isr, SA_INTERRUPT, -+ "Cpmac Driver", p_isr_cb_param)) -+ { -+ errPrint("Failed to register the irq %d for Cpmac %s.\n", -+ p_isr_cb_param->intr, p_dev->name); -+ return (-1); -+ } -+ -+ netif_start_queue(p_dev); -+ -+ MOD_INC_USE_COUNT; -+ p_cpmac_priv->stats->start_tick = jiffies; -+ dbgPrint("Started the network queue for %s.\n", p_dev->name); -+ return(0); -+} -+ -+/*************************************************************** -+ * cpmac_p_dev_disable -+ * -+ * Returns: -+ * An error code. -+ * Parms: -+ * dev The device structure of the device to -+ * close. -+ * -+ * This function shuts down the adapter. -+ * -+ **************************************************************/ -+int cpmac_p_dev_disable(struct net_device *p_dev) -+{ -+ int ret_val = 0; -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ -+ set_bit(0, &p_cpmac_priv->set_to_close); -+ set_bit(0, &p_cpmac_priv->non_data_irq_expected); -+ -+ /* The driver does not re-schedule the tasklet after kill is called. So, this -+ should take care of the bug in the kernel. */ -+ tasklet_kill(&p_cpmac_priv->cpmac_isr.tasklet); -+ -+ if(cpmac_drv_stop(p_drv_hal, p_cpmac_priv->tx_chan_info, -+ p_cpmac_priv->rx_chan_info, -+ CHAN_TEARDOWN | FREE_BUFFER | BLOCKING | COMPLETE) == -1) -+ { -+ ret_val = -1; -+ } -+ else -+ { -+ /* hope that the HAL closes down the tick timer.*/ -+ -+ dbgPrint("Device %s Closed.\n", p_dev->name); -+ p_cpmac_priv->stats->start_tick = jiffies; -+ -+ p_cpmac_priv->link_speed = 100000000; -+ p_cpmac_priv->link_mode = 1; -+ netif_carrier_off(p_dev); -+ -+//#if defined (CONFIG_MIPS_AVALANCHE_LED) -+// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_OFF); -+//#endif -+ -+ clear_bit(0, &p_cpmac_priv->non_data_irq_expected); -+ -+ } -+ -+ return (ret_val); -+ -+} /* cpmac_dev_close */ -+ -+ -+/*************************************************************** -+ * cpmac_dev_close -+ * -+ * Returns: -+ * An error code. -+ * Parms: -+ * dev The device structure of the device to -+ * close. -+ * -+ * This function shuts down the adapter. -+ * -+ **************************************************************/ -+static int cpmac_dev_close(struct net_device *p_dev) -+{ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_ISR_INFO_T *p_isr_cb_param = &p_cpmac_priv->cpmac_isr; -+ -+ /* inform the upper layers. */ -+ netif_stop_queue(p_dev); -+ -+ if(!g_init_enable_flag) -+ cpmac_p_dev_disable(p_dev); -+ else -+ free_irq(p_isr_cb_param->intr, p_isr_cb_param); -+ -+ MOD_DEC_USE_COUNT; -+ -+ return(0); -+} -+ -+static void cpmac_dev_mcast_set(struct net_device *p_dev) -+{ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ CPMAC_ABILITY_INFO_T *p_capability = p_cpmac_priv->ability_info; -+ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; -+ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; -+ int val = 1; -+ int channel = 0; -+ -+//#if defined (CONFIG_MIPS_AVALANCHE_LED) -+// if(netif_carrier_ok(p_dev)) -+// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_LINK_ON); -+//#endif -+ -+ if(p_dev->flags & IFF_PROMISC) -+ { -+ if(p_capability->promiscous) -+ { -+ /* multi mode in the HAL, check this */ -+ val = 0; -+ p_hal_funcs->Control(p_hal_dev, pszRX_MULTI_ALL, "Clear", &val); -+ -+ val = 1; -+ /* set the promiscous mode in the HAL */ -+ p_hal_funcs->Control(p_hal_dev, pszRX_CAF_EN, pszSet, &val); -+ p_hal_funcs->Control(p_hal_dev, pszRX_PROM_CH, pszSet, &channel); -+ -+ dbgPrint("%s set in the Promisc mode.\n", p_dev->name); -+ } -+ else -+ { -+ errPrint("%s not configured for Promisc mode.\n", p_dev->name); -+ } -+ } -+ else if(p_dev->flags & IFF_ALLMULTI) -+ { -+ if(p_capability->all_multi) -+ { -+ val = 0; -+ /* disable the promiscous mode in the HAL */ -+ p_hal_funcs->Control(p_hal_dev, pszRX_CAF_EN, "Clear", &val); -+ -+ val = 1; -+ /* set the all multi mode in the HAL */ -+ p_hal_funcs->Control(p_hal_dev, pszRX_MULTI_ALL, pszSet, &val); -+ p_hal_funcs->Control(p_hal_dev, pszRX_MULT_CH, pszSet, &channel); -+ -+ dbgPrint("%s has been set to the ALL_MULTI mode.\n", p_dev->name); -+ } -+ else -+ { -+ errPrint("%s not configured for ALL MULTI mode.\n", p_dev->name); -+ } -+ } -+ else if(p_dev->mc_count) -+ { -+ if(p_capability->multicast) -+ { -+ struct dev_mc_list *p_dmi = p_dev->mc_list; -+ int count; -+ -+ val = 0; -+ /* clear all the previous data, we are going to populate new ones.*/ -+ p_hal_funcs->Control(p_hal_dev, pszRX_MULTI_ALL, "Clear", &val); -+ /* disable the promiscous mode in the HAL */ -+ p_hal_funcs->Control(p_hal_dev, pszRX_CAF_EN, pszSet, &val); -+ -+ for(count = 0; count < p_dev->mc_count; count++, p_dmi = p_dmi->next) -+ { -+ p_hal_funcs->Control(p_hal_dev, "RX_MULTI_SINGLE", "Set", p_dmi->dmi_addr); -+ } -+ -+ dbgPrint("%s configured for %d multicast addresses.\n", p_dev->name, p_dev->mc_count); -+ } -+ else -+ { -+ errPrint("%s has not been configuted for multicast handling.\n", p_dev->name); -+ } -+ } -+ else -+ { -+ val = 0; -+ /* clear all the previous data, we are going to populate new ones.*/ -+ p_hal_funcs->Control(p_hal_dev, pszRX_MULTI_ALL, "Clear", &val); -+ /* disable the promiscous mode in the HAL */ -+ p_hal_funcs->Control(p_hal_dev, pszRX_CAF_EN, pszSet, &val); -+ dbgPrint("Dev set to Unicast mode.\n"); -+ } -+} -+ -+static int cpmac_dev_set_mac_addr(struct net_device *p_dev,void * addr) -+{ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; -+ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; -+ struct sockaddr *sa = addr; -+ -+ memcpy(p_cpmac_priv->mac_addr,sa->sa_data,p_dev->addr_len); -+ memcpy(p_dev->dev_addr,sa->sa_data,p_dev->addr_len); -+ p_hal_funcs->Control(p_hal_dev, pszMacAddr, pszSet, p_cpmac_priv->mac_addr); -+ -+ return 0; -+ -+} -+ -+/* VLAN is handled by vlan/vconfig support. Here, we just check for the -+ * 802.1q configuration of the device and en-queue the packet accordingly. -+ * We do not do any 802.1q processing here. -+ */ -+static int cpmac_dev_tx( struct sk_buff *skb, struct net_device *p_dev) -+{ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ int channel = 0; -+ int ret_val = 0; -+ FRAGLIST send_frag_list[1]; -+ -+#ifdef CPMAC_8021Q_SUPPORT -+ if(skb->len < TCI_END_OFFSET) -+ { -+ /* Whee, frame shorter than 14 bytes !! We need to copy -+ * fragments to understand the frame. Too much work. -+ * Hmm, dump it. */ -+ -+ /* Free the buffer */ -+ goto cpmac_dev_tx_drop_pkt; -+ } -+ -+ /* 802.1p/q stuff */ -+ if(IS_802_1Q_FRAME(skb->data + TPID_START_OFFSET)) -+ { -+ /* IEEE 802.1q, section 8.8 and section 8.11.9 */ -+ if(!p_cpmac_priv->enable_802_1q) -+ { -+ /* free the buffer */ -+ goto cpmac_dev_tx_drop_pkt; -+ } -+ -+ channel = GET_802_1P_CHAN(p_cpmac_priv->tx_chan_info->opened_chan, -+ skb->data[TCI_START_OFFSET]); -+ -+ } -+ /* sending a non 802.1q frame, when configured for 802.1q: dump it.*/ -+ else if(p_cpmac_priv->enable_802_1q) -+ { -+ /* free the buffer */ -+ goto cpmac_dev_tx_drop_pkt; -+ } -+ else -+ { -+ ;/* it is the good old non 802.1q */ -+ } -+#endif -+ -+ send_frag_list->len = skb->len; -+ send_frag_list->data = skb->data; -+ -+#ifdef CPMAC_TEST -+ xdump(skb->data, skb->len, "send"); -+#endif -+ -+ dma_cache_wback_inv((unsigned long)skb->data, skb->len); -+ -+ if(p_drv_hal->hal_funcs->Send(p_drv_hal->hal_dev, send_frag_list, 1, -+ skb->len, skb, channel) != 0) -+ { -+ /* code here to stop the queue, when allowing tx timeout, perhaps next release.*/ -+ p_cpmac_priv->net_dev_stats.tx_errors++; -+#ifndef TI_SLOW_PATH -+ /* Free the skb in case of Send return error */ -+ dev_kfree_skb_any(skb); -+ p_cpmac_priv->net_dev_stats.tx_dropped++; -+ return 0; -+#endif -+ goto cpmac_dev_tx_drop_pkt; -+ } -+ -+//#if defined (CONFIG_MIPS_AVALANCHE_LED) -+// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_TX_ACTIVITY); -+//#endif -+ -+ return(ret_val); -+ -+cpmac_dev_tx_drop_pkt: -+ -+ p_cpmac_priv->net_dev_stats.tx_dropped++; -+ ret_val = -1; -+ return (ret_val); -+ -+} /*cpmac_dev_tx */ -+ -+ -+//------------------------------------------------------------------------------ -+// Public functions : Called by outsiders to this file. -+//------------------------------------------------------------------------------ -+ -+ -+void *cpmac_hal_malloc_buffer(unsigned int size, void* mem_base, unsigned int mem_range, -+ OS_SETUP *p_os_setup, HAL_RECEIVEINFO *HalReceiveInfo, -+ OS_RECEIVEINFO **osReceiveInfo, OS_DEVICE *p_dev) -+{ -+ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info = (CPMAC_RX_CHAN_INFO_T *)p_os_setup; -+ int tot_buf_size = p_rx_chan_info->chan->tot_buf_size; -+ int tot_reserve_bytes = p_rx_chan_info->chan->tot_reserve_bytes; -+ struct sk_buff *p_skb; -+ void *ret_ptr; -+ -+ /* use TI SKB private pool */ -+ p_skb = dev_alloc_skb(tot_buf_size); -+ -+ if(p_skb == NULL) -+ { -+ errPrint("Failed to allocate skb for %s.\n", ((struct net_device*)p_dev)->name); -+ return (NULL); -+ } -+ -+ p_skb->dev = p_dev; -+ skb_reserve(p_skb, tot_reserve_bytes); -+ -+ *osReceiveInfo = p_skb; -+ -+ ret_ptr = skb_put(p_skb, p_rx_chan_info->chan->buffer_size); -+ -+ return(ret_ptr); -+} -+ -+void cpmac_hal_isr(int irq, void *p_param, struct pt_regs *regs) -+{ -+ CPMAC_ISR_INFO_T *p_cb_param = (CPMAC_ISR_INFO_T*) p_param; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cb_param->owner; -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_drv_hal->owner; -+ int pkts_to_handle = 0; -+ -+ if(p_cpmac_priv->non_data_irq_expected) -+ { -+ p_cb_param->hal_isr(p_drv_hal->hal_dev, &pkts_to_handle); -+ p_drv_hal->hal_funcs->PacketProcessEnd(p_drv_hal->hal_dev); -+ } -+ else if(!p_cpmac_priv->set_to_close) -+ tasklet_schedule(&((CPMAC_ISR_INFO_T*) p_param)->tasklet); -+ else -+ ; // back off from doing anything more. We are closing down. -+} -+ -+void cpmac_handle_tasklet(unsigned long data) -+{ -+ CPMAC_ISR_INFO_T *p_cb_param = (CPMAC_ISR_INFO_T*) data; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cb_param->owner; -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_drv_hal->owner; -+ int pkts_to_handle; -+ -+ p_cb_param->hal_isr(p_drv_hal->hal_dev, &pkts_to_handle); -+ -+ if(test_bit(0, &p_cpmac_priv->non_data_irq_expected) || !pkts_to_handle) -+ p_drv_hal->hal_funcs->PacketProcessEnd(p_drv_hal->hal_dev); -+ else if(!test_bit(0, &p_cpmac_priv->set_to_close)) -+ tasklet_schedule(&p_cb_param->tasklet); -+ else -+ ; // Back off from processing packets we are closing down. -+} -+ -+int cpmac_hal_control(OS_DEVICE *p_dev, const char *key, -+ const char *action, void *value) -+{ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ int ret_val = -1; -+ -+ if(key == NULL) -+ { -+ dbgPrint("Encountered NULL key.\n"); -+ return (-1); -+ } -+ -+ if(cpmac_ci_strcmp(key, "Sleep") == 0 && value != NULL) -+ { -+ unsigned int clocks_per_tick = cpmac_cpu_freq/HZ; -+ unsigned int requested_clocks = *(unsigned int*)value; -+ unsigned int requested_ticks = (requested_clocks + clocks_per_tick - 1)/clocks_per_tick; -+ mdelay(requested_ticks); -+ ret_val = 0; -+ } -+ else if(cpmac_ci_strcmp(key, "StateChange") == 0) -+ { -+ ret_val = cpmac_p_process_status_ind(p_cpmac_priv); -+ } -+ else if(cpmac_ci_strcmp(key, "Tick") == 0 && action != NULL) -+ { -+ if(cpmac_ci_strcmp(action, "Set") == 0 && value != NULL) -+ { -+ if(*(unsigned int*)value == 0) -+ { -+ cpmac_p_stop_timer(p_cpmac_priv->timer + TICK_TIMER); -+ ret_val = 0; -+ } -+ else -+ { -+ unsigned int clocks_per_tick = cpmac_cpu_freq/HZ; -+ unsigned int requested_clocks = *(unsigned int*)value; -+ unsigned int requested_ticks = (requested_clocks + clocks_per_tick - 1)/clocks_per_tick; -+ -+ p_cpmac_priv->delay_ticks = requested_ticks; /* save it for re-triggering */ -+ ret_val = cpmac_p_start_timer(p_cpmac_priv->timer + TICK_TIMER, -+ p_cpmac_priv->delay_ticks); -+ } -+ } -+ else if(cpmac_ci_strcmp(action, "Clear") == 0) -+ { -+ ret_val = cpmac_p_stop_timer(p_cpmac_priv->timer + TICK_TIMER); -+ } -+ else -+ ; -+ } -+ else if(cpmac_ci_strcmp(key, "MacAddr") == 0 && action != NULL) -+ { -+ if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL) -+ { -+ *(char **)value = p_cpmac_priv->mac_addr; -+ ret_val = 0; -+ } -+ } -+ else if(cpmac_ci_strcmp(key, "CpuFreq") == 0) -+ { -+ if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL) -+ { -+ *(unsigned int *)value = cpmac_cpu_freq; -+ dbgPrint("Cpu frequency for cpmacs is %u\n",cpmac_cpu_freq); -+ ret_val = 0; -+ } -+ } -+ else if(cpmac_ci_strcmp(key, "SioFlush") == 0) -+ { -+ ret_val = 0; -+ dbgPrint("\n"); -+ } -+ else if(cpmac_ci_strcmp(key, "CpmacFrequency") == 0) -+ { -+ /* For Sangam cpmac clock is off the PBUS */ -+ /* OS Needs to supply CORRECT frequency */ -+ if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL) -+ { -+ *(unsigned int *)value = CONFIG_AR7_SYS * 1000 * 1000; -+ ret_val = 0; -+ } -+ } -+ /* For now, providing back the default values. */ -+ else if(cpmac_ci_strcmp(key, "MdioClockFrequency") == 0) -+ { -+ if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL) -+ { -+ *(unsigned int *)value = 2200000; /*DEFAULT */ -+ ret_val = 0; -+ } -+ } -+ /* For now, providing back the default values. */ -+ else if(cpmac_ci_strcmp(key, "MdioBusFrequency") == 0) -+ { -+ /* For Sangam MdioBusFreq is off the PBUS */ -+ if(cpmac_ci_strcmp(action, "Get") == 0 && value != NULL) -+ { -+ *(unsigned int *)value = CONFIG_AR7_SYS * 1000 * 1000; -+ ret_val = 0; -+ } -+ } -+ -+#if 0 -+#if defined(CONFIG_AVALANCHE_AUTO_MDIX) -+ /* supporting Mdio Mdix switching */ -+ else if(cpmac_ci_strcmp(key, hcMdioMdixSwitch) == 0) -+ { -+ /* For Sangam Mdio-switching action should be always "set"*/ -+ if(cpmac_ci_strcmp(action, hcSet) == 0 && value != NULL ) -+ { -+ unsigned int mdix = *((unsigned int *) value) ; -+ -+ if(mdix) -+ avalanche_set_phy_into_mdix_mode(); -+ -+ else -+ avalanche_set_phy_into_mdi_mode(); -+ -+ ret_val = 0; -+ } -+ -+ } -+#endif -+#endif -+ else if(cpmac_ci_strcmp(key, hcMdioMdixSwitch) == 0) -+ { -+ /* For Sangam Mdio-switching action should be always "set"*/ -+ if(cpmac_ci_strcmp(action, hcSet) == 0 && value != NULL ) -+ { -+ unsigned int mdix = *((unsigned int *) value) ; -+ -+#ifdef CONFIG_AR7_MDIX -+ avalanche_set_mdix_on_chip(0xa8610000 , mdix ? 1: 0); -+#endif -+ -+ ret_val = 0; -+ } -+ -+ } -+ -+ return(ret_val); -+} -+ -+ -+int cpmac_hal_receive(OS_DEVICE *p_dev, FRAGLIST *fragList, -+ unsigned int fragCount, -+ unsigned int packet_size, -+ HAL_RECEIVEINFO *hal_receive_info, -+ unsigned int mode) -+{ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ struct sk_buff *p_skb = fragList[0].OsInfo; -+ p_skb->len = fragList[0].len; -+ -+ /* invalidate the cache. */ -+ dma_cache_inv((unsigned long)p_skb->data, fragList[0].len); -+#ifdef CPMAC_TEST -+ xdump(p_skb->data, p_skb->len, "recv"); -+#endif -+#ifdef CPMAC_8021Q_SUPPORT -+ /* 802.1q stuff, just does the basic checking here. */ -+ if(!p_cpmac_priv->enable_802_1q && -+ p_skb->len > TCI_END_OFFSET && -+ IS_802_1Q_FRAME(p_skb->data + TPID_START_OFFSET)) -+ { -+ goto cpmac_hal_recv_frame_mismatch; -+ } -+#endif -+ if(fragCount > 1) -+ { -+ int len; -+ struct sk_buff *p_temp_skb; -+ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info = p_cpmac_priv->rx_chan_info; -+ int count; -+ -+ dbgPrint("Recv: It is multifragment for %s.\n", p_dev->name); -+ -+ p_skb = dev_alloc_skb(packet_size + -+ p_rx_chan_info->chan->tot_reserve_bytes); -+ if(p_skb == NULL) -+ { -+ p_cpmac_priv->net_dev_stats.rx_errors++; -+ goto cpmac_hal_recv_alloc_failed; -+ } -+ -+ p_skb->dev = p_dev; -+ skb_reserve(p_skb, p_rx_chan_info->chan->tot_reserve_bytes); -+ -+ for(count = 0; count < fragCount; count++) -+ { -+ p_temp_skb = fragList[count].OsInfo; -+ len = fragList[count].len; -+ -+ dma_cache_inv((unsigned long)p_temp_skb->data, len); -+ -+ memcpy(skb_put(p_skb, len), p_temp_skb->data, len); -+ dev_kfree_skb_any(p_temp_skb); -+ } -+ } -+ -+ -+#if defined(CONFIG_MIPS_AVALANCHE_MARVELL) -+ /* Fetch the receiving port information from EGRESS TRAILOR Bytes*/ -+ p_dev->if_port = (unsigned char)p_skb->data[packet_size -(EGRESS_TRAILOR_LEN-1)] + AVALANCHE_MARVELL_BASE_PORT_ID; -+ skb_trim(p_skb, packet_size - EGRESS_TRAILOR_LEN); -+#else -+ /* set length & tail */ -+ skb_trim(p_skb, packet_size); -+#endif -+ -+ p_skb->protocol = eth_type_trans(p_skb, p_dev); -+ -+ netif_rx(p_skb); -+ -+//#if defined (CONFIG_MIPS_AVALANCHE_LED) -+// avalanche_led_action(p_cpmac_priv->led_handle, CPMAC_RX_ACTIVITY); -+//#endif -+ -+ p_cpmac_priv->net_dev_stats.rx_packets++; -+ p_cpmac_priv->net_dev_stats.rx_bytes += packet_size; -+ -+ p_drv_hal->hal_funcs->RxReturn(hal_receive_info,1); -+ -+ return(0); -+ -+cpmac_hal_recv_alloc_failed: -+ -+#ifdef CPMAC_8021Q_SUPPORT -+cpmac_hal_recv_frame_mismatch: -+#endif -+ -+ fragCount--; -+ -+ do -+ { -+ dev_kfree_skb_any(fragList[fragCount].OsInfo); -+ } -+ while(fragCount--); -+ -+ p_cpmac_priv->net_dev_stats.rx_dropped++; -+ -+ return(-1); -+} /*cpmac_receive*/ -+ -+ -+void cpmac_hal_tear_down_complete(OS_DEVICE*a, int b, int ch) -+{ -+ dbgPrint("what to do with this.\n"); -+} -+ -+ -+int cpmac_hal_send_complete(OS_SENDINFO *p_skb) -+{ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_skb->dev->priv; -+ -+ p_cpmac_priv->net_dev_stats.tx_packets++; -+ p_cpmac_priv->net_dev_stats.tx_bytes += p_skb->len; -+ -+ dev_kfree_skb_any(p_skb); -+ -+ return(0); -+} -+ -+ -+int cpmac_reset(CPMAC_PRIVATE_INFO_T *p_cpmac_priv) -+{ -+ // code here to reset the device/hal. Not now. -+ -+ netif_wake_queue(p_cpmac_priv->owner); -+ return(0); -+} -+ -+#ifdef CPMAC_TEST -+ -+#define isprint(a) ((a >=' ')&&(a<= '~')) -+void xdump( u_char* cp, int length, char* prefix ) -+{ -+ int col, count; -+ u_char prntBuf[120]; -+ u_char* pBuf = prntBuf; -+ count = 0; -+ while(count < length){ -+ pBuf += sprintf( pBuf, "%s", prefix ); -+ for(col = 0;count + col < length && col < 16; col++){ -+ if (col != 0 && (col % 4) == 0) -+ pBuf += sprintf( pBuf, " " ); -+ pBuf += sprintf( pBuf, "%02X ", cp[count + col] ); -+ } -+ while(col++ < 16){ /* pad end of buffer with blanks */ -+ if ((col % 4) == 0) -+ sprintf( pBuf, " " ); -+ pBuf += sprintf( pBuf, " " ); -+ } -+ pBuf += sprintf( pBuf, " " ); -+ for(col = 0;count + col < length && col < 16; col++){ -+ if (isprint((int)cp[count + col])) -+ pBuf += sprintf( pBuf, "%c", cp[count + col] ); -+ else -+ pBuf += sprintf( pBuf, "." ); -+ } -+ sprintf( pBuf, "\n" ); -+ // SPrint(prntBuf); -+ printk(prntBuf); -+ count += col; -+ pBuf = prntBuf; -+ } -+ -+} /* close xdump(... */ -+#endif -+ -+ -+static int __init cpmac_dev_probe(void) -+{ -+ int retVal = 0; -+ int unit; -+ int instance_count = CONFIG_MIPS_CPMAC_PORTS; -+ -+ //cpmac_cpu_freq = avalanche_clkc_get_freq(CLKC_MIPS); -+ cpmac_cpu_freq = CONFIG_AR7_CPU * 1000 * 1000; -+ -+ build_psp_config(); -+ -+ for(unit = 0; unit < instance_count; unit++) -+ { -+ struct net_device *p_dev; -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv; -+ size_t dev_size; -+ int failed; -+ -+ dev_size = sizeof(struct net_device) -+ + sizeof(CPMAC_PRIVATE_INFO_T); -+ -+ -+ if((p_dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL)) == NULL) -+ { -+ dbgPrint( "Could not allocate memory for device.\n" ); -+ retVal = -ENOMEM; -+ break; -+ } -+ -+ memset(p_dev, 0, dev_size ); -+ -+ p_dev->priv = p_cpmac_priv -+ = (CPMAC_PRIVATE_INFO_T*)(((char *) p_dev) + sizeof(struct net_device)); -+ p_cpmac_priv->owner = p_dev; -+ -+ ether_setup(p_dev); -+ -+ p_cpmac_priv->instance_num = unit; -+ p_dev->init = cpmac_dev_init; -+ -+ g_dev_array[p_cpmac_priv->instance_num] = p_dev; -+ -+#if defined CONFIG_MIPS_CPMAC_INIT_BUF_MALLOC -+ g_init_enable_flag = 1; -+ printk("Cpmac driver is allocating buffer memory at init time.\n"); -+#endif -+ -+ /* This section gives a default value by the number of PHY in order to -+ * replace the default MACRO. */ -+ { -+ char *mac_port = prom_getenv("MAC_PORT"); /* Internal: 0, External: 1 */ -+ if(!mac_port || 0 == strcmp(mac_port, "1")) { -+ printk("Using the MAC with external PHY\n"); -+ cfg_start_link_speed = _CPMDIO_NOPHY; -+ cpmac_max_frame_size = CPMAC_MAX_FRAME_SIZE + 4; -+ } -+ else { -+ printk("Using the MAC with internal PHY\n"); -+ cfg_start_link_speed = CFG_START_LINK_SPEED; -+ cpmac_max_frame_size = CPMAC_MAX_FRAME_SIZE; -+ } -+ g_cfg_start_link_params = cfg_start_link_speed; -+ } -+ -+ cpmac_p_detect_manual_cfg(cfg_link_speed, cfg_link_mode, cpmac_debug_mode); -+ -+ failed = register_netdev(p_dev); -+ if (failed) -+ { -+ dbgPrint("Could not register device for inst %d because of reason \ -+ code %d.\n", unit, failed); -+ retVal = -1; -+ kfree(p_dev); -+ break; -+ } -+ else -+ { -+ -+ char proc_name[100]; -+ int proc_category_name_len = 0; -+ -+ p_cpmac_priv->next_device = last_cpmac_device; -+ last_cpmac_device = p_dev; -+ -+ dbgPrint(" %s irq=%2d io=%04x\n",p_dev->name, (int) p_dev->irq, -+ (int) p_dev->base_addr); -+ -+ strcpy(proc_name, "avalanche/"); -+ strcat(proc_name, p_dev->name); -+ proc_category_name_len = strlen(proc_name); -+ -+ strcpy(proc_name + proc_category_name_len, "_rfc2665_stats"); -+ create_proc_read_entry(proc_name,0,NULL,cpmac_p_read_rfc2665_stats, p_dev); -+ -+ } -+ } -+ -+ if(retVal == 0) -+ { -+ /* To maintain backward compatibility with NSP. */ -+ gp_stats_file = create_proc_entry("avalanche/cpmac_stats", 0644, NULL); -+ if(gp_stats_file) -+ { -+ gp_stats_file->read_proc = cpmac_p_read_stats; -+ gp_stats_file->write_proc = cpmac_p_write_stats; -+ } -+ create_proc_read_entry("avalanche/cpmac_link", 0, NULL, cpmac_p_read_link, NULL); -+ create_proc_read_entry("avalanche/cpmac_ver", 0, NULL, cpmac_p_get_version, NULL); -+ -+ } -+ -+ cpmac_devices_installed = unit; -+ dbgPrint("Installed %d cpmac instances.\n", unit); -+ return ( (unit >= 0 ) ? 0 : -ENODEV ); -+ -+} /* init_module */ -+ -+ -+/*************************************************************** -+ * cleanup_module -+ * -+ * Returns: -+ * Nothing -+ * Parms: -+ * None -+ * -+ * Goes through the CpmacDevices list and frees the device -+ * structs and memory associated with each device (lists -+ * and buffers). It also ureserves the IO port regions -+ * associated with this device. -+ * -+ **************************************************************/ -+ -+void cpmac_exit(void) -+{ -+ struct net_device *p_dev; -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv; -+ -+ while (cpmac_devices_installed) -+ { -+ char proc_name[100]; -+ int proc_category_name_len = 0; -+ -+ p_dev = last_cpmac_device; -+ p_cpmac_priv = (CPMAC_PRIVATE_INFO_T *) p_dev->priv; -+ -+ dbgPrint("Unloading %s irq=%2d io=%04x\n",p_dev->name, (int) p_dev->irq, (int) p_dev->base_addr); -+ -+ if(g_init_enable_flag) -+ cpmac_p_dev_disable(p_dev); -+ -+ cpmac_drv_cleanup(p_cpmac_priv->drv_hal); -+ -+//#if defined (CONFIG_MIPS_AVALANCHE_LED) -+// avalanche_led_unregister(p_cpmac_priv->led_handle); -+//#endif -+ strcpy(proc_name, "avalanche/"); -+ strcat(proc_name, p_dev->name); -+ proc_category_name_len = strlen(proc_name); -+ -+ strcpy(proc_name + proc_category_name_len, "_rfc2665_stats"); -+ remove_proc_entry(proc_name, NULL); -+ -+ release_mem_region(p_dev->base_addr, p_cpmac_priv->dev_size); -+ unregister_netdev(p_dev); -+ last_cpmac_device = p_cpmac_priv->next_device; -+ -+ kfree(p_cpmac_priv->drv_hal); -+ kfree(p_dev); -+ -+ cpmac_devices_installed--; -+ } -+ -+ if(gp_stats_file) -+ remove_proc_entry("avalanche/cpmac_stats", NULL); -+ -+ remove_proc_entry("avalanche/cpmac_link", NULL); -+ remove_proc_entry("avalanche/cpmac_ver", NULL); -+ -+ psp_config_cleanup(); -+} -+ -+ -+module_init(cpmac_dev_probe); -+module_exit(cpmac_exit); -diff -urN linux.old/drivers/net/avalanche_cpmac/cpmac.h linux.dev/drivers/net/avalanche_cpmac/cpmac.h ---- linux.old/drivers/net/avalanche_cpmac/cpmac.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/cpmac.h 2005-07-12 02:48:42.043594000 +0200 -@@ -0,0 +1,379 @@ -+/****************************************************************************** -+ * FILE PURPOSE: CPMAC Linux Network Device Driver Header -+ ****************************************************************************** -+ * FILE NAME: cpmac.h -+ * -+ * DESCRIPTION: CPMAC Network Device Driver Header -+ * -+ * REVISION HISTORY: -+ * Date Name Details -+ *----------------------------------------------------------------------------- -+ * 27 Nov 2002 Suraj S Iyer Initial Create. -+ * 09 Jun 2003 Suraj S Iyer Preparing for GA. -+ * -+ * (C) Copyright 2003, Texas Instruments, Inc -+ *******************************************************************************/ -+ -+#ifndef CPMAC_H -+#define CPMAC_H -+ -+#include <linux/timer.h> -+#include <linux/netdevice.h> -+#include <asm/semaphore.h> -+#include <linux/ctype.h> -+#include <linux/interrupt.h> -+ -+#include "cpmacHalLx.h" -+/*----------------------------------------------------------------------------- -+ * Config macros. Use these to config the driver. -+ *---------------------------------------------------------------------------*/ -+#define CPMAC_MAX_FRAME_SIZE 1518 -+ -+#if defined(CONFIG_AR7WRD) || defined(CONFIG_AR7WI) || defined(CONFIG_AR7VWI)|| defined(CONFIG_AR7VW) -+#define CFG_RX_NUM_BUF_DESC 64 -+#define CFG_RX_NUM_BUF_SERVICE 32 -+#else -+#define CFG_RX_NUM_BUF_DESC 16 -+#define CFG_RX_NUM_BUF_SERVICE 8 -+#endif -+ -+#define CFG_RX_BUF_OFFSET 0 -+ -+#define CFG_TX_NUM_BUF_DESC 128 -+#define CFG_TX_NUM_BUF_SERVICE 20 -+#define CFG_TX_BUF_OFFSET 0 /* Lets not change this. */ -+#define CFG_TX_TIMEOUT 2000 /* ticks*/ -+#define CFG_TX_INT_DISABLE 1 /* Disable the Tx Complete interrupt */ -+ -+#define CFG_JUMBO_FRAMES 1 -+#define CFG_SHORT_FRAMES 1 -+#define CFG_PROMISCOUS 1 -+#define CFG_BROADCAST 1 -+#define CFG_MULTICAST 1 -+#define CFG_ALL_MULTI (1*(CFG_MULTICAST)) -+#define CFG_AUTO_NEGOTIATION 1 -+ -+#if defined (CONFIG_MIPS_AVALANCHE_MARVELL) -+#define EGRESS_TRAILOR_LEN 4 -+#define CFG_START_LINK_SPEED (_CPMDIO_NOPHY) -+#undef CPMAC_MAX_FRAME_SIZE -+#define CPMAC_MAX_FRAME_SIZE (1518 + EGRESS_TRAILOR_LEN) -+#else -+#define CFG_START_LINK_SPEED (_CPMDIO_10 | _CPMDIO_100 | _CPMDIO_HD | _CPMDIO_FD) /* auto nego */ -+#endif -+ -+#define CFG_LOOP_BACK 1 -+#define CFG_TX_FLOW_CNTL 0 -+#define CFG_RX_FLOW_CNTL 0 -+#define CFG_TX_PACING 0 -+#define CFG_RX_PASS_CRC 0 -+#define CFG_QOS_802_1Q 0 -+#define CFG_TX_NUM_CHAN 1 -+ -+ -+/*----------------------------------------------------------------------------- -+ * Private macros. -+ *---------------------------------------------------------------------------*/ -+#define MAX_TIMER 2 -+#define TX_TIMER 0 -+#define TICK_TIMER 0 -+#define MAX_TX_CHAN 8 -+ -+#define CPMAC_LINK_OFF 0 -+#define CPMAC_LINK_ON 1 -+/*#define CPMAC_SPEED_100 2 -+#define CPMAC_SPEED_10 3 -+#define CPMAC_FULL_DPLX 4 -+#define CPMAC_HALF_DPLX 5*/ -+#define CPMAC_RX_ACTIVITY 2 -+#define CPMAC_TX_ACTIVITY 3 -+ -+struct cpmac_timer_info; -+ -+typedef int (*CPMAC_HAL_ISR_FUNC_T)(HAL_DEVICE*, int*); -+typedef int (*CPMAC_TIMEOUT_CB_T)(struct cpmac_timer_info*); -+ -+typedef struct cpmac_ability_info -+{ -+ int promiscous; -+ int broadcast; -+ int multicast; -+ int all_multi; -+ int loop_back; -+ int jumbo_frames; -+ int short_frames; -+ int auto_negotiation; -+ int tx_flow_control; -+ int rx_flow_control; -+ int tx_pacing; -+ int link_speed; -+ int rx_pass_crc; -+ int qos_802_1q; -+ int tx_num_chan; -+} -+CPMAC_ABILITY_INFO_T; -+ -+#ifdef DEBUG -+typedef struct cpmac_timer_info -+{ -+ void *owner; -+ UINT32 delay_ticks; -+ WDOG_ID timer_id; -+ UINT32 is_running; -+ UINT32 timer_set_at; -+ CPMAC_TIMEOUT_CB_T timeout_CB; -+} CPMAC_TIMER_INFO_T; -+ -+typedef struct -+{ -+ void *owner; -+ unsigned int num_cl_desc; -+ CL_DESC *cl_desc_tbl; -+ M_CL_CONFIG *m_cl_blk_config; -+ NET_POOL *net_pool; -+ CL_POOL_ID clPoolId; -+ -+} CPMAC_NET_MEM_INFO_T; -+ -+#endif -+ -+typedef struct -+{ -+ void *owner; -+ CPMAC_HAL_ISR_FUNC_T hal_isr; -+ struct tasklet_struct tasklet; -+ int intr; -+ -+} CPMAC_ISR_INFO_T; -+ -+typedef struct cpmac_chan -+{ -+ int num_BD; -+ int buffer_size; -+ int buffer_offset; -+ int service_max; -+ int state; -+ int tot_buf_size; -+ int tot_reserve_bytes; -+ -+} CPMAC_CHAN_T; -+ -+#define CHAN_CLOSE 0 -+#define CHAN_OPENED 1 -+ -+typedef struct -+{ -+ int cfg_chan; -+ int dev_chan; -+ int opened_chan; -+ CPMAC_CHAN_T chan[1]; -+ int enable_802_1q; -+ -+} CPMAC_RX_CHAN_INFO_T; -+ -+typedef struct -+{ -+ int cfg_chan; -+ int dev_chan; -+ int opened_chan; -+ int tx_int_disable; -+ CPMAC_CHAN_T chan[MAX_TX_CHAN]; -+ -+} CPMAC_TX_CHAN_INFO_T; -+ -+ -+ -+typedef struct -+{ -+ void *owner; -+ HAL_FUNCTIONS *hal_funcs; -+ HAL_DEVICE *hal_dev; -+ OS_FUNCTIONS *os_funcs; -+// SEM_ID chan_teardown_sem; -+ int non_data_irq_expected; -+} CPMAC_DRV_HAL_INFO_T; -+ -+ -+typedef struct -+{ -+ unsigned long tx_discards; -+ unsigned long rx_discards; -+ unsigned long start_tick; -+ -+} CPMAC_DRV_STATS_T; -+ -+typedef struct -+{ -+ unsigned long ifInGoodFrames; -+ unsigned long ifInBroadcasts; -+ unsigned long ifInMulticasts; -+ unsigned long ifInPauseFrames; -+ unsigned long ifInCRCErrors; -+ unsigned long ifInAlignCodeErrors; -+ unsigned long ifInOversizedFrames; -+ unsigned long ifInJabberFrames; -+ unsigned long ifInUndersizedFrames; -+ unsigned long ifInFragments; -+ unsigned long ifInFilteredFrames; -+ unsigned long ifInQosFilteredFrames; -+ unsigned long ifInOctets; -+ unsigned long ifOutGoodFrames; -+ unsigned long ifOutBroadcasts; -+ unsigned long ifOutMulticasts; -+ unsigned long ifOutPauseFrames; -+ unsigned long ifDeferredTransmissions; -+ unsigned long ifCollisionFrames; -+ unsigned long ifSingleCollisionFrames; -+ unsigned long ifMultipleCollisionFrames; -+ unsigned long ifExcessiveCollisionFrames; -+ unsigned long ifLateCollisions; -+ unsigned long ifOutUnderrun; -+ unsigned long ifCarrierSenseErrors; -+ unsigned long ifOutOctets; -+ unsigned long if64OctetFrames; -+ unsigned long if65To127OctetFrames; -+ unsigned long if128To255OctetFrames; -+ unsigned long if256To511OctetFrames; -+ unsigned long if512To1023OctetFrames; -+ unsigned long if1024ToUPOctetFrames; -+ unsigned long ifNetOctets; -+ unsigned long ifRxSofOverruns; -+ unsigned long ifRxMofOverruns; -+ unsigned long ifRxDMAOverruns; -+ -+} CPMAC_DEVICE_MIB_T; -+ -+ -+typedef struct -+{ -+ void *owner; -+ int timer_count; -+ int timer_created; -+ struct timer_list timer[1]; -+ CPMAC_DRV_HAL_INFO_T *drv_hal; -+ unsigned int num_of_intr; -+ CPMAC_ISR_INFO_T cpmac_isr; -+ unsigned int link_speed; -+ unsigned int link_mode; -+ unsigned int enable_802_1q; -+ unsigned int timer_access_hal; -+ unsigned int loop_back; -+ CPMAC_RX_CHAN_INFO_T *rx_chan_info; -+ CPMAC_TX_CHAN_INFO_T *tx_chan_info; -+ CPMAC_ABILITY_INFO_T *ability_info; -+ CPMAC_DEVICE_MIB_T *device_mib; -+ CPMAC_DRV_STATS_T *stats; -+ unsigned int flags; -+ unsigned int delay_ticks; -+ char mac_addr[6]; -+ struct net_device_stats net_dev_stats; -+// rwlock_t rw_lock; -+ int set_to_close; -+ struct net_device *next_device; -+ unsigned int instance_num; -+ unsigned int non_data_irq_expected; -+ unsigned long dev_size; -+ void* led_handle; -+} CPMAC_PRIVATE_INFO_T; -+ -+ -+/* Private flags */ -+ -+/* bit 0 to 31, bit 32 is used to indicate set or reset */ -+ -+#define IFF_PRIV_SHORT_FRAMES 0x00010000 -+#define IFF_PRIV_JUMBO_FRAMES 0x00020000 -+#define IFF_PRIV_AUTOSPEED 0x00080000 -+#define IFF_PRIV_LINK10_HD 0x00100000 -+#define IFF_PRIV_LINK10_FD 0x00200000 -+#define IFF_PRIV_LINK100_HD 0x00400000 -+#define IFF_PRIV_LINK100_FD 0x00800000 -+#define IFF_PRIV_8021Q_EN 0x01000000 -+#define IFF_PRIV_NUM_TX_CHAN 0x02000000 -+#define IFF_PRIV_TX_FLOW_CNTL 0x04000000 -+#define IFF_PRIV_RX_FLOW_CNTL 0x08000000 -+#define IFF_PRIV_TX_PACING 0x10000000 -+#define IFF_PRIV_RX_PASS_CRC 0x20000000 -+ -+#define PRIVCSFLAGS 0x200 -+#define PRIVCGFLAGS 0x201 -+ -+ -+#define BLOCKING 1 -+#define CHAN_TEARDOWN 2 -+#define CHAN_SETUP 4 -+#define COMPLETE 8 -+#define FREE_BUFFER 16 -+ -+ -+static const char pszStats0[] = "Stats0"; -+static const char pszStats1[] = "Stats1"; -+static const char pszStats2[] = "Stats2"; -+static const char pszStats3[] = "Stats3"; -+static const char pszStats4[] = "Stats4"; -+static const char pszStatsDump[] = "StatsDump"; -+static const char pszStatsClear[] = "StatsClear"; -+static const char pszRX_PASS_CRC[] = "RX_PASS_CRC"; -+static const char pszRX_QOS_EN[] = "RX_QOS_EN"; -+static const char pszRX_NO_CHAIN[] = "RX_NO_CHAIN"; -+static const char pszRX_CMF_EN[] = "RX_CMF_EN"; -+static const char pszRX_CSF_EN[] = "RX_CSF_EN"; -+static const char pszRX_CEF_EN[] = "RX_CEF_EN"; -+static const char pszRX_CAF_EN[] = "RX_CAF_EN"; -+static const char pszRX_PROM_CH[] = "RX_PROM_CH"; -+static const char pszRX_BROAD_EN[] = "RX_BROAD_EN"; -+static const char pszRX_BROAD_CH[] = "RX_BROAD_CH"; -+static const char pszRX_MULT_EN[] = "RX_MULT_EN"; -+static const char pszRX_MULT_CH[] = "RX_MULT_CH"; -+static const char pszTX_PTYPE[] = "TX_PTYPE"; -+static const char pszTX_PACE[] = "TX_PACE"; -+static const char pszMII_EN[] = "MII_EN"; -+static const char pszTX_FLOW_EN[] = "TX_FLOW_EN"; -+static const char pszRX_FLOW_EN[] = "RX_FLOW_EN"; -+static const char pszRX_MAXLEN[] = "RX_MAXLEN"; -+static const char pszRX_FILTERLOWTHRESH[] = "RX_FILTERLOWTHRESH"; -+static const char pszRX0_FLOWTHRESH[] = "RX0_FLOWTHRESH"; -+static const char pszRX_UNICAST_SET[] = "RX_UNICAST_SET"; -+static const char pszRX_UNICAST_CLEAR[] = "RX_UNICAST_CLEAR"; -+static const char pszMdioConnect[] = "MdioConnect"; -+static const char pszMacAddr[] = "MacAddr"; -+static const char pszTick[] = "Tick"; -+static const char pszRX_MULTICAST[] = "RX_MULTICAST"; -+static const char pszRX_MULTI_ALL[] = "RX_MULTI_ALL"; -+static const char pszRX_MULTI_SINGLE[] = "RX_MULTI_SINGLE"; -+ -+static const char pszSet[] = "Set"; -+static const char pszGet[] = "Get"; -+static const char pszClear[] = "Clear"; -+ -+ -+void *cpmac_hal_malloc_buffer(unsigned int size, void *MemBase, unsigned int MemRange, -+ HAL_DEVICE *HalDev, HAL_RECEIVEINFO *HalReceiveInfo, -+ OS_RECEIVEINFO **OsReceiveInfo, OS_DEVICE *OsDev); -+ -+void cpmac_hal_tear_down_complete(OS_DEVICE*, int, int); -+int cpmac_hal_control(OS_DEVICE *p_END_obj, const char *key, -+ const char *action, void *value); -+int cpmac_hal_receive(OS_DEVICE *p_END_obj, FRAGLIST *fragList, -+ unsigned int FragCount, unsigned int pkt_len, -+ HAL_RECEIVEINFO *halReceiveInfo, -+ unsigned int mode); -+int cpmac_hal_send_complete(OS_SENDINFO*); -+ -+void cpmac_hal_isr(int irq, void *p_param, struct pt_regs *p_cb_param); -+void cpmac_handle_tasklet(unsigned long data); -+ -+inline static int cpmac_ci_strcmp(const char *s1, const char *s2) -+{ -+ while(*s1 && *s2) -+ { -+ if(tolower(*s1) != tolower(*s2)) -+ break; -+ s1++; -+ s2++; -+ } -+ -+ return(tolower(*s1) - tolower(*s2)); -+} -+ -+#endif -diff -urN linux.old/drivers/net/avalanche_cpmac/cpmacHalLx.c linux.dev/drivers/net/avalanche_cpmac/cpmacHalLx.c ---- linux.old/drivers/net/avalanche_cpmac/cpmacHalLx.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/cpmacHalLx.c 2005-07-12 02:48:42.044593000 +0200 -@@ -0,0 +1,492 @@ -+/****************************************************************************** -+ * FILE PURPOSE: CPMAC Net Driver HAL support Source -+ ****************************************************************************** -+ * FILE NAME: cpmacHalLx.c -+ * -+ * DESCRIPTION: CPMAC Network Device Driver Source -+ * -+ * REVISION HISTORY: -+ * -+ * Date Description Author -+ *----------------------------------------------------------------------------- -+ * 27 Nov 2002 Initial Creation Suraj S Iyer -+ * 09 Jun 2003 Updates for GA Suraj S Iyer -+ * 18 Dec 2003 Updated for 5.7 Suraj S Iyer -+ * -+ * (C) Copyright 2003, Texas Instruments, Inc -+ *******************************************************************************/ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/netdevice.h> -+#include <linux/etherdevice.h> -+#include <linux/delay.h> -+#include <linux/spinlock.h> -+#include <linux/proc_fs.h> -+#include <asm/io.h> -+#include <linux/string.h> -+ -+#include <asm/ar7/avalanche_intc.h> -+ -+#include "cpmacHalLx.h" -+#include "cpmac.h" -+ -+/* PSP config headers */ -+#include "psp_config_parse.h" -+#include "psp_config_mgr.h" -+ -+/* debug */ -+extern int cpmac_debug_mode; -+#define dbgPrint if (cpmac_debug_mode) printk -+#define errPrint printk -+ -+char CpmacSignature[] = "Cpmac driver"; -+static unsigned long irq_flags = 0; -+OS_SETUP *p_os_setup = NULL; -+ -+extern int avalanche_request_intr_pacing(int, unsigned int, unsigned int); -+extern int avalanche_free_intr_pacing(unsigned int blk_num); -+ -+/*---------------------------------------------------------------------------- -+ * Parameter extracting functionalities. -+ *--------------------------------------------------------------------------*/ -+static int os_find_parm_u_int(void *info_ptr, const char *param, unsigned int *val) -+{ -+ int ret_val = 0; -+ -+ if((ret_val = psp_config_get_param_uint(info_ptr, param, val)) == -1) -+ { -+ dbgPrint("Error: could not locate the requested \"%s\" param.\n",param); -+ ret_val = -1; -+ } -+ -+ return(ret_val); -+} -+ -+static int os_find_parm_val(void *info_ptr, const char *param, void *val) -+{ -+ int ret_val = 0; -+ -+ if(psp_config_get_param_string(info_ptr, param, val) == -1) -+ { -+ dbgPrint("Error: could not locate the requested \"%s\" param.\n",param); -+ ret_val = -1; -+ } -+ -+ return(ret_val); -+} -+ -+static int os_find_device(int unit, const char *find_name, void *device_info) -+{ -+ int ret_val = 0; -+ -+ if(psp_config_get((char *)find_name, unit, device_info) == -1) -+ { -+ dbgPrint("Error: could not locate the requested \"%s\" param.\n", find_name); -+ ret_val = -1; -+ } -+ -+ return(ret_val); -+} -+ -+/*--------------------------------------------------------------------------- -+ * Memory related OS abstraction. -+ *--------------------------------------------------------------------------*/ -+void os_free(void *mem_ptr) -+{ -+ kfree(mem_ptr); -+} -+ -+void os_free_buffer(OS_RECEIVEINFO *osReceiveInfo, void *mem_ptr) -+{ -+ dev_kfree_skb_any(osReceiveInfo); -+} -+ -+void os_free_dev(void *mem_ptr) -+{ -+ kfree(mem_ptr); -+} -+ -+void os_free_dma_xfer(void *mem_ptr) -+{ -+ kfree(mem_ptr); -+} -+ -+static void *os_malloc(unsigned int size) -+{ -+ return(kmalloc(size, GFP_KERNEL)); -+} -+ -+static void *os_malloc_dma_xfer(unsigned int size, -+ void *mem_base, -+ unsigned int mem_range) -+{ -+ return(kmalloc(size, GFP_KERNEL)); -+} -+ -+static void *os_malloc_dev(unsigned int size) -+{ -+ return(kmalloc(size, GFP_KERNEL)); -+} -+ -+ -+/*---------------------------------------------------------------------------- -+ * CRITICAL SECTION ENABLING/DISABLING. -+ *--------------------------------------------------------------------------*/ -+static void os_critical_on(void) -+{ -+ save_and_cli(irq_flags); -+} -+ -+static void os_critical_off(void) -+{ -+ restore_flags(irq_flags); -+} -+ -+/*---------------------------------------------------------------------------- -+ * Cache related abstraction -+ *--------------------------------------------------------------------------*/ -+static void os_cache_invalidate(void *mem_ptr, int size) -+{ -+ dma_cache_inv((unsigned long)mem_ptr, size); -+} -+ -+static void os_cache_writeback(void *mem_ptr, int size) -+{ -+ dma_cache_wback_inv((unsigned long)mem_ptr, size); -+} -+ -+/*----------------------------------------------------------------------------- -+ * Support functions. -+ *---------------------------------------------------------------------------*/ -+ -+static void hal_drv_unregister_isr(OS_DEVICE *p_dev, int intr) -+{ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_ISR_INFO_T *p_isr_cb_param = &p_cpmac_priv->cpmac_isr; -+ intr = LNXINTNUM(intr); -+ -+ free_irq(p_isr_cb_param->intr, p_isr_cb_param); -+ -+ dbgPrint("cpmac_hal_unregister called for the intr %d for unit %x and isr_cb_param %x.\n", -+ intr, p_cpmac_priv->instance_num, (unsigned int )&p_cpmac_priv->cpmac_isr); -+} -+ -+ -+static void hal_drv_register_isr(OS_DEVICE *p_dev, -+ CPMAC_HAL_ISR_FUNC_T hal_isr, int intr) -+{ -+ CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; -+ CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; -+ CPMAC_ISR_INFO_T *p_isr_cb_param = &p_cpmac_priv->cpmac_isr; -+ intr = LNXINTNUM(intr); -+ -+ dbgPrint("osRegister called for the intr %d for device %x and p_isr_cb_param %x.\n", -+ intr, (bit32u)p_dev, (bit32u)p_isr_cb_param); -+ -+ p_isr_cb_param->owner = p_drv_hal; -+ p_isr_cb_param->hal_isr = hal_isr; -+ p_isr_cb_param->intr = intr; -+ -+ tasklet_init(&p_isr_cb_param->tasklet, cpmac_handle_tasklet, (unsigned long)p_isr_cb_param); -+ dbgPrint("Success in registering irq %d for Cpmac unit# %d.\n", intr, p_cpmac_priv->instance_num); -+} -+ -+/*--------------------------------------------------------------------------- -+ * FUNCTIONS called by the CPMAC Net Device. -+ *-------------------------------------------------------------------------*/ -+static int load_os_funcs(OS_FUNCTIONS *os_func) -+{ -+ dbgPrint("os_init_module: Start\n"); -+ if( os_func == 0 ) -+ { -+ return(sizeof(OS_FUNCTIONS)); -+ } -+ -+ os_func->Control = cpmac_hal_control; -+ os_func->CriticalOn = os_critical_on; -+ os_func->CriticalOff = os_critical_off; -+ os_func->DataCacheHitInvalidate = os_cache_invalidate; -+ os_func->DataCacheHitWriteback = os_cache_writeback; -+ os_func->DeviceFindInfo = os_find_device; -+ os_func->DeviceFindParmUint = os_find_parm_u_int; -+ os_func->DeviceFindParmValue= os_find_parm_val; -+ os_func->Free = os_free; -+ os_func->FreeRxBuffer = os_free_buffer; -+ os_func->FreeDev = os_free_dev; -+ os_func->FreeDmaXfer = os_free_dma_xfer; -+ os_func->IsrRegister = hal_drv_register_isr; -+ os_func->IsrUnRegister = hal_drv_unregister_isr; -+ os_func->Malloc = os_malloc; -+ os_func->MallocDev = os_malloc_dev; -+ os_func->MallocDmaXfer = os_malloc_dma_xfer; -+ os_func->MallocRxBuffer = cpmac_hal_malloc_buffer; -+ os_func->Memset = memset; -+ os_func->Printf = printk; -+ os_func->Receive = cpmac_hal_receive; -+ os_func->SendComplete = cpmac_hal_send_complete; -+ os_func->Strcmpi = cpmac_ci_strcmp; -+ os_func->TeardownComplete = cpmac_hal_tear_down_complete; -+ os_func->Strstr = strstr; -+ os_func->Strtoul = simple_strtol; -+ os_func->Sprintf = sprintf; -+ os_func->Strlen = strlen; -+ -+ dbgPrint("os_init_module: Leave\n"); -+ -+ return(0); -+} -+ -+ -+int cpmac_drv_init(CPMAC_DRV_HAL_INFO_T *p_drv_hal) -+{ -+ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; -+ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; -+ -+ return(p_hal_funcs->Init(p_hal_dev)); -+} -+ -+int cpmac_drv_cleanup(CPMAC_DRV_HAL_INFO_T *p_drv_hal) -+{ -+ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; -+ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; -+ -+ int ret_val = p_hal_funcs->Shutdown(p_hal_dev); -+ -+#if 0 -+ if(ret_val == 0) -+ kfree(p_hal_funcs); -+ else -+ ret_val = -1; -+#endif -+ -+ kfree(p_drv_hal->os_funcs); -+ -+ return (ret_val); -+} -+ -+int cpmac_drv_tx_setup(HAL_FUNCTIONS *p_hal_funcs, -+ HAL_DEVICE *p_hal_dev, -+ CPMAC_TX_CHAN_INFO_T *p_tx_chan_info) -+{ -+ int ret_val = 0; -+ int count = 0; -+ CHANNEL_INFO chan_info; -+ -+ /* Let's setup the TX Channels. */ -+ for(count=0; count < p_tx_chan_info->cfg_chan; count++) -+ { -+ chan_info.Channel = count; -+ chan_info.Direction = DIRECTION_TX; -+ chan_info.TxNumBuffers = p_tx_chan_info->chan[count].num_BD; -+ chan_info.TxServiceMax = p_tx_chan_info->chan[count].service_max; -+ chan_info.TxNumQueues = 0; -+ -+ if((ret_val = p_hal_funcs->ChannelSetup(p_hal_dev, &chan_info, -+ NULL)) != 0) -+ { -+ errPrint("Error in opening channel %d for TX.\n", count); -+ ret_val = -1; -+ break; -+ } -+ -+ p_tx_chan_info->opened_chan++; -+ } -+ -+ return(ret_val); -+} -+ -+int cpmac_drv_rx_setup(HAL_FUNCTIONS *p_hal_funcs, -+ HAL_DEVICE *p_hal_dev, -+ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info) -+{ -+ int ret_val = 0; -+ CHANNEL_INFO chan_info; -+ -+ chan_info.Channel = 0; -+ chan_info.Direction = DIRECTION_RX; -+ chan_info.RxBufSize = p_rx_chan_info->chan[0].buffer_size; -+ chan_info.RxBufferOffset= p_rx_chan_info->chan[0].buffer_offset; -+ chan_info.RxNumBuffers = p_rx_chan_info->chan[0].num_BD; -+ chan_info.RxServiceMax = p_rx_chan_info->chan[0].service_max; -+ -+ if(p_hal_funcs->ChannelSetup(p_hal_dev, &chan_info, p_rx_chan_info) != 0) -+ { -+ errPrint("Error in opening channel %d for RX.\n", 0); -+ ret_val = -1; -+ } -+ -+ return(ret_val); -+} -+ -+int cpmac_drv_start(CPMAC_DRV_HAL_INFO_T *p_drv_hal, -+ CPMAC_TX_CHAN_INFO_T *p_tx_chan_info, -+ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info, -+ unsigned int flags) -+{ -+ int ret_val = 0; -+ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; -+ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; -+ -+ dbgPrint("It is in cpmac_drv_start for %x.\n", (unsigned int)p_drv_hal); -+ -+ if(flags & CHAN_SETUP) -+ { -+ if(cpmac_drv_tx_setup(p_hal_funcs, p_hal_dev, -+ p_tx_chan_info)!=0) -+ { -+ errPrint("Failed to set up tx channel(s).\n"); -+ ret_val = -1; -+ } -+ else if(cpmac_drv_rx_setup(p_hal_funcs, p_hal_dev, -+ p_rx_chan_info)!=0) -+ { -+ errPrint("Failed to set up rx channel.\n"); -+ ret_val = -1; -+ } -+ else -+ { -+ ret_val = 0; -+ } -+ } -+ -+ /* Error in setting up the Channels, quit. */ -+ if((ret_val == 0) && (ret_val = p_hal_funcs->Open(p_hal_dev)) != 0) -+ { -+ errPrint("failed to open the HAL!!!.\n"); -+ ret_val = -1; -+ } -+ -+ return (ret_val); -+} /* cpmac_drv_start */ -+ -+ -+ -+int cpmac_drv_tx_teardown(HAL_FUNCTIONS *p_hal_funcs, -+ HAL_DEVICE *p_hal_dev, -+ CPMAC_TX_CHAN_INFO_T *p_tx_chan_info, -+ unsigned int flags) -+{ -+ int ret_val = 0; -+ int count = 0; -+ -+ /* Let's setup the TX Channels. */ -+ for(; p_tx_chan_info->opened_chan > 0; -+ p_tx_chan_info->opened_chan--, count++) -+ { -+ if(p_hal_funcs->ChannelTeardown(p_hal_dev, count, flags) != 0) -+ { -+ errPrint("Error in tearing down channel %d for TX.\n", count); -+ ret_val = -1; -+ break; -+ } -+ } -+ -+ return(ret_val); -+} -+ -+ -+int cpmac_drv_rx_teardown(HAL_FUNCTIONS *p_hal_funcs, -+ HAL_DEVICE *p_hal_dev, -+ unsigned int flags) -+{ -+ int ret_val = 0; -+ -+ if(p_hal_funcs->ChannelTeardown(p_hal_dev, 0, flags) != 0) -+ { -+ errPrint("Error in tearing down channel %d for RX.\n", 0); -+ ret_val = -1; -+ } -+ -+ return(ret_val); -+} -+ -+int cpmac_drv_stop(CPMAC_DRV_HAL_INFO_T *p_drv_hal, -+ CPMAC_TX_CHAN_INFO_T *p_tx_chan_info, -+ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info, -+ unsigned int flags) -+{ -+ HAL_DEVICE *p_hal_dev = p_drv_hal->hal_dev; -+ HAL_FUNCTIONS *p_hal_funcs = p_drv_hal->hal_funcs; -+ int ret_val = 0; -+ -+ if(flags & CHAN_TEARDOWN) -+ { -+ unsigned int chan_flags = 0; -+ -+ if(flags & FREE_BUFFER) chan_flags |= 0x4; /* full tear down */ -+ if(flags & BLOCKING) chan_flags |= 0x8; /* blocking call */ -+ -+ dbgPrint("The teardown flags are %d.\n", flags); -+ dbgPrint("The teardown chan flags are %d.\n", chan_flags); -+ -+ if(cpmac_drv_tx_teardown(p_hal_funcs, p_hal_dev, -+ p_tx_chan_info, chan_flags | 0x1) != 0) -+ { -+ ret_val = -1; -+ errPrint("The tx channel teardown failed.\n"); -+ } -+ else if(cpmac_drv_rx_teardown(p_hal_funcs, p_hal_dev, chan_flags | 0x2) != 0) -+ { -+ ret_val = -1; -+ errPrint("The rx channel teardown failed.\n"); -+ } -+ else -+ { -+ ; -+ } -+ } -+ -+ if(ret_val == 0) -+ { -+ int close_flags = 1; -+ -+ if(flags & FREE_BUFFER) close_flags = 2; -+// if(flags & COMPLETE) close_flags = 3; -+ -+ if(p_hal_funcs->Close(p_hal_dev, close_flags) != 0) -+ { -+ ret_val = -1; -+ } -+ } -+ -+ return(ret_val); -+} -+ -+int cpmac_drv_init_module(CPMAC_DRV_HAL_INFO_T *p_drv_hal, OS_DEVICE *p_os_dev, int inst) -+{ -+ int ret_val = -1; -+ int hal_func_size; -+ -+ dbgPrint("Entering the CpmacInitModule for the inst %d \n", inst); -+ -+ if((p_drv_hal->os_funcs = kmalloc(sizeof(OS_FUNCTIONS), GFP_KERNEL)) == NULL) -+ { -+ errPrint("Failed to allocate memory for OS_FUNCTIONS.\n"); -+ } -+ else if(load_os_funcs(p_drv_hal->os_funcs) != 0) -+ { -+ errPrint("Failed to load OS funcs.\n"); -+ os_free(p_drv_hal->os_funcs); -+ } -+ else if(halCpmacInitModule(&p_drv_hal->hal_dev, p_os_dev, -+ &p_drv_hal->hal_funcs, p_drv_hal->os_funcs, -+ sizeof(*p_drv_hal->os_funcs), -+ &hal_func_size, inst) != 0) -+ { -+ errPrint("halCpmacInitModule failed for inst %d \n", inst); -+ os_free(p_drv_hal->os_funcs); -+ } -+ else if(p_drv_hal->hal_funcs->Probe(p_drv_hal->hal_dev) != 0) -+ { -+ errPrint("halCpmacProbe failed for inst %d \n", inst); -+ os_free(p_drv_hal->os_funcs); -+ } -+ else -+ { -+ /* every thing went well. */ -+ ret_val = 0; -+ } -+ -+ return (ret_val); -+} -diff -urN linux.old/drivers/net/avalanche_cpmac/cpmacHalLx.h linux.dev/drivers/net/avalanche_cpmac/cpmacHalLx.h ---- linux.old/drivers/net/avalanche_cpmac/cpmacHalLx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/cpmacHalLx.h 2005-07-12 02:48:42.044593000 +0200 -@@ -0,0 +1,51 @@ -+/****************************************************************************** -+ * FILE PURPOSE: CPMAC Linux Device Driver HAL support Header -+ ****************************************************************************** -+ * FILE NAME: cpmacHalVx.h -+ * -+ * DESCRIPTION: CPMAC Linux Device Driver Header -+ * -+ * REVISION HISTORY: -+ * -+ * Date Description Author -+ *----------------------------------------------------------------------------- -+ * 27 Nov 2002 Initial Creation Suraj S Iyer -+ * 09 Jun 2003 Updates for GA Suraj S Iyer -+ * -+ * (C) Copyright 2002, Texas Instruments, Inc -+ *******************************************************************************/ -+ -+#ifndef __CPMAC_HAL_LX_H -+#define __CPMAC_HAL_LX_H -+ -+ -+typedef struct net_device OS_DEVICE; -+typedef struct sk_buff OS_RECEIVEINFO; -+typedef struct sk_buff OS_SENDINFO; -+ -+#ifdef DEBUG -+typedef void HAL_RECEIVEINFO; -+typedef void HAL_DEVICE; -+typedef void OS_SETUP; -+#endif -+ -+#define OS_SETUP void -+#define HAL_DEVICE void -+#define HAL_RECEIVEINFO void -+ -+#define _CPHAL_CPMAC -+ -+#include "cpswhal_cpmac.h" -+#include "cpmac.h" -+ -+int cpmac_drv_start(CPMAC_DRV_HAL_INFO_T *, CPMAC_TX_CHAN_INFO_T*, -+ CPMAC_RX_CHAN_INFO_T *, unsigned int); -+int cpmac_drv_cleanup(CPMAC_DRV_HAL_INFO_T *); -+int cpmac_drv_init(CPMAC_DRV_HAL_INFO_T*); -+int cpmac_drv_close(CPMAC_DRV_HAL_INFO_T*); -+int cpmac_drv_open(CPMAC_DRV_HAL_INFO_T*); -+int cpmac_drv_init_module(CPMAC_DRV_HAL_INFO_T*, OS_DEVICE*, int); -+int cpmac_drv_stop(CPMAC_DRV_HAL_INFO_T *p_drv_hal,CPMAC_TX_CHAN_INFO_T *p_tx_chan_info, -+ CPMAC_RX_CHAN_INFO_T *p_rx_chan_info,unsigned int flags); -+ -+#endif -diff -urN linux.old/drivers/net/avalanche_cpmac/cpmac_reg.h linux.dev/drivers/net/avalanche_cpmac/cpmac_reg.h ---- linux.old/drivers/net/avalanche_cpmac/cpmac_reg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/cpmac_reg.h 2005-07-12 02:48:42.045593000 +0200 -@@ -0,0 +1,406 @@ -+/**************************************************************************** -+ TNETD73xx Software Support -+ Copyright(c) 2000, Texas Instruments Incorporated. All Rights Reserved. -+ -+ FILE: cpmac_reg.h Register definitions for the CPMAC module -+ -+ DESCRIPTION: -+ This include file contains register definitions for the -+ CPMAC module. -+ -+ HISTORY: -+ 15Nov00 BEGR Original version written -+ 30May02 MICK Added bits for Int Vector -+ 19Sep02 MICK Added INT_ACK per Channel -+ 08Nov02 GDUN Updated to use base -+ 12Nov02 MICK Incorporated into CPHAL -+*****************************************************************************/ -+#ifndef _INC_CPMAC_REG -+#define _INC_CPMAC_REG -+ -+#ifndef MEM_PTR -+#define MEM_PTR volatile bit32u * -+#endif -+ -+/*************************************************************************** -+ * -+ * C P M A C M E M O R Y M A P -+ * -+ **************************************************************************/ -+ -+#define pCPMAC_TX_IDVER(base) ((MEM_PTR)(base+0x000)) -+#define CPMAC_TX_IDVER(base) (*pCPMAC_TX_IDVER(base)) -+#define pCPMAC_TX_CONTROL(base) ((MEM_PTR)(base+0x004)) -+#define CPMAC_TX_CONTROL(base) (*pCPMAC_TX_CONTROL(base)) -+#define pCPMAC_TX_TEARDOWN(base) ((MEM_PTR)(base+0x008)) -+#define CPMAC_TX_TEARDOWN(base) (*pCPMAC_TX_TEARDOWN(base)) -+#define pCPMAC_RX_IDVER(base) ((MEM_PTR)(base+0x010)) -+#define CPMAC_RX_IDVER(base) (*pCPMAC_RX_IDVER(base)) -+#define pCPMAC_RX_CONTROL(base) ((MEM_PTR)(base+0x014)) -+#define CPMAC_RX_CONTROL(base) (*pCPMAC_RX_CONTROL(base)) -+#define pCPMAC_RX_TEARDOWN(base) ((MEM_PTR)(base+0x018)) -+#define CPMAC_RX_TEARDOWN(base) (*pCPMAC_RX_TEARDOWN(base)) -+#define pCPMAC_RX_MBP_ENABLE(base) ((MEM_PTR)(base+0x100)) -+#define CPMAC_RX_MBP_ENABLE(base) (*pCPMAC_RX_MBP_ENABLE(base)) -+#define pCPMAC_RX_UNICAST_SET(base) ((MEM_PTR)(base+0x104)) -+#define CPMAC_RX_UNICAST_SET(base) (*pCPMAC_RX_UNICAST_SET(base)) -+#define pCPMAC_RX_UNICAST_CLEAR(base) ((MEM_PTR)(base+0x108)) -+#define CPMAC_RX_UNICAST_CLEAR(base) (*pCPMAC_RX_UNICAST_CLEAR(base)) -+#define pCPMAC_RX_MAXLEN(base) ((MEM_PTR)(base+0x10C)) -+#define CPMAC_RX_MAXLEN(base) (*pCPMAC_RX_MAXLEN(base)) -+#define pCPMAC_RX_BUFFER_OFFSET(base) ((MEM_PTR)(base+0x110)) -+#define CPMAC_RX_BUFFER_OFFSET(base) (*pCPMAC_RX_BUFFER_OFFSET(base)) -+#define pCPMAC_RX_FILTERLOWTHRESH(base) ((MEM_PTR)(base+0x114)) -+#define CPMAC_RX_FILTERLOWTHRESH(base) (*pCPMAC_RX_FILTERLOWTHRESH(base)) -+#define pCPMAC_RX0_FLOWTHRESH(base) ((MEM_PTR)(base+0x120)) -+#define CPMAC_RX0_FLOWTHRESH(base) (*pCPMAC_RX0_FLOWTHRESH(base)) -+#define pCPMAC_RX1_FLOWTHRESH(base) ((MEM_PTR)(base+0x124)) -+#define CPMAC_RX1_FLOWTHRESH(base) (*pCPMAC_RX1_FLOWTHRESH(base)) -+#define pCPMAC_RX2_FLOWTHRESH(base) ((MEM_PTR)(base+0x128)) -+#define CPMAC_RX2_FLOWTHRESH(base) (*pCPMAC_RX2_FLOWTHRESH(base)) -+#define pCPMAC_RX3_FLOWTHRESH(base) ((MEM_PTR)(base+0x12C)) -+#define CPMAC_RX3_FLOWTHRESH(base) (*pCPMAC_RX3_FLOWTHRESH(base)) -+#define pCPMAC_RX4_FLOWTHRESH(base) ((MEM_PTR)(base+0x130)) -+#define CPMAC_RX4_FLOWTHRESH(base) (*pCPMAC_RX4_FLOWTHRESH(base)) -+#define pCPMAC_RX5_FLOWTHRESH(base) ((MEM_PTR)(base+0x134)) -+#define CPMAC_RX5_FLOWTHRESH(base) (*pCPMAC_RX5_FLOWTHRESH(base)) -+#define pCPMAC_RX6_FLOWTHRESH(base) ((MEM_PTR)(base+0x138)) -+#define CPMAC_RX6_FLOWTHRESH(base) (*pCPMAC_RX6_FLOWTHRESH(base)) -+#define pCPMAC_RX7_FLOWTHRESH(base) ((MEM_PTR)(base+0x13C)) -+#define CPMAC_RX7_FLOWTHRESH(base) (*pCPMAC_RX7_FLOWTHRESH(base)) -+#define pCPMAC_RX0_FREEBUFFER(base) ((MEM_PTR)(base+0x140)) -+#define CPMAC_RX0_FREEBUFFER(base) (*pCPMAC_RX0_FREEBUFFER(base)) -+#define pCPMAC_RX1_FREEBUFFER(base) ((MEM_PTR)(base+0x144)) -+#define CPMAC_RX1_FREEBUFFER(base) (*pCPMAC_RX1_FREEBUFFER(base)) -+#define pCPMAC_RX2_FREEBUFFER(base) ((MEM_PTR)(base+0x148)) -+#define CPMAC_RX2_FREEBUFFER(base) (*pCPMAC_RX2_FREEBUFFER(base)) -+#define pCPMAC_RX3_FREEBUFFER(base) ((MEM_PTR)(base+0x14C)) -+#define CPMAC_RX3_FREEBUFFER(base) (*pCPMAC_RX3_FREEBUFFER(base)) -+#define pCPMAC_RX4_FREEBUFFER(base) ((MEM_PTR)(base+0x150)) -+#define CPMAC_RX4_FREEBUFFER(base) (*pCPMAC_RX4_FREEBUFFER(base)) -+#define pCPMAC_RX5_FREEBUFFER(base) ((MEM_PTR)(base+0x154)) -+#define CPMAC_RX5_FREEBUFFER(base) (*pCPMAC_RX5_FREEBUFFER(base)) -+#define pCPMAC_RX6_FREEBUFFER(base) ((MEM_PTR)(base+0x158)) -+#define CPMAC_RX6_FREEBUFFER(base) (*pCPMAC_RX6_FREEBUFFER(base)) -+#define pCPMAC_RX7_FREEBUFFER(base) ((MEM_PTR)(base+0x15C)) -+#define CPMAC_RX7_FREEBUFFER(base) (*pCPMAC_RX7_FREEBUFFER(base)) -+#define pCPMAC_MACCONTROL(base) ((MEM_PTR)(base+0x160)) -+#define CPMAC_MACCONTROL(base) (*pCPMAC_MACCONTROL(base)) -+#define pCPMAC_MACSTATUS(base) ((MEM_PTR)(base+0x164)) -+#define CPMAC_MACSTATUS(base) (*pCPMAC_MACSTATUS(base)) -+#define pCPMAC_EMCONTROL(base) ((MEM_PTR)(base+0x168)) -+#define CPMAC_EMCONTROL(base) (*pCPMAC_EMCONTROL(base)) -+#define pCPMAC_TX_INTSTAT_RAW(base) ((MEM_PTR)(base+0x170)) -+#define CPMAC_TX_INTSTAT_RAW(base) (*pCPMAC_TX_INTSTAT_RAW(base)) -+#define pCPMAC_TX_INTSTAT_MASKED(base) ((MEM_PTR)(base+0x174)) -+#define CPMAC_TX_INTSTAT_MASKED(base) (*pCPMAC_TX_INTSTAT_MASKED(base)) -+#define pCPMAC_TX_INTMASK_SET(base) ((MEM_PTR)(base+0x178)) -+#define CPMAC_TX_INTMASK_SET(base) (*pCPMAC_TX_INTMASK_SET(base)) -+#define pCPMAC_TX_INTMASK_CLEAR(base) ((MEM_PTR)(base+0x17C)) -+#define CPMAC_TX_INTMASK_CLEAR(base) (*pCPMAC_TX_INTMASK_CLEAR(base)) -+#define pCPMAC_MAC_IN_VECTOR(base) ((MEM_PTR)(base+0x180)) -+#define CPMAC_MAC_IN_VECTOR(base) (*pCPMAC_MAC_IN_VECTOR(base)) -+#define pCPMAC_MAC_EOI_VECTOR(base) ((MEM_PTR)(base+0x184)) -+#define CPMAC_MAC_EOI_VECTOR(base) (*pCPMAC_MAC_EOI_VECTOR(base)) -+#define pCPMAC_RX_INTSTAT_RAW(base) ((MEM_PTR)(base+0x190)) -+#define CPMAC_RX_INTSTAT_RAW(base) (*pCPMAC_RX_INTSTAT_RAW(base)) -+#define pCPMAC_RX_INTSTAT_MASKED(base) ((MEM_PTR)(base+0x194)) -+#define CPMAC_RX_INTSTAT_MASKED(base) (*pCPMAC_RX_INTSTAT_MASKED(base)) -+#define pCPMAC_RX_INTMASK_SET(base) ((MEM_PTR)(base+0x198)) -+#define CPMAC_RX_INTMASK_SET(base) (*pCPMAC_RX_INTMASK_SET(base)) -+#define pCPMAC_RX_INTMASK_CLEAR(base) ((MEM_PTR)(base+0x19C)) -+#define CPMAC_RX_INTMASK_CLEAR(base) (*pCPMAC_RX_INTMASK_CLEAR(base)) -+#define pCPMAC_MAC_INTSTAT_RAW(base) ((MEM_PTR)(base+0x1A0)) -+#define CPMAC_MAC_INTSTAT_RAW(base) (*pCPMAC_MAC_INTSTAT_RAW(base)) -+#define pCPMAC_MAC_INTSTAT_MASKED(base) ((MEM_PTR)(base+0x1A4)) -+#define CPMAC_MAC_INTSTAT_MASKED(base) (*pCPMAC_MAC_INTSTAT_MASKED(base)) -+#define pCPMAC_MAC_INTMASK_SET(base) ((MEM_PTR)(base+0x1A8)) -+#define CPMAC_MAC_INTMASK_SET(base) (*pCPMAC_MAC_INTMASK_SET(base)) -+#define pCPMAC_MAC_INTMASK_CLEAR(base) ((MEM_PTR)(base+0x1AC)) -+#define CPMAC_MAC_INTMASK_CLEAR(base) (*pCPMAC_MAC_INTMASK_CLEAR(base)) -+#define pCPMAC_MACADDRLO_0(base) ((MEM_PTR)(base+0x1B0)) -+#define CPMAC_MACADDRLO_0(base) (*pCPMAC_MACADDRLO_0(base)) -+#define pCPMAC_MACADDRLO_1(base) ((MEM_PTR)(base+0x1B4)) -+#define CPMAC_MACADDRLO_1(base) (*pCPMAC_MACADDRLO_1(base)) -+#define pCPMAC_MACADDRLO_2(base) ((MEM_PTR)(base+0x1B8)) -+#define CPMAC_MACADDRLO_2(base) (*pCPMAC_MACADDRLO_2(base)) -+#define pCPMAC_MACADDRLO_3(base) ((MEM_PTR)(base+0x1BC)) -+#define CPMAC_MACADDRLO_3(base) (*pCPMAC_MACADDRLO_3(base)) -+#define pCPMAC_MACADDRLO_4(base) ((MEM_PTR)(base+0x1C0)) -+#define CPMAC_MACADDRLO_4(base) (*pCPMAC_MACADDRLO_4(base)) -+#define pCPMAC_MACADDRLO_5(base) ((MEM_PTR)(base+0x1C4)) -+#define CPMAC_MACADDRLO_5(base) (*pCPMAC_MACADDRLO_5(base)) -+#define pCPMAC_MACADDRLO_6(base) ((MEM_PTR)(base+0x1C8)) -+#define CPMAC_MACADDRLO_6(base) (*pCPMAC_MACADDRLO_6(base)) -+#define pCPMAC_MACADDRLO_7(base) ((MEM_PTR)(base+0x1CC)) -+#define CPMAC_MACADDRLO_7(base) (*pCPMAC_MACADDRLO_7(base)) -+#define pCPMAC_MACADDRMID(base) ((MEM_PTR)(base+0x1D0)) -+#define CPMAC_MACADDRMID(base) (*pCPMAC_MACADDRMID(base)) -+#define pCPMAC_MACADDRHI(base) ((MEM_PTR)(base+0x1D4)) -+#define CPMAC_MACADDRHI(base) (*pCPMAC_MACADDRHI(base)) -+#define pCPMAC_MACHASH1(base) ((MEM_PTR)(base+0x1D8)) -+#define CPMAC_MACHASH1(base) (*pCPMAC_MACHASH1(base)) -+#define pCPMAC_MACHASH2(base) ((MEM_PTR)(base+0x1DC)) -+#define CPMAC_MACHASH2(base) (*pCPMAC_MACHASH2(base)) -+#define pCPMAC_BOFFTEST(base) ((MEM_PTR)(base+0x1E0)) -+#define CPMAC_BOFFTEST(base) (*pCPMAC_BOFFTEST(base)) -+#define pCPMAC_PACTEST(base) ((MEM_PTR)(base+0x1E4)) -+#define CPMAC_PACTEST(base) (*pCPMAC_PACTEST(base)) -+#define pCPMAC_RXPAUSE(base) ((MEM_PTR)(base+0x1E8)) -+#define CPMAC_RXPAUSE(base) (*pCPMAC_RXPAUSE(base)) -+#define pCPMAC_TXPAUSE(base) ((MEM_PTR)(base+0x1EC)) -+#define CPMAC_TXPAUSE(base) (*pCPMAC_TXPAUSE(base)) -+/* STATISTICS */ -+#define pCPMAC_RXGOODFRAMES(base) ((MEM_PTR)(base+0x200)) -+#define CPMAC_RXGOODFRAMES(base) (*pCPMAC_RXGOODFRAMES(base)) -+#define pCPMAC_RXBROADCASTFRAMES(base) ((MEM_PTR)(base+0x204)) -+#define CPMAC_RXBROADCASTFRAMES(base) (*pCPMAC_RXBROADCASTFRAMES(base)) -+#define pCPMAC_RXMULTICASTFRAMES(base) ((MEM_PTR)(base+0x208)) -+#define CPMAC_RXMULTICASTFRAMES(base) (*pCPMAC_RXMULTICASTFRAMES(base)) -+#define pCPMAC_RXPAUSEFRAMES(base) ((MEM_PTR)(base+0x20C)) -+#define CPMAC_RXPAUSEFRAMES(base) (*pCPMAC_RXPAUSEFRAMES(base)) -+#define pCPMAC_RXCRCERRORS(base) ((MEM_PTR)(base+0x210)) -+#define CPMAC_RXCRCERRORS(base) (*pCPMAC_RXCRCERRORS(base)) -+#define pCPMAC_RXALIGNCODEERRORS(base) ((MEM_PTR)(base+0x214)) -+#define CPMAC_RXALIGNCODEERRORS(base) (*pCPMAC_RXALIGNCODEERRORS(base)) -+#define pCPMAC_RXOVERSIZEDFRAMES(base) ((MEM_PTR)(base+0x218)) -+#define CPMAC_RXOVERSIZEDFRAMES(base) (*pCPMAC_RXOVERSIZEDFRAMES(base)) -+#define pCPMAC_RXJABBERFRAMES(base) ((MEM_PTR)(base+0x21C)) -+#define CPMAC_RXJABBERFRAMES(base) (*pCPMAC_RXJABBERFRAMES(base)) -+#define pCPMAC_RXUNDERSIZEDFRAMES(base) ((MEM_PTR)(base+0x220)) -+#define CPMAC_RXUNDERSIZEDFRAMES(base) (*pCPMAC_RXUNDERSIZEDFRAMES(base)) -+#define pCPMAC_RXFRAGMENTS(base) ((MEM_PTR)(base+0x224)) -+#define CPMAC_RXFRAGMENTS(base) (*pCPMAC_RXFRAGMENTS(base)) -+#define pCPMAC_RXFILTEREDFRAMES(base) ((MEM_PTR)(base+0x228)) -+#define CPMAC_RXFILTEREDFRAMES(base) (*pCPMAC_RXFILTEREDFRAMES(base)) -+#define pCPMAC_RXQOSFILTEREDFRAMES(base) ((MEM_PTR)(base+0x22C)) -+#define CPMAC_RXQOSFILTEREDFRAMES(base) (*pCPMAC_RXQOSFILTEREDFRAMES(base)) -+#define pCPMAC_RXOCTETS(base) ((MEM_PTR)(base+0x230)) -+#define CPMAC_RXOCTETS(base) (*pCPMAC_RXOCTETS(base)) -+#define pCPMAC_TXGOODFRAMES(base) ((MEM_PTR)(base+0x234)) -+#define CPMAC_TXGOODFRAMES(base) (*pCPMAC_TXGOODFRAMES(base)) -+#define pCPMAC_TXBROADCASTFRAMES(base) ((MEM_PTR)(base+0x238)) -+#define CPMAC_TXBROADCASTFRAMES(base) (*pCPMAC_TXBROADCASTFRAMES(base)) -+#define pCPMAC_TXMULTICASTFRAMES(base) ((MEM_PTR)(base+0x23C)) -+#define CPMAC_TXMULTICASTFRAMES(base) (*pCPMAC_TXMULTICASTFRAMES(base)) -+#define pCPMAC_TXPAUSEFRAMES(base) ((MEM_PTR)(base+0x240)) -+#define CPMAC_TXPAUSEFRAMES(base) (*pCPMAC_TXPAUSEFRAMES(base)) -+#define pCPMAC_TXDEFERREDFRAMES(base) ((MEM_PTR)(base+0x244)) -+#define CPMAC_TXDEFERREDFRAMES(base) (*pCPMAC_TXDEFERREDFRAMES(base)) -+#define pCPMAC_TXCOLLISIONFRAMES(base) ((MEM_PTR)(base+0x248)) -+#define CPMAC_TXCOLLISIONFRAMES(base) (*pCPMAC_TXCOLLISIONFRAMES(base)) -+#define pCPMAC_TXSINGLECOLLFRAMES(base) ((MEM_PTR)(base+0x24C)) -+#define CPMAC_TXSINGLECOLLFRAMES(base) (*pCPMAC_TXSINGLECOLLFRAMES(base)) -+#define pCPMAC_TXMULTCOLLFRAMES(base) ((MEM_PTR)(base+0x250)) -+#define CPMAC_TXMULTCOLLFRAMES(base) (*pCPMAC_TXMULTCOLLFRAMES(base)) -+#define pCPMAC_TXEXCESSIVECOLLISIONS(base) ((MEM_PTR)(base+0x254)) -+#define CPMAC_TXEXCESSIVECOLLISIONS(base) (*pCPMAC_TXEXCESSIVECOLLISIONS(base)) -+#define pCPMAC_TXLATECOLLISIONS(base) ((MEM_PTR)(base+0x258)) -+#define CPMAC_TXLATECOLLISIONS(base) (*pCPMAC_TXLATECOLLISIONS(base)) -+#define pCPMAC_TXUNDERRUN(base) ((MEM_PTR)(base+0x25C)) -+#define CPMAC_TXUNDERRUN(base) (*pCPMAC_TXUNDERRUN(base)) -+#define pCPMAC_TXCARRIERSENSEERRORS(base) ((MEM_PTR)(base+0x260)) -+#define CPMAC_TXCARRIERSENSEERRORS(base) (*pCPMAC_TXCARRIERSENSEERRORS(base)) -+#define pCPMAC_TXOCTETS(base) ((MEM_PTR)(base+0x264)) -+#define CPMAC_TXOCTETS(base) (*pCPMAC_TXOCTETS(base)) -+#define pCPMAC_64OCTETFRAMES(base) ((MEM_PTR)(base+0x268)) -+#define CPMAC_64OCTETFRAMES(base) (*pCPMAC_64OCTETFRAMES(base)) -+#define pCPMAC_65T127OCTETFRAMES(base) ((MEM_PTR)(base+0x26C)) -+#define CPMAC_65T127OCTETFRAMES(base) (*pCPMAC_65T127OCTETFRAMES(base)) -+#define pCPMAC_128T255OCTETFRAMES(base) ((MEM_PTR)(base+0x270)) -+#define CPMAC_128T255OCTETFRAMES(base) (*pCPMAC_128T255OCTETFRAMES(base)) -+#define pCPMAC_256T511OCTETFRAMES(base) ((MEM_PTR)(base+0x274)) -+#define CPMAC_256T511OCTETFRAMES(base) (*pCPMAC_256T511OCTETFRAMES(base)) -+#define pCPMAC_512T1023OCTETFRAMES(base) ((MEM_PTR)(base+0x278)) -+#define CPMAC_512T1023OCTETFRAMES(base) (*pCPMAC_512T1023OCTETFRAMES(base)) -+#define pCPMAC_1024TUPOCTETFRAMES(base) ((MEM_PTR)(base+0x27C)) -+#define CPMAC_1024TUPOCTETFRAMES(base) (*pCPMAC_1024TUPOCTETFRAMES(base)) -+#define pCPMAC_NETOCTETS(base) ((MEM_PTR)(base+0x280)) -+#define CPMAC_NETOCTETS(base) (*pCPMAC_NETOCTETS(base)) -+#define pCPMAC_RXSOFOVERRUNS(base) ((MEM_PTR)(base+0x284)) -+#define CPMAC_RXSOFOVERRUNS(base) (*pCPMAC_RXSOFOVERRUNS(base)) -+#define pCPMAC_RXMOFOVERRUNS(base) ((MEM_PTR)(base+0x288)) -+#define CPMAC_RXMOFOVERRUNS(base) (*pCPMAC_RXMOFOVERRUNS(base)) -+#define pCPMAC_RXDMAOVERRUNS(base) ((MEM_PTR)(base+0x28C)) -+#define CPMAC_RXDMAOVERRUNS(base) (*pCPMAC_RXDMAOVERRUNS(base)) -+ -+#define CPMAC_TX_HDP(base,ch) (*(MEM_PTR)(base+0x600+(4*ch))) -+#define pCPMAC_TX0_HDP(base) ((MEM_PTR)(base+0x600)) -+#define CPMAC_TX0_HDP(base) (*pCPMAC_TX0_HDP(base)) -+#define pCPMAC_TX1_HDP(base) ((MEM_PTR)(base+0x604)) -+#define CPMAC_TX1_HDP(base) (*pCPMAC_TX1_HDP(base)) -+#define pCPMAC_TX2_HDP(base) ((MEM_PTR)(base+0x608)) -+#define CPMAC_TX2_HDP(base) (*pCPMAC_TX2_HDP(base)) -+#define pCPMAC_TX3_HDP(base) ((MEM_PTR)(base+0x60C)) -+#define CPMAC_TX3_HDP(base) (*pCPMAC_TX3_HDP(base)) -+#define pCPMAC_TX4_HDP(base) ((MEM_PTR)(base+0x610)) -+#define CPMAC_TX4_HDP(base) (*pCPMAC_TX4_HDP(base)) -+#define pCPMAC_TX5_HDP(base) ((MEM_PTR)(base+0x614)) -+#define CPMAC_TX5_HDP(base) (*pCPMAC_TX5_HDP(base)) -+#define pCPMAC_TX6_HDP(base) ((MEM_PTR)(base+0x618)) -+#define CPMAC_TX6_HDP(base) (*pCPMAC_TX6_HDP(base)) -+#define pCPMAC_TX7_HDP(base) ((MEM_PTR)(base+0x61C)) -+#define CPMAC_TX7_HDP(base) (*pCPMAC_TX7_HDP(base)) -+#define CPMAC_RX_HDP(base,ch) (*(MEM_PTR)(base+0x620+(4*ch))) -+#define pCPMAC_RX0_HDP(base) ((MEM_PTR)(base+0x620)) -+#define CPMAC_RX0_HDP(base) (*pCPMAC_RX0_HDP(base)) -+#define pCPMAC_RX1_HDP(base) ((MEM_PTR)(base+0x624)) -+#define CPMAC_RX1_HDP(base) (*pCPMAC_RX1_HDP(base)) -+#define pCPMAC_RX2_HDP(base) ((MEM_PTR)(base+0x628)) -+#define CPMAC_RX2_HDP(base) (*pCPMAC_RX2_HDP(base)) -+#define pCPMAC_RX3_HDP(base) ((MEM_PTR)(base+0x62C)) -+#define CPMAC_RX3_HDP(base) (*pCPMAC_RX3_HDP(base)) -+#define pCPMAC_RX4_HDP(base) ((MEM_PTR)(base+0x630)) -+#define CPMAC_RX4_HDP(base) (*pCPMAC_RX4_HDP(base)) -+#define pCPMAC_RX5_HDP(base) ((MEM_PTR)(base+0x634)) -+#define CPMAC_RX5_HDP(base) (*pCPMAC_RX5_HDP(base)) -+#define pCPMAC_RX6_HDP(base) ((MEM_PTR)(base+0x638)) -+#define CPMAC_RX6_HDP(base) (*pCPMAC_RX6_HDP(base)) -+#define pCPMAC_RX7_HDP(base) ((MEM_PTR)(base+0x63C)) -+#define CPMAC_RX7_HDP(base) (*pCPMAC_RX7_HDP(base)) -+ -+ -+#define CPMAC_TX_INT_ACK(base,ch) (*(MEM_PTR)(base+0x640+(4*ch))) -+ -+#define pCPMAC_TX0_INT_ACK(base) ((MEM_PTR)(base+0x640)) -+#define CPMAC_TX0_INT_ACK(base) (*pCPMAC_TX0_INT_ACK(base)) -+#define pCPMAC_TX1_INT_ACK(base) ((MEM_PTR)(base+0x644)) -+#define CPMAC_TX1_INT_ACK(base) (*pCPMAC_TX1_INT_ACK(base)) -+#define pCPMAC_TX2_INT_ACK(base) ((MEM_PTR)(base+0x648)) -+#define CPMAC_TX2_INT_ACK(base) (*pCPMAC_TX2_INT_ACK(base)) -+#define pCPMAC_TX3_INT_ACK(base) ((MEM_PTR)(base+0x64C)) -+#define CPMAC_TX3_INT_ACK(base) (*pCPMAC_TX3_INT_ACK(base)) -+#define pCPMAC_TX4_INT_ACK(base) ((MEM_PTR)(base+0x650)) -+#define CPMAC_TX4_INT_ACK(base) (*pCPMAC_TX4_INT_ACK(base)) -+#define pCPMAC_TX5_INT_ACK(base) ((MEM_PTR)(base+0x654)) -+#define CPMAC_TX5_INT_ACK(base) (*pCPMAC_TX5_INT_ACK(base)) -+#define pCPMAC_TX6_INT_ACK(base) ((MEM_PTR)(base+0x658)) -+#define CPMAC_TX6_INT_ACK(base) (*pCPMAC_TX6_INT_ACK(base)) -+#define pCPMAC_TX7_INT_ACK(base) ((MEM_PTR)(base+0x65C)) -+#define CPMAC_TX7_INT_ACK(base) (*pCPMAC_TX7_INT_ACK(base)) -+#define CPMAC_RX_INT_ACK(base,ch) (*(MEM_PTR)(base+0x660+(4*ch))) -+ -+#define pCPMAC_RX0_INT_ACK(base) ((MEM_PTR)(base+0x660)) -+#define CPMAC_RX0_INT_ACK(base) (*pCPMAC_RX0_INT_ACK(base)) -+#define pCPMAC_RX1_INT_ACK(base) ((MEM_PTR)(base+0x664)) -+#define CPMAC_RX1_INT_ACK(base) (*pCPMAC_RX1_INT_ACK(base)) -+#define pCPMAC_RX2_INT_ACK(base) ((MEM_PTR)(base+0x668)) -+#define CPMAC_RX2_INT_ACK(base) (*pCPMAC_RX2_INT_ACK(base)) -+#define pCPMAC_RX3_INT_ACK(base) ((MEM_PTR)(base+0x66C)) -+#define CPMAC_RX3_INT_ACK(base) (*pCPMAC_RX3_INT_ACK(base)) -+#define pCPMAC_RX4_INT_ACK(base) ((MEM_PTR)(base+0x670)) -+#define CPMAC_RX4_INT_ACK(base) (*pCPMAC_RX4_INT_ACK(base)) -+#define pCPMAC_RX5_INT_ACK(base) ((MEM_PTR)(base+0x674)) -+#define CPMAC_RX5_INT_ACK(base) (*pCPMAC_RX5_INT_ACK(base)) -+#define pCPMAC_RX6_INT_ACK(base) ((MEM_PTR)(base+0x678)) -+#define CPMAC_RX6_INT_ACK(base) (*pCPMAC_RX6_INT_ACK(base)) -+#define pCPMAC_RX7_INT_ACK(base) ((MEM_PTR)(base+0x67C)) -+#define CPMAC_RX7_INT_ACK(base) (*pCPMAC_RX7_INT_ACK(base)) -+ -+/****************************************************************************/ -+/* */ -+/* R E G I S T E R B I T D E F I N I T I O N S */ -+/* */ -+/****************************************************************************/ -+ -+/* TX_CONTROL */ -+ -+#define TX_EN (1 << 0) -+ -+/* RX_CONTROL */ -+ -+#define RX_EN (1 << 0) -+ -+/* RX_MBP_ENABLE */ -+ -+#define RX_PASS_CRC (1 << 30) -+#define RX_QOS_EN (1 << 29) -+#define RX_NO_CHAIN (1 << 28) -+ -+#define RX_CMF_EN (1 << 24) -+#define RX_CSF_EN (1 << 23) -+#define RX_CEF_EN (1 << 22) -+#define RX_CAF_EN (1 << 21) -+ -+#define RX_PROM_CH(n) (n << 16) -+#define RX_PROM_CH_MASK RX_PROM_CH(7) -+#define RX_PROM_CH_7 RX_PROM_CH(7) -+#define RX_PROM_CH_6 RX_PROM_CH(6) -+#define RX_PROM_CH_5 RX_PROM_CH(5) -+#define RX_PROM_CH_4 RX_PROM_CH(4) -+#define RX_PROM_CH_3 RX_PROM_CH(3) -+#define RX_PROM_CH_2 RX_PROM_CH(2) -+#define RX_PROM_CH_1 RX_PROM_CH(1) -+#define RX_PROM_CH_0 RX_PROM_CH(0) -+ -+#define RX_BROAD_EN (1 << 13) -+ -+#define RX_BROAD_CH(n) (n << 8) -+#define RX_BROAD_CH_MASK RX_BROAD_CH(7) -+#define RX_BROAD_CH_7 RX_BROAD_CH(7) -+#define RX_BROAD_CH_6 RX_BROAD_CH(6) -+#define RX_BROAD_CH_5 RX_BROAD_CH(5) -+#define RX_BROAD_CH_4 RX_BROAD_CH(4) -+#define RX_BROAD_CH_3 RX_BROAD_CH(3) -+#define RX_BROAD_CH_2 RX_BROAD_CH(2) -+#define RX_BROAD_CH_1 RX_BROAD_CH(1) -+#define RX_BROAD_CH_0 RX_BROAD_CH(0) -+ -+#define RX_MULT_EN (1 << 5) -+ -+#define RX_MULT_CH(n) (n << 0) -+#define RX_MULT_CH_MASK RX_MULT_CH(7) -+#define RX_MULT_CH_7 RX_MULT_CH(7) -+#define RX_MULT_CH_6 RX_MULT_CH(6) -+#define RX_MULT_CH_5 RX_MULT_CH(5) -+#define RX_MULT_CH_4 RX_MULT_CH(4) -+#define RX_MULT_CH_3 RX_MULT_CH(3) -+#define RX_MULT_CH_2 RX_MULT_CH(2) -+#define RX_MULT_CH_1 RX_MULT_CH(1) -+#define RX_MULT_CH_0 RX_MULT_CH(0) -+ -+ -+ -+/* RX_UNICAST_SET */ -+ -+#define RX_CH7_EN (1 << 7) -+#define RX_CH6_EN (1 << 6) -+#define RX_CH5_EN (1 << 5) -+#define RX_CH4_EN (1 << 4) -+#define RX_CH3_EN (1 << 3) -+#define RX_CH2_EN (1 << 2) -+#define RX_CH1_EN (1 << 1) -+#define RX_CH0_EN (1 << 0) -+ -+ -+ -+/* MAC control */ -+#define TX_PTYPE (1 << 9) -+#define TX_PACE (1 << 6) -+#define MII_EN (1 << 5) -+#define TX_FLOW_EN (1 << 4) -+#define RX_FLOW_EN (1 << 3) -+#define MTEST (1 << 2) -+#define CTRL_LOOPBACK (1 << 1) -+#define FULLDUPLEX (1 << 0) -+ -+ -+/* IntVec definitions */ -+#define MAC_IN_VECTOR_STATUS_INT (1 << 19) -+#define MAC_IN_VECTOR_HOST_INT (1 << 18) -+#define MAC_IN_VECTOR_RX_INT_OR (1 << 17) -+#define MAC_IN_VECTOR_TX_INT_OR (1 << 16) -+#define MAC_IN_VECTOR_RX_INT_VEC (7 << 8) -+#define MAC_IN_VECTOR_TX_INT_VEC (7) -+ -+ -+/* MacStatus */ -+ -+#define TX_HOST_ERR_CODE (0xF << 20) -+#define TX_ERR_CH (0x7 << 16) -+#define RX_HOST_ERR_CODE (0xF << 12) -+#define RX_ERR_CH (0x7 << 8) -+#define RX_QOS_ACT (1 << 2) -+#define RX_FLOW_ACT (1 << 1) -+#define TX_FLOW_ACT (1 << 0) -+#endif _INC_CPMAC_REG -diff -urN linux.old/drivers/net/avalanche_cpmac/cpmdio.c linux.dev/drivers/net/avalanche_cpmac/cpmdio.c ---- linux.old/drivers/net/avalanche_cpmac/cpmdio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/cpmdio.c 2005-07-12 02:48:42.046593000 +0200 -@@ -0,0 +1,960 @@ -+/*************************************************************************** -+** TNETD53xx Software Support -+** Copyright(c) 2002, Texas Instruments Incorporated. All Rights Reserved. -+** -+** FILE: cpmdio.c -+** -+** DESCRIPTION: -+** MDIO Polling State Machine API. Functions will enable mii-Phy -+** negotiation. -+** -+** HISTORY: -+** 01Jan01 Denis, Bill Original -+** 27Mar02 Michael Hanrahan (modified from emacmdio.c) -+** 07May02 Michael Hanrahan replaced clockwait for code delay -+** 10Jul02 Michael Hanrahan more debug, if fallback link is selected -+*****************************************************************************/ -+#define __CPHAL_CPMDIO -+ -+#include "mdio_reg.h" -+ -+#ifdef _CPHAL_CPMAC -+#define mdioPrintf PhyDev->HalDev->OsFunc->Printf -+#else -+#define mdioPrintf printf -+#endif -+ -+typedef struct _phy_device -+{ -+ bit32u miibase; -+ bit32u inst; -+ bit32u PhyState; -+ bit32u MdixMask; -+ bit32u PhyMask; -+ bit32u MLinkMask; -+ bit32u PhyMode; -+#ifdef _CPHAL_CPMAC -+ HAL_DEVICE *HalDev; -+#endif -+} _PHY_DEVICE; -+ -+static void _mdioDelayEmulate(PHY_DEVICE *PhyDev, int ClockWait); -+static void _mdioWaitForAccessComplete(PHY_DEVICE *PhyDev); -+static void _mdioUserAccess(PHY_DEVICE *PhyDev, bit32u method, bit32u regadr, bit32u phyadr, bit32u data); -+static bit32u _mdioUserAccessRead(PHY_DEVICE *PhyDev, bit32u regadr, bit32u phyadr); -+static void _mdioUserAccessWrite(PHY_DEVICE *PhyDev, bit32u regadr, bit32u phyadr, bit32u data); -+ -+static void _mdioDisablePhy(PHY_DEVICE *PhyDev,bit32u PhyNum); -+static void _mdioPhyTimeOut(PHY_DEVICE *PhyDev); -+static void _mdioResetPhy(PHY_DEVICE *PhyDev,bit32u PhyNum); -+ -+static void _mdioDumpPhy(PHY_DEVICE *PhyDev, bit32u p); -+static void _mdioDumpState(PHY_DEVICE *PhyDev); -+ -+/* Auto Mdix */ -+static void _mdioMdixDelay(PHY_DEVICE *PhyDev); -+static int _mdioMdixSupported(PHY_DEVICE *PhyDev); -+ -+static void _MdioDefaultState (PHY_DEVICE *PhyDev); -+static void _MdioFindingState (PHY_DEVICE *PhyDev); -+static void _MdioFoundState (PHY_DEVICE *PhyDev); -+static void _MdioInitState (PHY_DEVICE *PhyDev); -+static void _MdioLinkedState (PHY_DEVICE *PhyDev); -+static void _MdioLinkWaitState (PHY_DEVICE *PhyDev); -+static void _MdioLoopbackState (PHY_DEVICE *PhyDev); -+static void _MdioNwayStartState(PHY_DEVICE *PhyDev); -+static void _MdioNwayWaitState (PHY_DEVICE *PhyDev); -+ -+ -+ -+#ifndef TRUE -+#define TRUE (1==1) -+#endif -+ -+#ifndef FALSE -+#define FALSE (1==2) -+#endif -+ -+#define PHY_NOT_FOUND 0xFFFF /* Used in Phy Detection */ -+ -+/*PhyState breakout */ -+ -+#define PHY_DEV_OFFSET (0) -+#define PHY_DEV_SIZE (5) /* 5 Bits used */ -+#define PHY_DEV_MASK (0x1f<<PHY_DEV_OFFSET) -+ -+#define PHY_STATE_OFFSET (PHY_DEV_SIZE+PHY_DEV_OFFSET) -+#define PHY_STATE_SIZE (5) /* 10 Bits used */ -+#define PHY_STATE_MASK (0x1f<<PHY_STATE_OFFSET) -+ #define INIT (1<<PHY_STATE_OFFSET) -+ #define FINDING (2<<PHY_STATE_OFFSET) -+ #define FOUND (3<<PHY_STATE_OFFSET) -+ #define NWAY_START (4<<PHY_STATE_OFFSET) -+ #define NWAY_WAIT (5<<PHY_STATE_OFFSET) -+ #define LINK_WAIT (6<<PHY_STATE_OFFSET) -+ #define LINKED (7<<PHY_STATE_OFFSET) -+ #define LOOPBACK (8<<PHY_STATE_OFFSET) -+ -+#define PHY_SPEED_OFFSET (PHY_STATE_OFFSET+PHY_STATE_SIZE) -+#define PHY_SPEED_SIZE (1) /* 11 Bits used */ -+#define PHY_SPEED_MASK (1<<PHY_SPEED_OFFSET) -+ -+#define PHY_DUPLEX_OFFSET (PHY_SPEED_OFFSET+PHY_SPEED_SIZE) -+#define PHY_DUPLEX_SIZE (1) /* 12 Bits used */ -+#define PHY_DUPLEX_MASK (1<<PHY_DUPLEX_OFFSET) -+ -+#define PHY_TIM_OFFSET (PHY_DUPLEX_OFFSET+PHY_DUPLEX_SIZE) -+#define PHY_TIM_SIZE (10) /* 22 Bits used */ -+#define PHY_TIM_MASK (0x3ff<<PHY_TIM_OFFSET) -+ #define PHY_FIND_TO ( 2<<PHY_TIM_OFFSET) -+ #define PHY_RECK_TO (200<<PHY_TIM_OFFSET) -+ #define PHY_LINK_TO (500<<PHY_TIM_OFFSET) -+ #define PHY_NWST_TO (500<<PHY_TIM_OFFSET) -+ #define PHY_NWDN_TO (800<<PHY_TIM_OFFSET) -+ #define PHY_MDIX_TO (274<<PHY_TIM_OFFSET) /* 2.74 Seconds <--Spec and empirical */ -+ -+#define PHY_SMODE_OFFSET (PHY_TIM_OFFSET+PHY_TIM_SIZE) -+#define PHY_SMODE_SIZE (5) /* 27 Bits used */ -+#define PHY_SMODE_MASK (0x1f<<PHY_SMODE_OFFSET) -+ #define SMODE_AUTO (0x10<<PHY_SMODE_OFFSET) -+ #define SMODE_FD100 (0x08<<PHY_SMODE_OFFSET) -+ #define SMODE_HD100 (0x04<<PHY_SMODE_OFFSET) -+ #define SMODE_FD10 (0x02<<PHY_SMODE_OFFSET) -+ #define SMODE_HD10 (0x01<<PHY_SMODE_OFFSET) -+ #define SMODE_ALL (0x1f<<PHY_SMODE_OFFSET) -+ -+#define PHY_CHNG_OFFSET (PHY_SMODE_OFFSET+PHY_SMODE_SIZE) -+#define PHY_CHNG_SIZE (1) /* 28 Bits used */ -+#define PHY_CHNG_MASK (1<<PHY_CHNG_OFFSET) -+ #define PHY_CHANGE (1<<PHY_CHNG_OFFSET) -+ -+#define PHY_TIMEDOUT_OFFSET (PHY_CHNG_OFFSET+PHY_CHNG_SIZE) -+#define PHY_TIMEDOUT_SIZE (1) /* 29 Bits used */ -+#define PHY_TIMEDOUT_MASK (1<<PHY_TIMEDOUT_OFFSET) -+ #define PHY_MDIX_SWITCH (1<<PHY_TIMEDOUT_OFFSET) -+ -+#define PHY_MDIX_OFFSET (PHY_TIMEDOUT_OFFSET+PHY_TIMEDOUT_SIZE) -+#define PHY_MDIX_SIZE (1) /* 30 Bits used */ -+#define PHY_MDIX_MASK (1<<PHY_MDIX_OFFSET) -+ #define PHY_MDIX (1<<PHY_MDIX_OFFSET) -+ -+static char *lstate[]={"NULL","INIT","FINDING","FOUND","NWAY_START","NWAY_WAIT","LINK_WAIT","LINKED", "LOOPBACK"}; -+static int cpMacDebug; -+ -+/* Local MDIO Register Macros */ -+ -+#define myMDIO_ALIVE MDIO_ALIVE (PhyDev->miibase) -+#define myMDIO_CONTROL MDIO_CONTROL (PhyDev->miibase) -+#define myMDIO_LINK MDIO_LINK (PhyDev->miibase) -+#define myMDIO_LINKINT MDIO_LINKINT (PhyDev->miibase) -+#define myMDIO_USERACCESS MDIO_USERACCESS(PhyDev->miibase, PhyDev->inst) -+#define myMDIO_USERPHYSEL MDIO_USERPHYSEL(PhyDev->miibase, PhyDev->inst) -+#define myMDIO_VER MDIO_VER (PhyDev->miibase) -+ -+#ifndef VOLATILE32 -+#define VOLATILE32(addr) (*((volatile bit32u *)(addr))) -+#endif -+ -+/************************************ -+*** -+*** Delays at least ClockWait cylces -+*** before returning -+*** -+**************************************/ -+void _mdioDelayEmulate(PHY_DEVICE *PhyDev, int ClockWait) -+ { -+#ifdef _CPHAL_CPMAC /*+RC3.02*/ -+ HAL_DEVICE *HalDev = PhyDev->HalDev; /*+RC3.02*/ -+ osfuncSleep((int*)&ClockWait); /*+RC3.02*/ -+#else /*+RC3.02*/ -+ volatile bit32u i=0; -+ while(ClockWait--) -+ { -+ i |= myMDIO_LINK; /* MDIO register access to burn cycles */ -+ } -+#endif -+ } -+ -+void _mdioWaitForAccessComplete(PHY_DEVICE *PhyDev) -+ { -+ while((myMDIO_USERACCESS & MDIO_USERACCESS_GO)!=0) -+ { -+ } -+ } -+ -+void _mdioUserAccess(PHY_DEVICE *PhyDev, bit32u method, bit32u regadr, bit32u phyadr, bit32u data) -+ { -+ bit32u control; -+ -+ control = MDIO_USERACCESS_GO | -+ (method) | -+ (((regadr) << 21) & MDIO_USERACCESS_REGADR) | -+ (((phyadr) << 16) & MDIO_USERACCESS_PHYADR) | -+ ((data) & MDIO_USERACCESS_DATA); -+ -+ myMDIO_USERACCESS = control; -+ } -+ -+ -+ -+/************************************ -+*** -+*** Waits for MDIO_USERACCESS to be ready and reads data -+*** If 'WaitForData' set, waits for read to complete and returns Data, -+*** otherwise returns 0 -+*** Note: 'data' is 16 bits but we use 32 bits -+*** to be consistent with rest of the code. -+*** -+**************************************/ -+bit32u _mdioUserAccessRead(PHY_DEVICE *PhyDev, bit32u regadr, bit32u phyadr) -+ { -+ -+ _mdioWaitForAccessComplete(PhyDev); /* Wait until UserAccess ready */ -+ _mdioUserAccess(PhyDev, MDIO_USERACCESS_READ, regadr, phyadr, 0); -+ _mdioWaitForAccessComplete(PhyDev); /* Wait for Read to complete */ -+ -+ return(myMDIO_USERACCESS & MDIO_USERACCESS_DATA); -+ } -+ -+ -+/************************************ -+*** -+*** Waits for MDIO_USERACCESS to be ready and writes data -+*** -+**************************************/ -+void _mdioUserAccessWrite(PHY_DEVICE *PhyDev, bit32u regadr, bit32u phyadr, bit32u data) -+ { -+ _mdioWaitForAccessComplete(PhyDev); /* Wait until UserAccess ready */ -+ _mdioUserAccess(PhyDev, MDIO_USERACCESS_WRITE, regadr, phyadr, data); -+ } -+ -+void _mdioDumpPhyDetailed(PHY_DEVICE *PhyDev) -+{ -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u PhyNum; -+ int RegData; -+ -+ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; -+ -+ RegData = _mdioUserAccessRead(PhyDev, 0, PhyNum); -+ mdioPrintf("PhyControl: %04X, Lookback=%s, Speed=%s, Duplex=%s\n", -+ RegData, -+ RegData&PHY_LOOP?"On":"Off", -+ RegData&PHY_100?"100":"10", -+ RegData&PHY_FD?"Full":"Half"); -+ RegData = _mdioUserAccessRead(PhyDev, 1, PhyNum); -+ mdioPrintf("PhyStatus: %04X, AutoNeg=%s, Link=%s\n", -+ RegData, -+ RegData&NWAY_COMPLETE?"Complete":"NotComplete", -+ RegData&PHY_LINKED?"Up":"Down"); -+ RegData = _mdioUserAccessRead(PhyDev, 4, PhyNum); -+ mdioPrintf("PhyMyCapability: %04X, 100FD=%s, 100HD=%s, 10FD=%s, 10HD=%s\n", -+ RegData, -+ RegData&NWAY_FD100?"Yes":"No", -+ RegData&NWAY_HD100?"Yes":"No", -+ RegData&NWAY_FD10?"Yes":"No", -+ RegData&NWAY_HD10?"Yes":"No"); -+ -+ RegData = _mdioUserAccessRead(PhyDev, 5, PhyNum); -+ mdioPrintf("PhyPartnerCapability: %04X, 100FD=%s, 100HD=%s, 10FD=%s, 10HD=%s\n", -+ RegData, -+ RegData&NWAY_FD100?"Yes":"No", -+ RegData&NWAY_HD100?"Yes":"No", -+ RegData&NWAY_FD10?"Yes":"No", -+ RegData&NWAY_HD10?"Yes":"No"); -+} -+void _mdioDumpPhy(PHY_DEVICE *PhyDev, bit32u p) -+ { -+ bit32u j,n,PhyAcks; -+ bit32u PhyRegAddr; -+ bit32u phy_num; -+ bit32u PhyMask = PhyDev->PhyMask; -+ -+ PhyAcks=myMDIO_ALIVE; -+ PhyAcks&=PhyMask; /* Only interested in 'our' Phys */ -+ -+ for(phy_num=0,j=1;phy_num<32;phy_num++,j<<=1) -+ { -+ if (PhyAcks&j) -+ { -+ mdioPrintf("%2d%s:",phy_num,(phy_num==p)?">":" "); -+ for(PhyRegAddr=0;PhyRegAddr<6;PhyRegAddr++) -+ { -+ n = _mdioUserAccessRead(PhyDev, PhyRegAddr, phy_num); -+ mdioPrintf(" %04x",n&0x0ffff); -+ } -+ mdioPrintf("\n"); -+ } -+ } -+ _mdioDumpPhyDetailed(PhyDev); -+ } -+ -+void _mdioDumpState(PHY_DEVICE *PhyDev) -+ { -+ bit32u state = PhyDev->PhyState; -+ -+ if (!cpMacDebug) return; -+ -+ mdioPrintf("Phy: %d, ",(state&PHY_DEV_MASK)>>PHY_DEV_OFFSET); -+ mdioPrintf("State: %d/%s, ",(state&PHY_STATE_MASK)>>PHY_STATE_OFFSET,lstate[(state&PHY_STATE_MASK)>>PHY_STATE_OFFSET]); -+ mdioPrintf("Speed: %d, ",(state&PHY_SPEED_MASK)>>PHY_SPEED_OFFSET); -+ mdioPrintf("Dup: %d, ",(state&PHY_DUPLEX_MASK)>>PHY_DUPLEX_OFFSET); -+ mdioPrintf("Tim: %d, ",(state&PHY_TIM_MASK)>>PHY_TIM_OFFSET); -+ mdioPrintf("SMode: %d, ",(state&PHY_SMODE_MASK)>>PHY_SMODE_OFFSET); -+ mdioPrintf("Chng: %d",(state&PHY_CHNG_MASK)>>PHY_CHNG_OFFSET); -+ mdioPrintf("\n"); -+ -+ if (((state&PHY_STATE_MASK)!=FINDING)&&((state&PHY_STATE_MASK)!=INIT)) -+ _mdioDumpPhy(PhyDev, (state&PHY_DEV_MASK)>>PHY_DEV_OFFSET); -+ } -+ -+ -+void _mdioResetPhy(PHY_DEVICE *PhyDev,bit32u PhyNum) -+ { -+ bit16u PhyControlReg; -+ -+ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, PHY_RESET); -+ if (cpMacDebug) -+ mdioPrintf("cpMacMdioPhYReset(%d)\n",PhyNum); -+ -+ /* Read control register until Phy Reset is complete */ -+ do -+ { -+ PhyControlReg = _mdioUserAccessRead(PhyDev, PHY_CONTROL_REG, PhyNum); -+ } -+ while (PhyControlReg & PHY_RESET); /* Wait for Reset to clear */ -+ } -+ -+void _mdioDisablePhy(PHY_DEVICE *PhyDev,bit32u PhyNum) -+ { -+ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, PHY_ISOLATE|PHY_PDOWN); -+ -+ if (cpMacDebug) -+ mdioPrintf("cpMacMdioDisablePhy(%d)\n",PhyNum); -+ -+ } -+ -+void _MdioInitState(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u CurrentState; -+ -+ CurrentState=*PhyState; -+ CurrentState=(CurrentState&~PHY_TIM_MASK)|(PHY_FIND_TO); -+ CurrentState=(CurrentState&~PHY_STATE_MASK)|(FINDING); -+ CurrentState=(CurrentState&~PHY_SPEED_MASK); -+ CurrentState=(CurrentState&~PHY_DUPLEX_MASK); -+ CurrentState|=PHY_CHANGE; -+ -+ *PhyState=CurrentState; -+ -+ } -+ -+void _MdioFindingState(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u PhyMask = PhyDev->PhyMask; -+ bit32u PhyNum,i,j,PhyAcks; -+ -+ -+ PhyNum=PHY_NOT_FOUND; -+ -+ if (*PhyState&PHY_TIM_MASK) -+ { -+ *PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<<PHY_TIM_OFFSET)); -+ } -+ else -+ { -+ PhyAcks=myMDIO_ALIVE; -+ PhyAcks&=PhyMask; /* Only interested in 'our' Phys */ -+ -+ for(i=0,j=1;(i<32)&&((j&PhyAcks)==0);i++,j<<=1); -+ -+ if ((PhyAcks)&&(i<32)) PhyNum=i; -+ if (PhyNum!=PHY_NOT_FOUND) -+ { -+ /* Phy Found! */ -+ *PhyState=(*PhyState&~PHY_DEV_MASK)|((PhyNum&PHY_DEV_MASK)<<PHY_DEV_OFFSET); -+ *PhyState=(*PhyState&~PHY_STATE_MASK)|(FOUND); -+ *PhyState|=PHY_CHANGE; -+ if (cpMacDebug) -+ mdioPrintf("cpMacMdioFindingState: PhyNum: %d\n",PhyNum); -+ } -+ else -+ { -+ if (cpMacDebug) -+ mdioPrintf("cpMacMdioFindingState: Timed Out looking for a Phy!\n"); -+ *PhyState|=PHY_RECK_TO; /* This state currently has no support?*/ -+ } -+ } -+ } -+ -+void _MdioFoundState(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u PhyMask = PhyDev->PhyMask; -+ bit32u MLinkMask = PhyDev->MLinkMask; -+ bit32u PhyNum,PhyStatus,NWAYadvertise,m,phynum,i,j,PhyAcks; -+ bit32u PhySel; -+ -+ if ((*PhyState&PHY_SMODE_MASK)==0) return; -+ -+ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; -+ -+ PhyAcks=myMDIO_ALIVE; -+ PhyAcks&=PhyMask; /* Only interested in 'our' Phys */ -+ -+ /* Will now isolate all our Phys, except the one we have decided to use */ -+ for(phynum=0,j=1;phynum<32;phynum++,j<<=1) -+ { -+ if (PhyAcks&j) -+ { -+ if (phynum!=PhyNum) /* Do not disabled Found Phy */ -+ _mdioDisablePhy(PhyDev,phynum); -+ } -+ } -+ -+ /* Reset the Phy and proceed with auto-negotiation */ -+ _mdioResetPhy(PhyDev,PhyNum); -+ -+ /* Now setup the MDIOUserPhySel register */ -+ -+ PhySel=PhyNum; /* Set the phy address */ -+ -+ /* Set the way Link will be Monitored */ -+ /* Check the Link Selection Method */ -+ if ((1 << PhyNum) & MLinkMask) -+ PhySel |= MDIO_USERPHYSEL_LINKSEL; -+ -+ myMDIO_USERPHYSEL = PhySel; /* update PHYSEL */ -+ -+ /* Get the Phy Status */ -+ PhyStatus = _mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); -+ -+ -+#ifdef _CPHAL_CPMAC -+ /* For Phy Internal loopback test, need to wait until Phy -+ found, then set Loopback */ -+ if (PhyDev->HalDev->MdioConnect & _CPMDIO_LOOPBK) -+ { -+ /* Set Phy in Loopback */ -+ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, PHY_LOOP|PHY_FD); -+ /* Do a read to ensure PHY_LOOP has completed */ -+ _mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); -+ *PhyState=(*PhyState&~PHY_STATE_MASK)|(LOOPBACK); -+ *PhyState|=PHY_CHANGE; -+ return; -+ } -+#endif -+ -+ -+ if (cpMacDebug) -+ mdioPrintf("Enable Phy to negotiate external connection\n"); -+ -+ NWAYadvertise=NWAY_SEL; -+ if (*PhyState&SMODE_FD100) NWAYadvertise|=NWAY_FD100; -+ if (*PhyState&SMODE_HD100) NWAYadvertise|=NWAY_HD100; -+ if (*PhyState&SMODE_FD10) NWAYadvertise|=NWAY_FD10; -+ if (*PhyState&SMODE_HD10) NWAYadvertise|=NWAY_HD10; -+ -+ *PhyState&=~(PHY_TIM_MASK|PHY_STATE_MASK); -+ if ((PhyStatus&NWAY_CAPABLE)&&(*PhyState&SMODE_AUTO)) /*NWAY Phy Detected*/ -+ { -+ /*For NWAY compliant Phys */ -+ -+ _mdioUserAccessWrite(PhyDev, NWAY_ADVERTIZE_REG, PhyNum, NWAYadvertise); -+ -+ if (cpMacDebug) -+ { -+ mdioPrintf("NWAY Advertising: "); -+ if (NWAYadvertise&NWAY_FD100) mdioPrintf("FullDuplex-100 "); -+ if (NWAYadvertise&NWAY_HD100) mdioPrintf("HalfDuplex-100 "); -+ if (NWAYadvertise&NWAY_FD10) mdioPrintf("FullDuplex-10 "); -+ if (NWAYadvertise&NWAY_HD10) mdioPrintf("HalfDuplex-10 "); -+ mdioPrintf("\n"); -+ } -+ -+ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, AUTO_NEGOTIATE_EN); -+ -+ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, AUTO_NEGOTIATE_EN|RENEGOTIATE); -+ -+ *PhyState|=PHY_CHANGE|PHY_NWST_TO|NWAY_START; -+ } -+ else -+ { -+ *PhyState&=~SMODE_AUTO; /*The Phy is not capable of auto negotiation! */ -+ m=NWAYadvertise; -+ for(j=0x8000,i=0;(i<16)&&((j&m)==0);i++,j>>=1); -+ m=j; -+ j=0; -+ if (m&(NWAY_FD100|NWAY_HD100)) -+ { -+ j=PHY_100; -+ m&=(NWAY_FD100|NWAY_HD100); -+ } -+ if (m&(NWAY_FD100|NWAY_FD10)) -+ j |= PHY_FD; -+ if (cpMacDebug) -+ mdioPrintf("Requested PHY mode %s Duplex %s Mbps\n",(j&PHY_FD)?"Full":"Half",(j&PHY_100)?"100":"10"); -+ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, j); -+ *PhyState&=~PHY_SPEED_MASK; -+ if (j&PHY_100) -+ *PhyState|=(1<<PHY_SPEED_OFFSET); -+ *PhyState&=~PHY_DUPLEX_MASK; -+ if (j&PHY_FD) -+ *PhyState|=(1<<PHY_DUPLEX_OFFSET); -+ *PhyState|=PHY_CHANGE|PHY_LINK_TO|LINK_WAIT; -+ } -+ _mdioMdixDelay(PhyDev); /* If AutoMdix add delay */ -+ } -+ -+void _MdioNwayStartState(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u PhyNum,PhyMode; -+ -+ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; -+ -+ /*Wait for Negotiation to start */ -+ -+ PhyMode=_mdioUserAccessRead(PhyDev, PHY_CONTROL_REG, PhyNum); -+ -+ if((PhyMode&RENEGOTIATE)==0) -+ { -+ _mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); /*Flush pending latch bits*/ -+ *PhyState&=~(PHY_STATE_MASK|PHY_TIM_MASK); -+ *PhyState|=PHY_CHANGE|NWAY_WAIT|PHY_NWDN_TO; -+ _mdioMdixDelay(PhyDev); /* If AutoMdix add delay */ -+ } -+ else -+ { -+ if (*PhyState&PHY_TIM_MASK) -+ *PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<<PHY_TIM_OFFSET)); -+ else -+ _mdioPhyTimeOut(PhyDev); -+ } -+ } -+ -+void _MdioNwayWaitState(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u PhyNum,PhyStatus,NWAYadvertise,NWAYREadvertise,NegMode,i,j; -+ -+ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; -+ -+ PhyStatus=_mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); -+ -+ if (PhyStatus&NWAY_COMPLETE) -+ { -+ *PhyState|=PHY_CHANGE; -+ *PhyState&=~PHY_SPEED_MASK; -+ *PhyState&=~PHY_DUPLEX_MASK; -+ -+ NWAYadvertise =_mdioUserAccessRead(PhyDev, NWAY_ADVERTIZE_REG, PhyNum); -+ NWAYREadvertise =_mdioUserAccessRead(PhyDev, NWAY_REMADVERTISE_REG, PhyNum); -+ -+ /* Negotiated mode is we and the remote have in common */ -+ NegMode = NWAYadvertise & NWAYREadvertise; -+ -+ if (cpMacDebug) -+ { -+ mdioPrintf("Phy: %d, ",(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET); -+ mdioPrintf("NegMode %04X, NWAYadvertise %04X, NWAYREadvertise %04X\n", -+ NegMode, NWAYadvertise, NWAYREadvertise); -+ } -+ -+ /* Limit negotiation to fields below */ -+ NegMode &= (NWAY_FD100|NWAY_HD100|NWAY_FD10|NWAY_HD10); -+ -+ if (NegMode==0) -+ { -+ NegMode=(NWAY_HD100|NWAY_HD10)&NWAYadvertise; /*or 10 ?? who knows, Phy is not MII compliant*/ -+ if(cpMacDebug) -+ { -+ mdioPrintf("Mdio:WARNING: Negotiation complete but NO agreement, default is HD\n"); -+ _mdioDumpPhyDetailed(PhyDev); -+ } -+ } -+ for(j=0x8000,i=0;(i<16)&&((j&NegMode)==0);i++,j>>=1); -+ -+ -+ NegMode=j; -+ if (cpMacDebug) -+ { -+ mdioPrintf("Negotiated connection: "); -+ if (NegMode&NWAY_FD100) mdioPrintf("FullDuplex 100 Mbs\n"); -+ if (NegMode&NWAY_HD100) mdioPrintf("HalfDuplex 100 Mbs\n"); -+ if (NegMode&NWAY_FD10) mdioPrintf("FullDuplex 10 Mbs\n"); -+ if (NegMode&NWAY_HD10) mdioPrintf("HalfDuplex 10 Mbs\n"); -+ } -+ if (NegMode!=0) -+ { -+ if (PhyStatus&PHY_LINKED) -+ *PhyState=(*PhyState&~PHY_STATE_MASK)|LINKED; -+ else -+ *PhyState=(*PhyState&~PHY_STATE_MASK)|LINK_WAIT; -+ if (NegMode&(NWAY_FD100|NWAY_HD100)) -+ *PhyState=(*PhyState&~PHY_SPEED_MASK)|(1<<PHY_SPEED_OFFSET); -+ if (NegMode&(NWAY_FD100|NWAY_FD10)) -+ *PhyState=(*PhyState&~PHY_DUPLEX_MASK)|(1<<PHY_DUPLEX_OFFSET); -+ } -+ } -+ else -+ { -+ if (*PhyState&PHY_TIM_MASK) -+ *PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<<PHY_TIM_OFFSET)); -+ else -+ _mdioPhyTimeOut(PhyDev); -+ } -+ } -+ -+void _MdioLinkWaitState(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u PhyStatus; -+ bit32u PhyNum; -+ -+ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; -+ -+ PhyStatus=_mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); -+ -+ if (PhyStatus&PHY_LINKED) -+ { -+ *PhyState=(*PhyState&~PHY_STATE_MASK)|LINKED; -+ *PhyState|=PHY_CHANGE; -+ } -+ else -+ { -+ if (*PhyState&PHY_TIM_MASK) -+ *PhyState=(*PhyState&~PHY_TIM_MASK)|((*PhyState&PHY_TIM_MASK)-(1<<PHY_TIM_OFFSET)); -+ else -+ _mdioPhyTimeOut(PhyDev); -+ } -+ } -+ -+void _mdioPhyTimeOut(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState; -+ -+ if(_mdioMdixSupported(PhyDev) == 0) -+ return; /* AutoMdix not supported */ -+ -+ PhyState = &PhyDev->PhyState; -+ -+ /* Indicate MDI/MDIX mode switch is needed */ -+ *PhyState|=PHY_MDIX_SWITCH; -+ -+ /* Toggle the MDIX mode indicatir */ -+ if(*PhyState & PHY_MDIX) -+ *PhyState &= ~PHY_MDIX_MASK; /* Current State is MDIX, set to MDI */ -+ else -+ *PhyState |= PHY_MDIX_MASK; /* Current State is MDI, set to MDIX */ -+ -+ /* Reset state machine to FOUND */ -+ *PhyState=(*PhyState&~PHY_STATE_MASK)|(FOUND); -+ } -+ -+void _MdioLoopbackState(PHY_DEVICE *PhyDev) -+ { -+ return; -+ } -+ -+void _MdioLinkedState(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u PhyNum = (*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; -+ -+ if (myMDIO_LINK&(1<<PhyNum)) return; /* if still Linked, exit*/ -+ -+ /* Not Linked */ -+ *PhyState&=~(PHY_STATE_MASK|PHY_TIM_MASK); -+ if (*PhyState&SMODE_AUTO) -+ *PhyState|=PHY_CHANGE|NWAY_WAIT|PHY_NWDN_TO; -+ else -+ *PhyState|=PHY_CHANGE|PHY_LINK_TO|LINK_WAIT; -+ -+ _mdioMdixDelay(PhyDev); /* If AutoMdix add delay */ -+ } -+ -+void _MdioDefaultState(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ /*Awaiting a cpMacMdioInit call */ -+ *PhyState|=PHY_CHANGE; -+ } -+ -+ -+/*User Calls********************************************************* */ -+ -+void cpMacMdioClose(PHY_DEVICE *PhyDev, int Full) -+ { -+ } -+ -+ -+int cpMacMdioInit(PHY_DEVICE *PhyDev, bit32u miibase, bit32u inst, bit32u PhyMask, bit32u MLinkMask, bit32u MdixMask, bit32u ResetReg, bit32u ResetBit, bit32u MdioBusFreq, bit32u MdioClockFreq, int verbose, void *Info) -+ { -+ bit32u HighestChannel; -+ bit32u ControlState; -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u clkdiv; /*MJH+030328*/ -+ -+ cpMacDebug=verbose; -+ -+ PhyDev->miibase = miibase; -+ PhyDev->inst = inst; -+ PhyDev->PhyMask = PhyMask; -+ PhyDev->MLinkMask = MLinkMask; -+ PhyDev->MdixMask = MdixMask; -+#ifdef _CPHAL_CPMAC -+ PhyDev->HalDev = (HAL_DEVICE*) Info; -+#endif -+ -+ *PhyState &= ~PHY_MDIX_MASK; /* Set initial State to MDI */ -+ -+ /* Check that the channel supplied is within range */ -+ HighestChannel = (myMDIO_CONTROL & MDIO_CONTROL_HIGHEST_USER_CHANNEL) > 8; -+ if(inst > HighestChannel) -+ return(HighestChannel); -+ -+ /*Setup MII MDIO access regs */ -+ -+ /* Calculate the correct value for the mclkdiv */ -+ /* See PITS #14 */ -+ if (MdioClockFreq) /*MJH+030402*/ -+ clkdiv = (MdioBusFreq / MdioClockFreq) - 1; /*MJH+030402*/ -+ else /*MJH+030402*/ -+ clkdiv = 0xFF; /*MJH+030402*/ -+ -+ ControlState = MDIO_CONTROL_ENABLE; -+ ControlState |= (clkdiv & MDIO_CONTROL_CLKDIV); /*MJH+030328*/ -+ -+ /* -+ If mii is not out of reset or if the Control Register is not set correctly -+ then initalize -+ */ -+ if( !(VOLATILE32(ResetReg) & (1 << ResetBit)) || -+ ((myMDIO_CONTROL & (MDIO_CONTROL_CLKDIV | MDIO_CONTROL_ENABLE)) != ControlState) )/*GSG~030404*/ -+ { -+ /* MII not setup, Setup initial condition */ -+ VOLATILE32(ResetReg) &= ~(1 << ResetBit); -+ _mdioDelayEmulate(PhyDev, 64); -+ VOLATILE32(ResetReg) |= (1 << ResetBit); /* take mii out of reset */ -+ _mdioDelayEmulate(PhyDev, 64); -+ myMDIO_CONTROL = ControlState; /* Enable MDIO */ -+ } -+ -+ *PhyState=INIT; -+ -+ if (cpMacDebug) -+ mdioPrintf("cpMacMdioInit\n"); -+ _mdioDumpState(PhyDev); -+ return(0); -+ } -+ -+void cpMacMdioSetPhyMode(PHY_DEVICE *PhyDev,bit32u PhyMode) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u CurrentState; -+ -+ PhyDev->PhyMode = PhyMode; /* used for AUTOMIDX, planned to replace PhyState fields */ -+ -+ *PhyState&=~PHY_SMODE_MASK; -+ -+ if (PhyMode&NWAY_AUTO) *PhyState|=SMODE_AUTO; -+ if (PhyMode&NWAY_FD100) *PhyState|=SMODE_FD100; -+ if (PhyMode&NWAY_HD100) *PhyState|=SMODE_HD100; -+ if (PhyMode&NWAY_FD10) *PhyState|=SMODE_FD10; -+ if (PhyMode&NWAY_HD10) *PhyState|=SMODE_HD10; -+ -+ CurrentState=*PhyState&PHY_STATE_MASK; -+ if ((CurrentState==NWAY_START)|| -+ (CurrentState==NWAY_WAIT) || -+ (CurrentState==LINK_WAIT) || -+ (CurrentState==LINKED) ) -+ *PhyState=(*PhyState&~PHY_STATE_MASK)|FOUND|PHY_CHANGE; -+ if (cpMacDebug) -+ mdioPrintf("cpMacMdioSetPhyMode:%08X Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d\n", PhyMode, -+ PhyMode&NWAY_AUTO, PhyMode&NWAY_FD10, PhyMode&NWAY_HD10, PhyMode&NWAY_FD100, -+ PhyMode&NWAY_HD100); -+ _mdioDumpState(PhyDev); -+ } -+ -+/* cpMacMdioTic is called every 10 mili seconds to process Phy states */ -+ -+int cpMacMdioTic(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u CurrentState; -+ -+ /*Act on current state of the Phy */ -+ -+ CurrentState=*PhyState; -+ switch(CurrentState&PHY_STATE_MASK) -+ { -+ case INIT: _MdioInitState(PhyDev); break; -+ case FINDING: _MdioFindingState(PhyDev); break; -+ case FOUND: _MdioFoundState(PhyDev); break; -+ case NWAY_START: _MdioNwayStartState(PhyDev); break; -+ case NWAY_WAIT: _MdioNwayWaitState(PhyDev); break; -+ case LINK_WAIT: _MdioLinkWaitState(PhyDev); break; -+ case LINKED: _MdioLinkedState(PhyDev); break; -+ case LOOPBACK: _MdioLoopbackState(PhyDev); break; -+ default: _MdioDefaultState(PhyDev); break; -+ } -+ -+ /*Dump state info if a change has been detected */ -+ -+ if ((CurrentState&~PHY_TIM_MASK)!=(*PhyState&~PHY_TIM_MASK)) -+ _mdioDumpState(PhyDev); -+ -+ /* Check is MDI/MDIX mode switch is needed */ -+ if(*PhyState & PHY_MDIX_SWITCH) -+ { -+ bit32u Mdix; -+ -+ *PhyState &= ~PHY_MDIX_SWITCH; /* Clear Mdix Flip indicator */ -+ -+ if(*PhyState & PHY_MDIX) -+ Mdix = 1; -+ else -+ Mdix = 0; -+ return(_MIIMDIO_MDIXFLIP|Mdix); -+ } -+ -+ /*Return state change to user */ -+ -+ if (*PhyState&PHY_CHNG_MASK) -+ { -+ *PhyState&=~PHY_CHNG_MASK; -+ return(1); -+ } -+ else -+ return(0); -+ } -+ -+/* cpMacMdioGetDuplex is called to retrieve the Duplex info */ -+ -+int cpMacMdioGetDuplex(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ return((*PhyState&PHY_DUPLEX_MASK)?1:0); /* return 0 or a 1 */ -+ } -+ -+/* cpMacMdioGetSpeed is called to retreive the Speed info */ -+ -+int cpMacMdioGetSpeed(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ return(*PhyState&PHY_SPEED_MASK); -+ } -+ -+/* cpMacMdioGetPhyNum is called to retreive the Phy Device Adr info */ -+ -+int cpMacMdioGetPhyNum(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ return((*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET); -+ } -+ -+/* cpMacMdioGetLoopback is called to Determine if the LOOPBACK state has been reached*/ -+ -+int cpMacMdioGetLoopback(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ return((*PhyState&PHY_STATE_MASK)==LOOPBACK); -+ } -+/* cpMacMdioGetLinked is called to Determine if the LINKED state has been reached*/ -+ -+int cpMacMdioGetLinked(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ return((*PhyState&PHY_STATE_MASK)==LINKED); -+ } -+ -+void cpMacMdioLinkChange(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u PhyNum,PhyStatus; -+ -+ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; -+ -+ if (cpMacMdioGetLinked(PhyDev)) -+ { -+ PhyStatus=_mdioUserAccessRead(PhyDev, PHY_STATUS_REG, PhyNum); -+ -+ if ((PhyStatus&PHY_LINKED)==0) -+ { -+ *PhyState&=~(PHY_TIM_MASK|PHY_STATE_MASK); -+ if (*PhyState&SMODE_AUTO) -+ { -+ _mdioUserAccessWrite(PhyDev, PHY_CONTROL_REG, PhyNum, AUTO_NEGOTIATE_EN|RENEGOTIATE); -+ *PhyState|=PHY_CHANGE|PHY_NWST_TO|NWAY_START; -+ } -+ else -+ { -+ *PhyState|=PHY_CHANGE|PHY_LINK_TO|LINK_WAIT; -+ } -+ } -+ } -+ } -+ -+void cpMacMdioGetVer(bit32u miibase, bit32u *ModID, bit32u *RevMaj, bit32u *RevMin) -+ { -+ bit32u Ver; -+ -+ Ver = MDIO_VER(miibase); -+ -+ *ModID = (Ver & MDIO_VER_MODID) >> 16; -+ *RevMaj = (Ver & MDIO_VER_REVMAJ) >> 8; -+ *RevMin = (Ver & MDIO_VER_REVMIN); -+ } -+ -+int cpMacMdioGetPhyDevSize(void) -+ { -+ return(sizeof(PHY_DEVICE)); -+ } -+ -+ /* returns 0 if current Phy has AutoMdix support, otherwise 0 */ -+int _mdioMdixSupported(PHY_DEVICE *PhyDev) -+ { -+ bit32u *PhyState = &PhyDev->PhyState; -+ bit32u PhyNum; -+ -+ if((PhyDev->PhyMode & NWAY_AUTOMDIX) == 0) -+ return(0); /* AutoMdix not turned on */ -+ -+ PhyNum=(*PhyState&PHY_DEV_MASK)>>PHY_DEV_OFFSET; -+ if( ((1<<PhyNum) & PhyDev->MdixMask) == 0) -+ return(0); /* Phy does not support AutoMdix*/ -+ -+ return(1); -+ } -+ -+/* If current Phy has AutoMdix support add Mdix Delay to the Timer State Value */ -+void _mdioMdixDelay(PHY_DEVICE *PhyDev) -+ { -+ int Delay; -+ bit32u *PhyState = &PhyDev->PhyState; -+#ifdef _CPHAL_CPMAC -+ HAL_DEVICE *HalDev = PhyDev->HalDev; -+#endif -+ -+ if(_mdioMdixSupported(PhyDev) == 0) -+ return; /* AutoMdix not supported */ -+/* Currently only supported when used with the CPMAC */ -+#ifdef _CPHAL_CPMAC -+ /* Get the Delay value in milli-seconds and convert to ten-milli second value */ -+ Delay = cpmacRandomRange(HalDev, _AUTOMDIX_DELAY_MIN, _AUTOMDIX_DELAY_MAX); -+ Delay /= 10; -+ -+ /* Add AutoMidx Random Switch Delay to AutoMdix Link Delay */ -+ -+ Delay += (PHY_MDIX_TO>>PHY_TIM_OFFSET); -+ -+ /* Change Timeout value to AutoMdix standard */ -+ *PhyState &= ~(PHY_TIM_MASK); /* Clear current Time out value */ -+ *PhyState |= (Delay<<PHY_TIM_OFFSET); /* Set new value */ -+#endif -+ } -+ -+ -diff -urN linux.old/drivers/net/avalanche_cpmac/cpmdio.h linux.dev/drivers/net/avalanche_cpmac/cpmdio.h ---- linux.old/drivers/net/avalanche_cpmac/cpmdio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/cpmdio.h 2005-07-12 02:48:42.047593000 +0200 -@@ -0,0 +1,73 @@ -+/***************************************************************************** -+** TNETD53xx Software Support -+** Copyright(c) 2002, Texas Instruments Incorporated. All Rights Reserved. -+** -+** FILE: cpmdio.h User Include for MDIO API Access -+** -+** DESCRIPTION: -+** This include file contains definitions for the the MDIO API -+** -+** HISTORY: -+** 27Mar02 Michael Hanrahan Original (modified from emacmdio.h) -+** 04Apr02 Michael Hanrahan Added Interrupt Support -+*****************************************************************************/ -+#ifndef _INC_CPMDIO -+#define _INC_CPMDIO -+ -+ -+#ifndef __CPHAL_CPMDIO -+typedef void PHY_DEVICE; -+#endif -+ -+ -+/*Version Information */ -+ -+void cpMacMdioGetVer(bit32u miiBase, bit32u *ModID, bit32u *RevMaj, bit32u *RevMin); -+ -+/*Called once at the begining of time */ -+ -+int cpMacMdioInit(PHY_DEVICE *PhyDev, bit32u miibase, bit32u inst, bit32u PhyMask, bit32u MLinkMask, bit32u MdixMask, bit32u ResetBase, bit32u ResetBit, bit32u MdioBusFreq, bit32u MdioClockFreq, int verbose, void *Info); -+int cpMacMdioGetPhyDevSize(void); -+ -+ -+/*Called every 10 mili Seconds, returns TRUE if there has been a mode change */ -+ -+int cpMacMdioTic(PHY_DEVICE *PhyDev); -+ -+/*Called to set Phy mode */ -+ -+void cpMacMdioSetPhyMode(PHY_DEVICE *PhyDev,bit32u PhyMode); -+ -+/*Calls to retreive info after a mode change! */ -+ -+int cpMacMdioGetDuplex(PHY_DEVICE *PhyDev); -+int cpMacMdioGetSpeed(PHY_DEVICE *PhyDev); -+int cpMacMdioGetPhyNum(PHY_DEVICE *PhyDev); -+int cpMacMdioGetLinked(PHY_DEVICE *PhyDev); -+void cpMacMdioLinkChange(PHY_DEVICE *PhyDev); -+ -+/* Shot Down */ -+ -+void cpMacMdioClose(PHY_DEVICE *PhyDev, int Full); -+ -+ -+/* Phy Mode Values */ -+#define NWAY_AUTOMDIX (1<<16) -+#define NWAY_FD100 (1<<8) -+#define NWAY_HD100 (1<<7) -+#define NWAY_FD10 (1<<6) -+#define NWAY_HD10 (1<<5) -+#define NWAY_AUTO (1<<0) -+ -+/* -+ * -+ * Tic() return values -+ * -+ */ -+ -+#define _MIIMDIO_MDIXFLIP (1<<28) -+ -+#define _AUTOMDIX_DELAY_MIN 80 /* milli-seconds*/ -+#define _AUTOMDIX_DELAY_MAX 200 /* milli-seconds*/ -+ -+#endif /* _INC_CPMDIO */ -diff -urN linux.old/drivers/net/avalanche_cpmac/cppi_cpmac.c linux.dev/drivers/net/avalanche_cpmac/cppi_cpmac.c ---- linux.old/drivers/net/avalanche_cpmac/cppi_cpmac.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/cppi_cpmac.c 2005-07-12 02:48:42.048593000 +0200 -@@ -0,0 +1,1345 @@ -+/************************************************************************* -+ * TNETDxxxx Software Support -+ * Copyright (c) 2002,2003 Texas Instruments Incorporated. All Rights Reserved. -+ * -+ * FILE: cppi.c -+ * -+ * DESCRIPTION: -+ * This file contains shared code for all CPPI modules. -+ * -+ * HISTORY: -+ * 7Aug02 Greg RC1.00 Original Version created. -+ * 27Sep02 Mick RC1.01 Merged for use by CPMAC/CPSAR -+ * 16Oct02 Mick RC1.02 Performance Tweaks (see cppihist.txt) -+ * 12Nov02 Mick RC1.02 Updated to use cpmac_reg.h -+ * 09Jan03 Mick RC3.01 Removed modification to RxBuffer ptr -+ * 28Mar03 Mick 1.03 RxReturn now returns error if Malloc Fails -+ * 10Apr03 Mick 1.03.02 Added Needs Buffer Support -+ * 11Jun03 Mick 1.06.02 halSend() errors corrected -+ * 23Aug04 Mick 1.07.08 cpmac only - Send: bypass threshold check if TxInts re-enabled -+ * -+ * @author Greg Guyotte -+ * @version 1.00 -+ * @date 7-Aug-2002 -+ *****************************************************************************/ -+/* each CPPI module must modify this file, the rest of the -+ code in cppi.c should be totally shared *//* Each CPPI module MUST properly define all constants shown below */ -+ -+/* CPPI registers */ -+ -+/* the following defines are not CPPI specific */ -+ -+static int TxInt(HAL_DEVICE *HalDev, int Ch, int Queue, int *MoreWork); -+ -+static void FreeRx(HAL_DEVICE *HalDev, int Ch) -+ { -+ HAL_RCB *rcb_ptr; /*+GSG 030303*/ -+ int rcbSize = (sizeof(HAL_RCB)+0xf)&~0xf; /*+GSG 030303*/ -+ int Num = HalDev->ChData[Ch].RxNumBuffers, i; /*+GSG 030303*/ -+ -+ /* Free Rx data buffers attached to descriptors, if necessary */ -+ if (HalDev->RcbStart[Ch] != 0) /*+GSG 030303*/ -+ { /*+GSG 030303*/ -+ for(i=0;i<Num;i++) /*+GSG 030303*/ -+ { /*+GSG 030303*/ -+ rcb_ptr = (HAL_RCB *)(HalDev->RcbStart[Ch] + (i*rcbSize)); /*+GSG 030303*/ -+ -+ /* free the data buffer */ -+ if (rcb_ptr->DatPtr != 0) -+ { -+ -+ HalDev->OsFunc->FreeRxBuffer((void *)rcb_ptr->OsInfo, (void *)rcb_ptr->DatPtr); -+ rcb_ptr->OsInfo=0; /*MJH+030522*/ -+ rcb_ptr->DatPtr=0; /*MJH+030522*/ -+ } -+ } /*+GSG 030303*/ -+ } /*+GSG 030303*/ -+ -+ /* free up all desciptors at once */ -+ HalDev->OsFunc->FreeDmaXfer(HalDev->RcbStart[Ch]); -+ -+ /* mark buffers as freed */ -+ HalDev->RcbStart[Ch] = 0; -+ } -+ -+static void FreeTx(HAL_DEVICE *HalDev, int Ch, int Queue) -+ { -+ -+/*+GSG 030303*/ -+ -+ /* free all descriptors at once */ -+ HalDev->OsFunc->FreeDmaXfer(HalDev->TcbStart[Ch][Queue]); -+ -+ HalDev->TcbStart[Ch][Queue] = 0; -+ } -+ -+/* return of 0 means that this code executed, -1 means the interrupt was not -+ a teardown interrupt */ -+static int RxTeardownInt(HAL_DEVICE *HalDev, int Ch) -+ { -+ bit32u base = HalDev->dev_base; -+ -+ /* check to see if the interrupt is a teardown interrupt */ -+ if (((CPMAC_RX_INT_ACK( base , Ch )) & TEARDOWN_VAL) == TEARDOWN_VAL) -+ { -+ /* finish channel teardown */ -+ -+ /* Free channel resources on a FULL teardown */ -+ if (HalDev->RxTeardownPending[Ch] & FULL_TEARDOWN) -+ { -+ FreeRx(HalDev, Ch); -+ } -+ -+ /* bug fix - clear Rx channel pointers on teardown */ -+ HalDev->RcbPool[Ch] = 0; -+ HalDev->RxActQueueHead[Ch] = 0; -+ HalDev->RxActQueueCount[Ch] = 0; -+ HalDev->RxActive[Ch] = FALSE; -+ -+ /* write completion pointer */ -+ (CPMAC_RX_INT_ACK( base , Ch )) = TEARDOWN_VAL; -+ -+ /* use direction bit as a teardown pending bit! May be able to -+ use only one teardown pending integer in HalDev */ -+ -+ HalDev->RxTeardownPending[Ch] &= ~RX_TEARDOWN; -+ -+ HalDev->ChIsOpen[Ch][DIRECTION_RX] = 0; -+ -+ HalDev->ChIsOpen[Ch][DIRECTION_RX] = 0; -+ CPMAC_RX_INTMASK_CLEAR(HalDev->dev_base) = (1<<Ch); -+ if ((HalDev->RxTeardownPending[Ch] & BLOCKING_TEARDOWN) == 0) -+ { -+ -+ HalDev->OsFunc->TeardownComplete(HalDev->OsDev, Ch, DIRECTION_RX); -+ } -+ HalDev->RxTeardownPending[Ch] = 0; -+ -+ return (EC_NO_ERRORS); -+ } -+ return (-1); -+ } -+ -+/* return of 0 means that this code executed, -1 means the interrupt was not -+ a teardown interrupt. Note: this code is always called with Queue == 0 (hi priority). */ -+static int TxTeardownInt(HAL_DEVICE *HalDev, int Ch, int Queue) -+ { -+ bit32u base = HalDev->dev_base; -+ HAL_TCB *Last, *Curr, *First; /*+GSG 030303*/ -+ int i; -+ -+ if (((CPMAC_TX_INT_ACK( base , Ch )) & TEARDOWN_VAL) == TEARDOWN_VAL) -+ { -+ /* perform all actions for both queues (+GSG 040212) */ -+ for (i=0; i<HalDev->ChData[Ch].TxNumQueues; i++) -+ { -+ /* return outstanding buffers to OS +RC3.02*/ -+ Curr = HalDev->TxActQueueHead[Ch][i]; /*+GSG 030303*/ -+ First = Curr; /*+GSG 030303*/ -+ while (Curr) /*+GSG 030303*/ -+ { /*+GSG 030303*/ -+ /* Pop TCB(s) for packet from the stack */ /*+GSG 030303*/ -+ Last = Curr->Eop; /*+GSG 030303*/ -+ HalDev->TxActQueueHead[Ch][i] = Last->Next; /*+GSG 030303*/ -+ /*+GSG 030303*/ -+ /* return to OS */ /*+GSG 030303*/ -+ HalDev->OsFunc->SendComplete(Curr->OsInfo); /*+GSG 030303*/ -+ /*+GSG 030303*/ -+ /* Push Tcb(s) back onto the stack */ /*+GSG 030303*/ -+ Curr = Last->Next; /*+GSG 030303*/ -+ Last->Next = HalDev->TcbPool[Ch][i]; /*+GSG 030303*/ -+ HalDev->TcbPool[Ch][i] = First; /*+GSG 030303*/ -+ /*+GSG 030303*/ -+ /* set the first(SOP) pointer for the next packet */ /*+GSG 030303*/ -+ First = Curr; /*+GSG 030303*/ -+ } /*+GSG 030303*/ -+ } -+ -+ /* finish channel teardown */ -+ -+ if (HalDev->TxTeardownPending[Ch] & FULL_TEARDOWN) -+ { -+ FreeTx(HalDev, Ch, 0); -+ -+ if (HalDev->ChData[Ch].TxNumQueues == 2) -+ FreeTx(HalDev, Ch, 1); -+ } /* if FULL teardown */ -+ -+ /* perform all actions for both queues (+GSG 040212) */ -+ for (i=0; i<HalDev->ChData[Ch].TxNumQueues; i++) -+ { -+ /* bug fix - clear Tx channel pointers on teardown */ -+ HalDev->TcbPool[Ch][i] = 0; -+ HalDev->TxActQueueHead[Ch][i] = 0; -+ HalDev->TxActQueueCount[Ch][i] = 0; -+ HalDev->TxActive[Ch][i] = FALSE; -+ } -+ -+ /* write completion pointer, only needed for the high priority queue */ -+ (CPMAC_TX_INT_ACK( base , Ch )) = TEARDOWN_VAL; -+ -+ /* no longer pending teardown */ -+ HalDev->TxTeardownPending[Ch] &= ~TX_TEARDOWN; -+ -+ HalDev->ChIsOpen[Ch][DIRECTION_TX] = 0; -+ -+ HalDev->ChIsOpen[Ch][DIRECTION_TX] = 0; -+ CPMAC_TX_INTMASK_CLEAR(HalDev->dev_base) = (1<<Ch); -+ if ((HalDev->TxTeardownPending[Ch] & BLOCKING_TEARDOWN) == 0) -+ { -+ -+ HalDev->OsFunc->TeardownComplete(HalDev->OsDev, Ch, DIRECTION_TX); -+ } -+ HalDev->TxTeardownPending[Ch] = 0; -+ -+ return (EC_NO_ERRORS); -+ } -+ return (-1); -+ } -+ -+/* +GSG 030421 */ -+static void AddToRxQueue(HAL_DEVICE *HalDev, HAL_RCB *FirstRcb, HAL_RCB *LastRcb, int FragCount, int Ch) -+ { -+ if (HalDev->RxActQueueHead[Ch]==0) -+ { -+ -+ HalDev->RxActQueueHead[Ch]=FirstRcb; -+ HalDev->RxActQueueTail[Ch]=LastRcb; -+ if (!HalDev->RxActive[Ch]) -+ { -+ /* write Rx Queue Head Descriptor Pointer */ -+ ((CPMAC_RX_HDP( HalDev->dev_base , Ch )) ) = VirtToPhys(FirstRcb) - HalDev->offset; -+ HalDev->RxActive[Ch]=TRUE; -+ } -+ } -+ else -+ { -+ register HAL_RCB *OldTailRcb; -+ register bit32u rmode; -+ -+ HalDev->OsFunc->CriticalOn(); -+ OldTailRcb=HalDev->RxActQueueTail[Ch]; -+ OldTailRcb->Next=(void *)FirstRcb; -+ OldTailRcb=VirtToVirtNoCache(OldTailRcb); -+ OldTailRcb->HNext=VirtToPhys(FirstRcb) - HalDev->offset; -+ HalDev->RxActQueueTail[Ch]=LastRcb; -+ rmode=OldTailRcb->mode; -+ if (rmode&CB_EOQ_BIT) -+ { -+ rmode&=~CB_EOQ_BIT; -+ ((CPMAC_RX_HDP( HalDev->dev_base , Ch )) ) = VirtToPhys(FirstRcb) - HalDev->offset; -+ OldTailRcb->mode=rmode; -+ } -+ HalDev->OsFunc->CriticalOff(); -+ } -+ } -+ -+/** -+ * @ingroup CPHAL_Functions -+ * This function is called to indicate to the CPHAL that the upper layer -+ * software has finished processing the receive data (given to it by -+ * osReceive()). The CPHAL will then return the appropriate receive buffers -+ * and buffer descriptors to the available pool. -+ * -+ * @param HalReceiveInfo Start of receive buffer descriptor chain returned to -+ * CPHAL. -+ * @param StripFlag Flag indicating whether the upper layer software has -+ * retained ownership of the receive data buffers. -+ *<BR> -+ * 'FALSE' means that the CPHAL can reuse the receive data buffers. -+ *<BR> -+ * 'TRUE' : indicates the data buffers were retained by the OS -+ *<BR> -+ * NOTE: If StripFlag is TRUE, it is the responsibility of the upper layer software to free the buffers when they are no longer needed. -+ * -+ * @return EC_NO_ERRORS (ok). <BR> -+ * Possible Error Codes:<BR> -+ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"<BR> -+ * @ref EC_VAL_RCB_NEEDS_BUFFER "EC_VAL_RCB_NEEDS_BUFFER"<BR> -+ * @ref EC_VAL_RCB_DROPPED "EC_VAL_RCB_DROPPED"<BR> -+ */ -+static int halRxReturn(HAL_RECEIVEINFO *HalReceiveInfo, -+ int StripFlag) -+ { -+ int Ch, i; -+ HAL_RCB *LastRcb; -+ HAL_DEVICE *HalDev; -+ int RcbSize; -+ int FragCount; -+ -+ Ch = HalReceiveInfo->mode&0x0ff; -+ HalDev = (HAL_DEVICE *)HalReceiveInfo->Off_BLen; -+ FragCount = HalReceiveInfo->mode>>8; -+ -+ if (HalDev->State != enOpened) -+ return(EC_CPMAC |EC_FUNC_RXRETURN|EC_VAL_INVALID_STATE); -+ -+ LastRcb=(HAL_RCB *)HalReceiveInfo->Eop; -+ LastRcb->HNext=0; -+ LastRcb->Next=0; -+ RcbSize = HalDev->ChData[Ch].RxBufSize; -+ -+ if (FragCount>1) -+ { -+ LastRcb->Off_BLen=RcbSize; -+ LastRcb->mode=CB_OWNERSHIP_BIT; -+ } -+ -+ HalReceiveInfo->Off_BLen=RcbSize; -+ HalReceiveInfo->mode=CB_OWNERSHIP_BIT; -+ -+ /* If OS has kept the buffers for this packet, attempt to alloc new buffers */ -+ if (StripFlag) -+ { -+ int rc=0; /*MJH+030417*/ -+ int GoodCount=0; /*GSG+030421*/ -+ HAL_RCB *TempRcb; -+ char *pBuf; -+ HAL_RCB *CurrHeadRcb = HalReceiveInfo, *LastGoodRcb=0; /* +GSG 030421 */ -+ -+ TempRcb = HalReceiveInfo; -+ for (i=0; i<FragCount; i++) -+ { -+ if (TempRcb == 0) -+ { -+ dbgPrintf("Rx Return error while allocating new buffers\n"); -+ dbgPrintf("Rcb = %08x, Rcb->Eop = %08x, FragCount = %d:%d\n", -+ (bit32u)HalReceiveInfo, (bit32u)HalReceiveInfo->Eop, FragCount,i); -+ osfuncSioFlush(); -+ -+ return(EC_CPPI|EC_FUNC_RXRETURN|EC_VAL_CORRUPT_RCB_CHAIN); -+ } -+ -+ pBuf= (char *) HalDev->OsFunc->MallocRxBuffer(RcbSize,0, -+ 0xF,HalDev->ChData[Ch].OsSetup, -+ (void *)TempRcb, -+ (void *)&TempRcb->OsInfo, -+ (void *) HalDev->OsDev); -+ if (!pBuf) -+ { -+ /* malloc failed, add this RCB to Needs Buffer List */ -+ (HAL_RCB *)TempRcb->Eop = TempRcb; /* GSG +030430 */ -+ TempRcb->mode=1<<8|Ch; -+ TempRcb->Off_BLen=(bit32u)HalDev; -+ -+ if(HalDev->NeedsCount < MAX_NEEDS) /* +MJH 030410 */ -+ { /* +MJH 030410 */ -+ HalDev->Needs[HalDev->NeedsCount] = (HAL_RECEIVEINFO *) TempRcb; /* +MJH 030410 */ -+ HalDev->NeedsCount++; /* +MJH 030410 */ -+ rc = (EC_CPPI|EC_FUNC_RXRETURN|EC_VAL_RCB_NEEDS_BUFFER); /* ~MJH 030417 */ -+ } /* +MJH 030410 */ -+ else /* +MJH 030410 */ -+ rc = (EC_CPPI|EC_FUNC_RXRETURN|EC_VAL_RCB_DROPPED); /* ~MJH 030417 */ -+ -+ /* requeue any previous RCB's that were ready to go before this one */ -+ if (GoodCount > 0) /* +GSG 030421 */ -+ { /* +GSG 030421 */ -+ LastGoodRcb->HNext=0; /* +GSG 030430 */ -+ LastGoodRcb->Next=0; /* +GSG 030430 */ -+ osfuncDataCacheHitWritebackAndInvalidate((void *)LastGoodRcb, 16); /* +GSG 030430 */ -+ -+ AddToRxQueue(HalDev, CurrHeadRcb, LastGoodRcb, GoodCount, Ch); /* +GSG 030421 */ -+ GoodCount = 0; /* +GSG 030421 */ -+ } /* +GSG 030421 */ -+ -+ CurrHeadRcb = TempRcb->Next; /* +GSG 030421 */ -+ } -+ else /* +GSG 030421 */ -+ { /* +GSG 030421 */ -+ /* malloc succeeded, requeue the RCB to the hardware */ -+ TempRcb->BufPtr=VirtToPhys(pBuf) - HalDev->offset; -+ TempRcb->DatPtr=pBuf; -+ /* Emerald fix 10/29 */ -+ osfuncDataCacheHitWritebackAndInvalidate((void *)TempRcb, 16); -+ -+ /* i store the last good RCB in case the malloc fails for the -+ next fragment. This ensures that I can go ahead and return -+ a partial chain of RCB's to the hardware */ -+ LastGoodRcb = TempRcb; /* +GSG 030421 */ -+ GoodCount++; /* +GSG 030421 */ -+ } /* +GSG 030421 */ -+ TempRcb = TempRcb->Next; -+ } /* end of Frag loop */ -+ /* if there any good RCB's to requeue, do so here */ -+ if (GoodCount > 0) /* +GSG 030421 */ -+ { -+ AddToRxQueue(HalDev, CurrHeadRcb, LastGoodRcb, GoodCount, Ch); /* +GSG 030421 */ -+ } -+ return(rc); /* ~GSG 030421 */ -+ } -+ else -+ { -+ /* Not Stripping */ -+ /* Emerald */ -+ /* Write Back SOP and last RCB */ -+ osfuncDataCacheHitWritebackAndInvalidate((void *)HalReceiveInfo, 16); -+ -+ if (FragCount > 1) -+ { -+ osfuncDataCacheHitWritebackAndInvalidate((void *)LastRcb, 16); -+ } -+ /* if not stripping buffers, always add to queue */ -+ AddToRxQueue(HalDev, HalReceiveInfo, LastRcb, FragCount, Ch); /*MJH~030520*/ -+ } -+ -+ return(EC_NO_ERRORS); -+ } -+ -+/* +MJH 030410 -+ Trys to liberate an RCB until liberation fails. -+ Note: If liberation fails then RxReturn will re-add the RCB to the -+ Needs list. -+*/ -+static void NeedsCheck(HAL_DEVICE *HalDev) -+{ -+ HAL_RECEIVEINFO* HalRcb; -+ int rc; -+ HalDev->OsFunc->CriticalOn(); -+ while(HalDev->NeedsCount) -+ { -+ HalDev->NeedsCount--; -+ HalRcb = HalDev->Needs[HalDev->NeedsCount]; -+ rc = halRxReturn(HalRcb, 1); -+ /* short circuit if RxReturn starts to fail */ -+ if (rc != 0) -+ break; -+ } -+ HalDev->OsFunc->CriticalOff(); -+} -+ -+/* -+ * This function allocates transmit buffer descriptors (internal CPHAL function). -+ * It creates a high priority transmit queue by default for a single Tx -+ * channel. If QoS is enabled for the given CPHAL device, this function -+ * will also allocate a low priority transmit queue. -+ * -+ * @param HalDev CPHAL module instance. (set by cphalInitModule()) -+ * @param Ch Channel number. -+ * -+ * @return 0 OK, Non-Zero Not OK -+ */ -+static int InitTcb(HAL_DEVICE *HalDev, int Ch) -+ { -+ int i, Num = HalDev->ChData[Ch].TxNumBuffers; -+ HAL_TCB *pTcb=0; -+ char *AllTcb; -+ int tcbSize, Queue; -+ int SizeMalloc; -+ -+ tcbSize = (sizeof(HAL_TCB)+0xf)&~0xf; -+ SizeMalloc = (tcbSize*Num)+0xf; -+ -+ for (Queue=0; Queue < HalDev->ChData[Ch].TxNumQueues; Queue++) -+ { -+ if (HalDev->TcbStart[Ch][Queue] == 0) -+ { -+ -+ /* malloc all TCBs at once */ -+ AllTcb = (char *)HalDev->OsFunc->MallocDmaXfer(SizeMalloc,0,0xffffffff); -+ if (!AllTcb) -+ { -+ return(EC_CPPI|EC_FUNC_HAL_INIT|EC_VAL_TCB_MALLOC_FAILED); -+ } -+ -+ HalDev->OsFunc->Memset(AllTcb, 0, SizeMalloc); -+ -+ /* keep this address for freeing later */ -+ HalDev->TcbStart[Ch][Queue] = AllTcb; -+ } -+ else -+ { -+ /* if the memory has already been allocated, simply reuse it! */ -+ AllTcb = HalDev->TcbStart[Ch][Queue]; -+ } -+ -+ /* align to cache line */ -+ AllTcb = (char *)(((bit32u)AllTcb + 0xf) &~ 0xf); /*PITS #143 MJH~030522*/ -+ -+ /* default High priority transmit queue */ -+ HalDev->TcbPool[Ch][Queue]=0; -+ for(i=0;i<Num;i++) -+ { -+ /*pTcb=(HAL_TCB *) OsFunc->MallocDmaXfer(sizeof(HAL_TCB),0,0xffffffff); */ -+ pTcb= (HAL_TCB *)(AllTcb + (i*tcbSize)); -+ pTcb->mode=0; -+ pTcb->BufPtr=0; -+ pTcb->Next=HalDev->TcbPool[Ch][Queue]; -+ pTcb->Off_BLen=0; -+ HalDev->TcbPool[Ch][Queue]=pTcb; -+ } -+ /*HalDev->TcbEnd = pTcb;*/ -+ } -+ -+ return(EC_NO_ERRORS); -+ } -+ -+/* -+ * This function allocates receive buffer descriptors (internal CPHAL function). -+ * After allocation, the function 'queues' (gives to the hardware) the newly -+ * created receive buffers to enable packet reception. -+ * -+ * @param HalDev CPHAL module instance. (set by cphalInitModule()) -+ * @param Ch Channel number. -+ * -+ * @return 0 OK, Non-Zero Not OK -+ */ -+static int InitRcb(HAL_DEVICE *HalDev, int Ch) -+ { -+ int i, Num = HalDev->ChData[Ch].RxNumBuffers; -+ int Size = HalDev->ChData[Ch].RxBufSize; -+ HAL_RCB *pRcb; -+ char *pBuf; -+ char *AllRcb; -+ int rcbSize; -+ int DoMalloc = 0; -+ int SizeMalloc; -+ int MallocSize; -+ -+ rcbSize = (sizeof(HAL_RCB)+0xf)&~0xf; -+ SizeMalloc = (rcbSize*Num)+0xf; -+ -+ if (HalDev->RcbStart[Ch] == 0) -+ { -+ DoMalloc = 1; -+ -+ /* malloc all RCBs at once */ -+ AllRcb= (char *)HalDev->OsFunc->MallocDmaXfer(SizeMalloc,0,0xffffffff); -+ if (!AllRcb) -+ { -+ return(EC_CPPI|EC_FUNC_HAL_INIT|EC_VAL_RCB_MALLOC_FAILED); -+ } -+ -+ HalDev->OsFunc->Memset(AllRcb, 0, SizeMalloc); -+ -+ /* keep this address for freeing later */ -+ HalDev->RcbStart[Ch] = AllRcb; -+ } -+ else -+ { -+ /* if the memory has already been allocated, simply reuse it! */ -+ AllRcb = HalDev->RcbStart[Ch]; -+ } -+ -+ /* align to cache line */ -+ AllRcb = (char *)(((bit32u)AllRcb + 0xf)&~0xf); /*PITS #143 MJH~030522*/ -+ -+ HalDev->RcbPool[Ch]=0; -+ for(i=0;i<Num;i++) -+ { -+ pRcb = (HAL_RCB *)(AllRcb + (i*rcbSize)); -+ -+ if (DoMalloc == 1) -+ { -+ -+ MallocSize = Size; /*~3.01 */ -+ pBuf= (char *) HalDev->OsFunc->MallocRxBuffer(MallocSize,0,0xF,HalDev->ChData[Ch].OsSetup, (void *)pRcb, (void *)&pRcb->OsInfo, (void *) HalDev->OsDev); -+ if(!pBuf) -+ { -+ return(EC_CPPI|EC_FUNC_HAL_INIT|EC_VAL_RX_BUFFER_MALLOC_FAILED); -+ } -+ /* -RC3.01 pBuf = (char *)(((bit32u)pBuf+0xF) & ~0xF); */ -+ pRcb->BufPtr=VirtToPhys(pBuf) - HalDev->offset; -+ pRcb->DatPtr=pBuf; -+ } -+ pRcb->mode=(1<<8)|Ch; /* One Frag for Ch */ -+ pRcb->Next=(void *)HalDev->RcbPool[Ch]; -+ pRcb->Off_BLen=(bit32u)HalDev; -+ HalDev->RcbPool[Ch]=pRcb; -+ } -+ -+ /* Give all of the Rx buffers to hardware */ -+ -+ while(HalDev->RcbPool[Ch]) -+ { -+ pRcb=HalDev->RcbPool[Ch]; -+ HalDev->RcbPool[Ch]=pRcb->Next; -+ pRcb->Eop=(void*)pRcb; -+ pRcb->mode=(1<<8)|Ch; -+ halRxReturn((HAL_RECEIVEINFO *)pRcb, 0); -+ } -+ -+ return(EC_NO_ERRORS); -+ } -+ -+/** -+ * @ingroup CPHAL_Functions -+ * This function transmits the data in FragList using available transmit -+ * buffer descriptors. More information on the use of the Mode parameter -+ * is available in the module-specific appendices. Note: The OS should -+ * not call Send() for a channel that has been requested to be torndown. -+ * -+ * @param HalDev CPHAL module instance. (set by cphalInitModule()) -+ * @param FragList Fragment List structure. -+ * @param FragCount Number of fragments in FragList. -+ * @param PacketSize Number of bytes to transmit. -+ * @param OsSendInfo OS Send Information structure. <BR> -+ * @param Mode 32-bit value with the following bit fields: <BR> -+ * 31-16: Mode (used for module specific data). <BR> -+ * 15-08: Queue (transmit queue to send on). <BR> -+ * 07-00: Channel (channel number to send on). -+ * -+ * @return EC_NO_ERRORS (ok). <BR> -+ * Possible Error Codes:<BR> -+ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"<BR> -+ * @ref EC_VAL_NOT_LINKED "EC_VAL_NOT_LINKED"<BR> -+ * @ref EC_VAL_INVALID_CH "EC_VAL_INVALID_CH"<BR> -+ * @ref EC_VAL_OUT_OF_TCBS "EC_VAL_OUT_OF_TCBS"<BR> -+ * @ref EC_VAL_NO_TCBS "EC_VAL_NO_TCBS"<BR> -+ */ -+static int halSend(HAL_DEVICE *HalDev,FRAGLIST *FragList, -+ int FragCount,int PacketSize, OS_SENDINFO *OsSendInfo, -+ bit32u Mode) -+ { -+ HAL_TCB *tcb_ptr, *head; -+ int i; -+ int rc = EC_NO_ERRORS; -+ int Ch = Mode & 0xFF; -+ int Queue = (Mode>>8)&0xFF; -+ /*int DoThresholdCheck=1; */ /* Used when TxIntDisable is set and TxInts are re-enabled */ -+ -+ if (HalDev->State != enOpened) -+ return(EC_CPPI|EC_FUNC_SEND|EC_VAL_INVALID_STATE); -+ -+ if (!HalDev->Linked) -+ { -+ rc = EC_CPPI|EC_FUNC_SEND|EC_VAL_NOT_LINKED; -+ return(rc); -+ } -+ -+ if (HalDev->ChIsOpen[Ch][DIRECTION_TX] == 0) /*MJH~030611*/ /*PITS 148*/ -+ return(EC_CPMAC |EC_FUNC_SEND|EC_VAL_INVALID_CH); /*+GSG 030303*/ -+ -+ HalDev->OsFunc->CriticalOn(); -+ -+ /* Setup Tx mode and size */ -+ if (PacketSize<60) -+ { -+ FragList[FragCount-1].len += (60 - PacketSize); /*MJH~030506*//*PITS 132*/ -+ PacketSize = 60; /*MJH~030506*/ -+ } -+ Mode &= CB_PASSCRC_BIT; -+ -+ tcb_ptr = head = HalDev->TcbPool[Ch][Queue]; -+ -+ if (tcb_ptr) -+ { -+ -+ Mode|=PacketSize|CB_SOF_BIT|CB_OWNERSHIP_BIT; -+ -+ for (i=0; i<FragCount; i++) -+ -+ { -+ /* Setup Tx mode and size */ -+ tcb_ptr->Off_BLen = FragList[i].len; -+ -+ tcb_ptr->mode = Mode; -+ tcb_ptr->BufPtr = VirtToPhys((bit32 *)FragList[i].data) - HalDev->offset; -+ tcb_ptr->OsInfo = OsSendInfo; -+ -+ if (i == (FragCount - 1)) -+ { -+ /* last fragment */ -+ tcb_ptr->mode |= CB_EOF_BIT; -+ -+ /* since this is the last fragment, set the TcbPool pointer before -+ nulling out the Next pointers */ -+ -+ HalDev->TcbPool[Ch][Queue] = tcb_ptr->Next; -+ -+ tcb_ptr->Next = 0; -+ tcb_ptr->HNext = 0; -+ -+ /* In the Tx Interrupt handler, we will need to know which TCB is EOP, -+ so we can save that information in the SOP */ -+ head->Eop = tcb_ptr; -+ -+ /* Emerald fix 10/29 */ -+ osfuncDataCacheHitWritebackAndInvalidate((void *)tcb_ptr, 16); -+ -+ } -+ else -+ { -+ Mode=CB_OWNERSHIP_BIT; -+ tcb_ptr->HNext = VirtToPhys((bit32 *)tcb_ptr->Next) - HalDev->offset; -+ -+ /* Emerald fix 10/29 */ -+ osfuncDataCacheHitWritebackAndInvalidate((void *)tcb_ptr, 16); -+ -+ tcb_ptr = tcb_ptr->Next; /* what about the end of TCB list?? */ -+ -+ if (tcb_ptr == 0) -+ { -+ rc = EC_CPPI|EC_FUNC_SEND|EC_VAL_OUT_OF_TCBS; -+ goto ExitSend; -+ } -+ } -+ } /* for */ -+ -+ /* put it on the high priority queue */ -+ if (HalDev->TxActQueueHead[Ch][Queue] == 0) -+ { -+ HalDev->TxActQueueHead[Ch][Queue]=head; -+ HalDev->TxActQueueTail[Ch][Queue]=tcb_ptr; -+/*+GSG 030303*//*+GSG 030303*/ -+ if (!HalDev->TxActive[Ch][Queue]) -+ { -+ -+ bit32u base = HalDev->dev_base; -+ -+ /* write CPPI TX HDP */ -+ (CPMAC_TX_HDP( base , Ch )) = VirtToPhys(head) - HalDev->offset; -+ HalDev->TxActive[Ch][Queue]=TRUE; -+ -+ } -+ } -+ else -+ { -+ register volatile HAL_TCB *pTailTcb; -+ register bit32u tmode; -+ register bit32u pCurrentTcb; -+ -+ HalDev->TxActQueueTail[Ch][Queue]->Next=head; -+ /* Emerald fix 10/29 */ -+ -+ pTailTcb=(HAL_TCB *)VirtToVirtNoCache(&HalDev->TxActQueueTail[Ch][Queue]->HNext); -+ pCurrentTcb=VirtToPhys(head) - HalDev->offset; -+ pTailTcb->HNext=pCurrentTcb; -+ HalDev->TxActQueueTail[Ch][Queue]=tcb_ptr; -+/*+GSG 030303*/ -+ tmode=pTailTcb->mode; -+ if (tmode&CB_EOQ_BIT) -+ { -+ bit32u base = HalDev->dev_base; -+ -+ tmode&=~CB_EOQ_BIT; -+ pTailTcb->mode=tmode; -+ ((CPMAC_TX_HDP( base , Ch )) ) = pCurrentTcb; -+ } -+ -+ else -+ { -+ if(HalDev->TxIntDisable) -+ { -+ /* Enable Interrupts, to ensure packet goes out on wire */ -+ CPMAC_TX_INTMASK_SET(HalDev->dev_base) = (1<<Ch); -+ halPacketProcessEnd(HalDev); /* Allow Interrupt to be seen at the OS */ -+ /*DoThresholdCheck = 0; */ /* Disable Threshold Check */ -+ -+ } -+ } -+ -+ } -+ rc = EC_NO_ERRORS; -+ goto ExitSend; -+ } /* if (tcb_ptr) */ -+ else -+ { -+ rc = EC_CPPI|EC_FUNC_SEND|EC_VAL_NO_TCBS; -+ goto ExitSend; -+ } -+ExitSend: -+ -+/* 15 June 2004 - NSP Performance Update : If Tx Ints are disabled then process them here */ -+/* 29 June 2004 - NSP Performance Update : Moved to end at request of BCIL */ -+/* 23 Aug 2004 - NSP Performance Update : If Tx Ints are re-enabled do not do Threshold check */ -+ -+ if(HalDev->TxIntDisable /*&& DoThresholdCheck*/) -+ { -+ if(--HalDev->TxIntThreshold[Ch] <= 0) -+ { -+ int MoreWork; -+ TxInt(HalDev, Ch, 0, &MoreWork); -+ HalDev->TxIntThreshold[Ch] = HalDev->TxIntThresholdMaster[Ch]; -+ } -+ } -+ HalDev->OsFunc->CriticalOff(); -+ -+ return(rc); -+ } -+ -+/* -+ * This function processes receive interrupts. It traverses the receive -+ * buffer queue, extracting the data and passing it to the upper layer software via -+ * osReceive(). It handles all error conditions and fragments without valid data by -+ * immediately returning the RCB's to the RCB pool. -+ * -+ * @param HalDev CPHAL module instance. (set by cphalInitModule()) -+ * @param Ch Channel Number. -+ * @param MoreWork Flag that indicates that there is more work to do when set to 1. -+ * -+ * @return 0 if OK, non-zero otherwise. -+ */ -+static int RxInt(HAL_DEVICE *HalDev, int Ch, int *MoreWork) -+ { -+ HAL_RCB *CurrentRcb, *SopRcb, *EofRcb, *EopRcb; -+ bit32u RxBufStatus,PacketsServiced, RxPktLen = 0, RxSopStatus, -+ FrmFrags, TotalFrags, FrmLen; -+ int base = HalDev->dev_base, Ret; -+ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; -+ int RxServiceMax = HalDev->ChData[Ch].RxServiceMax; -+ int FragIndex; /* +GSG 030508 */ -+ -+ if(HalDev->NeedsCount) /* +MJH 030410 */ -+ NeedsCheck(HalDev); /* +MJH 030410 */ -+ -+ /* Handle case of teardown interrupt */ -+ if (HalDev->RxTeardownPending[Ch] != 0) -+ { -+ Ret = RxTeardownInt(HalDev, Ch); -+ if (Ret == 0) -+ { /*+GSG 030303*/ -+ *MoreWork = 0; -+ return (EC_NO_ERRORS); -+ } /*+GSG 030303*/ -+ } -+ -+ /* Examine first RCB on the software active queue */ -+ CurrentRcb=HalDev->RxActQueueHead[Ch]; -+ osfuncDataCacheHitInvalidate((void*)CurrentRcb, 16); -+ RxBufStatus=CurrentRcb->mode; -+ PacketsServiced=0; -+ -+ /* Process received packets until we find hardware owned descriptors -+ or until we hit RxServiceMax */ -+ while((CurrentRcb)&&((RxBufStatus&CB_OWNERSHIP_BIT)==0)&& -+ (PacketsServiced<RxServiceMax)) /* ~GSG 030307 */ -+ { -+ -+ PacketsServiced++; /* ~GSG 030307 */ -+ SopRcb=CurrentRcb; -+ RxSopStatus=RxBufStatus; -+ RxPktLen = RxSopStatus&CB_SIZE_MASK; -+ -+ FrmFrags=0; -+ TotalFrags=0; -+ FragIndex=0; -+ FrmLen=0; -+ EofRcb=0; -+ -+/* +GSG 030508 *//* +GSG 030508 */ -+ -+ /* Loop through all fragments that comprise current packet. Build -+ fraglist and exit when the end of the packet is reached, or the -+ end of the descriptor list is reached. */ -+ do -+ { -+ bit32u DmaLen; -+ -+ -+ DmaLen=CurrentRcb->Off_BLen; -+ -+ FrmLen+=DmaLen; -+ TotalFrags++; -+ if (!EofRcb) -+ { -+ HalDev->fraglist[FragIndex].data=((char *)CurrentRcb->DatPtr); /* ~GSG 030508 */ -+ -+ HalDev->fraglist[FragIndex].len=DmaLen; /* ~GSG 030508 */ -+ -+ /* GSG 12/9 */ -+ HalDev->fraglist[FragIndex].OsInfo = CurrentRcb->OsInfo; /* ~GSG 030508 */ -+ -+ /* Upper layer must do the data invalidate */ -+ -+ FrmFrags++; -+ FragIndex++; /* ~GSG 030508 */ -+ if (FrmLen>=RxPktLen) -+ EofRcb=CurrentRcb; -+ } -+ EopRcb=CurrentRcb; -+ CurrentRcb=EopRcb->Next; -+ if (CurrentRcb) -+ { -+ osfuncDataCacheHitInvalidate((void*)CurrentRcb,16); -+ } -+ }while(((EopRcb->mode&CB_EOF_BIT)==0)&&(CurrentRcb)); -+ -+ /* Write the completion pointer for interrupt acknowledgement*/ -+ (CPMAC_RX_INT_ACK( base , Ch )) = VirtToPhys(EopRcb) - HalDev->offset; -+ -+ EopRcb->Next=0; -+ -+ if (CurrentRcb == 0) -+ { -+ /* If we are out of RCB's we must not send this packet -+ to the OS. */ -+ int RcbSize = HalDev->ChData[Ch].RxBufSize; -+ -+ if (TotalFrags>1) -+ { -+ EopRcb->Off_BLen=RcbSize; -+ EopRcb->mode=CB_OWNERSHIP_BIT; -+ osfuncDataCacheHitWritebackAndInvalidate((void *)EopRcb, 16); -+ } -+ -+ SopRcb->Off_BLen=RcbSize; -+ SopRcb->mode=CB_OWNERSHIP_BIT; -+ osfuncDataCacheHitWritebackAndInvalidate((void *)SopRcb, 16); -+ -+ ((CPMAC_RX_HDP( base , Ch )) ) = VirtToPhys(SopRcb); -+ } -+ else -+ { -+ /* Dequeue packet and send to OS */ -+ int mode; -+ -+ /* setup SopRcb for the packet */ -+ SopRcb->Eop=(void*)EopRcb; -+ -+ /* dequeue packet */ -+ HalDev->RxActQueueHead[Ch]=CurrentRcb; -+ -+ if (EopRcb->mode&CB_EOQ_BIT) -+ { -+ /* Next pointer is non-null and EOQ bit is set, which -+ indicates misqueue packet in CPPI protocol. */ -+ -+ ((CPMAC_RX_HDP( base , Ch )) ) = EopRcb->HNext; -+ } -+ -+ mode = (SopRcb->mode & 0xFFFF0000) | Ch; -+ -+ SopRcb->mode=(FrmFrags<<8)|Ch; -+ SopRcb->Off_BLen=(bit32u)HalDev; -+ -+ /* send packet up the higher layer driver */ -+ OsFunc->Receive(HalDev->OsDev,HalDev->fraglist,FragIndex,RxPktLen, /* ~GSG 030508 */ -+ (HAL_RECEIVEINFO *)SopRcb,mode); -+ -+ RxBufStatus=CurrentRcb->mode; -+ } -+ } /* while loop */ -+ -+ if ((CurrentRcb)&&((RxBufStatus&CB_OWNERSHIP_BIT)==0)) /*~GSG 030307*/ -+ { -+ *MoreWork = 1; -+ } -+ else -+ { -+ *MoreWork = 0; -+ } -+ -+ return (EC_NO_ERRORS); -+} -+ -+/* -+ * This function processes transmit interrupts. It traverses the -+ * transmit buffer queue, detecting sent data buffers and notifying the upper -+ * layer software via osSendComplete(). (for SAR, i originally had this split -+ * into two functions, one for each queue, but joined them on 8/8/02) -+ * -+ * @param HalDev CPHAL module instance. (set by cphalInitModule()) -+ * @param Queue Queue number to service (always 0 for MAC, Choose 1 for SAR to service low priority queue) -+ * @param MoreWork Flag that indicates that there is more work to do when set to 1. -+ * -+ * @return 0 if OK, non-zero otherwise. -+ */ -+int TxInt(HAL_DEVICE *HalDev, int Ch, int Queue, int *MoreWork) -+ { -+ HAL_TCB *CurrentTcb,*LastTcbProcessed,*FirstTcbProcessed; -+ int PacketsServiced; -+ bit32u TxFrameStatus; -+ int base; -+ int TxServiceMax = HalDev->ChData[Ch].TxServiceMax; -+ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; -+ -+/*+GSG 030303*//*+GSG 030303*/ -+ -+ /* load the module base address */ -+ base = HalDev->dev_base; -+ -+ /* Handle case of teardown interrupt. This must be checked at -+ the top of the function rather than the bottom, because -+ the normal data processing can wipe out the completion -+ pointer which is used to determine teardown complete. */ -+ if (HalDev->TxTeardownPending[Ch] != 0) -+ { -+ int Ret; -+ -+ Ret = TxTeardownInt(HalDev, Ch, Queue); -+ if (Ret == 0) -+ { /*+GSG 030303*/ -+ *MoreWork = 0; /* bug fix 1/6 */ /*+GSG 030303*/ -+ return (EC_NO_ERRORS); -+ } /*+GSG 030303*/ -+ } -+ -+ OsFunc->CriticalOn(); /* 240904 */ -+ -+ CurrentTcb = HalDev->TxActQueueHead[Ch][Queue]; -+ FirstTcbProcessed=CurrentTcb; -+ -+ if (CurrentTcb==0) -+ { -+ /* I saw this error a couple of times when multi-channels were added */ -+ dbgPrintf("[cppi TxInt()]TxH int with no TCB in queue!\n"); -+ dbgPrintf(" Ch=%d, CurrentTcb = 0x%08x\n", Ch, (bit32u)CurrentTcb); -+ dbgPrintf(" HalDev = 0x%08x\n", (bit32u)HalDev); -+ osfuncSioFlush(); -+ OsFunc->CriticalOff(); -+ return(EC_CPPI|EC_FUNC_TXINT|EC_VAL_NULL_TCB); -+ } -+ -+ osfuncDataCacheHitInvalidate((void *)CurrentTcb, 16); -+ TxFrameStatus=CurrentTcb->mode; -+ PacketsServiced=0; -+ -+ /* should the ownership bit check be inside of the loop?? could make it a -+ while-do loop and take this check away */ -+ if ((TxFrameStatus&CB_OWNERSHIP_BIT)==0) -+ { -+ do -+ { -+ /* Pop TCB(s) for packet from the stack */ -+ LastTcbProcessed=CurrentTcb->Eop; -+ -+ /* new location for acknowledge */ -+ /* Write the completion pointer */ -+ (CPMAC_TX_INT_ACK( base , Ch )) = VirtToPhys(LastTcbProcessed) - HalDev->offset; -+ -+ HalDev->TxActQueueHead[Ch][Queue] = LastTcbProcessed->Next; -+ -+/*+GSG 030303*//*+GSG 030303*/ -+ -+ osfuncDataCacheHitInvalidate((void *)LastTcbProcessed, 16); -+ -+ if (LastTcbProcessed->mode&CB_EOQ_BIT) -+ { -+ if (LastTcbProcessed->Next) -+ { -+ /* Misqueued packet */ -+ -+ (CPMAC_TX_HDP( base , Ch )) = LastTcbProcessed->HNext; -+ -+ } -+ else -+ { -+ /* Tx End of Queue */ -+ -+ HalDev->TxActive[Ch][Queue]=FALSE; -+ } -+ } -+ -+ OsFunc->SendComplete(CurrentTcb->OsInfo); -+ -+ /* Push Tcb(s) back onto the stack */ -+ CurrentTcb = LastTcbProcessed->Next; -+ -+ LastTcbProcessed->Next=HalDev->TcbPool[Ch][Queue]; -+ -+ HalDev->TcbPool[Ch][Queue]=FirstTcbProcessed; -+ -+ PacketsServiced++; -+ -+ TxFrameStatus=CB_OWNERSHIP_BIT; -+ /* set the first(SOP) pointer for the next packet */ -+ FirstTcbProcessed = CurrentTcb; -+ if (CurrentTcb) -+ { -+ osfuncDataCacheHitInvalidate((void *)CurrentTcb, 16); -+ TxFrameStatus=CurrentTcb->mode; -+ } -+ -+ }while(((TxFrameStatus&CB_OWNERSHIP_BIT)==0) -+ &&(PacketsServiced<TxServiceMax)); -+ -+ if (((TxFrameStatus&CB_OWNERSHIP_BIT)==0) -+ &&(PacketsServiced==TxServiceMax)) -+ { -+ *MoreWork = 1; -+ } -+ else -+ { -+ *MoreWork = 0; -+ } -+ } -+ OsFunc->CriticalOff(); -+ -+ return(EC_NO_ERRORS); -+ } -+ -+/** -+ * @ingroup CPHAL_Functions -+ * This function performs a teardown for the given channel. The value of the -+ * Mode parameter controls the operation of the function, as documented below. -+ * -+ * Note: If bit 3 of Mode is set, this call is blocking, and will not return -+ * until the teardown interrupt has occurred and been processed. While waiting -+ * for a blocking teardown to complete, ChannelTeardown() will signal the OS -+ * (via Control(.."Sleep"..)) to allow the OS to perform other tasks if -+ * necessary. If and only if bit 3 of Mode is clear, the CPHAL will call the -+ * OS TeardownComplete() function to indicate that the teardown has completed. -+ * -+ * @param HalDev CPHAL module instance. (set by xxxInitModule()) -+ * @param Ch Channel number. -+ * @param Mode Bit 0 (LSB): Perform Tx teardown (if set).<BR> -+ * Bit 1: Perform Rx teardown (if set). <BR> -+ * Bit 2: If set, perform full teardown (free buffers/descriptors). -+ * If clear, perform partial teardown (keep buffers). <BR> -+ * Bit 3 (MSB): If set, call is blocking. -+ * If clear, call is non-blocking. -+ * -+ * @return EC_NO_ERRORS (ok). <BR> -+ * Possible Error Codes:<BR> -+ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"<BR> -+ * @ref EC_VAL_INVALID_CH "EC_VAL_INVALID_CH"<BR> -+ * @ref EC_VAL_TX_TEARDOWN_ALREADY_PEND "EC_VAL_TX_TEARDOWN_ALREADY_PEND"<BR> -+ * @ref EC_VAL_RX_TEARDOWN_ALREADY_PEND "EC_VAL_RX_TEARDOWN_ALREADY_PEND"<BR> -+ * @ref EC_VAL_TX_CH_ALREADY_TORNDOWN "EC_VAL_TX_CH_ALREADY_TORNDOWN"<BR> -+ * @ref EC_VAL_RX_CH_ALREADY_TORNDOWN "EC_VAL_RX_CH_ALREADY_TORNDOWN"<BR> -+ * @ref EC_VAL_TX_TEARDOWN_TIMEOUT "EC_VAL_TX_TEARDOWN_TIMEOUT"<BR> -+ * @ref EC_VAL_RX_TEARDOWN_TIMEOUT "EC_VAL_RX_TEARDOWN_TIMEOUT"<BR> -+ * @ref EC_VAL_LUT_NOT_READY "EC_VAL_LUT_NOT_READY"<BR> -+ */ -+static int halChannelTeardown(HAL_DEVICE *HalDev, int Ch, bit32 Mode) -+ { -+ int DoTx, DoRx, Sleep=2048, timeout=0; /*MJH~030306*/ -+ bit32u base = HalDev->dev_base; -+ -+/* Set the module, used for error returns */ -+ -+ DoTx = (Mode & TX_TEARDOWN); -+ DoRx = (Mode & RX_TEARDOWN); -+ -+ if (HalDev->State < enInitialized) -+ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_INVALID_STATE); -+ -+ if ((Ch < 0) || (Ch > (MAX_CHAN-1) )) -+ { -+ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_INVALID_CH); -+ } -+ -+ /* set teardown pending bits before performing the teardown, because they -+ will be used in the int handler (this is done for AAL5) */ -+ if (DoTx) -+ { -+ if (HalDev->TxTeardownPending[Ch] != 0) -+ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_TX_TEARDOWN_ALREADY_PEND); -+ -+ /* If a full teardown, this also means that the user must -+ setup all channels again to use them */ -+ if (Mode & FULL_TEARDOWN) -+ HalDev->ChIsSetup[Ch][DIRECTION_TX] = 0; -+ -+ if (HalDev->State < enOpened) -+ { -+ /* if the hardware has never been opened, the channel has never actually -+ been setup in the hardware, so I just need to reset the software flag -+ and leave */ -+ HalDev->ChIsSetup[Ch][DIRECTION_TX] = 0; -+ return (EC_NO_ERRORS); -+ } -+ else -+ { -+ if (HalDev->ChIsOpen[Ch][DIRECTION_TX] == 0) -+ { -+ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_TX_CH_ALREADY_TORNDOWN); -+ } -+ -+ /* set teardown flag */ -+ HalDev->TxTeardownPending[Ch] = Mode; -+ } -+ } -+ -+ if (DoRx) -+ { -+ if (HalDev->RxTeardownPending[Ch] != 0) -+ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_RX_TEARDOWN_ALREADY_PEND); -+ -+ if (Mode & FULL_TEARDOWN) -+ HalDev->ChIsSetup[Ch][DIRECTION_RX] = 0; -+ -+ if (HalDev->State < enOpened) -+ { -+ HalDev->ChIsSetup[Ch][DIRECTION_RX] = 0; -+ return (EC_NO_ERRORS); -+ } -+ else -+ { -+ if (HalDev->ChIsOpen[Ch][DIRECTION_RX] == 0) -+ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_RX_CH_ALREADY_TORNDOWN); -+ -+ HalDev->RxTeardownPending[Ch] = Mode; -+ } -+ } -+ -+ /* Perform Tx Teardown Duties */ -+ if ((DoTx) && (HalDev->State == enOpened)) -+ { -+ /* Request TX channel teardown */ -+ (CPMAC_TX_TEARDOWN( base )) = Ch; -+ -+ /* wait until teardown has completed */ -+ if (Mode & BLOCKING_TEARDOWN) -+ { -+ timeout = 0; -+ while (HalDev->ChIsOpen[Ch][DIRECTION_TX] == TRUE) -+ { -+ osfuncSleep(&Sleep); -+ -+ timeout++; -+ if (timeout > 100000) -+ { -+ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_TX_TEARDOWN_TIMEOUT); -+ } -+ } -+ } -+ } /* if DoTx */ -+ -+ /* Perform Rx Teardown Duties */ -+ if ((DoRx) && (HalDev->State == enOpened)) -+ { -+ -+ /* perform CPMAC specific RX channel teardown */ -+ CPMAC_RX_TEARDOWN(base) = Ch; -+ -+ if (Mode & BLOCKING_TEARDOWN) -+ { -+ timeout = 0; -+ while (HalDev->ChIsOpen[Ch][DIRECTION_RX] == TRUE) -+ { -+ osfuncSleep(&Sleep); -+ -+ timeout++; -+ if (timeout > 100000) -+ { -+ return(EC_CPMAC |EC_FUNC_CHTEARDOWN|EC_VAL_RX_TEARDOWN_TIMEOUT); -+ } -+ } -+ } -+ } /* if DoRx */ -+ -+ return (EC_NO_ERRORS); -+ } -+ -+/** -+ * @ingroup CPHAL_Functions -+ * This function closes the CPHAL module. The module will be reset. -+ * The Mode parameter should be used to determine the actions taken by -+ * Close(). -+ * -+ * @param HalDev CPHAL module instance. (set by xxxInitModule()) -+ * @param Mode Indicates actions to take on close. The following integer -+ * values are valid: <BR> -+ * 1: Does not free buffer resources, init parameters remain -+ * intact. User can then call Open() without calling Init() -+ * to attempt to reset the device and bring it back to the -+ * last known state.<BR> -+ * 2: Frees the buffer resources, but keeps init parameters. This -+ * option is a more aggressive means of attempting a device reset. -+ * 3: Frees the buffer resources, and clears all init parameters. <BR> -+ * At this point, the caller would have to call to completely -+ * reinitialize the device (Init()) before being able to call -+ * Open(). Use this mode if you are shutting down the module -+ * and do not plan to restart. -+ * -+ * @return EC_NO_ERRORS (ok).<BR> -+ * Possible Error Codes:<BR> -+ * @ref EC_VAL_INVALID_STATE "EC_VAL_INVALID_STATE"<BR> -+ * Any error code from halChannelTeardown().<BR> -+ */ -+static int halClose(HAL_DEVICE *HalDev, bit32 Mode) -+ { -+ int Ch, Inst, Ret; -+ OS_DEVICE *TmpOsDev; -+ OS_FUNCTIONS *TmpOsFunc; -+ HAL_FUNCTIONS *TmpHalFunc; -+ char *TmpDeviceInfo; -+ -+ int Ticks; /*MJH~030306*/ -+ -+ /* Verify proper device state */ -+ if (HalDev->State != enOpened) -+ return (EC_CPMAC | EC_FUNC_CLOSE|EC_VAL_INVALID_STATE); -+ -+ /* Teardown all open channels */ -+ for (Ch = 0; Ch <= (MAX_CHAN-1) ; Ch++) -+ { -+ if (HalDev->ChIsOpen[Ch][DIRECTION_TX] == TRUE) -+ { -+ if (Mode == 1) -+ { -+ Ret = halChannelTeardown(HalDev, Ch, TX_TEARDOWN | PARTIAL_TEARDOWN | BLOCKING_TEARDOWN); -+ if (Ret) return (Ret); -+ } -+ else -+ { -+ Ret = halChannelTeardown(HalDev, Ch, TX_TEARDOWN | FULL_TEARDOWN | BLOCKING_TEARDOWN); -+ if (Ret) return (Ret); -+ } -+ } -+ -+ if (HalDev->ChIsOpen[Ch][DIRECTION_RX] == TRUE) -+ { -+ if (Mode == 1) -+ { -+ Ret = halChannelTeardown(HalDev, Ch, RX_TEARDOWN | PARTIAL_TEARDOWN | BLOCKING_TEARDOWN); -+ if (Ret) return (Ret); -+ } -+ else -+ { -+ Ret = halChannelTeardown(HalDev, Ch, RX_TEARDOWN | FULL_TEARDOWN | BLOCKING_TEARDOWN); -+ if (Ret) return (Ret); -+ } -+ } -+ } -+ -+ /* free fraglist in HalDev */ -+ HalDev->OsFunc->Free(HalDev->fraglist); -+ HalDev->fraglist = 0; -+ -+ /* unregister the interrupt */ -+ HalDev->OsFunc->IsrUnRegister(HalDev->OsDev, HalDev->interrupt); -+ -+ Ticks = 0; /* Disable Tick Timer */ /*MJH+030306*/ -+ HalDev->OsFunc->Control(HalDev->OsDev, hcTick, hcClear, &Ticks); /*MJH+030306*/ -+ -+ /* Free the Phy Information Structure */ -+ if(HalDev->PhyDev) -+ { -+ HalDev->OsFunc->Free(HalDev->PhyDev); /*MJH+030513*/ -+ HalDev->PhyDev = 0; /*MJH+030522*/ -+ } -+ -+ /* Perform CPMAC specific closing functions */ -+ CPMAC_MACCONTROL(HalDev->dev_base) &= ~MII_EN; -+ CPMAC_TX_CONTROL(HalDev->dev_base) &= ~TX_EN; -+ CPMAC_RX_CONTROL(HalDev->dev_base) &= ~RX_EN; -+ -+ /* put device back into reset */ -+ (*(volatile bit32u *)(HalDev->ResetBase)) &=~ (1<<HalDev->ResetBit); -+ Ticks = 64; /*MJH~030306*/ -+ osfuncSleep(&Ticks); -+ -+ /* If mode is 3, than clear the HalDev and set next state to DevFound*/ -+ if (Mode == 3) -+ { -+ /* I need to keep the HalDev parameters that were setup in InitModule */ -+ TmpOsDev = HalDev->OsDev; -+ TmpOsFunc = HalDev->OsFunc; -+ TmpDeviceInfo = HalDev->DeviceInfo; -+ -+ TmpHalFunc = HalDev->HalFuncPtr; -+ Inst = HalDev->Inst; -+ -+ /* Clear HalDev */ -+ -+ HalDev->OsFunc->Memset(HalDev, 0, sizeof(HAL_DEVICE)); -+ -+ /* Restore key parameters */ -+ HalDev->OsDev = TmpOsDev; -+ HalDev->OsFunc = TmpOsFunc; -+ HalDev->DeviceInfo = TmpDeviceInfo; -+ -+ HalDev->HalFuncPtr = TmpHalFunc; -+ HalDev->Inst = Inst; -+ -+ HalDev->State = enDevFound; -+ } -+ else -+ { -+ HalDev->State = enInitialized; -+ } -+ -+ return(EC_NO_ERRORS); -+ } -diff -urN linux.old/drivers/net/avalanche_cpmac/cpremap_cpmac.c linux.dev/drivers/net/avalanche_cpmac/cpremap_cpmac.c ---- linux.old/drivers/net/avalanche_cpmac/cpremap_cpmac.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/cpremap_cpmac.c 2005-07-12 02:48:42.049593000 +0200 -@@ -0,0 +1,28 @@ -+#ifndef _INC_CPREMAP_C -+#define _INC_CPREMAP_C -+ -+#ifdef __ADAM2 -+static inline void osfuncDataCacheHitInvalidate(void *ptr, int Size) -+ { -+ asm(" cache 17, (%0)" : : "r" (ptr)); -+ } -+ -+static inline void osfuncDataCacheHitWriteback(void *ptr, int Size) -+ { -+ asm(" cache 25, (%0)" : : "r" (ptr)); -+ } -+ -+static inline void osfuncDataCacheHitWritebackAndInvalidate(void *ptr, int Size) -+ { -+ asm(" cache 21, (%0)" : : "r" (ptr)); -+ } -+ -+#else -+ -+#define osfuncDataCacheHitInvalidate(MemPtr, Size) __asm__(" .set mips3; cache 17, (%0); .set mips0" : : "r" (MemPtr)) -+#define osfuncDataCacheHitWritebackAndInvalidate(MemPtr, Size) __asm__(" .set mips3; cache 21, (%0); .set mips0" : : "r" (MemPtr)) -+#define osfuncDataCacheHitWriteback(MemPtr, Size) __asm__(" .set mips3; cache 25, (%0); .set mips0" : : "r" (MemPtr)) -+ -+#endif -+ -+#endif -diff -urN linux.old/drivers/net/avalanche_cpmac/cpswhal_cpmac.h linux.dev/drivers/net/avalanche_cpmac/cpswhal_cpmac.h ---- linux.old/drivers/net/avalanche_cpmac/cpswhal_cpmac.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/cpswhal_cpmac.h 2005-07-12 02:48:42.050593000 +0200 -@@ -0,0 +1,632 @@ -+/************************************************************************ -+ * TNETDxxxx Software Support -+ * Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved. -+ * -+ * FILE: cphal.h -+ * -+ * DESCRIPTION: -+ * User include file, contains data definitions shared between the CPHAL -+ * and the upper-layer software. -+ * -+ * HISTORY: -+ * Date Modifier Ver Notes -+ * 28Feb02 Greg 1.00 Original -+ * 06Mar02 Greg 1.01 Documentation enhanced -+ * 18Jul02 Greg 1.02 Many updates (OAM additions, general reorg) -+ * 22Nov02 Mick RC2 Additions from Denis' input on Control -+ * -+ * author Greg Guyotte -+ * version 1.02 -+ * date 18-Jul-2002 -+ *****************************************************************************/ -+#ifndef _INC_CPHAL_H -+#define _INC_CPHAL_H -+ -+#ifdef _CPHAL_CPMAC -+#include "ec_errors_cpmac.h" -+#endif -+ -+#ifdef _CPHAL_AAL5 -+#include "ec_errors_cpaal5.h" -+#endif -+ -+#ifdef _CPHAL_CPSAR -+#include "ec_errors_cpsar.h" -+#endif -+ -+#ifdef _CPHAL_AAL2 -+#include "ec_errors_cpaal2.h" -+#endif -+ -+#ifndef __ADAM2 -+typedef char bit8; -+typedef short bit16; -+typedef int bit32; -+ -+typedef unsigned char bit8u; -+typedef unsigned short bit16u; -+typedef unsigned int bit32u; -+ -+/* -+typedef char INT8; -+typedef short INT16; -+typedef int INT32; -+typedef unsigned char UINT8; -+typedef unsigned short UINT16; -+typedef unsigned int UINT32; -+*/ -+/*typedef unsigned int size_t;*/ -+#endif -+ -+#ifdef _CPHAL -+ -+#ifndef TRUE -+#define TRUE (1==1) -+#endif -+ -+#ifndef FALSE -+#define FALSE (1==2) -+#endif -+ -+#ifndef NULL -+#define NULL 0 -+#endif -+ -+#endif -+ -+#define VirtToPhys(a) (((int)a)&~0xe0000000) -+#define VirtToVirtNoCache(a) ((void*)((VirtToPhys(a))|0xa0000000)) -+#define VirtToVirtCache(a) ((void*)((VirtToPhys(a))|0x80000000)) -+#define PhysToVirtNoCache(a) ((void*)(((int)a)|0xa0000000)) -+#define PhysToVirtCache(a) ((void*)(((int)a)|0x80000000)) -+/* -+#define DataCacheHitInvalidate(a) {__asm__(" cache 17, (%0)" : : "r" (a));} -+#define DataCacheHitWriteback(a) {__asm__(" cache 25, (%0)" : : "r" (a));} -+*/ -+ -+#define PARTIAL 1 /**< Used in @c Close() and @c ChannelTeardown() */ -+#define FULL 2 /**< Used in @c Close() and @c ChannelTeardown() */ -+ -+/* Channel Teardown Defines */ -+#define RX_TEARDOWN 2 -+#define TX_TEARDOWN 1 -+#define BLOCKING_TEARDOWN 8 -+#define FULL_TEARDOWN 4 -+#define PARTIAL_TEARDOWN 0 -+ -+#define MAX_DIR 2 -+#define DIRECTION_TX 0 -+#define DIRECTION_RX 1 -+#define TX_CH 0 -+#define RX_CH 1 -+#define HAL_ERROR_DEVICE_NOT_FOUND 1 -+#define HAL_ERROR_FAILED_MALLOC 2 -+#define HAL_ERROR_OSFUNC_SIZE 3 -+#define HAL_DEFAULT 0xFFFFFFFF -+#define VALID(val) (val!=HAL_DEFAULT) -+ -+/* -+ERROR REPORTING -+ -+HAL Module Codes. Each HAL module reporting an error code -+should OR the error code with the respective Module error code -+from the list below. -+*/ -+#define EC_AAL5 EC_HAL|EC_DEV_AAL5 -+#define EC_AAL2 EC_HAL|EC_DEV_AAL2 -+#define EC_CPSAR EC_HAL|EC_DEV_CPSAR -+#define EC_CPMAC EC_HAL|EC_DEV_CPMAC -+#define EC_VDMA EC_HAL|EC_DEV_VDMA -+#define EC_VLYNQ EC_HAL|EC_DEV_VLYNQ -+#define EC_CPPI EC_HAL|EC_DEV_CPPI -+ -+/* -+HAL Function Codes. Each HAL module reporting an error code -+should OR the error code with one of the function codes from -+the list below. -+*/ -+#define EC_FUNC_HAL_INIT EC_FUNC(1) -+#define EC_FUNC_CHSETUP EC_FUNC(2) -+#define EC_FUNC_CHTEARDOWN EC_FUNC(3) -+#define EC_FUNC_RXRETURN EC_FUNC(4) -+#define EC_FUNC_SEND EC_FUNC(5) -+#define EC_FUNC_RXINT EC_FUNC(6) -+#define EC_FUNC_TXINT EC_FUNC(7) -+#define EC_FUNC_AAL2_VDMA EC_FUNC(8) -+#define EC_FUNC_OPTIONS EC_FUNC(9) -+#define EC_FUNC_PROBE EC_FUNC(10) -+#define EC_FUNC_OPEN EC_FUNC(11) -+#define EC_FUNC_CONTROL EC_FUNC(12) -+#define EC_FUNC_DEVICE_INT EC_FUNC(13) -+#define EC_FUNC_STATUS EC_FUNC(14) -+#define EC_FUNC_TICK EC_FUNC(15) -+#define EC_FUNC_CLOSE EC_FUNC(16) -+#define EC_FUNC_SHUTDOWN EC_FUNC(17) -+#define EC_FUNC_DEVICE_INT_ALT EC_FUNC(18) /* +GSG 030306 */ -+ -+/* -+HAL Error Codes. The list below defines every type of error -+used in all HAL modules. DO NOT CHANGE THESE VALUES! Add new -+values in integer order to the bottom of the list. -+*/ -+#define EC_VAL_PDSP_LOAD_FAIL EC_ERR(0x01)|EC_CRITICAL -+#define EC_VAL_FIRMWARE_TOO_LARGE EC_ERR(0x02)|EC_CRITICAL -+#define EC_VAL_DEVICE_NOT_FOUND EC_ERR(0x03)|EC_CRITICAL -+#define EC_VAL_BASE_ADDR_NOT_FOUND EC_ERR(0x04)|EC_CRITICAL -+#define EC_VAL_RESET_BIT_NOT_FOUND EC_ERR(0x05)|EC_CRITICAL -+#define EC_VAL_CH_INFO_NOT_FOUND EC_ERR(0x06) -+#define EC_VAL_RX_STATE_RAM_NOT_CLEARED EC_ERR(0x07)|EC_CRITICAL -+#define EC_VAL_TX_STATE_RAM_NOT_CLEARED EC_ERR(0x08)|EC_CRITICAL -+#define EC_VAL_MALLOC_DEV_FAILED EC_ERR(0x09) -+#define EC_VAL_OS_VERSION_NOT_SUPPORTED EC_ERR(0x0A)|EC_CRITICAL -+#define EC_VAL_CPSAR_VERSION_NOT_SUPPORTED EC_ERR(0x0B)|EC_CRITICAL -+#define EC_VAL_NULL_CPSAR_DEV EC_ERR(0x0C)|EC_CRITICAL -+ -+#define EC_VAL_LUT_NOT_READY EC_ERR(0x0D) -+#define EC_VAL_INVALID_CH EC_ERR(0x0E) -+#define EC_VAL_NULL_CH_STRUCT EC_ERR(0x0F) -+#define EC_VAL_RX_TEARDOWN_ALREADY_PEND EC_ERR(0x10) -+#define EC_VAL_TX_TEARDOWN_ALREADY_PEND EC_ERR(0x11) -+#define EC_VAL_RX_CH_ALREADY_TORNDOWN EC_ERR(0x12) -+#define EC_VAL_TX_CH_ALREADY_TORNDOWN EC_ERR(0x13) -+#define EC_VAL_TX_TEARDOWN_TIMEOUT EC_ERR(0x14) -+#define EC_VAL_RX_TEARDOWN_TIMEOUT EC_ERR(0x15) -+#define EC_VAL_CH_ALREADY_TORNDOWN EC_ERR(0x16) -+#define EC_VAL_VC_SETUP_NOT_READY EC_ERR(0x17) -+#define EC_VAL_VC_TEARDOWN_NOT_READY EC_ERR(0x18) -+#define EC_VAL_INVALID_VC EC_ERR(0x19) -+#define EC_VAL_INVALID_LC EC_ERR(0x20) -+#define EC_VAL_INVALID_VDMA_CH EC_ERR(0x21) -+#define EC_VAL_INVALID_CID EC_ERR(0x22) -+#define EC_VAL_INVALID_UUI EC_ERR(0x23) -+#define EC_VAL_INVALID_UUI_DISCARD EC_ERR(0x24) -+#define EC_VAL_CH_ALREADY_OPEN EC_ERR(0x25) -+ -+#define EC_VAL_RCB_MALLOC_FAILED EC_ERR(0x26) -+#define EC_VAL_RX_BUFFER_MALLOC_FAILED EC_ERR(0x27) -+#define EC_VAL_OUT_OF_TCBS EC_ERR(0x28) -+#define EC_VAL_NO_TCBS EC_ERR(0x29) -+#define EC_VAL_NULL_RCB EC_ERR(0x30)|EC_CRITICAL -+#define EC_VAL_SOP_ERROR EC_ERR(0x31)|EC_CRITICAL -+#define EC_VAL_EOP_ERROR EC_ERR(0x32)|EC_CRITICAL -+#define EC_VAL_NULL_TCB EC_ERR(0x33)|EC_CRITICAL -+#define EC_VAL_CORRUPT_RCB_CHAIN EC_ERR(0x34)|EC_CRITICAL -+#define EC_VAL_TCB_MALLOC_FAILED EC_ERR(0x35) -+ -+#define EC_VAL_DISABLE_POLLING_FAILED EC_ERR(0x36) -+#define EC_VAL_KEY_NOT_FOUND EC_ERR(0x37) -+#define EC_VAL_MALLOC_FAILED EC_ERR(0x38) -+#define EC_VAL_RESET_BASE_NOT_FOUND EC_ERR(0x39)|EC_CRITICAL -+#define EC_VAL_INVALID_STATE EC_ERR(0x40) -+#define EC_VAL_NO_TXH_WORK_TO_DO EC_ERR(0x41) -+#define EC_VAL_NO_TXL_WORK_TO_DO EC_ERR(0x42) -+#define EC_VAL_NO_RX_WORK_TO_DO EC_ERR(0x43) -+#define EC_VAL_NOT_LINKED EC_ERR(0x44) -+#define EC_VAL_INTERRUPT_NOT_FOUND EC_ERR(0x45) -+#define EC_VAL_OFFSET_NOT_FOUND EC_ERR(0x46) -+#define EC_VAL_MODULE_ALREADY_CLOSED EC_ERR(0x47) -+#define EC_VAL_MODULE_ALREADY_SHUTDOWN EC_ERR(0x48) -+#define EC_VAL_ACTION_NOT_FOUND EC_ERR(0x49) -+#define EC_VAL_RX_CH_ALREADY_SETUP EC_ERR(0x50) -+#define EC_VAL_TX_CH_ALREADY_SETUP EC_ERR(0x51) -+#define EC_VAL_RX_CH_ALREADY_OPEN EC_ERR(0x52) -+#define EC_VAL_TX_CH_ALREADY_OPEN EC_ERR(0x53) -+#define EC_VAL_CH_ALREADY_SETUP EC_ERR(0x54) -+#define EC_VAL_RCB_NEEDS_BUFFER EC_ERR(0x55) /* +GSG 030410 */ -+#define EC_VAL_RCB_DROPPED EC_ERR(0x56) /* +GSG 030410 */ -+#define EC_VAL_INVALID_VALUE EC_ERR(0x57) -+ -+/** -+@defgroup shared_data Shared Data Structures -+ -+The data structures documented here are shared by all modules. -+*/ -+ -+/** -+ * @ingroup shared_data -+ * This is the fragment list structure. Each fragment list entry contains a -+ * length and a data buffer. -+ */ -+typedef struct -+ { -+ bit32u len; /**< Length of the fragment in bytes (lower 16 bits are valid). For SOP, upper 16 bits is the buffer offset. */ -+ void *data; /**< Pointer to fragment data. */ -+ void *OsInfo; /**< Pointer to OS defined data. */ -+ }FRAGLIST; -+ -+#if defined (_CPHAL_CPMAC) -+#define CB_PASSCRC_BIT (1<<26) -+ -+/* CPMAC CPHAL STATUS */ -+#define CPMAC_STATUS_LINK (1 << 0) -+#define CPMAC_STATUS_LINK_DUPLEX (1 << 1) /* 0 - HD, 1 - FD */ -+#define CPMAC_STATUS_LINK_SPEED (1 << 2) /* 0 - 10, 1 - 100 */ -+ -+/* ADAPTER CHECK Codes */ -+ -+#define CPMAC_STATUS_ADAPTER_CHECK (1 << 7) -+#define CPMAC_STATUS_HOST_ERR_DIRECTION (1 << 8) -+#define CPMAC_STATUS_HOST_ERR_CODE (0xF << 9) -+#define CPMAC_STATUS_HOST_ERR_CH (0x7 << 13) -+ -+#define _CPMDIO_DISABLE (1 << 0) -+#define _CPMDIO_HD (1 << 1) -+#define _CPMDIO_FD (1 << 2) -+#define _CPMDIO_10 (1 << 3) -+#define _CPMDIO_100 (1 << 4) -+#define _CPMDIO_NEG_OFF (1 << 5) -+#define _CPMDIO_LOOPBK (1 << 16) -+#define _CPMDIO_AUTOMDIX (1 << 17) /* Bit 16 and above not used by MII register */ -+#define _CPMDIO_NOPHY (1 << 20) -+#endif -+ -+/** -+ * @ingroup shared_data -+ * Channel specific configuration information. This structure should be -+ * populated by upper-layer software prior to calling @c ChannelSetup(). Any -+ * configuration item that can be changed on a per channel basis should -+ * be represented here. Each module may define this structure with additional -+ * module-specific members. -+ */ -+typedef struct -+ { -+ int Channel; /**< Channel number. */ -+ int Direction; /**< DIRECTION_RX(1) or DIRECTION_TX(0). */ -+ OS_SETUP *OsSetup; /**< OS defined information associated with this channel. */ -+ -+#if defined(_CPHAL_AAL5) || defined (_CPHAL_CPSAR) || defined (_CPHAL_CPMAC) -+ int RxBufSize; /**< Size (in bytes) for each Rx buffer.*/ -+ int RxBufferOffset; /**< Number of bytes to offset rx data from start of buffer (must be less than buffer size). */ -+ int RxNumBuffers; /**< The number of Rx buffer descriptors to allocate for Ch. */ -+ int RxServiceMax; /**< Maximum number of packets to service at one time. */ -+ -+ int TxNumBuffers; /**< The number of Tx buffer descriptors to allocate for Ch. */ -+ int TxNumQueues; /**< Number of Tx queues for this channel (1-2). Choosing 2 enables a low priority SAR queue. */ -+ int TxServiceMax; /**< Maximum number of packets to service at one time. */ -+#endif -+ -+#if defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR) -+ int CpcsUU; /**< The 2-byte CPCS UU and CPI information. */ -+ int Gfc; /**< Generic Flow Control. */ -+ int Clp; /**< Cell Loss Priority. */ -+ int Pti; /**< Payload Type Indication. */ -+#endif -+ -+#if defined(_CPHAL_AAL2) || defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR) -+ int DaMask; /**< Specifies whether credit issuance is paused when Tx data not available. */ -+ int Priority; /**< Priority bin this channel will be scheduled within. */ -+ int PktType; /**< 0=AAL5,1=Null AAL,2=OAM,3=Transparent,4=AAL2. */ -+ int Vci; /**< Virtual Channel Identifier. */ -+ int Vpi; /**< Virtual Path Identifier. */ -+ int FwdUnkVc; /**< Enables forwarding of unknown VCI/VPI cells to host. 1=enable, 0=disable. */ -+ -+ /* Tx VC State */ -+ int TxVc_CellRate; /**< Tx rate, set as clock ticks between transmissions (SCR for VBR, CBR for CBR). */ -+ int TxVc_QosType; /**< 0=CBR,1=VBR,2=UBR,3=UBRmcr. */ -+ int TxVc_Mbs; /**< Min Burst Size in cells.*/ -+ int TxVc_Pcr; /**< Peak Cell Rate for VBR in clock ticks between transmissions. */ -+ -+ bit32 TxVc_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Tx Ch (must be big endian with 0 PTI). */ -+ int TxVc_OamTc; /**< TC Path to transmit OAM cells for TX connection (0,1). */ -+ int TxVc_VpOffset; /**< Offset to the OAM VP state table. */ -+ /* Rx VC State */ -+ int RxVc_OamCh; /**< Ch to terminate rx'd OAM cells to be forwarded to the host. */ -+ int RxVc_OamToHost; /**< 0=do not pass, 1=pass. */ -+ bit32 RxVc_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Rx conn (must be big endian with 0 PTI). */ -+ int RxVc_OamTc; /**< TC Path to transmit OAM cells for RX connection (0,1). */ -+ int RxVc_VpOffset; /**< Offset to the OAM VP state table. */ -+ /* Tx VP State */ -+ int TxVp_OamTc; /**< TC Path to transmit OAM cells for TX VP connection (0,1). */ -+ bit32 TxVp_AtmHeader; /**< ATM Header placed on firmware gen'd VP OAM cells for this Tx VP conn (must be big endian with 0 VCI). */ -+ /* Rx VP State */ -+ int RxVp_OamCh; /**< Ch to terminate rx'd OAM cells to be forwarded to the host. */ -+ int RxVp_OamToHost; /**< 0=do not pass, 1=pass. */ -+ bit32 RxVp_AtmHeader; /**< ATM Header placed on firmware gen'd OAM cells for this Rx VP conn (must be big endian with 0 VCI). */ -+ int RxVp_OamTc; /**< TC Path to transmit OAM cells for RX VP connection (0,1). */ -+ int RxVp_OamVcList; /**< Indicates all VC channels associated with this VP channel (one-hot encoded). */ -+#endif -+ -+ -+#ifdef _CPHAL_VDMAVT -+ bit32u RemFifoAddr; /* Mirror mode only. */ -+ bit32u FifoAddr; -+ bit32 PollInt; -+ bit32 FifoSize; -+ int Ready; -+#endif -+ -+ }CHANNEL_INFO; -+ -+/* -+ * This structure contains each statistic value gathered by the CPHAL. -+ * Applications may access statistics data by using the @c StatsGet() routine. -+ */ -+/* STATS */ -+#if defined(_CPHAL_AAL2) || defined(_CPHAL_AAL5) || defined(_CPHAL_CPSAR) -+typedef struct -+ { -+ bit32u CrcErrors[16]; -+ bit32u LenErrors[16]; -+ bit32u DmaLenErrors[16]; -+ bit32u AbortErrors[16]; -+ bit32u StarvErrors[16]; -+ bit32u TxMisQCnt[16][2]; -+ bit32u RxMisQCnt[16]; -+ bit32u RxEOQCnt[16]; -+ bit32u TxEOQCnt[16][2]; -+ bit32u RxPacketsServiced[16]; -+ bit32u TxPacketsServiced[16][2]; -+ bit32u RxMaxServiced; -+ bit32u TxMaxServiced[16][2]; -+ bit32u RxTotal; -+ bit32u TxTotal; -+ } STAT_INFO; -+#endif -+ -+/* -+ * VDMA Channel specific configuration information -+ */ -+#ifdef _CPHAL_AAL2 -+typedef struct -+ { -+ int Ch; /**< Channel Number */ -+ int RemoteEndian; /**< Endianness of remote VDMA-VT device */ -+ int CpsSwap; /**< When 0, octet 0 in CPS pkt located in LS byte of 16-bit word sent to rem VDMA device. When 1, in MS byte. */ -+ }VdmaChInfo; -+#endif -+ -+#ifndef _CPHAL -+ typedef void HAL_DEVICE; -+ typedef void HAL_PRIVATE; -+ typedef void HAL_RCB; -+ typedef void HAL_RECEIVEINFO; -+#endif -+ -+/** -+ * @ingroup shared_data -+ * The HAL_FUNCTIONS struct defines the function pointers used by upper layer -+ * software. The upper layer software receives these pointers through the -+ * call to xxxInitModule(). -+ */ -+typedef struct -+ { -+ int (*ChannelSetup) (HAL_DEVICE *HalDev, CHANNEL_INFO *Channel, OS_SETUP *OsSetup); -+ int (*ChannelTeardown) (HAL_DEVICE *HalDev, int Channel, int Mode); -+ int (*Close) (HAL_DEVICE *HalDev, int Mode); -+ int (*Control) (HAL_DEVICE *HalDev, const char *Key, const char *Action, void *Value); -+ int (*Init) (HAL_DEVICE *HalDev); -+ int (*Open) (HAL_DEVICE *HalDev); -+ int (*PacketProcessEnd) (HAL_DEVICE *HalDev); -+ int (*Probe) (HAL_DEVICE *HalDev); -+ int (*RxReturn) (HAL_RECEIVEINFO *HalReceiveInfo, int StripFlag); -+ int (*Send) (HAL_DEVICE *HalDev, FRAGLIST *FragList, int FragCount, int PacketSize, OS_SENDINFO *OsSendInfo, bit32u Mode); -+ int (*Shutdown) (HAL_DEVICE *HalDev); -+ int (*Tick) (HAL_DEVICE *HalDev); -+ -+#ifdef _CPHAL_AAL5 -+ int (*Kick) (HAL_DEVICE *HalDev, int Queue); -+ void (*OamFuncConfig) (HAL_DEVICE *HalDev, unsigned int OamConfig); -+ void (*OamLoopbackConfig) (HAL_DEVICE *HalDev, unsigned int OamConfig, unsigned int *LLID, unsigned int CorrelationTag); -+ volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset); -+ STAT_INFO* (*StatsGetOld)(HAL_DEVICE *HalDev); -+#endif -+ } HAL_FUNCTIONS; -+ -+/** -+ * @ingroup shared_data -+ * The OS_FUNCTIONS struct defines the function pointers for all upper layer -+ * functions accessible to the CPHAL. The upper layer software is responsible -+ * for providing the correct OS-specific implementations for the following -+ * functions. It is populated by calling InitModule() (done by the CPHAL in -+ * xxxInitModule(). -+ */ -+typedef struct -+ { -+ int (*Control)(OS_DEVICE *OsDev, const char *Key, const char *Action, void *Value); -+ void (*CriticalOn)(void); -+ void (*CriticalOff)(void); -+ void (*DataCacheHitInvalidate)(void *MemPtr, int Size); -+ void (*DataCacheHitWriteback)(void *MemPtr, int Size); -+ int (*DeviceFindInfo)(int Inst, const char *DeviceName, void *DeviceInfo); -+ int (*DeviceFindParmUint)(void *DeviceInfo, const char *Parm, bit32u *Value); -+ int (*DeviceFindParmValue)(void *DeviceInfo, const char *Parm, void *Value); -+ void (*Free)(void *MemPtr); -+ void (*FreeRxBuffer)(OS_RECEIVEINFO *OsReceiveInfo, void *MemPtr); -+ void (*FreeDev)(void *MemPtr); -+ void (*FreeDmaXfer)(void *MemPtr); -+ void (*IsrRegister)(OS_DEVICE *OsDev, int (*halISR)(HAL_DEVICE*, int*), int InterruptBit); -+ void (*IsrUnRegister)(OS_DEVICE *OsDev, int InterruptBit); -+ void* (*Malloc)(bit32u size); -+ void* (*MallocDev)(bit32u Size); -+ void* (*MallocDmaXfer)(bit32u size, void *MemBase, bit32u MemRange); -+ void* (*MallocRxBuffer)(bit32u size, void *MemBase, bit32u MemRange, -+ OS_SETUP *OsSetup, HAL_RECEIVEINFO *HalReceiveInfo, -+ OS_RECEIVEINFO **OsReceiveInfo, OS_DEVICE *OsDev); -+ void* (*Memset)(void *Dest, int C, bit32u N); -+ int (*Printf)(const char *Format, ...); -+ int (*Receive)(OS_DEVICE *OsDev,FRAGLIST *FragList,bit32u FragCount, -+ bit32u PacketSize,HAL_RECEIVEINFO *HalReceiveInfo, bit32u Mode); -+ int (*SendComplete)(OS_SENDINFO *OsSendInfo); -+ int (*Sprintf)(char *S, const char *Format, ...); -+ int (*Strcmpi)(const char *Str1, const char *Str2); -+ unsigned int (*Strlen)(const char *S); -+ char* (*Strstr)(const char *S1, const char *S2); -+ unsigned long (*Strtoul)(const char *Str, char **Endptr, int Base); -+ void (*TeardownComplete)(OS_DEVICE *OsDev, int Ch, int Direction); -+ } OS_FUNCTIONS; -+ -+/************** MODULE SPECIFIC STUFF BELOW **************/ -+ -+#ifdef _CPHAL_CPMAC -+ -+/* -+int halCpmacInitModule(HAL_DEVICE **HalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS *HalFunc, int (*osBridgeInitModule)(OS_FUNCTIONS *), void* (*osMallocDev) (bit32u), int *Size, int inst); -+*/ -+ -+int halCpmacInitModule(HAL_DEVICE **HalDev, -+ OS_DEVICE *OsDev, -+ HAL_FUNCTIONS **HalFunc, -+ OS_FUNCTIONS *OsFunc, -+ int OsFuncSize, -+ int *HalFuncSize, -+ int Inst); -+#endif -+ -+#ifdef _CPHAL_AAL5 -+/* -+ * @ingroup shared_data -+ * The AAL5_FUNCTIONS struct defines the AAL5 function pointers used by upper layer -+ * software. The upper layer software receives these pointers through the -+ * call to cphalInitModule(). -+ */ -+/* -+typedef struct -+ { -+ int (*ChannelSetup)(HAL_DEVICE *HalDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup); -+ int (*ChannelTeardown)(HAL_DEVICE *HalDev, int Ch, int Mode); -+ int (*Close)(HAL_DEVICE *HalDev, int Mode); -+ int (*Init)(HAL_DEVICE *HalDev); -+ int (*ModeChange)(HAL_DEVICE *HalDev, char *DeviceParms); -+ int (*Open)(HAL_DEVICE *HalDev); -+ int (*InfoGet)(HAL_DEVICE *HalDev, int Key, void *Value); -+ int (*Probe)(HAL_DEVICE *HalDev); -+ int (*RxReturn)(HAL_RECEIVEINFO *HalReceiveInfo, int StripFlag); -+ int (*Send)(HAL_DEVICE *HalDev,FRAGLIST *FragList,int FragCount, -+ int PacketSize,OS_SENDINFO *OsSendInfo,int Ch, int Queue, -+ bit32u Mode); -+ int (*StatsClear)(HAL_DEVICE *HalDev); -+ STAT_INFO* (*StatsGet)(HAL_DEVICE *HalDev); -+ int (*Status)(HAL_DEVICE *HalDev); -+ void (*Tick)(HAL_DEVICE *HalDev); -+ int (*Kick)(HAL_DEVICE *HalDev, int Queue); -+ volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset); -+ } AAL5_FUNCTIONS; -+*/ -+ -+int cpaal5InitModule(HAL_DEVICE **HalDev, -+ OS_DEVICE *OsDev, -+ HAL_FUNCTIONS **HalFunc, -+ OS_FUNCTIONS *OsFunc, -+ int OsFuncSize, -+ int *HalFuncSize, -+ int Inst); -+#endif -+ -+#ifdef _CPHAL_AAL2 -+/** -+ * @ingroup shared_data -+ * The AAL2_FUNCTIONS struct defines the AAL2 function pointers used by upper layer -+ * software. The upper layer software receives these pointers through the -+ * call to cphalInitModule(). -+ */ -+typedef struct -+ { -+ int (*ChannelSetup)(HAL_DEVICE *HalDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup); -+ int (*ChannelTeardown)(HAL_DEVICE *HalDev, int Ch, int Mode); -+ int (*Close)(HAL_DEVICE *HalDev, int Mode); -+ int (*Init)(HAL_DEVICE *HalDev); -+ int (*ModeChange)(HAL_DEVICE *HalDev, char *DeviceParms); -+ int (*Open)(HAL_DEVICE *HalDev); -+ int (*OptionsGet)(HAL_DEVICE *HalDev, char *Key, bit32u *Value); -+ int (*Probe)(HAL_DEVICE *HalDev); -+ -+ int (*StatsClear)(HAL_DEVICE *HalDev); -+ STAT_INFO* (*StatsGet)(HAL_DEVICE *HalDev); -+ int (*Status)(HAL_DEVICE *HalDev); -+ void (*Tick)(HAL_DEVICE *HalDev); -+ int (*Aal2UuiMappingSetup)(HAL_DEVICE *HalDev, int VC, int UUI, -+ int VdmaCh, int UUIDiscard); -+ int (*Aal2RxMappingSetup)(HAL_DEVICE *HalDev, int VC, int CID, -+ int LC); -+ int (*Aal2TxMappingSetup)(HAL_DEVICE *HalDev, int VC, int LC, int VdmaCh); -+ int (*Aal2VdmaChSetup)(HAL_DEVICE *HalDev, bit32u RemVdmaVtAddr, -+ VdmaChInfo *VdmaCh); -+ volatile bit32u* (*RegAccess)(HAL_DEVICE *HalDev, bit32u RegOffset); -+ int (*Aal2ModeChange)(HAL_DEVICE *HalDev, int Vc, int RxCrossMode, -+ int RxMultiMode, int TxMultiMode, int SchedMode, -+ int TcCh); -+ void (*Aal2VdmaEnable)(HAL_DEVICE *HalDev, int Ch); -+ int (*Aal2VdmaDisable)(HAL_DEVICE *HalDev, int Ch); -+ } AAL2_FUNCTIONS; -+ -+int cpaal2InitModule(HAL_DEVICE **HalDev, -+ OS_DEVICE *OsDev, -+ AAL2_FUNCTIONS **HalFunc, -+ OS_FUNCTIONS *OsFunc, -+ int OsFuncSize, -+ int *HalFuncSize, -+ int Inst); -+#endif -+ -+#ifdef _CPHAL_VDMAVT -+/** -+ * @ingroup shared_data -+ * The VDMA_FUNCTIONS struct defines the HAL function pointers used by upper layer -+ * software. The upper layer software receives these pointers through the -+ * call to InitModule(). -+ * -+ * Note that this list is still under definition. -+ */ -+typedef struct -+ { -+ bit32 (*Init)( HAL_DEVICE *VdmaVtDev); -+ /* bit32 (*SetupTxFifo)(HAL_DEVICE *VdmaVtDev, bit32u LclRem, -+ bit32u Addr, bit32u Size, bit32u PollInt); -+ bit32 (*SetupRxFifo)(HAL_DEVICE *VdmaVtDev, bit32u LclRem, -+ bit32u Addr, bit32u Size, bit32u PollInt); */ -+ bit32 (*Tx)(HAL_DEVICE *VdmaVtDev); -+ bit32 (*Rx)(HAL_DEVICE *VdmaVtDev); -+ bit32 (*SetRemoteChannel)(HAL_DEVICE *VdmaVtDev, bit32u RemAddr, -+ bit32u RemDevID); -+ bit32 (*ClearRxInt)(HAL_DEVICE *VdmaVtDev); -+ bit32 (*ClearTxInt)(HAL_DEVICE *VdmaVtDev); -+ bit32 (*Open)(HAL_DEVICE *VdmaVtDev); -+ bit32 (*Close)(HAL_DEVICE *VdmaVtDev); -+ int (*Control) (HAL_DEVICE *HalDev, const char *Key, const char *Action, void *Value); -+ int (*ChannelSetup)(HAL_DEVICE *VdmaVtDev, CHANNEL_INFO *HalCh, OS_SETUP *OsSetup); -+ int (*ChannelTeardown)(HAL_DEVICE *VdmaVtDev, int Ch, int Mode); -+ int (*Send)(HAL_DEVICE *VdmaVtDev,FRAGLIST *FragList,int FragCount, -+ int PacketSize,OS_SENDINFO *OsSendInfo,bit32u Mode); -+ } VDMA_FUNCTIONS; -+ -+int VdmaInitModule(HAL_DEVICE **VdmaVt, -+ OS_DEVICE *OsDev, -+ VDMA_FUNCTIONS **VdmaVtFunc, -+ OS_FUNCTIONS *OsFunc, -+ int OsFuncSize, -+ int *HalFuncSize, -+ int Inst); -+#endif -+ -+/* -+extern int cphalInitModule(MODULE_TYPE ModuleType, HAL_DEVICE **HalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS *HalFunc, -+ int (*osInitModule)(OS_FUNCTIONS *), void* (*osMallocDev)(bit32u), -+ int *Size, int Inst); -+*/ -+ -+ -+#ifdef _CPHAL_AAL5 -+extern const char hcSarFrequency[]; -+#endif -+ -+#ifdef _CPHAL_CPMAC -+/* following will be common, once 'utl' added */ -+extern const char hcClear[]; -+extern const char hcGet[]; -+extern const char hcSet[]; -+extern const char hcTick[]; -+ -+extern const char hcCpuFrequency[]; -+extern const char hcCpmacFrequency[]; -+extern const char hcMdioBusFrequency[]; -+extern const char hcMdioClockFrequency[]; -+extern const char hcCpmacBase[]; -+extern const char hcPhyNum[]; -+extern const char hcSize[]; -+extern const char hcCpmacSize[]; -+extern const char hcPhyAccess[]; -+extern const char hcMdixMask[]; -+extern const char hcMdioMdixSwitch[]; -+#endif -+ -+#endif /* end of _INC_ */ -diff -urN linux.old/drivers/net/avalanche_cpmac/dox_cpmac.h linux.dev/drivers/net/avalanche_cpmac/dox_cpmac.h ---- linux.old/drivers/net/avalanche_cpmac/dox_cpmac.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/dox_cpmac.h 2005-07-12 02:48:42.050593000 +0200 -@@ -0,0 +1,842 @@ -+/***************************************************************************** -+ * TNETDxxxx Software Support -+ * Copyright (c) 2002,2003 Texas Instruments Incorporated. All Rights Reserved. -+ * -+ * FILE: -+ * -+ * DESCRIPTION: -+ * This file contains documentation for the CPMAC -+ * -+ * HISTORY: -+ * @author Michael Hanrahan/Greg Guyotte -+ * @version 1.00 -+ * @date 03-Dec-2002 -+ *****************************************************************************/ -+#ifndef _DOX_CPMAC_H -+#define _DOX_CPMAC_H -+/** -+@page CPMAC_Implementation_Details Version -+ -+@copydoc CPMAC_Version -+*/ -+ -+/** -+@page cpmac_intro Introduction -+ -+The CPMAC implementation will support 8 channels for transmit and 8 channel for -+receive. Each of the 8 transmit channels has 1 queue associated with it. It is -+recommended that only 1 channel is used for @c Receive() per processor. -+*/ -+ -+/** -+@page cpmac_details API Implementation Details -+@par osReceive -+@p Mode parameter -+- The Upper 16 bits of Mode match Word 3 of the Rx Buffer Descriptor -+ -+@par halSend -+@p Mode parameter -+- Bits 0-7 contain the Channel Number -+- Bits 8-25 are reserved -+- Bit 26 - if 0, the CRC will be calculated, if 1 the CRC will be Passed -+- Bits 27-31 : reserved -+@section cpmac_keys Control Keys -+ -+@par StateChange -+CPHAL calls the OS when a state change is detected. -+OS should check the CPMAC Status. See the Control Key 'Status' for more details. -+ -+@par Status -+OS calls the CPHAL to obtain Status information. The Returned status is as follows -+ -+@par MaxFrags -+The OS may "Set" or "Get" this value. This defines the maximum -+number of fragments that can be received by the CPMAC Rx port. The default -+value for CPMAC is 2. This provides enough space to receive a maximum -+length packet (1,518 bytes) with the default buffer size of 1518 and any -+amount of RxBufferOffset. If the buffer size is configured to be smaller, -+the OS *MUST* modify this parameter according to the following formula: -+((System Max packet length)/(RxBufSize)) + 1. (The extra 1 fragment is to -+allow for RxBufferOffset) -+ -+@code -+// Following defined in "cpswhal_cpmac.h" -+// CPMAC CPHAL STATUS -+#define CPMAC_STATUS_LINK (1 << 0) -+#define CPMAC_STATUS_LINK_DUPLEX (1 << 1) // 0 - HD, 1 - FD -+#define CPMAC_STATUS_LINK_SPEED (1 << 2) // 0 - 10, 1 - 100 -+ -+// ADAPTER CHECK Codes -+#define CPMAC_STATUS_ADAPTER_CHECK (1 << 7) -+#define CPMAC_STATUS_HOST_ERR_DIRECTION (1 << 8) // 0 - Tx, 1 - Rx -+#define CPMAC_STATUS_HOST_ERR_CODE (0xF << 9) See CPMAC Guide -+#define CPMAC_STATUS_HOST_ERR_CH (0x7 << 13) See CPMAC Guide -+@endcode -+ -+@code -+void osStateChange(OS_DEVICE *OsDev) -+ { -+ int status; -+ OsDev->HalFunc->Control(OsDev->HalDev, "Status", hcGet, &status); -+ if(status & CPMAC_STATUS_ADAPTER_CHECK) -+ { -+ printf("[osStateChange[%d]] HAL notified OS of AdapterCheck (Link Status 0x%08X)\n", OsDev->port, status); -+ adaptercheck(OsDev->port); -+ } -+ else -+ { -+ printf("[osStateChange[%d]] HAL notified OS of State Change (Link Status %s)\n", OsDev->port, (status & CPMAC_STATUS_LINK) ? "Up" : "Down"); -+ if(status & CPMAC_STATUS_LINK) -+ { -+ printf("Speed %s, Duplex %s\n", -+ status & CPMAC_STATUS_LINK_SPEED ? "100" : "10", -+ status & CPMAC_STATUS_LINK_DUPLEX ? "FD" : "HD"); -+ } -+ } -+@endcode -+ -+@par Tick -+ The CPHAL calls the OS to set the interval for calling halTick()<BR> -+ Note: Predefined value hcTick now recommended for use. -+@code -+*** Example Code *** -+ -+*** CPHAL code *** -+int Ticks; -+HalDev->OsFunc->Control(HalDev->OsDev, hcTick, hcSet, &Ticks); -+ -+*** OS code *** -+ .. -+ if(osStrcmpi(pszKey, hcTick) == 0) -+ { -+ if(osStrcmpi(pszAction, hcSet) == 0) -+ { -+ // Enable the Tick Interval -+ if(*(unsigned int *) ParmValue) -+ printf("osTickSet: Interval = %d ticks\n", Interval); -+ } -+ else -+ if(osStrcmpi(pszAction, hcClear) == 0) -+ { -+ // Request disabling of the Tick Timer, ParmValue is ignored -+ } -+ } -+@endcode -+ -+@par The following information can be obtained by the OS via 'Get' -+ -+- StatsDump : OS supplies pointer to an 36 element unsigned int array -+CPHAL will populate the array with the current Statistics values.<BR> -+Note: all hcXXXX values are predefined and should be used by the OS. -+ -+- hcPhyNum : Returns the PHY number. -+- hcCpmacBase : Returns the base-address of the CPMAC device -+- hcCpmacSize : Returns size of the CPMAC memory map -+ -+ -+@par Phy Register Communication -+ -+halControl() is used to read and write the Phy Registers via the key hcPhyAccess -+ -+Both reading and writing the Phy registers involve setting the Value parameter of halControl() -+<BR> -+Value is a 32-bit value with bits partioned as follows -+<BR> -+ -+ 0 - 4 Phy Number <BR> -+ 5 - 9 Phy Register <BR> -+ 10 - 15 reserved <BR> -+ 16 - 31 Data (write only) -+<BR> -+ -+ -+<B>Reading the Phy register</B> -+ -+@code -+ bit32u Value; -+ bit32u RegAddr; -+ bit32u PhyNum; -+ bit32u PhyRegisterData; -+ -+ // Read Phy 31, register 20 -+ -+ PhyNum = 31; -+ RegAddr = 20; -+ -+ Value = (RegAddr << 5); -+ Value |= (PhyNum & 0x1F); -+ -+ rc = HalFunc->Control(HalDev, hcPhyAccess, hcGet, (bit32u *) &Value) -+ If(rc == 0) -+ { -+ // Value is overwriten with the value in Register 20 of Phy number 31. -+ PhyRegisterData = Value; -+ } -+@endcode -+ -+<B>Writing the Phy register</B> -+@code -+ bit32u Value; -+ bit32u RegAddr; -+ bit32u PhyNum; -+ bit32u PhyRegisterData; -+ -+ // Reset Phy 23 -+ -+ PhyNum = 23; -+ RegAddr = 0; -+ PhyRegisterData = 0x8000; // Reset bit set -+ -+ Value = (RegAddr << 5); -+ Value |= (PhyNum & 0x1F); -+ Value |= (PhyRegisterData << 16); -+ -+ rc = HalFunc->Control(HalDev, hcPhyAccess, hcSet, (bit32u *) &Value) -+ -+ // Check is reset if done -+ -+ PhyNum = 23; -+ RegAddr = 0; -+ -+ Value = (RegAddr << 5); -+ Value |= (PhyNum & 0x1F); -+ -+ rc = HalFunc->Control(HalDev, hcPhyAccess, hcGet, (bit32u *) &Value) -+ -+ If(rc == 0) -+ { -+ // Value is overwriten with the value in Register 0 of Phy number 23. -+ PhyRegisterData = Value; -+ if((PhyRegisterData & 0x8000) == 0) -+ ResetIsComplete; -+ } -+ -+@endcode -+<B> -+*** Example Showing turning values off/on *** -+<BR> -+</B> -+ -+@code -+ -+int On=1; -+int Off=0; -+ # Turn On loopback -+ OsDev->HalFunc->Control(OsDev->HalDev, "CTRL_LOOPBACK", hcSet, (int*) &On); -+ -+ # Turn off RX Flow -+ OsDev->HalFunc->Control(OsDev->HalDev, "RX_FLOW_EN", hcSet, (int*) &Off); -+@endcode -+ -+@par CPMAC Configurable Parameters -+ -+- RX_PASS_CRC : See MBP_Enable description -+- RX_QOS_EN : See MBP_Enable description -+- RX_NO_CHAIN : See MBP_Enable description -+- RX_CMF_EN : See MBP_Enable description -+- RX_CSF_EN : See MBP_Enable description -+- RX_CEF_EN : See MBP_Enable description -+- RX_CAF_EN : See MBP_Enable description -+- RX_PROM_CH : See MBP_Enable description -+- RX_BROAD_EN : See MBP_Enable description -+- RX_BROAD_CH : See MBP_Enable description -+- RX_MULT_EN : See MBP_Enable description -+- RX_MULT_CH : See MBP_Enable description -+ -+- TX_PTYPE : See MacControl description -+- TX_PACE : See MacControl description -+- TX_FLOW_EN : See MacControl description -+- RX_FLOW_EN : See MacControl description -+- CTRL_LOOPBACK : See MacControl description -+ -+- RX_MAXLEN : See CPMAC Guide -+- RX_FILTERLOWTHRESH : See CPMAC Guide -+- RX0_FLOWTHRESH : See CPMAC Guide -+- RX_UNICAST_SET : See CPMAC Guide -+- RX_UNICAST_CLEAR : See CPMAC Guide -+ -+@par Multicast Support -+- RX_MULTI_ALL : When used with hcSet, sets all the Hash Bits. When used -+with hcClear clears all the Hash Bits. -+- RX_MULTI_SINGLE : When used with hcSet, adds the Hashed Mac Address. When used -+with hcClear deletes the Hashed Mac Address. -+Note: Support will be added to keep track of Single additions and deletions. -+ -+@code -+*** Example Code *** -+ -+*** OS code *** -+ bit8u MacAddress[6]; -+ MacAddress[0] = 0x80; -+ MacAddress[1] = 0x12; -+ MacAddress[2] = 0x34; -+ MacAddress[3] = 0x56; -+ MacAddress[4] = 0x78; -+ MacAddress[5] = 0x78; -+ OsDev->HalFunc->Control(OsDev->HalDev, "RX_MULTI_SINGLE", hcSet, (bit8u*) &MacAddress); -+ OsDev->HalFunc->Control(OsDev->HalDev, "RX_MULTI_SINGLE", hcClear, (bit8u*) &MacAddress); -+ OsDev->HalFunc->Control(OsDev->HalDev, "RX_MULTI_ALL", hcSet, NULL); -+ OsDev->HalFunc->Control(OsDev->HalDev, "RX_MULTI_ALL", hcClear, NULL); -+@endcode -+@par MdioConnect Fields -+<BR> -+- "MdioConnect" : The OS can set the Phy connection using this key. The default connection is Auto-Negotiation ON, All modes possible. -+ -+ -+- _CPMDIO_HD <----- Allow Half Duplex, default is 1 (On) -+- _CPMDIO_FD <----- Allow Full Duplex, default is 1 (On) -+- _CPMDIO_10 <----- Allow 10 Mbs, default is 1 (On) -+- _CPMDIO_100 <----- Allow 100 Mbs, default is 1 (On) -+- _CPMDIO_NEG_OFF <----- Turn off Auto Negotiation, default is 0 (Auto Neg is on) -+- _CPMDIO_NOPHY <----- Set for use with Marvel-type switch, default is 0 (Phy present) -+- _CPMDIO_AUTOMDIX <---- Enables Auto Mdix (in conjunction with MdixMask), default is 1 (On) -+ -+Note: When _CPMDIO_NOPHY is set, CPMAC will report being linked at 100/FD. Reported PhyNum will be 0xFFFFFFFF -+ -+@par Setting CPMAC for use with a Marvel-type Switch -+@code -+ bit32u MdioConnect; -+ -+ MdioConnect = _CPMDIO_NOPHY; -+ OsDev->HalFunc->Control(OsDev->HalDev, "MdioConnect", hcSet, (bit32u*) &MdioConnect); -+@endcode -+ -+@par OS Support for MDIO -+@p The OS will need to supply the following values which the CPHAL will request via halControl() -+<BR> -+- MdioBusFrequency : The frequency of the BUS that MDIO is on (requested via hcMdioBusFrequency) -+<BR> -+- MdioClockFrequency : The desired Clock Frequency that MDIO qill operate at (requested via hcMdioClockFrequency) -+*/ -+ -+/** -+@page cpmac_conf DeviceFindxxx() Parameters -+ -+These are some of the parameters that the CPMAC will request via the DeviceFindxxx() functions - -+<BR> -+- "Mlink" : bit mask indicating what link status method Phy is using. Default is MDIO state machine (0x0) -+- "PhyMask" : bit mask indicating PhyNums used by this CPMAC (e.g 0x8000000, PhyNum is 31) -+- "MdixMask" : bit mask indicating which Phys support AutoMdix. Default is 0x0 (None) -+<BR> -+@par Example cpmac definition from the options.conf for the Sangam VDB -+<BR> -+- cpmac( id=eth0, base=0xA8610000, size=0x800, reset_bit=17, int_line=19, PhyMask=0x80000000, MLink=0, MdixMask=0 ) -+*/ -+ -+/** -+@page auto_mdix Auto Mdix Support -+ -+Auto Mdix selection is controlled by two elements in the CPMAC. First the OS can turn Auto Midx On or Off by the use of the -+MdioConnect field, _CPMDIO_AUTOMDIX. This is defaulted ON. For actual Auto Mdix operation the Phy must also be Auto Mdix capable. -+This is specified by the DeviceFindxxx() field, "MdixMask" (supplied as the variable hcMdixMask). -+If both these fields are set then the CPMDIO state machine will be enabled for Auto Mdix checking. -+If a switch to MDI or MDIX mode is needed, the CPMAC will signal this to the OS via Control() using -+the hcMdioMdixSwitch key. -+ -+@par OS example for responding to a Mdix Switch Request -+<BR> -+@code -+if(osStrcmpi(pszKey, hcMdioMdixSwitch) == 0) // See if key is Mdix Switch Request -+ { -+ if(osStrcmpi(pszAction, hcSet) == 0) // Only respond to Set requests -+ { -+ -+ bit32u Mdix; -+ -+ Mdix = *(bit32u *) ParmValue; // Extract requested Mode -+ // 0 : MDI -+ // 1 : MDIX -+ if(Mdix) -+ osSetPhyIntoMdixMode(); // Device specific logic -+ else -+ osSetPhyIntoMdiMode(); // Device specific logic -+ rc = 0; // Set return code as Successfull -+ } -+@endcode -+*/ -+ -+/** -+@page cpmac_stats CPMAC Specific Statistics -+ -+Statistics level '0' contains all CPMAC specific statistics. -+ -+ -+*/ -+ -+/** -+@page Example_Driver_Code -+ -+@section example_intro Introduction -+This section provides an in-depth code example for driver implementations. The code -+below illustrates the use of the CPMAC HAL, but is equally applicable to any CPHAL -+implementation. Note: the CPHAl constants hcGet, hcSet etc., are currently available for use with teh CPMAC module. -+Other modules should continue to use pszGET, etc. until these are made generally available. -+ -+@par Pull Model Example -+ -+@code -+ -+#define _CPHAL_CPMAC -+ -+typedef struct _os_device_s OS_DEVICE; -+typedef struct _os_receive_s OS_RECEIVEINFO; -+typedef struct _os_send_s OS_SENDINFO; -+typedef struct _os_setup_s OS_SETUP; -+ -+#include "cpswhal_cpmac.h" -+ -+#define dbgPrintf printf -+ -+typedef struct _os_device_s -+{ -+ HAL_DEVICE *HalDev; -+ HAL_FUNCTIONS *HalFunc; -+ OS_FUNCTIONS *OsFunc; -+ OS_SETUP *OsSetup; -+ bit32u Interrupt; -+ int (*halIsr)(HAL_DEVICE *HalDev, int*); -+ int ModulePort; -+ int Protocol; -+ int LinkStatus; // 0-> down, otherwise up -+}os_device_s; -+ -+typedef struct _os_receive_s -+{ -+ HAL_RECEIVEINFO *HalReceiveInfo; -+ char *ReceiveBuffer; -+ OS_DEVICE *OsDev; -+}os_receive_s; -+ -+typedef struct _os_send_s -+{ -+ OS_DEVICE *OsDev; -+}os_send_s; -+ -+typedef struct _os_setup_s -+{ -+ OS_DEVICE *OsDev; -+}os_setup_s; -+ -+ -+ -+void FlowForCphal(OS_DEVICE *OsDev) -+{ -+ CHANNEL_INFO ChannelInfo; -+ int nChannels = 200; -+ int halFuncSize; -+ int rc; -+ -+ // Populate OsFunc structure -+ rc = osInitModule(OsDev); -+ -+ if(rc) -+ { -+ sprintf(bufTmp, "%s: return code from osInitModule:'0x%08X'", __FUNCTION__, rc); -+ errorout(bufTmp); -+ } -+ -+ -+ // OS-Cphal handshake -+ rc = halCpmacInitModule(&OsDev->HalDev, OsDev, &OsDev->HalFunc, OsDev->OsFunc, -+ sizeof(OS_FUNCTIONS), &halFuncSize, OsDev->ModulePort); -+ -+ if(rc) -+ { -+ sprintf(bufTmp, "%s: return code from halCpmacInitModule:'0x%08X'", __FUNCTION__, rc); -+ errorout(bufTmp); -+ } -+ -+ // See if hardware module exists -+ rc = OsDev->HalFunc->Probe(OsDev->HalDev); -+ -+ if(rc) -+ { -+ sprintf(bufTmp, "%s: return code from Probe:'0x%08X'", __FUNCTION__, rc); -+ errorout(bufTmp); -+ } -+ -+ // Initialize hardware module -+ rc = OsDev->HalFunc->Init(OsDev->HalDev); -+ -+ if(rc) -+ { -+ sprintf(bufTmp, "%s: return code from Init:'0x%08X'", __FUNCTION__, rc); -+ errorout(bufTmp); -+ } -+ -+ // Setup Channel Information (Tranmsit, channel 0) -+ ChannelInfo.Channel = 0; -+ ChannelInfo.Direction = DIRECTION_TX; -+ ChannelInfo.TxNumBuffers = nChannels; -+ ChannelInfo.TxNumQueues = 1; -+ ChannelInfo.TxServiceMax = nChannels/3; -+ -+ rc = OsDev->HalFunc->ChannelSetup(OsDev->HalDev, &ChannelInfo, OsDev->OsSetup); -+ -+ // Setup Channel Information (Receive, channel 0) -+ ChannelInfo.Channel = 0; -+ ChannelInfo.Direction = DIRECTION_RX; -+ ChannelInfo.RxBufSize = 1518; -+ ChannelInfo.RxBufferOffset = 0; -+ ChannelInfo.RxNumBuffers = 2*nChannels; -+ ChannelInfo.RxServiceMax = nChannels/3; -+ -+ rc = OsDev->HalFunc->ChannelSetup(OsDev->HalDev, &ChannelInfo, OsDev->OsSetup); -+ -+ // Open the hardware module -+ rc = OsDev->HalFunc->Open(OsDev->HalDev); -+ -+ // Module now ready to Send/Receive data -+} -+ -+ -+int osInitModule(OS_FUNCTIONS **pOsFunc) -+ { -+ OS_FUNCTIONS *OsFunc; -+ -+ OsFunc = (OS_FUNCTIONS *) malloc(sizeof(OS_FUNCTIONS)); -+ if (!OsFunc) -+ return (-1); -+ -+ *pOsFunc = OsFunc; -+ -+ OsFunc->CriticalOff = osCriticalOff; -+ OsFunc->CriticalOn = osCriticalOn; -+ OsFunc->DataCacheHitInvalidate = osDataCacheHitInvalidate; -+ OsFunc->DataCacheHitWriteback = osDataCacheHitWriteback; -+ OsFunc->DeviceFindInfo = osDeviceFindInfo; -+ OsFunc->DeviceFindParmUint = osDeviceFindParmUint; -+ OsFunc->DeviceFindParmValue = osDeviceFindParmValue; -+ OsFunc->Free = osFree; -+ OsFunc->FreeDev = osFreeDev; -+ OsFunc->FreeDmaXfer = osFreeDmaXfer; -+ OsFunc->FreeRxBuffer = osFreeRxBuffer; -+ OsFunc->IsrRegister = osIsrRegister; -+ OsFunc->IsrUnRegister = osIsrUnRegister; -+ OsFunc->Malloc = osMalloc; -+ OsFunc->MallocDev = osMallocDev; -+ OsFunc->MallocDmaXfer = osMallocDmaXfer; -+ OsFunc->MallocRxBuffer = osMallocRxBuffer; -+ -+ -+ OsFunc->Memset = memset; -+ OsFunc->Printf = printf; -+ OsFunc->Sprintf = sprintf; -+ OsFunc->Strcmpi = osStrcmpi; -+ OsFunc->Strlen = strlen; -+ OsFunc->Strstr = strstr; -+ OsFunc->Strtoul = strtoul; -+ -+ OsFunc->Control = osControl; -+ OsFunc->Receive = osReceive; -+ OsFunc->SendComplete = osSendComplete; -+ OsFunc->TeardownComplete = osTearDownComplete; -+ -+ return(0); -+ } -+ -+ -+int osReceive(OS_DEVICE *OsDev,FRAGLIST *Fraglist,bit32u FragCount,bit32u PacketSize,HAL_RECEIVEINFO *halInfo, bit32u mode) -+ { -+ OS_RECEIVEINFO *skb = (OS_RECEIVEINFO *)Fraglist[0].OsInfo; -+ dcache_i((char *)Fraglist->data, Fraglist->len); -+ OsDev->HalFunc->RxReturn(halInfo,0); -+ return(0); -+ } -+ -+int osSendComplete(OS_SENDINFO *skb) -+ { -+ return(0); -+ } -+ -+ -+static void *osMallocRxBuffer(bit32u Size,void *MemBase, bit32u MemRange, -+ OS_SETUP *OsSetup, HAL_RECEIVEINFO *HalReceiveInfo, -+ OS_RECEIVEINFO **OsReceiveInfo, OS_DEVICE *OsDev ) -+ { -+ void *HalBuffer; -+ OS_RECEIVEINFO *OsPriv; -+ -+ HalBuffer=malloc(Size); -+ if (!HalBuffer) -+ { -+ return(0); -+ } -+ -+ // Malloc the OS block -+ *OsReceiveInfo = malloc(sizeof(OS_RECEIVEINFO)); -+ if (!*OsReceiveInfo) -+ { -+ free(HalBuffer); -+ return(0); -+ } -+ -+ // Initialize the new buffer descriptor -+ OsPriv = *OsReceiveInfo; -+ OsPriv->OsDev = OsDev; -+ OsPriv->ReceiveBuffer = HalBuffer; -+ OsPriv->HalReceiveInfo = HalReceiveInfo; -+ -+ return(HalBuffer); -+ } -+ -+ -+void SendBuffer(OS_DEVICE *OsDev, char *Buffer, int Size) -+{ -+ FRAGLIST Fraglist; -+ bit32u FragCount; -+ -+ tcb_pending++; -+ Fraglist.len = Size; -+ Fraglist.data = (unsigned *) Buffer; -+ FragCount = 1; -+ mode = 0; // Channel 0 -+ -+ dcache_wb(Fraglist.data, Fraglist.len); -+ OsDev->HalFunc->Send(OsDev->HalDev, &Fraglist, FragCount, Size, (OS_SENDINFO *) Buffer, mode); -+} -+ -+ -+void osStateChange(OS_DEVICE *OsDev) -+ { -+ int status; -+ int LinkStatus; -+ OsDev->HalFunc->Control(OsDev->HalDev, "Status", hcGet, &status); -+ if(status & CPMAC_STATUS_ADAPTER_CHECK) -+ { -+ // Adapter Check, take appropiate action -+ } -+ else -+ { -+ LinkStatus = status & CPMAC_STATUS_LINK; -+ if(LinkStatus != OsDev->LinkStatus) -+ { -+ dbgPrintf("\n%s:Link %s for inst %d Speed %s, Duplex %s\n", -+ __FUNCTION__, -+ LinkStatus ? "up" : "down", -+ OsDev->ModulePort, -+ status & CPMAC_STATUS_LINK_SPEED ? "100" : "10", -+ status & CPMAC_STATUS_LINK_DUPLEX ? "FD" : "HD"); -+ OsDev->LinkStatus = LinkStatus; -+ } -+ } -+ } -+ -+ -+int osControl(OS_DEVICE *OsDev, const char *pszKey, const char* pszAction, void *ParmValue) -+ { -+ int rc=-1; -+ -+ if (osStrcmpi(pszKey, hcCpuFrequency) == 0) -+ { -+ if(osStrcmpi(pszAction, hcGet) == 0) -+ { -+ *(bit32u*) ParmValue = cpufreq; -+ rc = 0; -+ } -+ } -+ if (osStrcmpi(pszKey, hcMdioBusFrequency) == 0) -+ { -+ if(osStrcmpi(pszAction, hcGet) == 0) -+ { -+ *(bit32u *)ParmValue = MdioBusFrequency; -+ rc = 0; -+ } -+ } -+if (osStrcmpi(pszKey, hcMdioClockFrequency) == 0) -+ { -+ if(osStrcmpi(pszAction, hcGet) == 0) -+ { -+ *(bit32u *)ParmValue = MdioClockFrequency; -+ rc = 0; -+ } -+ } -+ -+ if (osStrcmpi(pszKey, hcTick) == 0) -+ { -+ if(osStrcmpi(pszAction, hcSet) == 0) -+ { -+ osTickSetInterval(OsDev, *(unsigned int *) ParmValue); -+ rc = 0; -+ } -+ else -+ if(osStrcmpi(pszAction, hcClear) == 0) -+ { -+ osTickDisable(OsDev); -+ rc = 0; -+ } -+ } -+ -+ if (osStrcmpi(pszKey, "SioFlush") == 0) -+ { -+ MySioFlush(); -+ rc = 0; -+ } -+ -+ if (osStrcmpi(pszKey, "StateChange") == 0) -+ { -+ osStateChange(OsDev); -+ rc = 0; -+ } -+ -+ if (osStrcmpi(pszKey, "Sleep") == 0) -+ { -+ osSleep(*(int *)ParmValue); -+ rc = 0; -+ } -+ return(rc); -+ } -+ -+@endcode -+ -+ -+@par Push Model Example (Currently Eswitch ONLY) -+ -+@code -+ -+typedef struct _os_device_s OS_DEVICE; -+typedef struct _os_receive_s OS_RECEIVEINFO; -+typedef struct _os_send_s OS_SENDINFO; -+typedef struct _os_setup_s OS_SETUP; -+ -+#include "cpswhal.h" //Get glogal HAL stuff -+#include "cpswhaleswitch.h" //Get device specific hal stuff -+ -+ -+typedef struct _os_device_s -+{ -+ HAL_DEVICE *HalDev; -+ HAL_FUNCTIONS *HalFunc; -+ OS_FUNCTIONS *OsFunc; -+ OS_SETUP *OsSetup; -+ bit32u Interrupt; -+ int (*halIsr)(HAL_DEVICE *HalDev, int*); -+ int ModulePort; -+ int Protocol; -+ int LinkStatus; // 0-> down, otherwise up -+}os_device_s; -+ -+typedef struct _os_receive_s -+{ -+ HAL_RECEIVEINFO *HalReceiveInfo; -+ char *ReceiveBuffer; -+ OS_DEVICE *OsDev; -+}os_receive_s; -+ -+typedef struct _os_send_s -+{ -+ OS_DEVICE *OsDev; -+}os_send_s; -+ -+typedef struct _os_setup_s -+{ -+ OS_DEVICE *OsDev; -+}os_setup_s; -+ -+ -+ -+void FlowForCphal(OS_DEVICE *OsDev) -+{ -+CHANNEL_INFO ChannelInfo; -+ int nChannels = 200; -+ int halFuncSize; -+ int rc; -+ -+ // Populate OsFunc structure -+ rc = osInitModule(OsDev); -+ -+ if(rc) -+ { -+ sprintf(bufTmp, "%s: return code from osInitModule:'0x%08X'", __FUNCTION__, rc); -+ errorout(bufTmp); -+ } -+ -+ -+ // OS-Cphal handshake -+ rc = cpswHalEswitchInitModule(&OsDev->HalDev, OsDev, &OsDev->HalFunc, OsDev->OsFunc, -+ sizeof(OS_FUNCTIONS), &halFuncSize, OsDev->ModulePort); -+ -+ if(rc) -+ { -+ sprintf(bufTmp, "%s: return code from cpswHalEswitchInitModule:'0x%08X'", __FUNCTION__, rc); -+ errorout(bufTmp); -+ } -+ -+ -+ ChannelInfo.Channel = 7; -+ ChannelInfo.Direction = DIRECTION_RX; -+ ChanInfo.Receive = osReceiveSS; // Specify function to receive data for this channel -+ -+ rc = OsDev->HalFunc->ChannelSetup(OsDev->HalDev, &ChannelInfo, OsDev->OsSetup); -+ -+ MyConfig.debug=0; -+ MyConfig.CpuFrequency = CpuFreq; -+ MyConfig.EswitchFrequency = EswitchFreq; -+ MyConfig.ResetBase = 0xa8611600; -+ MyConfig.MacAddress = MacAddr; -+ -+ MyConfig.EswitchResetBit= 27; -+ MyConfig.Cpmac0ResetBit = 17; -+ MyConfig.Cpmac1ResetBit = 21; -+ MyConfig.MdioResetBit = 22; -+ MyConfig.Phy0ResetBit = 26; -+ MyConfig.Phy1ResetBit = 28; -+ MyConfig.HdmaResetBit = 13; -+ MyConfig.Cpmac0IntBit = 19; -+ MyConfig.Cpmac1IntBit = 33; -+ MyConfig.EswitchIntBit = 27; -+ MyConfig.EswitchBase = 0xa8640000; -+ MyConfig.EswitchBufferSize = 64; -+ MyConfig.EswitchHostBufCount = 0; -+ MyConfig.EswitchDefaultCamSize = 64; -+ MyConfig.EswitchOverFlowCount = 200; -+ MyConfig.EswitchOverFlowSize = 256; -+ -+ -+ -+ -+ rc=EswitchConfig(HalDev,HalFunc,&MyConfig); -+ -+ -+ // Open the hardware module -+ rc = OsDev->HalFunc->Open(OsDev->HalDev); -+ -+ // Module now ready to Send/Receive data -+} -+ -+ -+int EswitchConfig(HAL_DEVICE *HalDev, HAL_FUNCTIONS *HalFunc, ESWITCH_CONFIG *Config) -+{ -+ bit32u sts; -+ sts = 0; -+ -+ sts |= cpswhalPushBin(hcdebug, Config->debug); -+ sts |= cpswhalPushBin(hcCpuFrequency , Config->CpuFrequency ); -+ sts |= cpswhalPushBin(hcEswitchFrequency , Config->EswitchFrequency ); -+ sts |= cpswhalPushBin(hcResetBase , Config->ResetBase ); -+ sts |= cpswhalPushBin(hcMacAddress , Config->MacAddress ); -+ sts |= cpswhalPushBin(hcEswitchResetBit, Config->EswitchResetBit); -+ sts |= cpswhalPushBin(hcCpmac0ResetBit , Config->Cpmac0ResetBit ); -+ sts |= cpswhalPushBin(hcCpmac1ResetBit , Config->Cpmac1ResetBit ); -+ sts |= cpswhalPushBin(hcMdioResetBit , Config->MdioResetBit ); -+ sts |= cpswhalPushBin(hcPhy0ResetBit , Config->Phy0ResetBit ); -+ sts |= cpswhalPushBin(hcPhy1ResetBit , Config->Phy1ResetBit ); -+ sts |= cpswhalPushBin(hcHdmaResetBit , Config->HdmaResetBit ); -+ sts |= cpswhalPushBin(hcCpmac0IntBit , Config->Cpmac0IntBit ); -+ sts |= cpswhalPushBin(hcCpmac1IntBit , Config->Cpmac1IntBit ); -+ sts |= cpswhalPushBin(hcEswitchIntBit , Config->EswitchIntBit ); -+ sts |= cpswhalPushBin(hcEswitchBase , Config->EswitchBase ); -+ sts |= cpswhalPushBin(hcEswitchBufferSize , Config->EswitchBufferSize ); -+ sts |= cpswhalPushBin(hcEswitchHostBufCount , Config->EswitchHostBufCount ); -+ sts |= cpswhalPushBin(hcEswitchDefaultCamSize , Config->EswitchDefaultCamSize ); -+ sts |= cpswhalPushBin(hcEswitchOverFlowCount , Config->EswitchOverFlowCount ); -+ sts |= cpswhalPushBin(hcEswitchOverFlowSize , Config->EswitchOverFlowSize ); -+ return(sts); -+} -+ -+ -+ -+@endcode -+*/ -+ -+#endif -diff -urN linux.old/drivers/net/avalanche_cpmac/ec_errors_cpmac.h linux.dev/drivers/net/avalanche_cpmac/ec_errors_cpmac.h ---- linux.old/drivers/net/avalanche_cpmac/ec_errors_cpmac.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/ec_errors_cpmac.h 2005-07-12 02:48:42.051592000 +0200 -@@ -0,0 +1,118 @@ -+/*************************************************************************** -+ Copyright(c) 2001, Texas Instruments Incorporated. All Rights Reserved. -+ -+ FILE: ec_errors.h -+ -+ DESCRIPTION: -+ This file contains definitions and function declarations for -+ error code support. -+ -+ HISTORY: -+ 14Dec00 MJH Added masking to EC_CLASS etc macros -+ 17Sep02 GSG Added HAL support (new class&devices) -+ 03Oct02 GSG Removed C++ style comments -+***************************************************************************/ -+#ifndef _INC_EC_ERRORS -+#define _INC_EC_ERRORS -+ -+/* -+ 31 - CRITICAL -+ 30-28 - CLASS (ie. DIAG, KERNEL, FLASH, etc) -+ 27-24 - INSTANCE (ie. 1, 2, 3, etc ) -+ 23-16 - DEVICE (ie. EMAC, IIC, etc) -+ 15-08 - FUNCTION (ie. RX, TX, INIT, etc) -+ 07-00 - ERROR CODE (ie. NO_BASE, FILE_NOT_FOUND, etc ) -+*/ -+ -+/*--------------------------------------------------------------------------- -+ Useful defines for accessing fields within error code -+---------------------------------------------------------------------------*/ -+#define CRITICAL_SHIFT 31 -+#define CLASS_SHIFT 28 -+#define INST_SHIFT 24 -+#define DEVICE_SHIFT 16 -+#define FUNCTION_SHIFT 8 -+#define ERROR_CODE_SHIFT 0 -+ -+#define CRITICAL_MASK 1 -+#define CLASS_MASK 0x07 -+#define DEVICE_MASK 0xFF -+#define INST_MASK 0x0F -+#define FUNCTION_MASK 0xFF -+#define ERROR_CODE_MASK 0xFF -+ -+#define EC_CLASS(val) ((val&CLASS_MASK) << CLASS_SHIFT) -+#define EC_DEVICE(val) ((val&DEVICE_MASK) << DEVICE_SHIFT) -+#define EC_INST(val) ((val&INST_MASK) << INST_SHIFT) -+#define EC_FUNC(val) ((val&FUNCTION_MASK) << FUNCTION_SHIFT) -+#define EC_ERR(val) ((val&ERROR_CODE_MASK) << ERROR_CODE_SHIFT) -+ -+/*--------------------------------------------------------------------------- -+ Operation classes -+---------------------------------------------------------------------------*/ -+#define EC_HAL EC_CLASS(0) -+#define EC_DIAG EC_CLASS(8) -+ -+/*--------------------------------------------------------------------------- -+ Device types -+---------------------------------------------------------------------------*/ -+#define EC_DEV_EMAC EC_DEVICE(1) -+#define EC_DEV_IIC EC_DEVICE(2) -+#define EC_DEV_RESET EC_DEVICE(3) -+#define EC_DEV_ATMSAR EC_DEVICE(4) -+#define EC_DEV_MEM EC_DEVICE(5) -+#define EC_DEV_DES EC_DEVICE(6) -+#define EC_DEV_DMA EC_DEVICE(7) -+#define EC_DEV_DSP EC_DEVICE(8) -+#define EC_DEV_TMR EC_DEVICE(9) -+#define EC_DEV_WDT EC_DEVICE(10) -+#define EC_DEV_DCL EC_DEVICE(11) -+#define EC_DEV_BBIF EC_DEVICE(12) -+#define EC_DEV_PCI EC_DEVICE(13) -+#define EC_DEV_XBUS EC_DEVICE(14) -+#define EC_DEV_DSLIF EC_DEVICE(15) -+#define EC_DEV_USB EC_DEVICE(16) -+#define EC_DEV_CLKC EC_DEVICE(17) -+#define EC_DEV_RAPTOR EC_DEVICE(18) -+#define EC_DEV_DSPC EC_DEVICE(19) -+#define EC_DEV_INTC EC_DEVICE(20) -+#define EC_DEV_GPIO EC_DEVICE(21) -+#define EC_DEV_BIST EC_DEVICE(22) -+#define EC_DEV_HDLC EC_DEVICE(23) -+#define EC_DEV_UART EC_DEVICE(24) -+#define EC_DEV_VOIC EC_DEVICE(25) -+/* 9.17.02 (new HAL modules) */ -+#define EC_DEV_CPSAR EC_DEVICE(0x1A) -+#define EC_DEV_AAL5 EC_DEVICE(0x1B) -+#define EC_DEV_AAL2 EC_DEVICE(0x1C) -+#define EC_DEV_CPMAC EC_DEVICE(0x1D) -+#define EC_DEV_VDMA EC_DEVICE(0x1E) -+#define EC_DEV_VLYNQ EC_DEVICE(0x1F) -+#define EC_DEV_CPPI EC_DEVICE(0x20) -+#define EC_DEV_CPMDIO EC_DEVICE(0x21) -+ -+/*--------------------------------------------------------------------------- -+ Function types -+---------------------------------------------------------------------------*/ -+#define EC_FUNC_READ_CONF EC_FUNC(1) -+#define EC_FUNC_INIT EC_FUNC(2) -+ -+/*--------------------------------------------------------------------------- -+ Error codes -+---------------------------------------------------------------------------*/ -+#define EC_CRITICAL (1<<CRITICAL_SHIFT) -+#define EC_NO_ERRORS 0 -+#define EC_VAL_NO_BASE EC_ERR(1) -+#define EC_VAL_NO_RESET_BIT EC_ERR(2) -+#define EC_VAL_NO_RESET EC_ERR(3) -+#define EC_VAL_BAD_BASE EC_ERR(4) -+#define EC_VAL_MALLOCFAILED EC_ERR(5) -+#define EC_VAL_NO_RESETBASE EC_ERR(6) -+#define EC_DEVICE_NOT_FOUND EC_ERR(7) -+ -+/*--------------------------------------------------------------------------- -+ Function declarations -+---------------------------------------------------------------------------*/ -+extern void ec_log_error( unsigned int ); -+ -+#endif /* _INC_EC_ERRORS */ -diff -urN linux.old/drivers/net/avalanche_cpmac/hcpmac.c linux.dev/drivers/net/avalanche_cpmac/hcpmac.c ---- linux.old/drivers/net/avalanche_cpmac/hcpmac.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/hcpmac.c 2005-07-12 02:48:42.174574000 +0200 -@@ -0,0 +1,1878 @@ -+/****************************************************************************** -+ * TNETDxxxx Software Support -+ * Copyright (c) 2002-2004 Texas Instruments Incorporated. All Rights Reserved. -+ * -+ * FILE: -+ * -+ * DESCRIPTION: -+ * This file contains the code for the HAL EMAC Bridge Test -+ * -+ * HISTORY: -+ * xxXxx01 Denis RC1.00 Original Version created. -+ * 22Jan02 Denis/Mick RC1.01 Modified for HAL EMAC API -+ * 24Jan02 Denis/Mick RC1.02 Speed Improvements -+ * 28Jan02 Denis/Mick RC1.16 Made function calls pointers -+ * 28Jan02 Mick RC1.18 Split into separate modules -+ * 29Jan02 Mick RC1.19 Hal include file cleaned up -+ * 15Jul02 Michael Hanrahan RC1.20 Synch'd with Linux Version -+ * 23Sep02 Michael Hanrahan RC1.21 Added CPPI.C -+ * 16Oct02 Michael Hanrahan RC1.22 Added CAF etc to Options.Conf -+ * 09Jan03 Michael Hanrahan RC3.01 Fixed incorrect MDIO check -+ * 01Feb03 Michael Hanrahan RC3.02 Updated for GPIO/PBUSFREQ -+ * 29Mar03 Michael Hanrahan 1.03 Corrected ChannelConfigGet -+ * 29Mar03 Michael Hanrahan 1.03 Removed user setting of TxNumQueues -+ * 23Aug04 Michael Hanrahan 1.7.8 Support for Setting Mac Address -+ * @author Michael Hanrahan -+ * @version 1.02 -+ * @date 24-Jan-2002 -+ *****************************************************************************/ -+#define _HAL_CPMAC -+#define _CPHAL_CPMAC -+#define _CPHAL -+#define __CPHAL_CPMDIO -+ -+#include "dox_cpmac.h" /* Documentation information */ -+ -+/* OS Data Structure definitions */ -+ -+typedef void OS_PRIVATE; -+typedef void OS_DEVICE; -+typedef void OS_SENDINFO; -+typedef void OS_RECEIVEINFO; -+typedef void OS_SETUP; -+ -+/* HAL Data Structure definitions */ -+ -+typedef struct _phy_device PHY_DEVICE; -+typedef struct hal_device HAL_DEVICE; -+typedef struct hal_private HAL_PRIVATE; -+typedef struct hal_private HAL_RECEIVEINFO; -+ -+#include "cpcommon_cpmac.h" -+#include "cpswhal_cpmac.h" -+#include "cpmdio.h" -+#include "hcpmac.h" -+#include "cpmac_reg.h" -+ -+ -+#define EC_MODULE -+ -+/* MDIO Clock Frequency Default Value */ -+ -+/* Rcb/Tcb Constants */ -+ -+#define CB_SOF_BIT (1<<31) -+#define CB_EOF_BIT (1<<30) -+#define CB_SOF_AND_EOF_BIT (CB_SOF_BIT|CB_EOF_BIT) -+#define CB_OWNERSHIP_BIT (1<<29) -+#define CB_EOQ_BIT (1<<28) -+#define CB_SIZE_MASK 0x0000ffff -+#define RCB_ERRORS_MASK 0x03fe0000 -+ -+static char *channel_names[] = CHANNEL_NAMES; /* GSG 11/22 (may change this implementation) */ -+ -+#define scFound(Module) if (HalDev->State != enDevFound) return (Module|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE) -+#define scInit(Module) if (HalDev->State < enInitialized) return (Module|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE) -+#define scOpen(Module) if (HalDev->State < enOpened) return (Module|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE) -+ -+ -+ -+/******************************************************************** -+** -+** L O C A L F U N C T I O N S -+** -+********************************************************************/ -+static int halIsr(HAL_DEVICE *HalDev, int *MorePackets); -+static int cpmacRandom(HAL_DEVICE *HalDev); -+static int cpmacRandomRange(HAL_DEVICE *HalDev, int min, int max); -+static int halPacketProcessEnd(HAL_DEVICE *HalDev); -+ -+#include "cpcommon_cpmac.c" /*~RC3.02*/ -+#include "cppi_cpmac.c" -+#include "cpmdio.c" /*~RC3.02*/ -+ -+static int MacAddressSave(HAL_DEVICE *HalDev, unsigned char *MacAddr) -+ { -+ int i; -+ int inst = HalDev->inst; -+ -+ HalDev->MacAddr = MacAddr; -+ -+ if(HalDev->debug) -+ { -+ dbgPrintf("MacAddrSave[%d]: ", inst); -+ for (i=0;i<6;i++) -+ dbgPrintf("%X", HalDev->MacAddr[i]); -+ dbgPrintf("\n"); -+ osfuncSioFlush(); -+ } -+ return(EC_NO_ERRORS); -+ } -+static int MacAddressSet(HAL_DEVICE *HalDev) -+ { -+ unsigned char *macadr = &HalDev->MacAddr[0]; -+ int base = HalDev->dev_base; -+ -+ scOpen(EC_CPMAC); -+ CPMAC_MACADDRLO_0(base) = macadr[5]; -+ CPMAC_MACADDRMID(base) = macadr[4]; -+ CPMAC_MACADDRHI(base) = (macadr[0])|(macadr[1]<<8)|(macadr[2]<<16)|(macadr[3]<<24); -+ if(HalDev->debug) -+ { -+ dbgPrintf("MacAddrSet: MacAddr(%d) %X %X %X\n", HalDev->inst, CPMAC_MACADDRLO_0(base), -+ CPMAC_MACADDRMID(base), -+ CPMAC_MACADDRHI(base)); -+ -+ dbgPrintf("Start MAC: %d\n",HalDev->dev_base); -+ osfuncSioFlush(); -+ } -+ return(EC_NO_ERRORS); -+ } -+ -+ -+/* -+ Updates the MacHash registers -+*/ -+static void MacHashSet(HAL_DEVICE *HalDev) -+ { -+ if(HalDev->State < enOpened) -+ return; -+ -+ CPMAC_MACHASH1(HalDev->dev_base) = HalDev->MacHash1; -+ CPMAC_MACHASH2(HalDev->dev_base) = HalDev->MacHash2; -+ if (DBG(11)) -+ dbgPrintf("CPMAC[%X]: MacHash1 0x%08X, MacHash2 0x%08X\n", HalDev->dev_base, CPMAC_MACHASH1(HalDev->dev_base), CPMAC_MACHASH2(HalDev->dev_base)); -+ } -+ -+/* -+ Reads the MacControl register and updates -+ the changable bits. (See MACCONTROL_MASK) -+*/ -+static void RxMBP_EnableSet(HAL_DEVICE *HalDev) -+ { -+ bit32u RxMbpEnable; -+ if(HalDev->State < enOpened) -+ return; -+ RxMbpEnable = CPMAC_RX_MBP_ENABLE(HalDev->dev_base); -+ RxMbpEnable &= ~RX_MBP_ENABLE_MASK; /* Clear out updatable bits */ -+ RxMbpEnable |= HalDev->RxMbpEnable; -+ CPMAC_RX_MBP_ENABLE(HalDev->dev_base) = RxMbpEnable; -+ } -+/* -+ Reads the MacControl register and updates -+ the changable bits. (See MACCONTROL_MASK) -+*/ -+static void MacControlSet(HAL_DEVICE *HalDev) -+ { -+ bit32u MacControl; -+ if(HalDev->State < enOpened) -+ return; -+ MacControl = CPMAC_MACCONTROL(HalDev->dev_base); -+ MacControl &= ~MACCONTROL_MASK; /* Clear out updatable bits */ -+ MacControl |= HalDev->MacControl; -+ if(!(MacControl & MII_EN)) /* If Enable is not set just update register */ -+ CPMAC_MACCONTROL(HalDev->dev_base) = MacControl; -+ else -+ { -+ if(MacControl & CTRL_LOOPBACK) /* Loopback Set */ -+ { -+ /* mii_en is set and loopback is needed, -+ clear mii_en, set loopback, then set mii_en -+ */ -+ MacControl &= ~MII_EN; /* Clear MII_EN */ -+ CPMAC_MACCONTROL(HalDev->dev_base) = MacControl; -+ CPMAC_MACCONTROL(HalDev->dev_base) |= MII_EN; /* Set MII_EN */ -+ HalDev->Linked = 1; /* if in loopback the logically linked */ -+ } -+ else /* If Loopback not set just update */ -+ { -+ CPMAC_MACCONTROL(HalDev->dev_base) = MacControl; -+ } -+ } -+ if(DBG(0)) -+ dbgPrintf("[halMacControlSet]MacControl:%08X\n", CPMAC_MACCONTROL(HalDev->dev_base)); -+ } -+static int UnicastSet(HAL_DEVICE *HalDev) -+ { -+ CPMAC_RX_UNICAST_SET(HalDev->dev_base) = HalDev->RxUnicastSet; -+ CPMAC_RX_UNICAST_CLEAR(HalDev->dev_base) = HalDev->RxUnicastClear; -+ return(EC_NO_ERRORS); -+ } -+ -+ -+static bit32u HashGet(bit8u *Address) -+ { -+ bit32u hash; -+ bit8u tmpval; -+ int i; -+ -+ hash = 0; -+ for( i=0; i<2; i++ ) -+ { -+ tmpval = *Address++; -+ hash ^= (tmpval>>2)^(tmpval<<4); -+ tmpval = *Address++; -+ hash ^= (tmpval>>4)^(tmpval<<2); -+ tmpval = *Address++; -+ hash ^= (tmpval>>6)^(tmpval); -+ } -+ -+ return( hash & 0x3F ); -+ } -+ -+static void HashAdd(HAL_DEVICE *HalDev, bit8u *MacAddress) -+{ -+ bit32u HashValue; -+ bit32u HashBit; -+ -+ HashValue = HashGet(MacAddress); -+ -+ if(HashValue < 32) -+ { -+ HashBit = (1 << HashValue); -+ HalDev->MacHash1 |= HashBit; -+ } -+ else -+ { -+ HashBit = (1 << (HashValue-32)); -+ HalDev->MacHash2 |= HashBit; -+ } -+} -+ -+static void HashDel(HAL_DEVICE *HalDev, bit8u *MacAddress) -+{ -+ bit32u HashValue; -+ bit32u HashBit; -+ -+ HashValue = HashGet(MacAddress); -+ -+ if(HashValue < 32) -+ { -+ HashBit = (1 << HashValue); -+ HalDev->MacHash1 &= ~HashBit; -+ } -+ else -+ { -+ HashBit = (1 << (HashValue-32)); -+ HalDev->MacHash2 &= ~HashBit; -+ } -+} -+ -+/* Replace with an array based on key, with a ptr to the code to do */ -+/* e.g. [enRX_PASS_CRC] = {Set, MBP_UPDATE() } */ -+static void DuplexUpdate(HAL_DEVICE *HalDev) -+{ -+ int base = HalDev->dev_base; -+ PHY_DEVICE *PhyDev = HalDev->PhyDev; -+ -+ if(HalDev->State < enOpened) -+ return; -+ -+ /* No Phy Condition */ -+ if(HalDev->MdioConnect & _CPMDIO_NOPHY) /*MJH+030805*/ -+ { -+ /* No Phy condition, always linked */ -+ HalDev->Linked = 1; -+ HalDev->EmacSpeed = 1; -+ HalDev->EmacDuplex = 1; -+ HalDev->PhyNum = 0xFFFFFFFF; /* No Phy Num */ -+ CPMAC_MACCONTROL(base) |= FULLDUPLEX; /*MJH+030909*/ -+ osfuncStateChange(); -+ return; -+ } -+ -+ if(HalDev->MacControl & CTRL_LOOPBACK) /* Loopback Set */ -+ { -+ HalDev->Linked = 1; -+ return; -+ } -+ -+ if (HalDev->MdioConnect & _CPMDIO_LOOPBK) -+ { -+ HalDev->Linked = cpMacMdioGetLoopback(HalDev->PhyDev); -+ } -+ else -+ { -+ HalDev->Linked = cpMacMdioGetLinked(HalDev->PhyDev); -+ } -+ if (HalDev->Linked) -+ { -+ /* Retreive Duplex and Speed and the Phy Number */ -+ if(HalDev->MdioConnect & _CPMDIO_LOOPBK) -+ HalDev->EmacDuplex = 1; -+ else -+ HalDev->EmacDuplex = cpMacMdioGetDuplex(PhyDev); -+ HalDev->EmacSpeed = cpMacMdioGetSpeed(PhyDev); -+ HalDev->PhyNum = cpMacMdioGetPhyNum(PhyDev); -+ -+ if(HalDev->EmacDuplex) -+ CPMAC_MACCONTROL(base) |= FULLDUPLEX; -+ else -+ CPMAC_MACCONTROL(base) &= ~FULLDUPLEX; -+ if(HalDev->debug) -+ dbgPrintf("%d: Phy= %d, Speed=%s, Duplex=%s\n",HalDev->inst,HalDev->PhyNum,(HalDev->EmacSpeed)?"100":"10",(HalDev->EmacDuplex)?"Full":"Half"); -+ } -+ if(HalDev->debug) -+ dbgPrintf("DuplexUpdate[%d]: MACCONTROL 0x%08X, %s\n", HalDev->inst, CPMAC_MACCONTROL(base),(HalDev->Linked)?"Linked":"Not Linked"); -+} -+static void MdioSetPhyMode(HAL_DEVICE *HalDev) -+ { -+ unsigned int PhyMode; -+ /* Verify proper device state */ -+ if (HalDev->State < enOpened) -+ return; -+ -+ PhyMode = NWAY_AUTO|NWAY_FD100|NWAY_HD100|NWAY_FD10|NWAY_HD10; -+ if(DBG(0)) -+ { -+ dbgPrintf("halSetPhyMode1: MdioConnect:%08X ,", HalDev->MdioConnect); -+ dbgPrintf("PhyMode:%08X Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d\n", PhyMode, -+ PhyMode&NWAY_AUTO, PhyMode&NWAY_FD10, PhyMode&NWAY_HD10, PhyMode&NWAY_FD100, -+ PhyMode&NWAY_HD100); -+ } -+ -+ -+ if ( HalDev->MdioConnect & _CPMDIO_NEG_OFF) /* ~RC3.01 */ -+ PhyMode &= ~(NWAY_AUTO); /* Disable Auto Neg */ -+ if (!(HalDev->MdioConnect & _CPMDIO_HD)) -+ PhyMode &= ~(NWAY_HD100|NWAY_HD10); /* Cannot support HD */ -+ if (!(HalDev->MdioConnect & _CPMDIO_FD)) -+ PhyMode &= ~(NWAY_FD100|NWAY_FD10); /* Cannot support FD */ -+ if (!(HalDev->MdioConnect & _CPMDIO_10)) -+ PhyMode &= ~(NWAY_HD10|NWAY_FD10); /* Cannot support 10 Mbs */ -+ if (!(HalDev->MdioConnect & _CPMDIO_100)) -+ PhyMode &= ~(NWAY_HD100|NWAY_FD100); /* Cannot support 100 Mbs */ -+ -+ if(HalDev->MdioConnect & _CPMDIO_AUTOMDIX) PhyMode |= NWAY_AUTOMDIX; /* Set AutoMdix */ -+ -+ if (HalDev->CpmacFrequency <= 50000000) -+ PhyMode &= ~(NWAY_FD100|NWAY_HD100); /* Cannot support 100 MBS */ -+ if(DBG(7)) -+ dbgPrintf("halNeg: PhyMode[0x%08X] %d\n", HalDev->dev_base, PhyMode); -+ -+ if(DBG(0)) -+ { -+ dbgPrintf("halSetPhyMode2: MdioConnect:%08X ,", HalDev->MdioConnect); -+ dbgPrintf("PhyMode:%08X Auto:%d, FD10:%d, HD10:%d, FD100:%d, HD100:%d\n", PhyMode, -+ PhyMode&NWAY_AUTO, PhyMode&NWAY_FD10, PhyMode&NWAY_HD10, PhyMode&NWAY_FD100, -+ PhyMode&NWAY_HD100); -+ } -+ -+ -+ cpMacMdioSetPhyMode(HalDev->PhyDev,PhyMode); -+ DuplexUpdate(HalDev); -+ } -+static int StatsClear(HAL_DEVICE *HalDev) -+{ -+ int i; -+ MEM_PTR pStats; -+ -+ scOpen(EC_CPMAC); -+ -+ pStats = pCPMAC_RXGOODFRAMES(HalDev->dev_base); -+ for (i=0;i<STATS_MAX;i++) -+ { -+ *(MEM_PTR)(pStats) = 0xFFFFFFFF; -+ pStats++; -+ } -+ -+ return(EC_NO_ERRORS); -+} -+static void StatsDump(HAL_DEVICE *HalDev, void *Value) -+ { -+ MEM_PTR ptrStats; -+ MEM_PTR ptrValue; -+ int i; -+ ptrStats = pCPMAC_RXGOODFRAMES(HalDev->dev_base); -+ ptrValue = (bit32u*) Value; -+ for (i=0; i<STATS_MAX; i++) -+ { -+ *ptrValue = *ptrStats; -+ if(DBG(4)) -+ { -+ dbgPrintf("halStatsDump: Stat[%d:0x%08X] %d 0x%08X %d\n", i, ptrStats, *ptrStats, ptrValue, *ptrValue); -+ osfuncSioFlush(); -+ } -+ ptrStats++; -+ ptrValue++; -+ } -+ } -+static void ConfigApply(HAL_DEVICE *HalDev) -+ { -+ CPMAC_RX_MAXLEN(HalDev->dev_base) = HalDev->RxMaxLen; -+ CPMAC_RX_FILTERLOWTHRESH(HalDev->dev_base) = HalDev->RxFilterLowThresh; -+ CPMAC_RX0_FLOWTHRESH(HalDev->dev_base) = HalDev->Rx0FlowThresh; -+ UnicastSet(HalDev); -+ MacAddressSet(HalDev); -+ RxMBP_EnableSet(HalDev); -+ MacHashSet(HalDev); -+ MacControlSet(HalDev); -+ if(DBG(0)) -+ dbgPrintf("ValuesUpdate[%d]: MBP_ENABLE 0x%08X\n", HalDev->inst, CPMAC_RX_MBP_ENABLE(HalDev->dev_base)); -+ } -+static int halStatus(HAL_DEVICE *HalDev) -+{ -+ int status; -+ -+ if(HalDev->State < enOpened) -+ return (EC_CPMAC|EC_FUNC_STATUS|EC_VAL_INVALID_STATE); /*MJH+030805*/ -+ -+ /* No Phy Condition */ -+ if(HalDev->MdioConnect & _CPMDIO_NOPHY) /*MJH+030805*/ -+ { -+ /* No Phy condition, always linked */ -+ status = HalDev->Linked; -+ status |= CPMAC_STATUS_LINK_DUPLEX; -+ status |= CPMAC_STATUS_LINK_SPEED; -+ return(status); -+ } -+ -+ -+ if (HalDev->HostErr) /* Adapter Check */ -+ { -+ bit32u tmp; -+ status = CPMAC_STATUS_ADAPTER_CHECK; -+ if(HalDev->MacStatus & RX_HOST_ERR_CODE) -+ { -+ status |= CPMAC_STATUS_HOST_ERR_DIRECTION; -+ tmp = (HalDev->MacStatus & RX_HOST_ERR_CODE) >> 12; /* Code */ -+ status |= (tmp << 9); /* Code */ -+ tmp = (HalDev->MacStatus & RX_ERR_CH) >> 8; /* Channel */ -+ status |= (tmp << 13); -+ } -+ else -+ if(HalDev->MacStatus & TX_HOST_ERR_CODE) -+ { -+ status |= CPMAC_STATUS_HOST_ERR_DIRECTION; -+ tmp = (HalDev->MacStatus & TX_HOST_ERR_CODE) >> 20; /* Code */ -+ status |= (tmp << 9); /* Code */ -+ tmp = (HalDev->MacStatus & TX_ERR_CH) >> 16; /* Channel */ -+ status |= (tmp << 13); -+ } -+ } -+ else -+ { -+ status = HalDev->Linked; -+ if(status) -+ { -+ status = CPMAC_STATUS_LINK; -+ if(cpMacMdioGetDuplex(HalDev->PhyDev)) -+ status |= CPMAC_STATUS_LINK_DUPLEX; -+ if(cpMacMdioGetSpeed(HalDev->PhyDev)) -+ status |= CPMAC_STATUS_LINK_SPEED; -+ } -+ } -+ if(HalDev->debug) -+ dbgPrintf("[halStatus] Link Status is %d for 0x%X\n", status, HalDev->dev_base); -+ return(status); -+} -+static int InfoAccess(HAL_DEVICE *HalDev, int Key, int Action, void *ParmValue) -+ { -+ int rc = 0; -+ int Update=0; -+ -+ switch (Key) -+ { -+ /********************************************************************/ -+ /* */ -+ /* GENERAL */ -+ /* */ -+ /********************************************************************/ -+ -+ case enVersion : -+ if(Action==enGET) -+ { -+ *(const char **)ParmValue = pszVersion_CPMAC; -+ } -+ break; -+ case enDebug : -+ if(Action==enSET) -+ { -+ HalDev->debug = *(unsigned int *)ParmValue; -+ } -+ break; -+ -+ case enStatus : -+ if(Action==enGET) -+ { -+ int status; -+ status = halStatus(HalDev); -+ *(int *)ParmValue = status; -+ } -+ break; -+ /********************************************************************/ -+ /* */ -+ /* RX_MBP_ENABLE */ -+ /* */ -+ /********************************************************************/ -+ -+ case enRX_PASS_CRC : -+ if(Action==enSET) -+ { -+ UPDATE_RX_PASS_CRC(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_QOS_EN : -+ if(Action==enSET) -+ { -+ UPDATE_RX_QOS_EN(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_NO_CHAIN : -+ if(Action==enSET) -+ { -+ UPDATE_RX_NO_CHAIN(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_CMF_EN : -+ if(Action==enSET) -+ { -+ UPDATE_RX_CMF_EN(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_CSF_EN : -+ if(Action==enSET) -+ { -+ UPDATE_RX_CSF_EN(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_CEF_EN : -+ if(Action==enSET) -+ { -+ UPDATE_RX_CEF_EN(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_CAF_EN : -+ if(Action==enSET) -+ { -+ UPDATE_RX_CAF_EN(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_PROM_CH : -+ if(Action==enSET) -+ { -+ UPDATE_RX_PROM_CH(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_BROAD_EN : -+ if(Action==enSET) -+ { -+ UPDATE_RX_BROAD_EN(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_BROAD_CH : -+ if(Action==enSET) -+ { -+ UPDATE_RX_BROAD_CH(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_MULT_EN : -+ if(Action==enSET) -+ { -+ UPDATE_RX_MULT_EN(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_MULT_CH : -+ if(Action==enSET) -+ { -+ UPDATE_RX_MULT_CH(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ -+ /********************************************************************/ -+ /* */ -+ /* MAC_CONTROL */ -+ /* */ -+ /********************************************************************/ -+ -+ case enTX_PTYPE : -+ if(Action==enSET) -+ { -+ UPDATE_TX_PTYPE(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enTX_PACE : -+ if(Action==enSET) -+ { -+ UPDATE_TX_PACE(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enTX_FLOW_EN : -+ if(Action==enSET) -+ { -+ UPDATE_TX_FLOW_EN(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_FLOW_EN : -+ if(Action==enSET) -+ { -+ UPDATE_RX_FLOW_EN(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ -+ case enCTRL_LOOPBACK : -+ if(Action==enSET) -+ { -+ UPDATE_CTRL_LOOPBACK(*(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ /********************************************************************/ -+ /* */ -+ /* RX_UNICAST_SET */ -+ /* */ -+ /********************************************************************/ -+ -+ case enRX_UNICAST_SET : -+ if(Action==enSET) -+ { -+ HalDev->RxUnicastSet |= (1 << *(unsigned int *)ParmValue); -+ HalDev->RxUnicastClear &= ~(1 << *(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_UNICAST_CLEAR : -+ if(Action==enSET) -+ { -+ HalDev->RxUnicastClear |= (1 << *(unsigned int *)ParmValue); -+ HalDev->RxUnicastSet &= ~(1 << *(unsigned int *)ParmValue); -+ Update=1; -+ } -+ break; -+ -+ case enRX_MAXLEN : -+ if(Action==enSET) -+ { -+ HalDev->RxMaxLen = *(unsigned int *)ParmValue; -+ Update=1; -+ } -+ break; -+ -+ case enRX_FILTERLOWTHRESH : -+ if(Action==enSET) -+ { -+ HalDev->RxFilterLowThresh = *(unsigned int *)ParmValue; -+ Update=1; -+ } -+ break; -+ case enRX0_FLOWTHRESH : -+ if(Action==enSET) -+ { -+ HalDev->Rx0FlowThresh = *(unsigned int *)ParmValue; -+ Update=1; -+ } -+ break; -+ /********************************************************************/ -+ /* */ -+ /* RX_MULTICAST */ -+ /* */ -+ /********************************************************************/ -+ -+ case enRX_MULTICAST : -+ break; -+ case enRX_MULTI_SINGLE : -+ if(DBG(11)) -+ { -+ int tmpi; -+ bit8u *MacAddress; -+ MacAddress = (bit8u *) ParmValue; -+ dbgPrintf("CPMAC[%X]: MacAddress '", HalDev->dev_base); -+ for (tmpi=0; tmpi<6; tmpi++) -+ dbgPrintf("%02X:", MacAddress[tmpi]); -+ dbgPrintf("\n"); -+ } -+ if(Action==enCLEAR) -+ { -+ HashDel(HalDev, ParmValue); -+ Update=1; -+ } -+ else -+ if(Action==enSET) -+ { -+ HashAdd(HalDev, ParmValue); -+ Update=1; -+ } -+ break; -+ case enRX_MULTI_ALL : -+ if(Action==enCLEAR) -+ { -+ HalDev->MacHash1 = 0; -+ HalDev->MacHash2 = 0; -+ Update=1; -+ } -+ else -+ if(Action==enSET) -+ { -+ HalDev->MacHash1 = 0xFFFFFFFF; -+ HalDev->MacHash2 = 0xFFFFFFFF; -+ Update=1; -+ } -+ break; -+ -+ /********************************************************************/ -+ /* */ -+ /* MDIO */ -+ /* */ -+ /********************************************************************/ -+ -+ case enMdioConnect : -+ if(Action==enSET) -+ { -+ HalDev->MdioConnect = *(unsigned int *)ParmValue; -+ MdioSetPhyMode(HalDev); -+ } -+ if(Action==enGET) -+ { -+ *(unsigned int *)ParmValue = HalDev->MdioConnect; -+ } -+ break; -+ -+ -+ /********************************************************************/ -+ /* */ -+ /* STATISTICS */ -+ /* */ -+ /********************************************************************/ -+ case enStatsClear : -+ StatsClear(HalDev); -+ break; -+ case enStatsDump : -+ if(Action==enGET) -+ { -+ StatsDump(HalDev, ParmValue); -+ } -+ break; -+ -+/* Not implemented -+ case enStats1 : -+ if(Action==enGET) -+ { -+ StatsGet(HalDev, ParmValue, 1); -+ } -+ break; -+ -+ case enStats2 : -+ if(Action==enGET) -+ { -+ StatsGet(HalDev, ParmValue, 2); -+ } -+ break; -+ case enStats3 : -+ if(Action==enGET) -+ { -+ StatsGet(HalDev, ParmValue, 3); -+ } -+ break; -+ case enStats4 : -+ if(Action==enGET) -+ { -+ StatsGet(HalDev, ParmValue, 4); -+ } -+ break; -+ -+*/ -+ -+ default: -+ rc = EC_CPMAC|EC_FUNC_OPTIONS|EC_VAL_KEY_NOT_FOUND; -+ break; -+ } -+ -+ /* Verify proper device state */ -+ if (HalDev->State == enOpened) -+ switch (Update) -+ { -+ case 1 : -+ ConfigApply(HalDev); -+ break; -+ default: -+ break; -+ } -+ -+ return (rc); -+ } -+static const char pszStats[] = "Stats;"; -+ -+static int halControl(HAL_DEVICE *HalDev, const char *pszKey, const char *pszAction, void *Value) -+ { -+ int i; -+ int rc=0; -+ int Action; -+ int ActionFound; -+ int KeyFound; -+ -+#ifdef __CPHAL_DEBUG -+ if (DBG(1)) -+ { -+ dbgPrintf("\nhalControl-HalDev:%08X,Action:%s,Key:%s\n", (bit32u)HalDev, pszAction, pszKey); -+ } -+#endif -+ -+ /* 23Aug04 - BCIL needs to set Mac Address */ -+ if(HalDev->OsFunc->Strcmpi(pszKey, pszMacAddr) == 0) -+ { -+ KeyFound=1; -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) -+ { -+ unsigned char *MacAddr; -+ MacAddr = (unsigned char *) Value; -+ MacAddressSave(HalDev, MacAddr); -+ MacAddressSet(HalDev); -+ return(0); -+ } -+ else -+ { -+ return(-1); -+ } -+ } -+ -+ if(HalDev->OsFunc->Strcmpi(pszKey, hcLinked) == 0) -+ { -+ KeyFound=1; -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) -+ { -+ HalDev->Linked = *(int *)Value; -+ return(0); -+ } -+ else -+ { -+ return(-1); -+ } -+ } -+ -+ if(HalDev->OsFunc->Strcmpi(pszKey, "TxIntDisable") == 0) -+ { -+ KeyFound=1; -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) -+ { -+ HalDev->TxIntDisable = *(int *)Value; -+ if(HalDev->TxIntDisable && (HalDev->State == enOpened)) -+ { -+ /* if Opened and need TxIntDisabled, clear Ints for Channel 0 */ -+ CPMAC_TX_INTMASK_CLEAR(HalDev->dev_base) = 1; -+ } -+ return(0); -+ } -+ else -+ { -+ return(-1); -+ } -+ } -+ -+ if(HalDev->OsFunc->Strcmpi(pszKey, hcPhyAccess) == 0) -+ { -+ bit32u RegAddr; -+ bit32u PhyNum; -+ bit32u Data; -+ bit32u ValueIn; -+ -+ ValueIn = *(bit32u*) Value; -+ -+ KeyFound=1; -+ /* Cannot access MII if not opended */ -+ -+ if(HalDev->State < enOpened) -+ return(-1); -+ -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) -+ { -+ -+ PhyNum = (ValueIn & 0x1F); /* Phynum 0-32 */ -+ RegAddr = (ValueIn >> 5) & 0xFF; /* RegAddr in upper 11 bits */ -+ -+ *(bit32u*)Value = _mdioUserAccessRead(HalDev->PhyDev, RegAddr, PhyNum); -+ -+ return(0); -+ } /* end of hcGet */ -+ -+ -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) -+ { -+ PhyNum = (ValueIn & 0x1F); /* Phynum 0-32 */ -+ RegAddr = (ValueIn >> 5) & 0xFF; /* RegAddr in upper 11 bits of lower 16 */ -+ -+ Data = ValueIn >> 16; /* Data store in upper 16 bits */ -+ -+ _mdioUserAccessWrite(HalDev->PhyDev, RegAddr, PhyNum, Data); -+ return(0); -+ } -+ } /* End of hcPhyAccess */ -+ -+ if(HalDev->OsFunc->Strcmpi(pszKey, hcPhyNum) == 0) -+ { -+ KeyFound=1; -+ if(!HalDev->Linked) -+ return(-1); /* if not linked the no Phy Connected */ -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) -+ { -+ *(int *)Value = HalDev->PhyNum; -+ return(0); -+ } -+ } -+ -+ if(HalDev->OsFunc->Strcmpi(pszKey, hcCpmacSize) == 0) -+ { -+ KeyFound=1; -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) -+ { -+ *(bit32u *)Value = HalDev->CpmacSize; -+ return(0); -+ } -+ } -+ -+ if(HalDev->OsFunc->Strcmpi(pszKey, hcCpmacBase) == 0) -+ { -+ KeyFound=1; -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) -+ { -+ *(int *)Value = HalDev->dev_base; -+ return(0); -+ } -+ } -+ -+ if(HalDev->OsFunc->Strcmpi(pszKey, hcFullDuplex) == 0) -+ { -+ KeyFound=1; -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) -+ { -+ UPDATE_FULLDUPLEX(*(unsigned int *)Value); -+ if(HalDev->State == enOpened) -+ ConfigApply(HalDev); -+ return(0); -+ } -+ else -+ return(-1); -+ } -+ -+ if(HalDev->OsFunc->Strcmpi(pszKey, pszDebug) == 0) -+ { -+ KeyFound=1; -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) -+ { -+ ActionFound=1; -+ HalDev->debug = *(int *)Value; -+ } -+ } -+ -+ if(HalDev->OsFunc->Strcmpi(pszKey, hcMaxFrags) == 0) -+ { -+ KeyFound=1; -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) -+ { -+ ActionFound=1; -+ -+ if ((*(int *)Value) > 0) -+ HalDev->MaxFrags = *(int *)Value; -+ else -+ rc = (EC_AAL5|EC_FUNC_CONTROL|EC_VAL_INVALID_VALUE); -+ } -+ -+ if (HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) -+ { -+ ActionFound=1; -+ -+ *(int *)Value = HalDev->MaxFrags; -+ } -+ } -+ -+ if(HalDev->OsFunc->Strstr(pszKey, pszStats) != 0) -+ { -+ KeyFound=1; -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) -+ { -+ int Level; -+ int Ch; -+ char *TmpKey = (char *)pszKey; -+ ActionFound=1; -+ TmpKey += HalDev->OsFunc->Strlen(pszStats); -+ Level = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); -+ TmpKey++; -+ Ch = HalDev->OsFunc->Strtoul(TmpKey, &TmpKey, 10); -+ TmpKey++; -+ osfuncSioFlush(); -+#ifdef __CPHAL_DEBUG -+ if (DBG(1)) -+ { -+ dbgPrintf("\nhalControl-HalDev:%08X, Level:%d, Ch:%d\n", (bit32u)HalDev, Level, Ch); -+ } -+#endif -+ StatsGet(HalDev, (void **)Value, Level, Ch, 0); -+ osfuncSioFlush(); -+ } -+ } -+ -+ -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcSet) == 0) -+ Action = enSET; -+ else -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcClear) == 0) -+ Action = enCLEAR; -+ else -+ if(HalDev->OsFunc->Strcmpi(pszAction, hcGet) == 0) -+ Action = enGET; -+ else -+ Action = enNULL; -+ -+ -+ -+ for(i=enCommonStart+1;i<enCommonEnd;i++) -+ { -+ if(HalDev->OsFunc->Strcmpi(KeyCommon[i].strKey, pszKey)==0) -+ { -+ rc = InfoAccess(HalDev, KeyCommon[i].enKey, Action, Value); -+ } -+ } -+ for(i=enCpmacStart+1;i<enCpmacEnd;i++) -+ { -+ if(HalDev->OsFunc->Strcmpi(KeyCpmac[i].strKey, pszKey)==0) -+ { -+ rc = InfoAccess(HalDev, KeyCpmac[i].enKey, Action, Value); -+ } -+ } -+/* -+ if (KeyFound == 0) -+ rc = (EC_MODULE|EC_FUNC_CONTROL|EC_VAL_KEY_NOT_FOUND); -+ -+ if (ActionFound == 0) -+ rc = (EC_MODULE|EC_FUNC_CONTROL|EC_VAL_ACTION_NOT_FOUND); -+*/ -+ -+ return(rc); -+ } -+static bit32u ConfigGet(HAL_DEVICE *HalDev) -+ { -+ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; -+ char *DeviceInfo = HalDev->DeviceInfo; -+ int i = HalDev->inst; -+ bit32u Value; -+ int Error; -+ -+ /* get the configuration parameters common to all modules */ -+ Error = ConfigGetCommon(HalDev); -+ if (Error) return (EC_CPMAC|Error); -+ -+ if (HalDev->debug) -+ { -+ dbgPrintf("ConfigGet: haldev:0x%08X inst:%d base:0x%08X reset:%d\n", (bit32u) &HalDev, HalDev->inst, HalDev->dev_base, HalDev->ResetBit); -+ osfuncSioFlush(); -+ } -+ -+ Error = OsFunc->DeviceFindParmUint(DeviceInfo, pszMdioConnect,&Value); /*MJH+030805*/ -+ if(!Error) HalDev->MdioConnect = Value; -+ -+ Error = OsFunc->DeviceFindParmUint(DeviceInfo, "PhyMask",&Value); -+ if(!Error) HalDev->PhyMask = Value; -+ -+ Error = OsFunc->DeviceFindParmUint(DeviceInfo, "MLink",&Value); -+ if(!Error) HalDev->MLinkMask = Value; -+ -+ Error = OsFunc->DeviceFindParmUint(DeviceInfo, hcMdixMask, &Value); -+ if(!Error) -+ HalDev->MdixMask = Value; -+ else -+ HalDev->MdixMask = 0; -+ -+ Error = OsFunc->DeviceFindParmUint(DeviceInfo, hcSize, &Value); /*MJH+030425*/ -+ if(!Error) HalDev->CpmacSize = Value; -+ -+ for(i=enCommonStart+1;i<enCommonEnd;i++) -+ { -+ Error = OsFunc->DeviceFindParmUint(DeviceInfo, KeyCommon[i].strKey, (bit32u*)&Value); -+ if(!Error) -+ { -+ InfoAccess(HalDev, KeyCommon[i].enKey, enSET, (bit32u*)&Value); -+ } -+ } -+ for(i=enCpmacStart+1;i<enCpmacEnd;i++) -+ { -+ Error = OsFunc->DeviceFindParmUint(DeviceInfo, KeyCpmac[i].strKey, (bit32u*)&Value); -+ if(!Error) -+ { -+ InfoAccess(HalDev, KeyCpmac[i].enKey, enSET, (bit32u*)&Value); -+ } -+ } -+ return (EC_NO_ERRORS); -+ } -+ -+ -+static void ConfigInit(HAL_DEVICE *HalDev) -+ { -+ if(HalDev->inst == 0) -+ { -+ HalDev->dev_base = 0xA8610000; -+ HalDev->ResetBit = 17; -+ HalDev->interrupt = 19; -+ HalDev->MLinkMask = 0; -+ HalDev->PhyMask = 0xAAAAAAAA; -+ } -+ else -+ { -+ HalDev->dev_base = 0xA8612800; -+ HalDev->ResetBit = 21; -+ HalDev->interrupt = 33; /*~RC3.02*/ -+ HalDev->MLinkMask = 0; -+ HalDev->PhyMask = 0x55555555; -+ } -+ HalDev->RxMaxLen = 1518; -+ HalDev->MaxFrags = 2; -+ HalDev->MdioConnect = _CPMDIO_HD|_CPMDIO_FD|_CPMDIO_10|_CPMDIO_100|_CPMDIO_AUTOMDIX; -+ HalDev->debug=0xFFFFFFFF; -+ HalDev->debug=0; -+ } -+/* Shuts down the EMAC device -+ * -+ *@param HalDev EMAC instance. This was returned by halOpen() -+ *@param mode Indicates actions to tak on close. -+ <br> -+ *PARTIAL - Disable EMAC -+ <br> -+ *FULL - Disable EMAC and call OS to free all allocated memory -+ * -+ *@retval -+ * 0 OK -+ <br> -+ * Non-Zero Not OK -+ * -+ */ -+static int halInit( HAL_DEVICE *HalDev) -+ { -+ int rc; -+ -+ /* Verify proper device state */ -+ if (HalDev->State != enDevFound) -+ return(EC_CPMAC|EC_FUNC_HAL_INIT|EC_VAL_INVALID_STATE); -+ -+ /* Configure HAL defaults */ -+ ConfigInit(HalDev); -+ -+ /* Retrieve HAL configuration parameters from data store */ -+ rc = ConfigGet(HalDev); -+ if (rc) return (rc); -+ -+ /* Updated 030403*/ -+ rc = HalDev->OsFunc->Control(HalDev->OsDev, hcCpuFrequency, hcGet, &HalDev->CpuFrequency); /*MJH+030403*/ -+ if(rc) -+ HalDev->CpuFrequency = 20000000; /*20 Mhz default */ /*MJH+030403*/ -+ -+ rc = HalDev->OsFunc->Control(HalDev->OsDev, hcCpmacFrequency, hcGet, &HalDev->CpmacFrequency); /*MJH+030331*/ -+ if(rc) -+ HalDev->CpmacFrequency = HalDev->CpuFrequency/2; /*MJH~030404*/ -+ -+ rc = HalDev->OsFunc->Control(HalDev->OsDev, hcMdioBusFrequency, hcGet, &HalDev->MdioBusFrequency); /*MJH+030402*/ -+ if(rc) -+ HalDev->MdioBusFrequency = HalDev->CpmacFrequency; -+ -+ rc = HalDev->OsFunc->Control(HalDev->OsDev, hcMdioClockFrequency, hcGet, &HalDev->MdioClockFrequency); /*MJH+030402*/ -+ if(rc) -+ HalDev->MdioClockFrequency = 2200000; /* 2.2 Mhz PITS #14 */ -+ -+ -+ /* update device state */ -+ HalDev->State = enInitialized; -+ -+ /* initialize statistics */ -+ StatsInit(HalDev); /* +RC3.02 */ -+ -+ /* -RC3.02 -+ StatsTable3[0].StatPtr = &HalDev->ChData[0].RxBufSize; -+ StatsTable3[1].StatPtr = &HalDev->ChData[0].RxBufferOffset; -+ StatsTable3[2].StatPtr = &HalDev->ChData[0].RxNumBuffers; -+ StatsTable3[3].StatPtr = &HalDev->ChData[0].RxServiceMax; -+ StatsTable3[4].StatPtr = &HalDev->ChData[0].TxNumBuffers; -+ StatsTable3[5].StatPtr = &HalDev->ChData[0].TxNumQueues; -+ StatsTable3[6].StatPtr = &HalDev->ChData[0].TxServiceMax; -+ */ -+ -+ return(EC_NO_ERRORS); -+ } -+static int halProbe(HAL_DEVICE *HalDev) -+ { -+ int inst = HalDev->inst; -+ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; -+ int error_code; -+ -+ if (HalDev->State != enConnected) -+ return (EC_CPMAC|EC_FUNC_PROBE|EC_VAL_INVALID_STATE); -+ -+ if(HalDev->debug) dbgPrintf("halProbe: %d ",inst); -+ -+ error_code = OsFunc->DeviceFindInfo(inst,"cpmac",&HalDev->DeviceInfo); -+ -+ if(error_code) -+ return (EC_CPMAC|EC_FUNC_PROBE|EC_VAL_DEVICE_NOT_FOUND ); -+ -+ /* Set device state to DevFound */ -+ HalDev->State = enDevFound; -+ return(EC_NO_ERRORS); -+ } -+static void ChannelConfigInit(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn) -+ { -+ int Ch = HalChn->Channel; -+ int Direction = HalChn->Direction; -+ int nTxBuffers = 256; -+ -+ if (Direction == DIRECTION_TX) -+ { -+ HalDev->ChData[Ch].TxNumBuffers = nTxBuffers; -+ HalDev->ChData[Ch].TxNumQueues = 1; -+ HalDev->ChData[Ch].TxServiceMax = nTxBuffers/3; -+ HalDev->TxIntThreshold[Ch] = HalDev->ChData[Ch].TxServiceMax; -+ HalDev->TxIntThresholdMaster[Ch] = HalDev->TxIntThreshold[Ch]; -+ } -+ -+ if (Direction == DIRECTION_RX) -+ { -+ HalDev->ChData[Ch].RxNumBuffers = nTxBuffers*2; -+ HalDev->ChData[Ch].RxBufferOffset = 0; -+ HalDev->ChData[Ch].RxBufSize = 1518; -+ HalDev->ChData[Ch].RxServiceMax = nTxBuffers/3; /*Not a typo*/ -+ } -+ } -+static int ChannelConfigApply(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn) -+ { -+ int Ch = HalChn->Channel; -+ int Direction = HalChn->Direction; -+ -+ if (DBG(11)) -+ { -+ dbgPrintf("halChannelConfigApply[%d:%d] haldev:0x%08X inst:%d base:0x%08X reset:%d\n", Ch, Direction, (bit32u) &HalDev, HalDev->inst, HalDev->dev_base, HalDev->ResetBit); -+ osfuncSioFlush(); -+ } -+ -+ if (Direction == DIRECTION_TX) -+ { -+ if (HalDev->ChIsOpen[Ch][Direction] == TRUE) -+ { -+ return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_TX_CH_ALREADY_OPEN); -+ } -+ -+ /* Initialize Queue Data */ -+ HalDev->TxActQueueHead[Ch][0] = 0; -+ HalDev->TxActQueueCount[Ch][0] = 0; -+ HalDev->TxActive[Ch][0] = FALSE; -+ -+ /* Need to use a macro that takes channel as input */ -+ CPMAC_TX0_HDP(HalDev->dev_base)=0; -+ -+ /* Initialize buffer memory for the channel */ -+ InitTcb(HalDev, Ch); -+ -+ if(!HalDev->TxIntDisable) -+ CPMAC_TX_INTMASK_SET(HalDev->dev_base) = (1<<Ch); /* GSG 11/22 */ -+ } -+ else -+ { -+ if (HalDev->ChIsOpen[Ch][Direction] == TRUE) -+ { -+ return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_RX_CH_ALREADY_OPEN); -+ } -+ -+ /* Initialize Queue Data */ -+ HalDev->RxActQueueHead[Ch] = 0; -+ HalDev->RxActQueueCount[Ch] = 0; -+ -+ HalDev->RxActive[Ch] = FALSE; -+ -+ /* Need to use a macro that takes channel as input */ -+ CPMAC_RX0_HDP(HalDev->dev_base)=0; -+ -+ /* Initialize buffer memory for the channel */ -+ InitRcb(HalDev, Ch); -+ -+ CPMAC_RX_INTMASK_SET(HalDev->dev_base) = (1<<Ch); /* GSG 11/22 */ -+ } -+ -+ HalDev->ChIsOpen[Ch][Direction] = TRUE; /* channel is open */ -+ -+ return (EC_NO_ERRORS); -+ } -+ -+/* GSG 11/22 -+ * Retrieves channel parameters from configuration file. Any parameters -+ * which are not found are ignored, and the HAL default value will apply, -+ * unless a new value is given through the channel structure in the call -+ * to ChannelSetup. -+ */ -+static int ChannelConfigGet(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn) -+ { -+ int Ch = HalChn->Channel; -+ int Direction = HalChn->Direction; -+ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; -+ unsigned int rc, Value; -+ void *ChInfo; -+ -+ rc=OsFunc->DeviceFindParmValue(HalDev->DeviceInfo, channel_names[Ch], &ChInfo); -+ /* Do not fail if Channel Info not available for RC2 */ -+ if (rc) return(0); -+/* if (rc) return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_CH_INFO_NOT_FOUND);*/ -+ -+ /* i don't care if a value is not found because they are optional */ -+ if(Direction == DIRECTION_TX) -+ { -+ rc=OsFunc->DeviceFindParmUint(ChInfo, "TxNumBuffers", &Value); -+ if (!rc) HalDev->ChData[Ch].TxNumBuffers = Value; -+ -+ /*rc=OsFunc->DeviceFindParmUint(ChInfo, "TxNumQueues", &Value);*/ /*MJH-030329*/ -+ /*if (!rc) HalDev->ChData[Ch].TxNumQueues = Value;*/ /*MJH-030329*/ -+ -+ rc=OsFunc->DeviceFindParmUint(ChInfo, "TxServiceMax", &Value); -+ if (!rc) -+ { -+ HalDev->ChData[Ch].TxServiceMax = Value; -+ HalDev->TxIntThreshold[Ch] = HalDev->ChData[Ch].TxServiceMax; -+ HalDev->TxIntThresholdMaster[Ch] = HalDev->TxIntThreshold[Ch]; -+ } -+ } -+ if(Direction == DIRECTION_RX) -+ { -+ rc=OsFunc->DeviceFindParmUint(ChInfo, "RxNumBuffers", &Value); -+ if (!rc) HalDev->ChData[Ch].RxNumBuffers = Value; -+ -+ rc=OsFunc->DeviceFindParmUint(ChInfo, "RxBufferOffset", &Value); -+ if (!rc) HalDev->ChData[Ch].RxBufferOffset = Value; -+ -+ rc=OsFunc->DeviceFindParmUint(ChInfo, "RxBufSize", &Value); -+ if (!rc) HalDev->ChData[Ch].RxBufSize = Value; -+ -+ rc=OsFunc->DeviceFindParmUint(ChInfo, "RxServiceMax", &Value); -+ if (!rc) HalDev->ChData[Ch].RxServiceMax = Value; -+ } -+ return (EC_NO_ERRORS); -+ } -+#define ChannelUpdate(Field) if(HalChn->Field != 0xFFFFFFFF) HalDev->ChData[Ch].Field = HalChn->Field -+ -+static void ChannelConfigUpdate(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn) -+ { -+ int Ch = HalChn->Channel; -+ int Direction = HalChn->Direction; -+#ifdef __CPHAL_DEBUG -+ if (DBG(1)) -+ { -+ dbgPrintf("\nChnUpd-HalDev:%08X,Chn:%d:%d\n", (bit32u)HalDev, Ch, Direction); osfuncSioFlush(); -+ } -+#endif -+ if (Direction == DIRECTION_TX) -+ { -+ ChannelUpdate(TxNumBuffers); -+ /*ChannelUpdate(TxNumQueues);*/ /*MJH~030329*/ -+ ChannelUpdate(TxServiceMax); -+ HalDev->TxIntThreshold[Ch] = HalDev->ChData[Ch].TxServiceMax; -+ HalDev->TxIntThresholdMaster[Ch] = HalDev->TxIntThreshold[Ch]; -+ } -+ else -+ if (Direction == DIRECTION_RX) -+ { -+ ChannelUpdate(RxBufferOffset); -+ ChannelUpdate(RxBufSize); -+ ChannelUpdate(RxNumBuffers); -+ ChannelUpdate(RxServiceMax); -+#ifdef __CPHAL_DEBUG -+ if (DBG(1)) -+ { -+ dbgPrintf("\nRxNumBuffers %d\n",HalChn->RxNumBuffers); osfuncSioFlush(); -+ } -+#endif -+ } -+ } -+static int halChannelSetup(HAL_DEVICE *HalDev, CHANNEL_INFO *HalChn, OS_SETUP *OsSetup) -+ { -+ int Direction; -+ int Ch; -+ int rc; -+ -+ /* Verify proper device state */ -+ if (HalDev->State < enInitialized) -+ return (EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_INVALID_STATE); -+ -+ /* We require the channel structure to be passed, even if it only contains -+ the channel number */ -+ if (HalChn == NULL) -+ { -+ return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_NULL_CH_STRUCT); -+ } -+ -+ Ch = HalChn->Channel; -+ Direction = HalChn->Direction; -+ -+ /* This should check on Maximum Channels for RX or TX, -+ they might be different Mick 021124 */ -+ if ((Ch < 0) || (Ch > (MAX_CHAN-1))) -+ { -+ return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_INVALID_CH); -+ } -+ -+ /* if channel is already open, this call is invalid */ -+ if (HalDev->ChIsOpen[Ch][Direction] == TRUE) -+ { -+ return(EC_CPMAC|EC_FUNC_CHSETUP|EC_VAL_CH_ALREADY_OPEN); -+ } -+ -+ /* channel is closed, but might be setup. If so, reopen the hardware channel. */ -+ if (HalDev->ChIsSetup[Ch][Direction] == FALSE) -+ { -+ /* Setup channel configuration */ -+ HalDev->ChData[Ch].Channel = Ch; -+ -+ /* Store OS_SETUP */ -+ HalDev->ChData[Ch].OsSetup = OsSetup; -+ -+ /* Framework : -+ Set Default Values -+ Update with options.conf -+ Apply driver updates -+ */ -+ ChannelConfigInit(HalDev, HalChn); -+ ChannelConfigGet(HalDev, HalChn); -+ ChannelConfigUpdate(HalDev, HalChn); -+ -+ /* cppi.c needs to use Rx/TxServiceMax */ -+ HalDev->BuffersServicedMax = 169; /* TEMP */ -+ -+ HalDev->ChIsSetup[Ch][Direction] = TRUE; -+ } -+ -+ rc = EC_NO_ERRORS; -+ -+ /* If the hardware has been opened (is out of reset), then configure the channel -+ in the hardware. NOTE: ChannelConfigApply calls the CPSAR ChannelSetup()! */ -+ if (HalDev->State == enOpened) -+ { -+ rc = ChannelConfigApply(HalDev, HalChn); -+ } -+ -+ return (rc); -+ } -+ -+ -+static int miiInfoGet(HAL_DEVICE *HalDev, bit32u *miiBaseAddress, bit32u *miiResetBit) -+ { -+ int rc; -+ void *DeviceInfo; -+ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; -+ -+ /* Only one instance of cpmdio */ -+ rc = OsFunc->DeviceFindInfo(0,"cpmdio",&DeviceInfo); /*~RC3.02*/ -+ -+ if(rc) -+ return (EC_DEV_CPMDIO|EC_FUNC_OPEN|EC_VAL_DEVICE_NOT_FOUND ); -+ -+ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "base",miiBaseAddress); -+ if(rc) -+ rc=EC_DEV_CPMDIO|EC_FUNC_OPEN|EC_VAL_NO_BASE; -+ -+ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "reset_bit",miiResetBit); -+ if(rc) -+ rc=EC_DEV_CPMDIO|EC_FUNC_OPEN|EC_VAL_NO_BASE; -+ -+ -+ /* See if need to make mdio functional in GPIO */ -+ gpioCheck(HalDev, DeviceInfo); -+ -+ if(DBG(0)) -+ dbgPrintf("miiBase: 0x%08X %u\n", *miiBaseAddress, *miiResetBit); -+ return(rc); -+ } -+static void ephyCheck(HAL_DEVICE *HalDev) -+ { /*+RC3.02*/ -+ int rc; -+ void *DeviceInfo; -+ int mii_phy; -+ int reset_bit; -+ OS_FUNCTIONS *OsFunc = HalDev->OsFunc; -+ -+ rc = OsFunc->DeviceFindInfo(0,"ephy",&DeviceInfo); -+ if(rc) return; -+ -+ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "mii_phy",&mii_phy); -+ if(rc) return; -+ -+ rc = OsFunc->DeviceFindParmUint(DeviceInfo, "reset_bit",&reset_bit); -+ if(rc) return; -+ -+ if (HalDev->PhyMask & (1 << mii_phy)) -+ { -+ *(volatile bit32u *)(HalDev->ResetBase) |= (1 << reset_bit); /*+RC3.02*/ -+ resetWait(HalDev); -+ } -+ } /*+RC3.02*/ -+static void AutoNegotiate(HAL_DEVICE *HalDev) -+ { -+ int size; -+ bit32u ModID, RevMaj, RevMin; -+ PHY_DEVICE *PhyDev; -+ bit32u miiBaseAddress; -+ bit32u miiResetBit; -+ -+ /* Verify proper device state */ -+ if (HalDev->State < enOpened) -+ return; -+ -+ miiInfoGet(HalDev, &miiBaseAddress, &miiResetBit); -+ -+ cpMacMdioGetVer(miiBaseAddress, &ModID, &RevMaj, &RevMin); -+ if(HalDev->debug) -+ dbgPrintf("Mdio Module Id %d, Version %d.%d\n", ModID, RevMaj, RevMin); -+ -+ size = cpMacMdioGetPhyDevSize(); -+ PhyDev = (PHY_DEVICE *) HalDev->OsFunc->Malloc( size ); -+ -+ HalDev->PhyDev = PhyDev; -+ -+ ephyCheck(HalDev); -+ -+ cpMacMdioInit( PhyDev, miiBaseAddress, HalDev->inst, HalDev->PhyMask, HalDev->MLinkMask, HalDev->MdixMask, HalDev->ResetBase, miiResetBit, HalDev->MdioBusFrequency, HalDev->MdioClockFrequency, HalDev->debug, HalDev); /*MJH~030402*/ -+ MdioSetPhyMode(HalDev); -+ -+ return; -+ } -+static int halOpen(HAL_DEVICE *HalDev) -+ { -+ unsigned char *MacAddr; -+ int i; -+ int j; -+ int rc, Ticks; -+ -+ if (HalDev->debug) -+ { -+ dbgPrintf("halOpen: haldev:0x%08X inst:%d base:0x%08X reset:%d\n", (bit32u) &HalDev, HalDev->inst, HalDev->dev_base, HalDev->ResetBit); -+ osfuncSioFlush(); -+ } -+ -+ /* Verify proper device state */ -+ if (HalDev->State < enInitialized) -+ return (EC_CPMAC|EC_FUNC_OPEN|EC_VAL_INVALID_STATE); -+ -+ -+ /* take CPMAC out of reset - GSG 11/20*/ -+ if ((VOLATILE32(HalDev->ResetBase) & (1 << HalDev->ResetBit)) != 0) -+ { -+ /* perform normal close duties */ -+ CPMAC_MACCONTROL(HalDev->dev_base) &= ~MII_EN; -+ CPMAC_TX_CONTROL(HalDev->dev_base) &= ~TX_EN; -+ CPMAC_RX_CONTROL(HalDev->dev_base) &= ~RX_EN; -+ -+ /* disable interrupt masks */ -+ CPMAC_TX_INTMASK_CLEAR(HalDev->dev_base) = 0xFF; -+ CPMAC_RX_INTMASK_CLEAR(HalDev->dev_base) = 0xFF; -+ } -+ -+ /* take CPMAC out of reset */ -+ *(volatile bit32u *)(HalDev->ResetBase) &= ~(1 << HalDev->ResetBit); -+ resetWait(HalDev); -+ *(volatile bit32u *)(HalDev->ResetBase) |= (1 << HalDev->ResetBit); -+ resetWait(HalDev); -+ -+ /* After Reset clear the Transmit and Receive DMA Head Descriptor Pointers */ -+ -+ CPMAC_TX0_HDP(HalDev->dev_base)=0; -+ CPMAC_TX1_HDP(HalDev->dev_base)=0; -+ CPMAC_TX2_HDP(HalDev->dev_base)=0; -+ CPMAC_TX3_HDP(HalDev->dev_base)=0; -+ CPMAC_TX4_HDP(HalDev->dev_base)=0; -+ CPMAC_TX5_HDP(HalDev->dev_base)=0; -+ CPMAC_TX6_HDP(HalDev->dev_base)=0; -+ CPMAC_TX7_HDP(HalDev->dev_base)=0; -+ -+ /* Rx Init */ -+ -+ CPMAC_RX0_HDP(HalDev->dev_base) = 0; -+ CPMAC_RX1_HDP(HalDev->dev_base) = 0; -+ CPMAC_RX2_HDP(HalDev->dev_base) = 0; -+ CPMAC_RX3_HDP(HalDev->dev_base) = 0; -+ CPMAC_RX4_HDP(HalDev->dev_base) = 0; -+ CPMAC_RX5_HDP(HalDev->dev_base) = 0; -+ CPMAC_RX6_HDP(HalDev->dev_base) = 0; -+ CPMAC_RX7_HDP(HalDev->dev_base) = 0; -+ -+ CPMAC_RX_BUFFER_OFFSET(HalDev->dev_base) = 0; -+ -+ /* Init Tx and Rx DMA */ -+ -+ CPMAC_TX_CONTROL(HalDev->dev_base) |= TX_EN; -+ CPMAC_RX_CONTROL(HalDev->dev_base) |= RX_EN; -+ -+ CPMAC_MAC_INTMASK_SET(HalDev->dev_base) |=2; /* Enable Adaptercheck Ints */ -+ HalDev->OsFunc->Control(HalDev->OsDev, pszMacAddr, hcGet, &MacAddr); /* GSG 11/22 */ -+ MacAddressSave(HalDev, MacAddr); -+ -+ HalDev->HostErr = 0; /* Clear Adapter Check indicator */ -+ HalDev->State = enOpened; /* Change device state */ -+ -+ /* Start MDIO Negotiation */ -+ AutoNegotiate(HalDev); -+ -+ /* Enable the Os Timer */ -+ Ticks = HalDev->CpuFrequency / 100; /* 10 milli-secs */ /*MJH~030402*/ -+ HalDev->OsFunc->Control(HalDev->OsDev, pszTick, hcSet, &Ticks); /* GSG 11/22 */ -+ HalDev->OsFunc->IsrRegister(HalDev->OsDev, halIsr, HalDev->interrupt); -+ -+ /* GSG +030523 Malloc space for the Rx fraglist */ -+ HalDev->fraglist = HalDev->OsFunc->Malloc(HalDev->MaxFrags * sizeof(FRAGLIST)); -+ -+ /* Any pre-open configuration */ -+ -+ /* For any channels that have been pre-initialized, set them up now */ -+ /* Note : This loop should not use MAX_CHN, it should only -+ loop through Channels Setup, memory should not be reserved -+ until Channel is Setup -+ */ -+ for(i=0; i<MAX_CHAN; i++) /* i loops through Channels */ -+ for(j=0; j<2; j++) /* j loops through DIRECTION values, 0 and 1 */ -+ { -+ if(HalDev->ChIsSetup[i][j]==TRUE) /* If the Channel and Direction have been Setup */ -+ if(HalDev->ChIsOpen[i][j]==FALSE) /* but not opened, then Apply Values now */ -+ { -+ CHANNEL_INFO HalChn; -+ HalChn.Channel = i; -+ HalChn.Direction = j; -+ rc = ChannelConfigApply(HalDev, &HalChn); -+ if(rc != EC_NO_ERRORS) -+ return(rc); -+ } -+ } /* End of looping through Channel/Direction */ -+ -+ ConfigApply(HalDev); /* Apply Configuration Values to Device */ -+ CPMAC_MACCONTROL(HalDev->dev_base) |= MII_EN; /* MAC_EN */ -+ if(DBG(0)) -+ dbgPrintf("[halOpen]MacControl:%08X\n", CPMAC_MACCONTROL(HalDev->dev_base)); -+ return(EC_NO_ERRORS); -+ } -+ -+#define INT_PENDING (MAC_IN_VECTOR_TX_INT_OR | MAC_IN_VECTOR_RX_INT_OR | MAC_IN_VECTOR_HOST_INT) -+static int halShutdown(HAL_DEVICE *HalDev) -+ { -+ int Ch, Queue; /*GSG+030514*/ -+ -+ /* Verify proper device state */ -+ if (HalDev->State == enOpened) -+ halClose(HalDev, 3); /* GSG ~030429 */ -+ -+ /* Buffer/descriptor resources may still need to be freed if a Close -+ Mode 1 was performed prior to Shutdown - clean up here */ /*GSG+030514*/ -+ for (Ch=0; Ch<MAX_CHAN; Ch++) -+ { -+ if (HalDev->RcbStart[Ch] != 0) -+ FreeRx(HalDev,Ch); -+ -+ for(Queue=0; Queue<MAX_QUEUE; Queue++) -+ { -+ if (HalDev->TcbStart[Ch][Queue] != 0) -+ FreeTx(HalDev,Ch,Queue); -+ } -+ } -+ -+ /* free the HalFunc */ -+ HalDev->OsFunc->Free(HalDev->HalFuncPtr); -+ -+ /* free the HAL device */ -+ HalDev->OsFunc->Free(HalDev); -+ -+ return(EC_NO_ERRORS); -+ } -+int halIsr(HAL_DEVICE *HalDev, int *MorePackets) -+{ -+ bit32u IntVec; -+ int Serviced; -+ int PacketsServiced=0; -+ int Channel; -+ int TxMorePackets=0; -+ int RxMorePackets=0; -+ -+ /* Verify proper device state - important because a call prior to Open would -+ result in a lockup */ -+ if (HalDev->State != enOpened) -+ return(EC_CPMAC|EC_FUNC_DEVICE_INT|EC_VAL_INVALID_STATE); -+ -+ IntVec = CPMAC_MAC_IN_VECTOR(HalDev->dev_base); -+ -+#ifdef __CPHAL_DEBUG -+ if (DBG(0)) -+ { -+ dbgPrintf("\nhalIsr: inst %d, IntVec 0x%X\n", HalDev->inst, IntVec); osfuncSioFlush();/* GSG 11/22 */ -+ } -+#endif -+ -+ HalDev->IntVec = IntVec; -+ if (IntVec & MAC_IN_VECTOR_TX_INT_OR) -+ { -+ int TxServiceMax=0; /* Compiler complains if not initialized */ -+ -+ Channel = (IntVec & 0x7); -+ -+ if(HalDev->TxIntDisable) -+ { -+ CPMAC_TX_INTMASK_CLEAR(HalDev->dev_base) = (1<<Channel); /* Disable Interrupt for Channel */ -+ TxServiceMax = HalDev->ChData[Channel].TxServiceMax; -+ HalDev->ChData[Channel].TxServiceMax = 10000; /* Need to service all packets in the Queue */ -+ } -+ -+ PacketsServiced |= TxInt(HalDev, Channel, 0, &TxMorePackets); -+ -+ if(HalDev->TxIntDisable) -+ HalDev->ChData[Channel].TxServiceMax = TxServiceMax; -+ } -+ -+ if (IntVec & MAC_IN_VECTOR_RX_INT_OR) -+ { -+ Channel = (IntVec >> 8) & 0x7; -+ Serviced = RxInt(HalDev, Channel, &RxMorePackets); -+ PacketsServiced |= (Serviced<<16); -+ } -+ -+ if (IntVec & MAC_IN_VECTOR_HOST_INT) -+ { -+ /* Adaptercheck */ -+ HalDev->HostErr = 1; -+ HalDev->MacStatus = CPMAC_MACSTATUS(HalDev->dev_base); -+ osfuncStateChange(); /*MJH+030328*/ -+ if(DBG(0)) -+ { -+ dbgPrintf("Adaptercheck: %08x for base:%X\n",HalDev->MacStatus, (bit32u)HalDev->dev_base); -+ osfuncSioFlush(); -+ } -+ } -+ *MorePackets = (TxMorePackets | RxMorePackets); -+ return (PacketsServiced); -+} -+ -+int halPacketProcessEnd(HAL_DEVICE *HalDev) -+{ -+ int base = HalDev->dev_base; -+ CPMAC_MAC_EOI_VECTOR(base) = 0; -+ return(0); -+} -+ -+ -+ -+static int PhyCheck(HAL_DEVICE *HalDev) -+ { -+ return(cpMacMdioTic(HalDev->PhyDev)); -+ } -+static int halTick(HAL_DEVICE *HalDev) -+{ -+ int TickChange; -+ -+ if(HalDev->State < enOpened) -+ return (EC_CPMAC|EC_FUNC_TICK|EC_VAL_INVALID_STATE); -+ -+ /* if NO Phy no need to check Link */ -+ if(HalDev->MdioConnect & _CPMDIO_NOPHY) -+ return(EC_NO_ERRORS); /* No change in Phy State detected */ -+ -+ TickChange = PhyCheck(HalDev); -+ /* Phy State Change Detected */ -+ if(TickChange == 1) -+ { -+ /* MDIO indicated a change */ -+ DuplexUpdate(HalDev); -+ osfuncStateChange(); -+ return(EC_NO_ERRORS); -+ } -+ -+ /* if in AutoMdix mode, and Flip request received, inform OS */ -+ if( (HalDev->MdioConnect & _CPMDIO_AUTOMDIX) && -+ (TickChange & _MIIMDIO_MDIXFLIP)) -+ { -+ bit32u Mdix; -+ Mdix = TickChange & 0x1; /* Mdix mode stored in bit 0 */ -+ HalDev->OsFunc->Control(HalDev->OsDev, hcMdioMdixSwitch, hcSet, &Mdix); -+ return(EC_NO_ERRORS); -+ } -+ -+ return(EC_NO_ERRORS); -+} -+ -+int halCpmacInitModule(HAL_DEVICE **pHalDev, OS_DEVICE *OsDev, HAL_FUNCTIONS **pHalFunc, -+ OS_FUNCTIONS *OsFunc, int OsFuncSize, int *HalFuncSize, int Inst) -+ { -+ HAL_DEVICE *HalDev; -+ HAL_FUNCTIONS *HalFunc; -+ -+ if (OsFuncSize < sizeof(OS_FUNCTIONS)) -+ return (EC_CPMAC|EC_FUNC_HAL_INIT|EC_VAL_OS_VERSION_NOT_SUPPORTED); -+ -+ HalDev = (HAL_DEVICE *) OsFunc->MallocDev(sizeof(HAL_DEVICE)); -+ if (!HalDev) -+ return (EC_CPMAC|EC_FUNC_HAL_INIT|EC_VAL_MALLOC_DEV_FAILED); -+ -+ /* clear the HalDev area */ -+ OsFunc->Memset(HalDev, 0, sizeof(HAL_DEVICE)); -+ -+ /* Initialize the size of hal functions */ -+ *HalFuncSize = sizeof (HAL_FUNCTIONS); -+ -+ HalFunc = (HAL_FUNCTIONS *) OsFunc->Malloc(sizeof(HAL_FUNCTIONS)); -+ if (!HalFunc) -+ return (EC_CPMAC|EC_FUNC_HAL_INIT|EC_VAL_MALLOC_FAILED); -+ -+ /* clear the function pointers */ -+ OsFunc->Memset(HalFunc, 0, sizeof(HAL_FUNCTIONS)); -+ -+ HalDev->OsDev = OsDev; -+ HalDev->OsOpen = OsDev; -+ HalDev->inst = Inst; -+ HalDev->OsFunc = OsFunc; -+ HalDev->HalFunc = HalFunc; -+ /* Remove the following from cppi, replace with HalFunc */ -+ HalDev->HalFuncPtr = HalFunc; /* GSG 11/20 changed name to match cppi */ -+ -+ /****************************************************************/ -+ /* POPULATE HALFUNC */ -+ /****************************************************************/ -+ HalFunc->ChannelSetup = halChannelSetup; -+ HalFunc->ChannelTeardown = halChannelTeardown; /* GSG 11/20 */ -+ HalFunc->Close = halClose; /* GSG 11/20 */ -+ HalFunc->Control = halControl; /* GSG 11/22 */ -+ HalFunc->Init = halInit; -+ HalFunc->Open = halOpen; -+ HalFunc->PacketProcessEnd = halPacketProcessEnd; -+ HalFunc->Probe = halProbe; -+ HalFunc->RxReturn = halRxReturn; -+ HalFunc->Send = halSend; -+ HalFunc->Shutdown = halShutdown; -+ HalFunc->Tick = halTick; -+ -+ /* HalFunc->Status = halStatus;*/ /* GSG 11/22 */ -+ /* pass the HalDev and HalFunc back to the caller */ -+ -+ *pHalDev = HalDev; -+ *pHalFunc = HalFunc; -+ -+ HalDev->State = enConnected; /* Initialize the hardware state */ -+ -+ if (HalDev->debug) HalDev->OsFunc->Printf("halCpmacInitModule: Leave\n"); -+ return(0); -+ } -+ -+int cpmacRandomRange(HAL_DEVICE *HalDev, int min, int max) -+{ -+ int iTmp; -+ iTmp = cpmacRandom(HalDev); -+ iTmp %= ((max-min)+1); -+ iTmp += min; -+ return(iTmp); -+} -+ -+int cpmacRandom(HAL_DEVICE *HalDev) -+{ -+ int iTmp; -+ iTmp = CPMAC_BOFFTEST(HalDev->dev_base); -+ iTmp >>= 16; /* get rndnum field */ -+ iTmp &= (0x3FF); /* field is 10 bits wide */ -+ return(iTmp); -+} -diff -urN linux.old/drivers/net/avalanche_cpmac/hcpmac.h linux.dev/drivers/net/avalanche_cpmac/hcpmac.h ---- linux.old/drivers/net/avalanche_cpmac/hcpmac.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/hcpmac.h 2005-07-12 02:48:42.175574000 +0200 -@@ -0,0 +1,383 @@ -+/** @file*********************************************************************** -+ * TNETDxxxx Software Support -+ * Copyright (c) 2002 Texas Instruments Incorporated. All Rights Reserved. -+ * -+ * FILE: -+ * -+ * DESCRIPTION: -+ * This file contains definitions for the HAL EMAC API -+ * -+ * HISTORY: -+ * xxXxx01 Denis 1.00 Original Version created. -+ * 22Jan02 Denis/Mick 1.01 Modified for HAL EMAC API -+ * 24Jan02 Denis/Mick 1.02 Speed Improvements -+ * 28Jan02 Denis/Mick 1.16 Made function calls pointers -+ * 28Jan02 Mick 1.18 Split into separate modules -+ * @author Michael Hanrahan -+ * @version 1.02 -+ * @date 24-Jan-2002 -+ *****************************************************************************/ -+#ifndef _INC_HCPMAC -+#define _INC_HCPMAC -+ -+/** \namespace CPMAC_Version -+This documents version 01.07.04 of the CPMAC CPHAL. -+*/ -+const char *pszVersion_CPMAC="CPMAC 01.07.08 "__DATE__" "__TIME__; -+ -+/* CHECK THESE LOCATIONS */ -+#define TEARDOWN_VAL 0xfffffffc -+#define CB_OFFSET_MASK 0xFFFF0000 -+ -+ -+#define MAX_CHAN 8 -+#define MAX_QUEUE 1 -+ -+typedef struct -+ { -+ bit32 HNext; /*< Hardware's pointer to next buffer descriptor */ -+ bit32 BufPtr; /*< Pointer to the data buffer */ -+ bit32 Off_BLen; /*< Contains buffer offset and buffer length */ -+ bit32 mode; /*< SOP, EOP, Ownership, EOQ, Teardown, Q Starv, Length */ -+ void *Next; -+ void *OsInfo; -+ void *Eop; -+#ifdef __CPHAL_DEBUG -+ bit32 DbgSop; -+ bit32 DbgData; -+ bit32 DbgFraglist; -+#endif -+ }HAL_TCB; -+ -+typedef volatile struct hal_private -+ { -+ bit32 HNext; /*< Hardware's pointer to next buffer descriptor */ -+ bit32 BufPtr; /*< Pointer to the data buffer */ -+ bit32 Off_BLen; /*< Contains buffer offset and buffer length */ -+ bit32 mode; /*< SOP, EOP, Ownership, EOQ, Teardown Complete bits */ -+ void *DatPtr; -+ void *Next; -+ void *OsInfo; -+ void *Eop; -+ }HAL_RCB; -+ -+#define MAX_NEEDS 512 /*MJH+030409*/ -+/* HAL */ -+ -+typedef struct hal_device -+ { -+ OS_DEVICE *OsDev; -+ OS_FUNCTIONS *OsFunc; -+ /*OS_SETUP *OsSetup;*/ /* -GSG 030508 */ -+ int inst; -+ bit32u rxbufseq; -+ -+ -+ bit32 dev_base; -+ bit32 offset; -+ -+ bit32u ResetBase; /* GSG 10/20 */ -+ int ResetBit; -+ void *OsOpen; -+ bit32u IntVec; -+ PHY_DEVICE *PhyDev; -+ bit32u EmacDuplex; -+ bit32u EmacSpeed; -+ bit32u PhyNum; -+ bit32u MLinkMask; -+ bit32u PhyMask; -+ bit32u MdixMask; -+ -+ bit32u Linked; -+ DEVICE_STATE State; -+ unsigned char *MacAddr; -+ HAL_FUNCTIONS *HalFuncPtr; /* GSG 11/20 changed name to match cppi */ -+ HAL_FUNCTIONS *HalFunc; -+/* unsigned int CpuFreq;*/ /*MJH-030402*/ -+ unsigned int MdioConnect; -+ unsigned int HostErr; -+ -+/************************************************************************/ -+/* */ -+/* R E G I S T E R S */ -+/* */ -+/************************************************************************/ -+ -+ bit32u RxMbpEnable; -+ bit32u RxUnicastSet; -+ bit32u RxUnicastClear; -+ bit32u RxMaxLen; -+ bit32u RxFilterLowThresh; -+ bit32u Rx0FlowThresh; -+ bit32u MacControl; -+ bit32u MacStatus; -+ bit32u MacHash1; -+ bit32u MacHash2; -+ -+/************************************************************************/ -+/* */ -+/* O P T I O N S */ -+/* */ -+/************************************************************************/ -+ -+ char *DeviceInfo; -+ bit32u interrupt; -+ -+ -+ bit32u RxPassCrc; -+ bit32u RxCaf; -+ bit32u RxCef; -+ bit32u RxBcast; -+ bit32u RxBcastCh; -+ HAL_RCB *RcbPool[MAX_CHAN]; -+ bit32 RxActQueueCount[MAX_CHAN]; -+ HAL_RCB *RxActQueueHead[MAX_CHAN]; -+ HAL_RCB *RxActQueueTail[MAX_CHAN]; -+ bit32 RxActive[MAX_CHAN]; -+ HAL_TCB *TcbPool[MAX_CHAN][MAX_QUEUE]; -+ bit32 TxActQueueCount[MAX_CHAN][MAX_QUEUE]; -+ HAL_TCB *TxActQueueHead[MAX_CHAN][MAX_QUEUE]; -+ HAL_TCB *TxActQueueTail[MAX_CHAN][MAX_QUEUE]; -+ bit32 TxActive[MAX_CHAN][MAX_QUEUE]; -+ bit32 TxTeardownPending[MAX_CHAN]; -+ bit32 RxTeardownPending[MAX_CHAN]; -+ bit32 ChIsOpen[MAX_CHAN][2]; -+ bit32 ChIsSetup[MAX_CHAN][2]; -+ FRAGLIST *fraglist; -+ char *TcbStart[MAX_CHAN][MAX_QUEUE]; -+ char *RcbStart[MAX_CHAN]; -+ bit32 RcbSize[MAX_CHAN]; -+/* STAT_INFO Stats; */ -+ bit32 Inst; -+ bit32u BuffersServicedMax; -+ CHANNEL_INFO ChData[MAX_CHAN]; -+ bit32u MdioClockFrequency; /*MJH+030402*/ -+ bit32u MdioBusFrequency; /*MJH+030402*/ -+ bit32u CpuFrequency; /*MJH+030402*/ -+ bit32u CpmacFrequency; /*MJH+030403*/ -+ bit32u CpmacSize; /*MJH+030425*/ -+ int debug; -+ bit32u NeedsCount; /*MJH+030409*/ -+ HAL_RECEIVEINFO *Needs[MAX_NEEDS]; /*MJH+030409*/ -+ int MaxFrags; -+ int TxIntThreshold[MAX_CHAN]; /* MJH 040621 NSP Performance Update */ -+ int TxIntThresholdMaster[MAX_CHAN]; /* MJH 040827 NSP Performance Update */ -+ int TxIntDisable; /* MJH 040621 NSP Performance Update */ -+ }HALDEVICE; -+ -+#define STATS_MAX 36 -+ -+#define MACCONTROL_MASK (TX_PTYPE|TX_PACE|TX_FLOW_EN|RX_FLOW_EN|CTRL_LOOPBACK) -+#define RX_MBP_ENABLE_MASK \ -+ (RX_PASS_CRC|RX_QOS_EN|RX_NO_CHAIN| \ -+ RX_CMF_EN|RX_CSF_EN|RX_CEF_EN|RX_CAF_EN|RX_PROM_CH_MASK| \ -+ RX_BROAD_EN|RX_BROAD_CH_MASK|RX_MULT_EN|RX_MULT_CH_MASK) -+ -+ -+#define MBP_UPDATE(Mask, On) \ -+ if(On) HalDev->RxMbpEnable |= Mask; \ -+ else HalDev->RxMbpEnable &= ~Mask -+ -+#define CONTROL_UPDATE(Mask, On) \ -+ if(On) HalDev->MacControl |= Mask; \ -+ else HalDev->MacControl &= ~Mask -+ -+ -+#define UPDATE_TX_PTYPE(Value) CONTROL_UPDATE(TX_PTYPE,Value) -+#define UPDATE_TX_PACE(Value) CONTROL_UPDATE(TX_PACE,Value) -+#define UPDATE_MII_EN(Value) CONTROL_UPDATE(MII_EN,Value) -+#define UPDATE_TX_FLOW_EN(Value) CONTROL_UPDATE(TX_FLOW_EN,Value) -+#define UPDATE_RX_FLOW_EN(Value) CONTROL_UPDATE(RX_FLOW_EN,Value) -+#define UPDATE_CTRL_LOOPBACK(Value) CONTROL_UPDATE(CTRL_LOOPBACK,Value) -+#define UPDATE_FULLDUPLEX(Value) CONTROL_UPDATE(FULLDUPLEX,(Value)) -+ -+#define UPDATE_RX_PASS_CRC(Value) MBP_UPDATE(RX_PASS_CRC, Value) -+#define UPDATE_RX_QOS_EN(Value) MBP_UPDATE(RX_QOS_EN, Value) -+#define UPDATE_RX_NO_CHAIN(Value) MBP_UPDATE(RX_NO_CHAIN, Value) -+#define UPDATE_RX_CMF_EN(Value) MBP_UPDATE(RX_CMF_EN, Value) -+#define UPDATE_RX_CSF_EN(Value) MBP_UPDATE(RX_CSF_EN, Value) -+#define UPDATE_RX_CEF_EN(Value) MBP_UPDATE(RX_CEF_EN, Value) -+#define UPDATE_RX_CAF_EN(Value) MBP_UPDATE(RX_CAF_EN, Value) -+#define UPDATE_RX_BROAD_EN(Value) MBP_UPDATE(RX_BROAD_EN, Value) -+#define UPDATE_RX_MULT_EN(Value) MBP_UPDATE(RX_MULT_EN, Value) -+ -+#define UPDATE_RX_PROM_CH(Value) \ -+ HalDev->RxMbpEnable &= ~RX_PROM_CH_MASK; \ -+ HalDev->RxMbpEnable |= RX_PROM_CH(Value) -+ -+#define UPDATE_RX_BROAD_CH(Value) \ -+ HalDev->RxMbpEnable &= ~RX_BROAD_CH_MASK; \ -+ HalDev->RxMbpEnable |= RX_BROAD_CH(Value) -+ -+#define UPDATE_RX_MULT_CH(Value) \ -+ HalDev->RxMbpEnable &= ~RX_MULT_CH_MASK; \ -+ HalDev->RxMbpEnable |= RX_MULT_CH(Value) -+ -+ -+ -+typedef enum -+ { -+ /* CPMAC */ -+ enCpmacStart=0, -+ enStats0, -+ enStats1, -+ enStats2, -+ enStats3, -+ enStats4, -+ enStatsDump, -+ enStatsClear, -+ enRX_PASS_CRC, -+ enRX_QOS_EN, -+ enRX_NO_CHAIN, -+ enRX_CMF_EN, -+ enRX_CSF_EN, -+ enRX_CEF_EN, -+ enRX_CAF_EN, -+ enRX_PROM_CH, -+ enRX_BROAD_EN, -+ enRX_BROAD_CH, -+ enRX_MULT_EN, -+ enRX_MULT_CH, -+ -+ enTX_PTYPE, -+ enTX_PACE, -+ enMII_EN, -+ enTX_FLOW_EN, -+ enRX_FLOW_EN, -+ enCTRL_LOOPBACK, -+ -+ enRX_MAXLEN, -+ enRX_FILTERLOWTHRESH, -+ enRX0_FLOWTHRESH, -+ enRX_UNICAST_SET, -+ enRX_UNICAST_CLEAR, -+ enMdioConnect, -+ enMAC_ADDR_GET, -+ enTick, -+ enRX_MULTICAST, -+ enRX_MULTI_ALL, -+ enRX_MULTI_SINGLE, -+ enVersion, -+ enCpmacEnd /* Last entry */ -+ }INFO_KEY_CPMAC; -+ -+static const char pszVersion[] = "Version"; -+static const char pszStats0[] = "Stats0"; -+static const char pszStats1[] = "Stats1"; -+static const char pszStats2[] = "Stats2"; -+static const char pszStats3[] = "Stats3"; -+static const char pszStats4[] = "Stats4"; -+static const char pszStatsDump[] = "StatsDump"; -+static const char pszStatsClear[] = "StatsClear"; -+ -+/******************************************************************** -+** -+** RX MBP ENABLE -+** -+********************************************************************/ -+static const char pszRX_PASS_CRC[] = "RX_PASS_CRC"; -+static const char pszRX_QOS_EN[] = "RX_QOS_EN"; -+static const char pszRX_NO_CHAIN[] = "RX_NO_CHAIN"; -+static const char pszRX_CMF_EN[] = "RX_CMF_EN"; -+static const char pszRX_CSF_EN[] = "RX_CSF_EN"; -+static const char pszRX_CEF_EN[] = "RX_CEF_EN"; -+static const char pszRX_CAF_EN[] = "RX_CAF_EN"; -+static const char pszRX_PROM_CH[] = "RX_PROM_CH"; -+static const char pszRX_BROAD_EN[] = "RX_BROAD_EN"; -+static const char pszRX_BROAD_CH[] = "RX_BROAD_CH"; -+static const char pszRX_MULT_EN[] = "RX_MULT_EN"; -+static const char pszRX_MULT_CH[] = "RX_MULT_CH"; -+ -+ -+/******************************************************************** -+** -+** MAC CONTROL -+** -+********************************************************************/ -+static const char pszTX_PTYPE[] = "TX_PTYPE"; -+static const char pszTX_PACE[] = "TX_PACE"; -+static const char pszMII_EN[] = "MII_EN"; -+static const char pszTX_FLOW_EN[] = "TX_FLOW_EN"; -+static const char pszRX_FLOW_EN[] = "RX_FLOW_EN"; -+static const char pszCTRL_LOOPBACK[] = "CTRL_LOOPBACK"; -+ -+static const char pszRX_MAXLEN[] = "RX_MAXLEN"; -+static const char pszRX_FILTERLOWTHRESH[] = "RX_FILTERLOWTHRESH"; -+static const char pszRX0_FLOWTHRESH[] = "RX0_FLOWTHRESH"; -+static const char pszRX_UNICAST_SET[] = "RX_UNICAST_SET"; -+static const char pszRX_UNICAST_CLEAR[] = "RX_UNICAST_CLEAR"; -+static const char pszMdioConnect[] = "MdioConnect"; -+static const char pszMacAddr[] = "MacAddr"; -+static const char pszTick[] = "Tick"; -+ -+/******************************************************************** -+** -+** MULTICAST -+** -+********************************************************************/ -+ -+static const char pszRX_MULTICAST[] = "RX_MULTICAST"; -+static const char pszRX_MULTI_ALL[] = "RX_MULTI_ALL"; -+static const char pszRX_MULTI_SINGLE[] = "RX_MULTI_SINGLE"; -+ -+/* -+static const char* pszGFHN = "GFHN"; -+*/ -+ -+static const CONTROL_KEY KeyCpmac[] = -+ { -+ {"" , enCpmacStart}, -+ {pszStats0 , enStats0}, -+ {pszStats1 , enStats1}, -+ {pszStats2 , enStats2}, -+ {pszStats3 , enStats3}, -+ {pszStats4 , enStats4}, -+ {pszStatsClear , enStatsClear}, -+ {pszStatsDump , enStatsDump}, -+ {pszRX_PASS_CRC , enRX_PASS_CRC}, -+ {pszRX_QOS_EN , enRX_QOS_EN}, -+ {pszRX_NO_CHAIN , enRX_NO_CHAIN}, -+ {pszRX_CMF_EN , enRX_CMF_EN}, -+ {pszRX_CSF_EN , enRX_CSF_EN}, -+ {pszRX_CEF_EN , enRX_CEF_EN}, -+ {pszRX_CAF_EN , enRX_CAF_EN}, -+ {pszRX_PROM_CH , enRX_PROM_CH}, -+ {pszRX_BROAD_EN , enRX_BROAD_EN}, -+ {pszRX_BROAD_CH , enRX_BROAD_CH}, -+ {pszRX_MULT_EN , enRX_MULT_EN}, -+ {pszRX_MULT_CH , enRX_MULT_CH}, -+ -+ {pszTX_PTYPE , enTX_PTYPE}, -+ {pszTX_PACE , enTX_PACE}, -+ {pszMII_EN , enMII_EN}, -+ {pszTX_FLOW_EN , enTX_FLOW_EN}, -+ {pszRX_FLOW_EN , enRX_FLOW_EN}, -+ {pszCTRL_LOOPBACK , enCTRL_LOOPBACK}, -+ {pszRX_MAXLEN , enRX_MAXLEN}, -+ {pszRX_FILTERLOWTHRESH , enRX_FILTERLOWTHRESH}, -+ {pszRX0_FLOWTHRESH , enRX0_FLOWTHRESH}, -+ {pszRX_UNICAST_SET , enRX_UNICAST_SET}, -+ {pszRX_UNICAST_CLEAR , enRX_UNICAST_CLEAR}, -+ {pszMdioConnect , enMdioConnect}, -+ {pszRX_MULTICAST , enRX_MULTICAST}, -+ {pszRX_MULTI_ALL , enRX_MULTI_ALL}, -+ {pszRX_MULTI_SINGLE , enRX_MULTI_SINGLE}, -+ {pszTick , enTick}, -+ {pszVersion , enVersion}, -+ {"" , enCpmacEnd} -+ }; -+ -+const char hcCpuFrequency[] = "CpuFreq"; -+const char hcCpmacFrequency[] = "CpmacFrequency"; -+const char hcMdioBusFrequency[] = "MdioBusFrequency"; -+const char hcMdioClockFrequency[] = "MdioClockFrequency"; -+const char hcCpmacBase[] = "CpmacBase"; -+const char hcPhyNum[] = "PhyNum"; -+const char hcSize[] = "size"; -+const char hcCpmacSize[] = "CpmacSize"; -+const char hcPhyAccess[] = "PhyAccess"; -+const char hcLinked[] = "Linked"; -+const char hcFullDuplex[] = "FullDuplex"; -+const char hcMdixMask[] = "MdixMask"; -+const char hcMdioMdixSwitch[] = "MdixSet"; -+#endif -diff -urN linux.old/drivers/net/avalanche_cpmac/Makefile linux.dev/drivers/net/avalanche_cpmac/Makefile ---- linux.old/drivers/net/avalanche_cpmac/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/Makefile 2005-07-12 02:48:42.175574000 +0200 -@@ -0,0 +1,26 @@ -+# File: drivers/net/avalanche_cpmac/Makefile -+# -+# Makefile for the Linux network (CPMAC) device drivers. -+# -+ -+O_TARGET := avalanche_cpmac.o -+ -+ -+list-multi := avalanche_cpmac.o -+obj-$(CONFIG_MIPS_AVALANCHE_CPMAC) := avalanche_cpmac.o -+ -+avalanche_cpmac-objs += cpmac.o cpmacHalLx.o hcpmac.o \ -+ psp_config_build.o psp_config_mgr.o \ -+ psp_config_parse.o psp_config_util.o -+ -+ -+include $(TOPDIR)/Rules.make -+ -+ -+avalanche_cpmac.o: $(avalanche_cpmac-objs) -+ $(LD) -r -o $@ $(avalanche_cpmac-objs) -+ -+ -+ -+clean: -+ rm -f core *.o *.a *.s -diff -urN linux.old/drivers/net/avalanche_cpmac/mdio_reg.h linux.dev/drivers/net/avalanche_cpmac/mdio_reg.h ---- linux.old/drivers/net/avalanche_cpmac/mdio_reg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/mdio_reg.h 2005-07-12 02:48:42.176573000 +0200 -@@ -0,0 +1,121 @@ -+/**************************************************************************** -+** TNETD53xx Software Support -+** Copyright(c) 2002, Texas Instruments Incorporated. All Rights Reserved. -+** -+** FILE: mdio_reg.h Register definitions for the VBUS MII module -+** -+** DESCRIPTION: -+** This include file contains register definitions for the -+** VBUS MII module. -+** -+** HISTORY: -+** 27Mar02 Michael Hanrahan Original (modified from emacmdio.h) -+** 01Apr02 Michael Hanrahan Modified to include all regs. in spec -+** 03Apr02 Michael Hanrahan Updated to Version 0.6 of spec -+** 05Apr02 Michael Hanrahan Moved Phy Mode values into here -+** 30Apr02 Michael Hanrahan Updated to Version 0.8 of spec -+** 30Apr02 Michael Hanrahan Updated to recommended format -+** 10May02 Michael Hanrahan Updated to Version 0.9 of spec -+*****************************************************************************/ -+#ifndef _INC_MDIO_REG -+#define _INC_MDIO_REG -+ -+/*************************************************************************** -+** -+** M D I O M E M O R Y M A P -+** -+***************************************************************************/ -+ -+ -+#define pMDIO_VER(base) ((volatile bit32u *)(base+0x00)) -+#define pMDIO_CONTROL(base) ((volatile bit32u *)(base+0x04)) -+#define pMDIO_ALIVE(base) ((volatile bit32u *)(base+0x08)) -+#define pMDIO_LINK(base) ((volatile bit32u *)(base+0x0C)) -+#define pMDIO_LINKINTRAW(base) ((volatile bit32u *)(base+0x10)) -+#define pMDIO_LINKINTMASKED(base) ((volatile bit32u *)(base+0x14)) -+#define pMDIO_USERINTRAW(base) ((volatile bit32u *)(base+0x20)) -+#define pMDIO_USERINTMASKED(base) ((volatile bit32u *)(base+0x24)) -+#define pMDIO_USERINTMASKED_SET(base) ((volatile bit32u *)(base+0x28)) -+#define pMDIO_USERINTMASKED_CLR(base) ((volatile bit32u *)(base+0x2C)) -+#define pMDIO_USERACCESS(base, channel) ((volatile bit32u *)(base+(0x80+(channel*8)))) -+#define pMDIO_USERPHYSEL(base, channel) ((volatile bit32u *)(base+(0x84+(channel*8)))) -+ -+ -+/*************************************************************************** -+** -+** M D I O R E G I S T E R A C C E S S M A C R O S -+** -+***************************************************************************/ -+ -+ -+#define MDIO_ALIVE(base) (*(pMDIO_ALIVE(base))) -+#define MDIO_CONTROL(base) (*(pMDIO_CONTROL(base))) -+#define MDIO_CONTROL_IDLE (1 << 31) -+#define MDIO_CONTROL_ENABLE (1 << 30) -+#define MDIO_CONTROL_PREAMBLE (1 << 20) -+#define MDIO_CONTROL_FAULT (1 << 19) -+#define MDIO_CONTROL_FAULT_DETECT_ENABLE (1 << 18) -+#define MDIO_CONTROL_INT_TEST_ENABLE (1 << 17) -+#define MDIO_CONTROL_HIGHEST_USER_CHANNEL (0x1F << 8) -+#define MDIO_CONTROL_CLKDIV (0xFF) -+#define MDIO_LINK(base) (*(pMDIO_LINK(base))) -+#define MDIO_LINKINTRAW(base) (*(pMDIO_LINKINTRAW(base))) -+#define MDIO_LINKINTMASKED(base) (*(pMDIO_LINKINTMASKED(base))) -+#define MDIO_USERINTRAW(base) (*(pMDIO_USERINTRAW(base))) -+#define MDIO_USERINTMASKED(base) (*(pMDIO_USERINTMASKED(base))) -+#define MDIO_USERINTMASKED_CLR(base) (*(pMDIO_USERINTMASKED_CLR(base))) -+#define MDIO_USERINTMASKED_SET(base) (*(pMDIO_USERINTMASKED_SET(base))) -+#define MDIO_USERINTRAW(base) (*(pMDIO_USERINTRAW(base))) -+#define MDIO_USERACCESS(base, channel) (*(pMDIO_USERACCESS(base, channel))) -+#define MDIO_USERACCESS_GO (1 << 31) -+#define MDIO_USERACCESS_WRITE (1 << 30) -+#define MDIO_USERACCESS_READ (0 << 30) -+#define MDIO_USERACCESS_ACK (1 << 29) -+#define MDIO_USERACCESS_REGADR (0x1F << 21) -+#define MDIO_USERACCESS_PHYADR (0x1F << 16) -+#define MDIO_USERACCESS_DATA (0xFFFF) -+#define MDIO_USERPHYSEL(base, channel) (*(pMDIO_USERPHYSEL(base, channel))) -+#define MDIO_USERPHYSEL_LINKSEL (1 << 7) -+#define MDIO_USERPHYSEL_LINKINT_ENABLE (1 << 6) -+#define MDIO_USERPHYSEL_PHYADR_MON (0x1F) -+#define MDIO_VER(base) (*(pMDIO_VER(base))) -+#define MDIO_VER_MODID (0xFFFF << 16) -+#define MDIO_VER_REVMAJ (0xFF << 8) -+#define MDIO_VER_REVMIN (0xFF) -+ -+ -+ -+ -+/****************************************************************************/ -+/* */ -+/* P H Y R E G I S T E R D E F I N I T I O N S */ -+/* */ -+/****************************************************************************/ -+ -+ -+#define PHY_CONTROL_REG 0 -+ #define PHY_RESET (1<<15) -+ #define PHY_LOOP (1<<14) -+ #define PHY_100 (1<<13) -+ #define AUTO_NEGOTIATE_EN (1<<12) -+ #define PHY_PDOWN (1<<11) -+ #define PHY_ISOLATE (1<<10) -+ #define RENEGOTIATE (1<<9) -+ #define PHY_FD (1<<8) -+ -+#define PHY_STATUS_REG 1 -+ #define NWAY_COMPLETE (1<<5) -+ #define NWAY_CAPABLE (1<<3) -+ #define PHY_LINKED (1<<2) -+ -+#define NWAY_ADVERTIZE_REG 4 -+#define NWAY_REMADVERTISE_REG 5 -+ #define NWAY_FD100 (1<<8) -+ #define NWAY_HD100 (1<<7) -+ #define NWAY_FD10 (1<<6) -+ #define NWAY_HD10 (1<<5) -+ #define NWAY_SEL (1<<0) -+ #define NWAY_AUTO (1<<0) -+ -+ -+#endif _INC_MDIO_REG -diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_build.c linux.dev/drivers/net/avalanche_cpmac/psp_config_build.c ---- linux.old/drivers/net/avalanche_cpmac/psp_config_build.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/psp_config_build.c 2005-07-12 02:48:42.176573000 +0200 -@@ -0,0 +1,335 @@ -+/****************************************************************************** -+ * FILE PURPOSE: PSP Config Manager - Configuration Build Source -+ ****************************************************************************** -+ * FILE NAME: psp_config_build.c -+ * -+ * DESCRIPTION: Configuration Build API Implementation -+ * -+ * REVISION HISTORY: -+ * 27 Nov 02 - PSP TII -+ * -+ * (C) Copyright 2002, Texas Instruments, Inc -+ *******************************************************************************/ -+ -+#ifdef INCLUDE_FFS -+#include "ffs.h" -+#endif /* INCLUDE_FFS */ -+ -+#include "psp_config_mgr.h" -+#include "psp_config_build.h" -+#include "psp_config_util.h" -+ -+#define MAX_DEVICE_NAME_LEN 16 -+#define MAX_DEVICE_STR_LEN 512 -+ -+#ifndef NULL -+#define NULL (char *)0 -+#endif -+ -+#include <asm/ar7/sangam.h> -+#include <linux/slab.h> -+#include <linux/config.h> -+ -+ -+#define os_malloc(size) kmalloc(size, GFP_KERNEL) -+ -+int psp_run_enumerator(void) -+{ -+ return(0); -+} -+ -+#if defined (CONFIG_AVALANCHE_CPMAC_AUTO) -+ -+static int auto_detect_cpmac_phy(void) -+{ -+ -+#define SELECT_INT_PHY_MAC 0 -+#define SELECT_EXT_PHY_MAC 1 -+ -+ volatile unsigned long *reset_cntl = AVALANCHE_RESET_CONTROL_BASE, *mdio_cntl = ((int)AVALANCHE_MDIO_BASE + 0x4); -+ unsigned int j= 0, detected_phy_map = 0, auto_select = SELECT_INT_PHY_MAC; -+ -+ *reset_cntl |= (1 << AVALANCHE_MDIO_RESET_BIT) | (1 << AVALANCHE_LOW_CPMAC_RESET_BIT) | (1 << AVALANCHE_HIGH_CPMAC_RESET_BIT) | (1 << AVALANCHE_LOW_EPHY_RESET_BIT); -+ *mdio_cntl = (1 << 30) | ((CONFIG_AR7_SYS * 1000)/2200); -+ -+ for(j=0;j < 300000; j++) -+ { -+ if(j%100000) continue; -+ -+ detected_phy_map = *(mdio_cntl + 1); -+ if(detected_phy_map) -+ { -+ detected_phy_map &= ~AVALANCHE_LOW_CPMAC_PHY_MASK; -+ -+ if(detected_phy_map && !(detected_phy_map & (detected_phy_map - 1))) -+ { -+ auto_select = SELECT_EXT_PHY_MAC; -+ break; -+ } -+ } -+ } -+ -+ return(auto_select); -+ -+} -+ -+#endif -+ -+ -+#ifndef AVALANCHE_LOW_CPMAC_MDIX_MASK -+#define AVALANCHE_LOW_CPMAC_MDIX_MASK 0 -+#endif -+ -+void psp_load_default_static_cfg(void) -+{ -+ char s2[100], s3[100]; -+ char s4[2000], s6[2000]; -+ int threshold = 20; -+ char *tx_threshold_ptr = prom_getenv("threshold"); -+ -+ if(tx_threshold_ptr) -+ threshold = simple_strtol(tx_threshold_ptr, (char **)NULL, 10); -+ -+ /* Static configuration if options.conf not present */ -+ sprintf(s3,"cpmdio(id=mii, base=%u, reset_bit=%d)", AVALANCHE_MDIO_BASE, 22); -+ sprintf(s2, "reset( id=[ResetRegister], base=%u)", AVALANCHE_RESET_CONTROL_BASE); -+ -+ sprintf(s4, "cpmac(id=[cpmac], unit=0, base=%u, size=0x800, reset_bit=%d, PhyMask=%u, MdixMask=%u, MLink=0, int_line=%d, memory_offset=0, RX_CAF=1, RX_PASSCRC=0, RX_CEF=1, RX_BCAST=0, RX_BCASTCH=0, Ch0=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128], Ch1=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128], Ch2=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128])", AVALANCHE_LOW_CPMAC_BASE, AVALANCHE_LOW_CPMAC_RESET_BIT, AVALANCHE_LOW_CPMAC_PHY_MASK, AVALANCHE_LOW_CPMAC_MDIX_MASK, AVALANCHE_LOW_CPMAC_INT,threshold,threshold,threshold); -+ -+ sprintf(s6, "cpmac(id=[cpmac], unit=1, base=%u, size=0x800, reset_bit=%d, PhyMask=%u, MLink=0, int_line=%d, memory_offset=0, RX_CAF=1, RX_PASSCRC=0, RX_CEF=1, RX_BCAST=0, RX_BCASTCH=0, Ch0=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128], Ch1=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128], Ch2=[TxNumBuffers=256, TxNumQueues=1, TxServiceMax=%d, RxNumBuffers=256, RxBufferOffset=0, RxBufSize=1000, RxServiceMax=128])", AVALANCHE_HIGH_CPMAC_BASE, AVALANCHE_HIGH_CPMAC_RESET_BIT, AVALANCHE_HIGH_CPMAC_PHY_MASK, AVALANCHE_HIGH_CPMAC_INT,threshold,threshold,threshold); -+ -+ psp_config_add("reset", s2, psp_config_strlen(s2), en_compile); -+ -+ -+#if defined (CONFIG_AVALANCHE_LOW_CPMAC) -+ -+ psp_config_add("cpmdio", s3, psp_config_strlen(s3), en_compile); -+ psp_config_add("cpmac", s4, psp_config_strlen(s4), en_compile); -+ -+#endif -+ -+ -+#if defined (CONFIG_AVALANCHE_HIGH_CPMAC) -+ -+ psp_config_add("cpmdio", s3, psp_config_strlen(s3), en_compile); -+ psp_config_add("cpmac", s6, psp_config_strlen(s6), en_compile); -+ -+#endif -+ -+#if defined (CONFIG_AVALANCHE_CPMAC_AUTO) -+ { -+ char *phy_sel_ptr = prom_getenv("mac_phy_sel"); -+ int phy_sel = SELECT_EXT_PHY_MAC; -+ char *mac_port = prom_getenv("MAC_PORT"); /* Internal: 0, External: 1 */ -+ -+ if(phy_sel_ptr && (0 == strcmp(phy_sel_ptr, "int"))) -+ { -+ phy_sel = SELECT_INT_PHY_MAC; -+ } -+ -+ //if(phy_sel == auto_detect_cpmac_phy()) -+ if(!mac_port || 0 == strcmp(mac_port, "1")) -+ { -+ printk("Using the MAC with external PHY\n"); -+ psp_config_add("cpmdio", s3, psp_config_strlen(s3), en_compile); -+ psp_config_add("cpmac", s6, psp_config_strlen(s6), en_compile); -+ } -+ else -+ { -+ printk("Using the MAC with internal PHY\n"); -+ psp_config_add("cpmdio", s3, psp_config_strlen(s3), en_compile); -+ psp_config_add("cpmac", s4, psp_config_strlen(s4), en_compile); -+ } -+ } -+ -+#endif -+ -+} -+ -+char* psp_conf_read_file(char *p_file_name) -+{ -+#ifdef INCLUDE_FFS -+ -+ char *p_file_data = NULL; -+ unsigned int file_size; -+ FFS_FILE *p_file = NULL; -+ -+ if(p_file_name == NULL) -+ { -+ return (NULL); -+ } -+ -+ if(!(p_file = ffs_fopen(p_file_name, "r"))) -+ { -+ return(NULL); -+ } -+ -+ file_size = p_file->_AvailableBytes; -+ -+ p_file_data = os_malloc(file_size + 1); -+ -+ if(ffs_fread(p_file_data, file_size, 1, p_file) == 0) -+ { -+ kfree(p_file_data); -+ return(NULL); -+ } -+ -+ ffs_fclose(p_file); -+ -+ p_file_data[file_size] = '\0'; -+ -+ return(p_file_data); -+ -+#else /* NO FFS */ -+ return(NULL); -+#endif /* INCLUDE_FFS */ -+} -+ -+int psp_conf_get_line(char *p_in_data, char **next_line) -+{ -+ char *p = p_in_data; -+ -+ while(*p && *p++ != '\n') -+ { -+ -+ } -+ -+ *next_line = p; -+ -+ return(p - 1 - p_in_data); -+} -+ -+ -+int psp_conf_is_data_line(char *line) -+{ -+ int ret_val = 1; -+ -+ if(*line == '\0' || *line == '\n' || *line == '#') -+ ret_val = 0; -+ -+ return(ret_val); -+} -+ -+int psp_conf_get_key_size(char *data) -+{ -+ char *p = data; -+ -+ while(*p && *p != '\n' && *p != '(' && *p != ' ') -+ p++; -+ -+ return(p - data); -+} -+ -+char* psp_conf_eat_white_spaces(char *p) -+{ -+ while(*p && *p != '\n' && *p == ' ') -+ p++; -+ -+ return (p); -+} -+ -+int psp_build_from_opt_conf(void) -+{ -+ char *data = NULL; -+ char *data_hold = NULL; -+ char *next_line = NULL; -+ int line_size = 0; -+ -+ if((data = psp_conf_read_file("/etc/options.conf")) == NULL) -+ return(-1); -+ -+ data_hold = data; -+ -+ while((line_size=psp_conf_get_line(data, &next_line)) != -1) -+ { -+ -+ char *name = NULL; -+ int name_size; -+ -+ data = psp_conf_eat_white_spaces(data); -+ -+ if(psp_conf_is_data_line(data)) -+ { -+ data[line_size] = '\0'; -+ -+ name_size = psp_conf_get_key_size(data); -+ -+ if(name_size > 0) -+ { -+ name = (char *) os_malloc(name_size + 1); -+ if(name == NULL) break; -+ -+ psp_config_memcpy(name, data, name_size); -+ name[name_size] = '\0'; -+ -+ psp_config_add(name, data, line_size, en_opt_conf); -+ -+ kfree(name); -+ } -+ -+ data[line_size] = '\n'; -+ } -+ -+ data = next_line; -+ } -+ -+ kfree(data_hold); -+ return (0); -+} -+ -+ -+int psp_write_conf_file(char *p_write_file, char * dev_cfg_string) -+{ -+#ifdef INCLUDE_FFS -+ int bytes_written=0; -+ FFS_FILE *file_ptr=NULL; -+ -+ /* -+ * NOTE: In current implementation of FFS in ADAM2 if the file exists beforehand, it -+ * can't be opened for write. -+ */ -+ if(!(file_ptr=ffs_fopen(p_write_file, "w"))) { -+ return(-1); -+ } -+ -+ /* Write into the file "output.con" the character string */ -+ /* write a \n before a writing a line */ -+ if(!(bytes_written = ffs_fwrite("\n", 1, sizeof(char), file_ptr))) { -+ return (-1); -+ } -+ -+ if(!(bytes_written = ffs_fwrite(dev_cfg_string, psp_config_strlen(dev_cfg_string), sizeof(char), file_ptr))) { -+ return (-1); -+ } -+ ffs_fclose(file_ptr); -+ return (bytes_written+1); -+#else /* NO FFS */ -+ return(-1); -+#endif /* INCLUDE_FFS */ -+} -+ -+void build_psp_config(void) -+{ -+ -+ /* initialize the repository. */ -+ psp_config_init(); -+ -+#ifdef INCLUDE_FFS -+ ffs_init(); -+#endif /* INCLUDE_FFS */ -+ -+ /* read the configuration from the options.conf to override default ones */ -+ psp_build_from_opt_conf(); -+ -+ /* read the configuration which were not over ridden in options.conf */ -+ psp_load_default_static_cfg(); -+ -+ /* let the vlynq be enumerated. Enumerator will add cfg info -+ of the discovered device instances to the repository.*/ -+ psp_run_enumerator(); -+ -+ /* dump the repository*/ -+ dump_device_cfg_pool(); -+ -+} -+ -diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_build.h linux.dev/drivers/net/avalanche_cpmac/psp_config_build.h ---- linux.old/drivers/net/avalanche_cpmac/psp_config_build.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/psp_config_build.h 2005-07-12 02:48:42.176573000 +0200 -@@ -0,0 +1,138 @@ -+/****************************************************************************** -+ * FILE PURPOSE: PSP Config Manager - Configuration Build Header -+ ****************************************************************************** -+ * FILE NAME: psp_config_build.h -+ * -+ * DESCRIPTION: Configuration Build API's. -+ * -+ * REVISION HISTORY: -+ * 27 Nov 02 - PSP TII -+ * -+ * (C) Copyright 2002, Texas Instruments, Inc -+ *******************************************************************************/ -+ -+#ifndef __PSP_CONF_BUILD_H__ -+#define __PSP_CONF_BUILD_H__ -+ -+/*------------------------------------------------------------------------------ -+ * Name: psp_conf_read_file -+ * -+ * Parameters: -+ * in: p_file_name - the name of the file to read from. -+ * -+ * Description: -+ * Reads the entire file in one shot. This function opens the -+ * file, determines the size of the data to be read, allocates -+ * the required memory, NULL terminates the data and closes the -+ * file. -+ * -+ * It is responsibily of the callee to free the memory after it is -+ * done with that data. -+ * -+ * -+ * Returns: -+ * A NULL pointer, if failed to read the data otherwise, a valid -+ * pointer referring to the data read from the file. -+ * -+ * Example: -+ * -+ * psp_conf_read_file("/etc/options.conf"); -+ *---------------------------------------------------------------------------*/ -+ char *psp_conf_read_file(char *p_file_name); -+ -+ /*---------------------------------------------------------------------------- -+ * Function : psp_conf_write_file -+ * -+ * Parameters: -+ * in: p_file_name - the file to which data is to be written. -+ * in: data - the NULL terminated data string. -+ * -+ * Description: -+ * Write the indicated data into the file. This function opens the file, -+ * appends the data to end of the file, closes the file. -+ * -+ * Returns: -+ * -+ * The number of bytes on success. -+ * 0 on failure. -+ * -+ * Example: -+ * -+ * psp_conf_write_file("/etc/outcon.conf", data); -+ *--------------------------------------------------------------------------*/ -+ int psp_conf_write_file(char *p_file_name, char *data); -+ -+ /*---------------------------------------------------------------------------- -+ * Function: psp_conf_get_line -+ * -+ * Parameters: -+ * in: data - the data from which the line is to identified. -+ * out: next_line - the pointer to start of the next line. -+ * -+ * Description: -+ * Expects the data to be '\n' separated segments and data is NULL -+ * terminated. Parses the given data for '\n' or '\0'. Provides a pointer -+ * to the start of next line in the next_line. -+ * -+ * Returns: -+ * -1 on error. -+ * 0 or more to indicate the number of bytes in the line starting at -+ * data. -+ *--------------------------------------------------------------------------*/ -+ int psp_get_conf_line(char *p_in_data, char **next_line); -+ -+ /*---------------------------------------------------------------------------- -+ * Function: psp_conf_is_data_line -+ * -+ * Parameters: -+ * in: line - the array of bytes. -+ * -+ * Description: -+ * Tests the first byte in the array for '\0' or '\n' or '#'. Lines -+ * starting with these characters are not considered data. -+ * -+ * Returns: -+ * 1 if the line has data. -+ * 0 otherwise. -+ * -+ *--------------------------------------------------------------------------*/ -+ int psp_conf_is_data_line(char *line); -+ -+ /*---------------------------------------------------------------------------- -+ * Function: psp_conf_eat_white_spaces -+ * -+ * Parameters: -+ * in: line - the array of bytes. -+ * -+ * Description: -+ * Eats white spaces at the begining of the line while looking out for -+ * '\0' or '\n' or ' '. -+ * -+ * Returns: -+ * Pointer to the begining of the non white space character. -+ * NULL if '\0' or '\n' is found. -+ * -+ *--------------------------------------------------------------------------*/ -+ char *psp_conf_eat_white_spaces(char *line); -+ -+ /*--------------------------------------------------------------------------- -+ * Function: psp_conf_get_key_size -+ * -+ * Parameters: -+ * in: line - the array of bytes. -+ * -+ * Description: -+ * Identifies the size of the 'key' in array formatted as -+ * key(id=[key1]....). This function also checks out for '\0' and '\n'. -+ * -+ * Returns: -+ * On success, The number of bytes that forms the key. -+ * 0 otherwise. -+ * -+ *-------------------------------------------------------------------------*/ -+ int psp_conf_get_key_size(char *line); -+ -+ -+ -+#endif /* __PSP_CONF_BUILD_H__ */ -+ -diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_mgr.c linux.dev/drivers/net/avalanche_cpmac/psp_config_mgr.c ---- linux.old/drivers/net/avalanche_cpmac/psp_config_mgr.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/psp_config_mgr.c 2005-07-12 02:48:42.177573000 +0200 -@@ -0,0 +1,464 @@ -+/****************************************************************************** -+ * FILE PURPOSE: PSP Config Manager Source -+ ****************************************************************************** -+ * FILE NAME: psp_config_mgr.c -+ * -+ * DESCRIPTION: -+ * -+ * Manages configuration information. The repository is managed on the basis of -+ * <key, info> pair. It is possible to have multiple occurrence of the same key. -+ * Multiple occurences of the same keys are referred to as 'instances'. -+ * 'instances' are assigned in the order of configuration arrival. The first -+ * config for a 'key' added to the repository would be treated as instance 0 and -+ * next config to arrive for the same key would be treated as instance '1' and -+ * so on. -+ * -+ * Info is retrieved from the repository based on the 'key' and 'instance' value. -+ * -+ * No assumption is made about the format of the information that is put in the -+ * repository. The only requirement is that 'key' should be NULL terminated -+ * string. -+ * -+ * REVISION HISTORY: -+ * 27 Nov 02 - PSP TII -+ * -+ * (C) Copyright 2002, Texas Instruments, Inc -+ *******************************************************************************/ -+ -+//#include <stdio.h> -+//#include <stdlib.h> -+#include "psp_config_mgr.h" -+#include "psp_config_util.h" -+ -+#include <linux/slab.h> -+ -+/*----------------------------------------------------------- -+ Implemented elsewhere -+ -----------------------------------------------------------*/ -+extern int sys_read_options_conf(void); -+extern int sys_write_options_conf(char *cfg_info); -+extern int sys_load_default_static_cfg(void); -+extern int sys_run_enumerator(void); -+ -+#define os_malloc(size) kmalloc(size, GFP_KERNEL) -+ -+/*--------------------------------------------------------- -+ * Data structures. -+ *--------------------------------------------------------*/ -+struct device_cfg_data; -+ -+typedef struct device_instance_cfg_data -+{ -+ struct device_instance_cfg_data *next; -+ char locale[100]; -+ unsigned int data_size; -+ char *data; -+ -+} DEV_INSTANCE_CFG_DATA_T; -+ -+struct device_cfg_collection; -+ -+typedef struct device_cfg_collection -+{ -+ struct device_cfg_collection *next; -+ char *device_name; -+ CFG_TYPE_T cfg_type; -+ int count; -+ DEV_INSTANCE_CFG_DATA_T *dev_inst_list_begin; -+ DEV_INSTANCE_CFG_DATA_T *dev_inst_list_end; -+} DEVICE_CFG_T; -+ -+ -+typedef struct device_cfg_list -+{ -+ DEVICE_CFG_T *device_cfg_begin; -+ int count; -+} DEVICE_CFG_LIST_T; -+ -+/*----------------------------------------------------------------------------- -+ * Functions used locally with in the file. -+ *---------------------------------------------------------------------------*/ -+static void p_init_device_cfg_list(void); -+static int p_add_instance_cfg_data(DEVICE_CFG_T *p_dev_cfg, -+ DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data); -+static DEVICE_CFG_T* p_create_dev_cfg(char *device_name); -+static DEVICE_CFG_T* p_get_dev_cfg(char *device_name); -+static int p_set_device_cfg_type(DEVICE_CFG_T *p_dev_cfg, -+ CFG_TYPE_T cfg_type); -+ -+/* PSP Config manager debug */ -+#define PSP_CFG_MGR_DEBUG 0 -+ -+#define dbgPrint if (PSP_CFG_MGR_DEBUG) printk -+ -+/*----------------------------------------------------------------------------- -+ * The repository. -+ *---------------------------------------------------------------------------*/ -+static DEVICE_CFG_LIST_T g_device_cfg_list; -+ -+/*--------------------------------------------- -+ * Initialize the device collection pool. -+ *--------------------------------------------*/ -+void p_init_device_cfg_list(void) -+{ -+ g_device_cfg_list.count = 0; -+ g_device_cfg_list.device_cfg_begin = NULL; -+} -+ -+/*---------------------------------------------------------------------- -+ * Add the device cfg into the device linked list. -+ *---------------------------------------------------------------------*/ -+int p_add_dev_cfg_to_list(DEVICE_CFG_LIST_T *p_dev_list, -+ DEVICE_CFG_T *p_dev_cfg) -+{ -+ if(p_dev_list->count != 0) -+ p_dev_cfg->next = p_dev_list->device_cfg_begin; -+ -+ p_dev_list->device_cfg_begin = p_dev_cfg; -+ -+ p_dev_list->count++; -+ -+ return (0); -+} -+ -+/*------------------------------------------------------------------ -+ * Add the cfg data into the cfg data linked list of the collection. -+ *------------------------------------------------------------------*/ -+int p_add_instance_cfg_data(DEVICE_CFG_T *p_dev_cfg, -+ DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data) -+{ -+ if(p_dev_cfg->count == 0) -+ p_dev_cfg->dev_inst_list_begin = p_dev_inst_data; -+ else -+ p_dev_cfg->dev_inst_list_end->next = p_dev_inst_data; -+ -+ p_dev_cfg->dev_inst_list_end = p_dev_inst_data; -+ -+ p_dev_cfg->count++; -+ -+ return (0); -+} -+ -+/*----------------------------------------------------------------------------- -+ * Create the device cfg. -+ *---------------------------------------------------------------------------*/ -+DEVICE_CFG_T *p_create_dev_cfg(char *device_name) -+{ -+ DEVICE_CFG_T *p_dev_cfg = NULL; -+ -+ if((p_dev_cfg = os_malloc(sizeof(DEVICE_CFG_T))) == NULL) -+ { -+ dbgPrint("Failed to allocate memory for DEVICE_CFG_T.\n"); -+ } -+ else if((p_dev_cfg->device_name = os_malloc(psp_config_strlen(device_name) + 1))==NULL) -+ { -+ dbgPrint("Failed to allocate memory for device name.\n"); -+ } -+ else -+ { -+ psp_config_strcpy(p_dev_cfg->device_name, device_name); -+ p_dev_cfg->cfg_type = en_raw; -+ p_dev_cfg->count = 0; -+ p_dev_cfg->dev_inst_list_begin = NULL; -+ p_dev_cfg->dev_inst_list_end = NULL; -+ p_dev_cfg->next = NULL; -+ } -+ -+ return(p_dev_cfg); -+} -+ -+/*------------------------------------------------------------------------------ -+ * Get the device cfg collection. -+ *-----------------------------------------------------------------------------*/ -+DEVICE_CFG_T *p_get_dev_cfg(char *device_name) -+{ -+ int count = 0; -+ DEVICE_CFG_T *p_dev_cfg = g_device_cfg_list.device_cfg_begin; -+ -+ for(count=0; count < g_device_cfg_list.count; count++) -+ { -+ if(psp_config_strcmp(device_name, p_dev_cfg->device_name) == 0) -+ { -+ break; -+ } -+ -+ p_dev_cfg = p_dev_cfg->next; -+ } -+ -+ return(p_dev_cfg); -+} -+ -+/*------------------------------------------------------------------------- -+ * Gets the name for the static cfg type. Utility function. Debug purposes. -+ *-------------------------------------------------------------------------*/ -+char *p_get_cfg_type_name_for_en(CFG_TYPE_T cfg_type) -+{ -+ static char raw_str [] = "still raw"; -+ static char compile_str [] = "configured at compile time"; -+ static char optconf_str [] = "configured by options.conf"; -+ static char vlynq_str [] = "configured by VLYNQ"; -+ static char no_static_str[] = "no static configuration"; -+ -+ if(cfg_type == en_raw) -+ return (raw_str); -+ else if(cfg_type == en_compile) -+ return (compile_str); -+ else if(cfg_type == en_opt_conf) -+ return (optconf_str); -+ else if(cfg_type == en_vlynq) -+ return (vlynq_str); -+ else -+ return (no_static_str); -+ -+} -+ -+/*----------------------------------------------------------------------------- -+ * Sets the static cfg status of the device collection. -+ * -+ * If the collection is en_virgin then, the collection is assigned to cfg_type. -+ * If the cfg_type is en_vlynq then, the old cfg_type is retained. -+ * en_compile and en_opt_conf are mutually exclusive. One of these can be -+ * accomodated. -+ * -+ *---------------------------------------------------------------------------*/ -+int p_set_device_cfg_type(DEVICE_CFG_T *p_dev_cfg, -+ CFG_TYPE_T cfg_type) -+{ -+ int ret_val = 0; -+ -+ if(p_dev_cfg->cfg_type == en_raw) -+ p_dev_cfg->cfg_type = cfg_type; -+ else if((cfg_type == en_vlynq) || (p_dev_cfg->cfg_type == cfg_type)) -+ ; -+ else -+ { -+ dbgPrint("Device %s has been %s which overrides %s.\n", -+ p_dev_cfg->device_name, -+ p_get_cfg_type_name_for_en(p_dev_cfg->cfg_type), -+ p_get_cfg_type_name_for_en(cfg_type)); -+ ret_val = -1; -+ } -+ -+ return(ret_val); -+} -+ -+/*------------------------------------------------------------------------ -+ * Add the config str into the repository. The cfg type indicates -+ * whether the device has been configured statically, from options.conf or -+ * by vlynq enumeration. -+ *------------------------------------------------------------------------*/ -+int psp_config_add(char *key, void *p_cfg_str, unsigned int cfg_len, -+ CFG_TYPE_T cfg_type) -+{ -+ int ret_val = -1; -+ DEVICE_CFG_T *p_dev_cfg = NULL; -+ DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data = NULL; -+ -+ if(p_cfg_str == NULL || key == NULL) -+ { -+ dbgPrint("Null input pointer(s).\n"); -+ } -+ /* check if there exist a dev_cfg for the given key, if not, -+ then create one and add it to the device list. */ -+ else if(((p_dev_cfg = p_get_dev_cfg(key)) == NULL) && -+ (((p_dev_cfg = p_create_dev_cfg(key)) == NULL) || -+ p_add_dev_cfg_to_list(&g_device_cfg_list, p_dev_cfg) != 0)) -+ { -+ dbgPrint("Failed to allocate mem or add dev cfg for %s.\n", key); -+ } -+ /* make sure that we can add this cfg type to the repository */ -+ else if(p_set_device_cfg_type(p_dev_cfg, cfg_type) == -1) -+ { -+ dbgPrint("Ignoring \"%s\" for device \"%s\".\n", -+ p_get_cfg_type_name_for_en(cfg_type), -+ p_dev_cfg->device_name); -+ } -+ else if((p_dev_inst_data = os_malloc(sizeof(DEV_INSTANCE_CFG_DATA_T)))== NULL) -+ { -+ dbgPrint("Failed to allocate memory for DEV_INSTANCE_CFG_DATA_T.\n"); -+ } -+ else if((p_dev_inst_data->data = os_malloc(cfg_len) + 1) == NULL) -+ { -+ dbgPrint("Failed to allocate memory for the config data.\n"); -+ } -+ else -+ { -+ p_dev_inst_data->next = NULL; -+ -+ if(cfg_type == en_opt_conf || cfg_type == en_compile) -+ psp_config_strcpy(p_dev_inst_data->locale, "dev on chip "); -+ else if(cfg_type == en_vlynq) -+ psp_config_strcpy(p_dev_inst_data->locale, "dev on vlynq"); -+ else -+ psp_config_strcpy(p_dev_inst_data->locale, "dev locale ?"); -+ -+ psp_config_memcpy(p_dev_inst_data->data, p_cfg_str, cfg_len); -+ p_dev_inst_data->data_size = cfg_len; -+ *(p_dev_inst_data->data + cfg_len) = '\0'; -+ -+ ret_val = p_add_instance_cfg_data(p_dev_cfg, p_dev_inst_data); -+ } -+ -+ return(ret_val); -+} -+ -+/*------------------------------------------------------------- -+ * Get the total number of device instances in the repository -+ *------------------------------------------------------------*/ -+int psp_config_get_num_keys(void) -+{ -+ return(g_device_cfg_list.count); -+} -+ -+ -+/*-------------------------------------------------------------------- -+ * Get the device configuration info from the repository. -+ *-------------------------------------------------------------------*/ -+int psp_config_get(char *key, int instance, char **cfg_data_out) -+{ -+ int ret_val = -1; -+ DEVICE_CFG_T *p_dev_cfg = NULL; -+ *cfg_data_out = NULL; -+ -+ if(key == NULL && cfg_data_out == NULL) -+ { -+ dbgPrint("Key has a NULL value.\n"); -+ } -+ else if((p_dev_cfg = p_get_dev_cfg(key)) == NULL) -+ { -+ dbgPrint("cfg information for %s could not be found.\n", key); -+ } -+ else if(p_dev_cfg->count) -+ { -+ DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data = -+ p_dev_cfg->dev_inst_list_begin; -+ int index = 0; -+ for(index = 0; -+ index != instance && index < p_dev_cfg->count; -+ index++) -+ { -+ p_dev_inst_data = p_dev_inst_data->next; -+ } -+ -+ if(p_dev_inst_data != NULL && p_dev_inst_data->data != NULL) -+ { -+ *cfg_data_out = p_dev_inst_data->data; -+ ret_val = p_dev_inst_data->data_size; -+ } -+ } -+ -+ return (ret_val); -+} -+ -+/*---------------------------------------------------------------- -+ * Returns the number of instances found in the repository for the -+ * specified key. -+ *---------------------------------------------------------------*/ -+int psp_config_get_num_instances(char *key) -+{ -+ int ret_val = 0; -+ DEVICE_CFG_T *p_dev_cfg = NULL; -+ -+ if(key == NULL) -+ { -+ dbgPrint("Key has a NULL value.\n"); -+ } -+ else if((p_dev_cfg = p_get_dev_cfg(key)) == NULL) -+ { -+ dbgPrint("cfg information for %s could not be found.\n", key); -+ } -+ else -+ { -+ ret_val = p_dev_cfg->count; -+ } -+ -+ return (ret_val); -+} -+ -+/*------------------------------------------------------------------ -+ * Dump the configuration repository. -+ * Caution: DO NOT USE THIS FOR ANY NON NBU specified config format. -+ *-----------------------------------------------------------------*/ -+void psp_config_print(char *key) -+{ -+ DEVICE_CFG_T *p_dev_cfg = NULL; -+ -+ if(key == NULL) -+ { -+ dbgPrint("Key has a NULL value.\n"); -+ } -+ else if((p_dev_cfg = p_get_dev_cfg(key)) == NULL) -+ { -+ dbgPrint("cfg information for %s could not be found.\n", key); -+ } -+ else if(p_dev_cfg && p_dev_cfg->count) -+ { -+ DEV_INSTANCE_CFG_DATA_T *p_dev_inst_data; -+ -+ p_dev_inst_data = p_dev_cfg->dev_inst_list_begin; -+ -+ do -+ { -+ dbgPrint("%s : %s\n", p_dev_inst_data->locale, -+ p_dev_inst_data->data); -+ p_dev_inst_data = p_dev_inst_data->next; -+ -+ } while(p_dev_inst_data); -+ } -+ else -+ { -+ dbgPrint("Nothing was found for %s.\n", key); -+ } -+} -+ -+void dump_device_cfg_pool(void) -+{ -+ DEVICE_CFG_T *p_dev_cfg = g_device_cfg_list.device_cfg_begin; -+ -+ if(p_dev_cfg != NULL && g_device_cfg_list.count) -+ { -+ int index=0; -+ -+ for(index=0; index < g_device_cfg_list.count; index++) -+ { -+ psp_config_print(p_dev_cfg->device_name); -+ p_dev_cfg = p_dev_cfg->next; -+ } -+ } -+ else -+ { -+ dbgPrint("repository is empty.\n"); -+ } -+} -+ -+void psp_config_init(void) -+{ -+ p_init_device_cfg_list(); -+} -+ -+void psp_config_cleanup() -+{ -+ int dev_count = 0; -+ int inst_count = 0; -+ DEVICE_CFG_T *p = g_device_cfg_list.device_cfg_begin; -+ DEV_INSTANCE_CFG_DATA_T *q = NULL; -+ -+ for(dev_count = 0; dev_count < g_device_cfg_list.count; dev_count++) -+ { -+ DEVICE_CFG_T *p_temp = NULL; -+ if(p) q = p->dev_inst_list_begin; -+ -+ for(inst_count = 0; inst_count < p->count && q != NULL; inst_count++) -+ { -+ DEV_INSTANCE_CFG_DATA_T *q_temp = q; -+ q_temp = q->next; -+ kfree(q->data); -+ kfree(q); -+ q = q_temp; -+ } -+ -+ p_temp = p->next; -+ kfree(p); -+ p = p_temp; -+ } -+} -diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_mgr.h linux.dev/drivers/net/avalanche_cpmac/psp_config_mgr.h ---- linux.old/drivers/net/avalanche_cpmac/psp_config_mgr.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/psp_config_mgr.h 2005-07-12 02:48:42.177573000 +0200 -@@ -0,0 +1,110 @@ -+/****************************************************************************** -+ * FILE PURPOSE: PSP Config Manager Header -+ ****************************************************************************** -+ * FILE NAME: psp_config_mgr.h -+ * -+ * DESCRIPTION: Storing and retrieving the configuration based on key -+ * A set of APIs to be used by one and sundry (including drivers and enumerator) to build -+ * and read cfg information of the devices for an avalanche SOC. -+ * -+ * This set of APIs isolates the configuration management from the world and provides simple -+ * access convinience. -+ * -+ * Device in this set refers to the peripherals that can be found on the SOC or on VLYNQ. -+ * The configuration is stored in the form of string and drivers can use these APIs to get -+ * a particular parameter value. -+ * -+ * The memory allocation for the pass back parameters is done by the caller. -+ * -+ * 0 is returned for SUCCESS or TRUE. -+ * -1 is returned for FAILURE or FALSE. -+ * -+ * REVISION HISTORY: -+ * 27 Nov 02 - PSP TII -+ * -+ * (C) Copyright 2002, Texas Instruments, Inc -+ *******************************************************************************/ -+ -+#ifndef __PSP_CONFIG_MGR_H__ -+#define __PSP_CONFIG_MGR_H__ -+ -+typedef enum cfg_type -+{ -+ en_raw = 0, -+ en_compile, -+ en_opt_conf, -+ en_vlynq -+} CFG_TYPE_T; -+ -+/* Build psp configuration */ -+void build_psp_config(void); -+ -+/******************************************************** -+ * Access Operations. -+ ********************************************************/ -+ -+/*------------------------------------------------------------------------- -+ initializes the configuration repository. -+ -------------------------------------------------------------------------*/ -+void psp_config_init(void); -+ -+/*-------------------------------------------------------------------------- -+ Adds the configuration information into the repository. 'key' is required -+ to be NULL terminated string. 'cfg_ptr' points to the configuration data. -+ 'cfg_len' is the length of the data pointed to by 'cfg_ptr' in bytes. -+ 'cfg_type' indicates the type of config information. -+ -+ psp_config_mgr copies the 'cfg_len' bytes of data pointed to by 'cfg_ptr' -+ into its internal repository. -+ -+ Returns: 0 on success, -1 on failure. -+ -------------------------------------------------------------------------*/ -+int psp_config_add(char *key, void *cfg_ptr, -+ unsigned int cfg_len, CFG_TYPE_T cfg_type); -+ -+ -+/* -------------------------------------------------------------------------- -+ Passes back, in "*cfg_out_val" a pointer to the config data in the repository -+ for the specified 'key' and 'instance'. It returns the size of the config -+ info -+ -+ psp_config_mgr passes back a pointer in '*cfg_out_val' which refers to -+ some location in its internal repository. It is strongly recommended that -+ if the user intends to modify the contents of the config info for reasons -+ whatsoever, then, user should allocate memory of size returned by this -+ routine and copy the contents from '*cfg_out_val'. -+ -+ Any, modification carried out on the repository would lead to un-expected -+ results. -+ -+ Returns: 0 or more for the size of config info, -1 on error. -+ --------------------------------------------------------------------------*/ -+int psp_config_get(char *key, int instance, char **cfg_out_val); -+ -+ -+/*-------------------------------------------------------------------------- -+ Get the number of keys that have been added in the repository so far. -+ -+ Returns: 0 or more for the num of keys, -1 on error. -+ -------------------------------------------------------------------------*/ -+int psp_config_get_num_keys(void); -+ -+ -+/*-------------------------------------------------------------------------- -+ Get the number of instances that are present in the repository for the -+ given 'key'. -+ -+ Returns: 0 or more for the num of instances, -1 on error. -+ -------------------------------------------------------------------------*/ -+int psp_config_get_num_instances(char *key); -+ -+ -+/*-------------------------------------------------------------------------- -+ Prints the config data for all instances associated with the specified -+ 'key'. -+ -------------------------------------------------------------------------*/ -+void psp_config_print(char *key); -+ -+void dump_device_cfg_pool(void); -+ -+#endif /* __PSP_CONFIG_MGR_H__ */ -diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_parse.c linux.dev/drivers/net/avalanche_cpmac/psp_config_parse.c ---- linux.old/drivers/net/avalanche_cpmac/psp_config_parse.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/psp_config_parse.c 2005-07-12 02:48:42.178573000 +0200 -@@ -0,0 +1,362 @@ -+/****************************************************************************** -+ * FILE PURPOSE: PSP Config Manager - Parse API Source -+ ****************************************************************************** -+ * FILE NAME: psp_config_parse.c -+ * -+ * DESCRIPTION: These APIs should be used only for scanvenging parameters which -+ * are stored in the following format. -+ * -+ * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)" -+ * -+ * REVISION HISTORY: -+ * 27 Nov 02 - PSP TII -+ * -+ * (C) Copyright 2002, Texas Instruments, Inc -+ *******************************************************************************/ -+ -+//#include <stdio.h> -+#include <linux/stddef.h> -+ -+/*-------------------------------------------------- -+ * MACROS. -+ *-------------------------------------------------*/ -+#define my_isdigit(c) (c >= '0' && c <= '9') -+#define my_isoct(c) (c >= '0' && c <= '7') -+#define my_xtod(c) ((c) <= '9' ? (c) - '0' : (c) - 'a' + 10) -+#define my_ifupper(c) (c >= 'A' && c <= 'F') -+#define XTOD(c) ((c) - 'A' + 10) -+#define my_ishex(c) ((c >= 'a' && c <='f') || (c >= 'A' && c<='F') || my_isdigit(c) ) -+ -+/*--------------------------------------------------- -+ * Local Functions. -+ *--------------------------------------------------*/ -+static int p_get_substr_from_str(char *p_in_str, char begin_delimiter, -+ char end_delimiter, int pair_flag, -+ char **p_out_str); -+static int p_get_u_int_from_str(char *p_in_str, char begin_delimiter, -+ char end_delimiter, unsigned long *out_val); -+ -+/*--------------------------------------------------- -+ * Return pointer to first instance of the char. -+ *--------------------------------------------------*/ -+static char* psp_config_strchr(char *str, char chr) -+{ -+ while(*str) -+ { -+ if(*str == chr) -+ break; -+ str++; -+ } -+ -+ return((*str) ? str : NULL); -+} -+ -+/*------------------------------------------------------------------------ -+ * Convert the string upto delimiter to unsigned long. -+ *-----------------------------------------------------------------------*/ -+unsigned long my_atoul(char *p, char end_delimiter, unsigned long *out_val) -+{ -+ unsigned long n; -+ int c; -+ -+ /* check the for null input */ -+ if (!p) -+ return -1; -+ -+ c = *p; -+ -+ /* pass through the leading spaces */ -+ if (!my_isdigit(c)) -+ { -+ while ( c == ' ') -+ c = *++p; -+ -+ } -+ -+ if (c == '0') -+ { -+ if(*(p + 1) == 'x' || *(p+1) == 'X' ) -+ { -+ /* string is in hex format */ -+ -+ p += 2; -+ c = *p; -+ -+ if(my_ishex(c)) -+ { -+ if(my_ifupper(c)) -+ n = XTOD(c); -+ else -+ n = my_xtod(c); -+ } -+ else -+ return -1; /* invalid hex string format */ -+ -+ while ((c = *++p) && my_ishex(c)) -+ { -+ n *= 16; -+ if(my_ifupper(c)) -+ n += XTOD(c); -+ else -+ n += my_xtod(c); -+ } -+ } -+ else -+ { -+ /* string is in octal format */ -+ -+ if( my_isoct(c) ) -+ n = c - '0'; -+ else -+ return -1; /* invalid octal string format */ -+ -+ while ((c = *++p) && my_isoct(c)) -+ { -+ n *= 8; -+ n += c - '0'; -+ } -+ } -+ -+ } -+ else -+ { -+ /* string is in decimal format */ -+ -+ if( my_isdigit(c) ) -+ n = c - '0'; -+ else -+ return -1; /* invalid decimal string format */ -+ -+ while ((c = *++p) && my_isdigit(c)) -+ { -+ n *= 10; -+ n += c - '0'; -+ } -+ } -+ -+ /* move through the trailing spaces */ -+ while(*p == ' ') -+ p++; -+ -+ if(*p == end_delimiter) -+ { -+ *out_val = n; -+ return 0; -+ } -+ -+ else -+ return -1; /* invalid string format */ -+} -+ -+/*--------------------------------------------------------------------------------- -+ * Gets the substring de-limited by the 'begin_delimiter' and 'end_delimiter'. -+ * and returns the size of the substring. -+ * -+ * Parses the NULL terminated p_in_str for a character array delimited by -+ * begin_delimiter and end_delimiter, passes back the pointer to the character -+ * array in ' *p_out_str '. The passed pointer ' *p_out_str ' should point to -+ * the location next (byte) to the begin_delimiter. The function routine returns -+ * the number of characters excluding the begin_delimiter and end_delimiter, -+ * found in the array delimited by the said delimiters. -+ * -+ * If the pair_flag is set to 1, then, number of begin_delimiter and end_delimiter -+ * found in the parsing should match (equal) and this routine passes back the -+ * pointer to the character array, starting at a location next (byte) to the -+ * first begin_delimiter, inclusive of all intermediate matching delimiter -+ * characters found between outer delimiters. If the pair flag is set and if -+ * begin_delimiter and end_delimiter happens to be same, then error (-1) is -+ * returned. -+ * -+ * Return: 0 or more to indicate the size of the substring, -1 on error. -+ *-------------------------------------------------------------------------------*/ -+int p_get_substr_from_str(char *p_in_str, char begin_delimiter, -+ char end_delimiter, int pair_flag, -+ char **p_out_str) -+{ -+ int cnt,pos; -+ -+ if(pair_flag && begin_delimiter == end_delimiter) -+ return -1; -+ -+ if((p_in_str = psp_config_strchr(p_in_str, begin_delimiter)) == 0) -+ return -1; /* no start delimiter found */ -+ -+ p_in_str++; -+ *p_out_str = p_in_str; -+ -+ for(pos = 0,cnt =1; cnt && p_in_str[pos] ; pos++) -+ { -+ if(p_in_str[pos] == end_delimiter) -+ { -+ if(pair_flag == 0) -+ return pos; -+ -+ cnt--; -+ } -+ else if(p_in_str[pos] == begin_delimiter) -+ cnt++; -+ else -+ ; /* We do nothing */ -+ -+ } -+ -+ if( cnt == 0) -+ return pos - 1; -+ else -+ return -1; /* no corresponding end delimiter found */ -+} -+ -+/*-------------------------------------------------------------------------- -+ * Parses the NULL terminated p_in_str for unsigned long value delimited by -+ * begin_delimiter and end_delimiter, passes back the found in ' *out_val '. -+ * The function routine returns 0 on success and returns -1 on failure. -+ * The first instance of the de-limiter should be accounted for the parsing. -+ * -+ * The base for unsigned value would 10, octal and hex. The value passed back -+ * would be of the base 10. Spaces at the begining of the byte array are valid -+ * and should be ingnored in the calculation of the value. Space character in -+ * the middle of the byte array or any character other than the valid ones -+ * (based on base type) should return error. The octal value begins with '0', -+ * the hex value begins with "0x" or "0X", the base value can begin with -+ * '1' to '9'. -+ * -+ * Returns: 0 on success, -1 on failure. -+ *-------------------------------------------------------------------------*/ -+int p_get_u_int_from_str(char *p_in_str, char begin_delimiter, -+ char end_delimiter, unsigned long *out_val) -+{ -+ char *start; -+ unsigned long num; -+ -+ num = p_get_substr_from_str(p_in_str, begin_delimiter, end_delimiter, -+ 0, &start); -+ -+ if(num == (unsigned long)-1) -+ return -1; -+ -+ return my_atoul(start,end_delimiter,out_val); -+} -+ -+/*-------------------------------------------------------------------------- -+ * Finds the first occurrence of the substring p_find_str in the string -+ * p_in_str. -+ *-------------------------------------------------------------------------*/ -+char *my_strstr(char *p_in_str, const char *p_find_str) -+{ -+ char *p = (char *)p_find_str; -+ char *ret = NULL; -+ -+ while(*p_in_str) -+ { -+ if(!(*p)) -+ return (ret); -+ else if(*p_in_str == *p) -+ { -+ if(!ret) ret = p_in_str; -+ p++; -+ p_in_str++; -+ } -+ else if(ret) -+ { -+ p = (char *)p_find_str; -+ p_in_str = ret + 1; -+ ret = NULL; -+ } -+ else -+ p_in_str++; -+ } -+ -+ if(*p_in_str != *p) ret = NULL; -+ -+ return (ret); -+ -+} -+ -+/*------------------------------------------------------------------------------ -+ * Gets the value of the config param in the unsigned int format. The value is -+ * stored in the following format in the string. -+ * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)" -+ *-----------------------------------------------------------------------------*/ -+int psp_config_get_param_uint(char *p_in_str, const char *param, unsigned int *out_val) -+{ -+ int ret_val = -1; -+ char *p_strstr; -+ -+ if(!p_in_str || !param || !out_val) -+ { -+ ; -+ } -+ else if((p_strstr = my_strstr(p_in_str, param)) == NULL) -+ { -+ ; -+ } -+ else if(p_get_u_int_from_str(p_strstr, '=', ',', (unsigned long *)out_val) == 0) -+ { -+ ret_val = 0; -+ } -+ else if(p_get_u_int_from_str(p_strstr, '=', ']', (unsigned long*)out_val) == 0) -+ { -+ ret_val = 0; -+ } -+ else if(p_get_u_int_from_str(p_strstr, '=', ')', (unsigned long*)out_val) == 0) -+ { -+ ret_val = 0; -+ } -+ else -+ { -+ /* we failed */ -+ } -+ -+ return (ret_val); -+} -+ -+/*------------------------------------------------------------------------------ -+ * Gets the value of the config param in the Non NULL terminated format. The value -+ * is stored in the following format in the string. -+ * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)" -+ *-----------------------------------------------------------------------------*/ -+int psp_config_get_param_string(char *p_in_str, const char *param, char **out_val) -+{ -+ int ret_val = -1; -+ char *p_strstr; -+ -+ if(!p_in_str || !param || !(out_val)) -+ ; -+ else if((p_strstr = my_strstr(p_in_str, param)) == NULL) -+ { -+ ; -+ } -+ else if((ret_val = p_get_substr_from_str(p_strstr, '[', ']', 1, out_val)) == -1) -+ { -+ ; -+ } -+ else -+ { -+ ; /* we got the value */ -+ } -+ -+ return (ret_val); -+} -+ -+#ifdef PSP_CONFIG_MGR_DEBUG_TEST -+main() -+{ -+ unsigned long num =999; -+ int ret = 0; -+ char *val1 = NULL; -+ char val[30]; -+ char str1[] = "cpmac(id=[cpmac], k0=[a1=[a2=[test], a3=2], k1=100, k2=[k3=300, k4=200], k7=722)"; -+ -+ psp_config_get_param_uint(str1, "k7", &num); -+ printf("%u.\n", num); -+ ret = psp_config_get_param_string(str1, "a1", &val1); -+ if(ret >= 0) { printf("%d.\n", ret); strncpy(val, val1, ret); val[ret] = '\0';} -+ -+ printf("val = \"%s\", and size = %d \n", val, ret); -+ -+ if(val[ret]) ; else printf("jeee.\n"); -+} -+#endif /* PSP_CONFIG_MGR_DEBUG_TEST */ -+ -+ -+ -diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_parse.h linux.dev/drivers/net/avalanche_cpmac/psp_config_parse.h ---- linux.old/drivers/net/avalanche_cpmac/psp_config_parse.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/psp_config_parse.h 2005-07-12 02:48:42.178573000 +0200 -@@ -0,0 +1,32 @@ -+/****************************************************************************** -+ * FILE PURPOSE: PSP Config Manager - Parse API Header -+ ****************************************************************************** -+ * FILE NAME: psp_config_parse.h -+ * -+ * DESCRIPTION: Parsing for params from string available in the NBU format. -+ * These APIs should be used only for scanvenging parameters which -+ * are stored in the following format. -+ * -+ * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)" -+ * -+ * REVISION HISTORY: -+ * 27 Nov 02 - PSP TII -+ * -+ * (C) Copyright 2002, Texas Instruments, Inc -+ *******************************************************************************/ -+ -+#ifndef __PSP_CONFIG_PARSER_H__ -+#define __PSP_CONFIG_PARSER_H__ -+ -+/*------------------------------------------------------------------ -+ * These APIs should be used only for scanvenging parameters which -+ * are stored in the following format. -+ * -+ * str[] = "module(id=[module], k1=v1, k2=[k3=v3, k4=v4], k5=v5)" -+ *-----------------------------------------------------------------*/ -+int psp_config_get_param_uint(char *p_in_str, const char *param, -+ unsigned int *out_val); -+int psp_config_get_param_string(char *p_in_str, const char *param, -+ char **out_val); -+ -+#endif /* __PSP_CONFIG_PARSER_H__ */ -diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_util.c linux.dev/drivers/net/avalanche_cpmac/psp_config_util.c ---- linux.old/drivers/net/avalanche_cpmac/psp_config_util.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/psp_config_util.c 2005-07-12 02:48:42.178573000 +0200 -@@ -0,0 +1,106 @@ -+/****************************************************************************** -+ * FILE PURPOSE: PSP Config Manager - Utilities API Source -+ ****************************************************************************** -+ * FILE NAME: psp_config_util.c -+ * -+ * DESCRIPTION: These APIs provide the standard "C" string interfaces. -+ * Provided here to reduce dependencies on the standard libraries -+ * and for cases where psp_config would required to run before -+ * the whole system is loaded or outside the scope of the OS. -+ * -+ * REVISION HISTORY: -+ * 27 Nov 02 - PSP TII -+ * -+ * (C) Copyright 2002, Texas Instruments, Inc -+ *******************************************************************************/ -+ -+//#include <stdio.h> -+#include "psp_config_util.h" -+#include <linux/stddef.h> -+ -+/*--------------------------------------------- -+ * strlen. -+ *-------------------------------------------*/ -+int psp_config_strlen(char *p) -+{ -+ char *p_orig = p; -+ while(*p) -+ p++; -+ return(p - p_orig); -+} -+ -+/*-------------------------------------------- -+ * strcmp. -+ *-------------------------------------------*/ -+int psp_config_strcmp(char *s1, char *s2) -+{ -+ while(*s1 && *s2) -+ { -+ if(*s1 != *s2) -+ break; -+ s1++; -+ s2++; -+ } -+ -+ return(*s1 - *s2); -+} -+ -+/*-------------------------------------------- -+ * strcpy. -+ *------------------------------------------*/ -+char* psp_config_strcpy(char *dest, char *src) -+{ -+ char *dest_orig = dest; -+ -+ while(*src) -+ { -+ *dest++ = *src++; -+ } -+ -+ *dest = '\0'; -+ -+ return(dest_orig); -+} -+ -+/*---------------------------------------------- -+ * psp_config_memcpy. -+ *--------------------------------------------*/ -+void* psp_config_memcpy(void* dest, void* src, unsigned int n) -+{ -+ void *dest_orig = dest; -+ -+ while(n) -+ { -+ *(char *)dest++ = *(char *)src++; -+ n--; -+ } -+ -+ return (dest_orig); -+} -+ -+/*--------------------------------------------------- -+ * Return pointer to first instance of the char. -+ *--------------------------------------------------*/ -+char* psp_config_strchr(char *str, char chr) -+{ -+ while(*str) -+ { -+ if(*str == chr) -+ break; -+ str++; -+ } -+ -+ return((*str) ? str : NULL); -+} -+ -+#ifdef PSP_CONFIG_MGR_DEBUG_TEST -+ -+int main( ) -+{ -+ char s[] = "hello "; -+ printf("%d.\n", psp_config_strlen("hello\n")); -+ printf("%d.\n", psp_config_strcmp("hells", "hellq")); -+ printf("%s %s.\n", psp_config_strcpy(s + 6, "test1"), s); -+} -+ -+#endif /* PSP_CONFIG_MGR_DEBUG_TEST */ -diff -urN linux.old/drivers/net/avalanche_cpmac/psp_config_util.h linux.dev/drivers/net/avalanche_cpmac/psp_config_util.h ---- linux.old/drivers/net/avalanche_cpmac/psp_config_util.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/psp_config_util.h 2005-07-12 02:48:42.179573000 +0200 -@@ -0,0 +1,26 @@ -+/****************************************************************************** -+ * FILE PURPOSE: PSP Config Manager - Utilities API Header -+ ****************************************************************************** -+ * FILE NAME: psp_config_util.h -+ * -+ * DESCRIPTION: These APIs provide the standard "C" string interfaces. -+ * Provided here to reduce dependencies on the standard libraries -+ * and for cases where psp_config would required to run before -+ * the whole system is loaded or outside the scope of the OS. -+ * -+ * REVISION HISTORY: -+ * 27 Nov 02 - PSP TII -+ * -+ * (C) Copyright 2002, Texas Instruments, Inc -+ *******************************************************************************/ -+ -+#ifndef __PSP_CONFIG_UTIL_H__ -+#define __PSP_CONFIG_UTIL_H__ -+ -+extern int psp_config_strlen(char*); -+extern int psp_config_strcmp(char*, char*); -+extern char* psp_config_strcpy(char*, char*); -+extern void* psp_config_memcpy(void*, void*, unsigned int n); -+extern char* psp_config_strchr(char*, char); -+ -+#endif /* __PSP_CONFIG_UTIL_H__ */ -diff -urN linux.old/drivers/net/avalanche_cpmac/readme.txt linux.dev/drivers/net/avalanche_cpmac/readme.txt ---- linux.old/drivers/net/avalanche_cpmac/readme.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/avalanche_cpmac/readme.txt 2005-07-12 02:48:42.179573000 +0200 -@@ -0,0 +1,545 @@ -+23 August 2004 CPMAC 1.7.8 (NSP Performance Team Release) -+ -+CC Labels: REL_20040823_HALdallas_cpmac_01.07.08 -+ -+New features: Key "MacAddr" can now be used to set the Mac Address after Open. -+ -+ unsigned char MacAddr[6]; -+ -+ // Set Mac Address to "00.B0.D0.10.80.C1" -+ MacAddr[0] = 0x00; -+ MacAddr[1] = 0xB0; -+ MacAddr[2] = 0xD0; -+ MacAddr[3] = 0x10; -+ MacAddr[4] = 0x80; -+ MacAddr[5] = 0xC1; -+ -+ HalFunc->Control(HalDev, "MacAddr", hcSet, &MacAddr); -+ -+Bug fixes: in Send(), Threshold is not checked if Tx Ints are re-enabled. -+ -+Modules affected: hcpmac.c, hcpmac.h, cppi_cpmac.c -+ -+22 June 2004 CPMAC 1.7.6 (NSP Performance Team Release) -+ -+CC Labels: REL_20040622_HALdallas_cpmac_01.07.06 -+ -+New features: Key "TxIntDisable" used to disable Tx Interrupts. If it is set, then Tx Interrupts will be processed on Send() controlled by Tx ServiceMax Setting. -+ -+ int On = 1; -+ HalFunc->Control(HalDev, "TxIntDisable", "Set", &On); -+ -+Bug fixes: NTR -+ -+10 June 2004 CPMAC 1.7.5 (external release) -+ -+CC Labels: REL_20040610_HALdallas_cpmac_01.07.05 -+ -+New features: NTR -+ -+Bug fixes: Fixed an issue with calculation for the multicast hash. -+ -+27 May 2004 CPSAR 1.7.4, CPMAC 1.7.4 (external release) -+ -+CC Labels: REL_20040527_HALdallas_cpsar_01.07.04 -+ REL_20040527_HALdallas_cpmac_01.07.04 -+ -+New features: NTR -+ -+Bug fixes: A flaw was fixed in the critical sectioning of the CPPI file, affecting both -+ the MAC and the SAR releases. This flaw was detected on Titan PSP 4.7 BFT2. -+ -+05 May 2004 CPSAR 1.7.3, CPMAC 1.7.3 (external release) -+ -+CC Labels: REL_20040505_HALdallas_cpsar_01.07.03 -+ REL_20040505_HALdallas_cpmac_01.07.03 -+ -+New features: NTR -+ -+Bug fixes: 1) Firmware has been updated to fix a problem with Host OAM mode operation. -+ 2) Cache macros have been fixed. -+ -+Notes: This release contains all performance enhancements currently available for CPHAL 1.x. -+ -+19 April 2004 CPSAR 1.7.2, CPMAC 1.7.2 (external release) -+ -+CC Labels: REL_20040419_HALdallas_cpsar_01.07.02 -+ REL_20040419_HALdallas_cpmac_01.07.02 -+ -+New features: NTR -+ -+Bug fixes: Fixes merge problem in 1.7.1. -+ -+Notes: This is a branch release which contains only a subset of the performance improvements. -+ The remaining performance improvements are stiill being qualified at this time. -+ -+1 April 2004 CPSAR 1.7.1, CPMAC 1.7.1 (external release) -+ -+NOTICE: DO NOT USE 1.7.1. It has a known problem (see 1.7.2 notes) -+ -+CC Labels: REL_20040401_HALdallas_cpsar_01.07.01 -+ REL_20040401_HALdallas_cpmac_01.07.01 -+ -+New features: Performance improvement in CPPI layer, affecting both CPSAR and CPMAC. -+ -+Bug fixes: NTR -+ -+17 Februrary 2004 CPSAR 1.7.0 (external release) -+ -+CC Labels: REL_20040217_HALdallas_cpsar_01.07.00 -+ -+New features: Added support for "TxFlush" feature. This allows the upper -+ layer to flush all or part of a given Tx queue for a given -+ channel. This is to be used during call setup for a voice -+ connection. -+ -+30 January 2004 CPMAC 1.7.0 (external release) -+ -+CC Labels: REL_20040130_HALdallas_cpmac_01.07.00 -+ -+Bug fixes: CPMDIO - When in manual negotiate mode and linked, dropping link would move into NWAY state rather than manual state. -+ CPMDIO - Extraneous debug message corrected -+New features: CPMDIO - Support for AutoMdix usage added. -+ -+25 September 2003 CPSAR 1.6.6 (external release) -+ -+CC Labels: REL_20030925_HALdallas_cpsar_01.06.06 -+ -+Bug fixes: PDSP firmware has been updated to fix the OAM padding problem. It previously -+ wrote pad bytes into a reserved field of the OAM cell. There is a small -+ change to the CPSAR configuration code which corresponds to the PDSP spec -+ change. -+ -+New features: NTR -+ -+09 September 2003 CPMAC 1.6.6 (external release) -+ -+CC Labels: REL_20030909_HALdallas_cpmac_01.06.06 -+ -+Bug fixes: CPMAC : When _CPMDIO_NOPHY is set, Cpmac COntrol is set to Full Duplex -+ Bridge loopback test does not show a problem using 1.6.5 if packet rate is -+ below 50,000 pbs. Now testing with a 100% send from Ixia. -+ -+New features: NTR -+ -+05 August 2003 CPHAL 1.6.5 (external release) -+ -+CC Labels: REL_20030805_HALdallas_cpmac_01.06.05 -+ -+Bug fixes: NTR -+ -+New features: CPMAC : Added support for CPMAC modules that do not have a Phy connected. -+ The CPMAC is informed of this by the MdioConnect option -+ _CPMDIO_NOPHY. This is the only driver change needed to -+ receive and transmit packets through the Marvel switch. -+ Note In this mode Link status will reported linked at 100/FD to -+ PhyNum 0xFFFFFFFF. -+ -+ ALL: Cleaned up some Vlynq support logic. -+ -+16 July 2003 CPSAR 1.6.3 (external release), no CPMAC release -+ -+CC Labels: REL_20030716_HALdallas_cpsar_01.06.03 -+ -+Bug fixes: 1) Changed default value of CPCS_UU from 0x5aa5 to 0. The old default value caused -+ problems with Cisco routers. -+ -+New features: NTR -+ -+Known issues not addressed in this release: NTR. -+ -+01 July 2003 CPHAL 1.6.2 (external release) -+ -+CC Labels: REL_20030701_HALdallas_cpmac_01.06.02 -+ REL_20030701_HALdallas_cpsar_01.06.02 -+ -+Bug fixes: 1) A previous firmware upgrade caused firmware OAM loopback cells to only work on every other -+ command. This has been fixed in the new firmware version (0.47). -+ 2) Problem with PTI values changing on transparent mode packets has been resolved. -+ 3) Previously, successful firmware OAM loopback cells waited 5 seconds before notifying the -+ OS of success, rather that notifying immediately. This has been resolved in firmware. -+ 4) PITS #148 (MAC and SAR), #149 (MAC) have been fixed. -+ -+New features: 1) AAL5 HAL now capable of receiving unknown VCI/VPI cells on a single transparent channel. -+ See updated HAL document (AAL5 appendix) for implementation details. -+ 2) AAL5 HAL now allows OS to modify the OAM loopback timeout window. Previously, failed -+ OAM loopback attempts timed out after a nominal 5 seconds (based on the SAR frequency -+ provided by the OS). Now, the default is 5 seconds, but the OS may change the -+ value via halControl() to any integer number of milliseconds. See updated HAL document -+ (AAL5 appendix) for implementation details. -+ 3) MAC (cpmdio): added loopback to Istate. Used for debug. -+ -+Known issues not addressed in this release: NTR. -+ -+09 June 2003 CPSAR 1.6.1 (external release), CPMAC 1.6.1 (internal release - no functional change) -+ -+Note: This is the same set of fixes being applied to 1.6.0 that were applied to 1.5.3. The only difference -+ between 1.6.1 and 1.5.4 is that 1.6.1 has the TurboDSL fix. -+ -+CC Labels: REL_20030609_HALdallas_cpmac_01.06.01 -+ REL_20030609_HALdallas_cpsar_01.06.01 -+ -+Bug fixes: 1) Bug in OamLoopbackConfig fixed. -+ 2) New firmware version (.43) to fix Westell issue of dropped downstream packets in -+ presence of OAM traffic when operating at or near line rate. -+ -+New features: NTR. -+ -+09 June 2003 CPSAR 1.5.4 (external release), CPMAC 1.5.4 (internal release - no functional change) -+ -+Note: This is a branch release from 1.5.3. This does not contain anything from 1.6.0. The CPMAC is -+only being labeled to keep the release flow consistent. -+ -+CC Labels: REL_20030609_HALdallas_cpmac_01.05.04 -+ REL_20030609_HALdallas_cpsar_01.05.04 -+ -+Bug fixes: 1) Bug in OamLoopbackConfig fixed. -+ 2) New firmware version (.43) to fix Westell issue of dropped downstream packets in -+ presence of OAM traffic when operating at or near line rate. -+ -+New features: NTR. -+ -+30 May 2003 CPSAR 1.6.0 (external release), CPMAC 1.6.0 (internal release - no functional change) -+ -+CC Labels: REL_20030530_HALdallas_cpmac_01.06.00 -+ REL_20030530_HALdallas_cpsar_01.06.00 -+ -+Bug fixes: 1) TurboDSL issue has been fixed with a software workaround in TxInt. This workaround -+ has been verified under Adam2 ONLY at this point. Testing remains to be done on -+ Linux and VxWorks. -+ -+New features: NTR. -+ -+Known issues not addressed in this release: NTR. -+ -+30 May 2003 CPSAR 1.5.3 (external release), CPMAC 1.5.3 (internal release - no functional change) -+ -+CC Labels: REL_20030530_HALdallas_cpmac_01.05.03 -+ REL_20030530_HALdallas_cpsar_01.05.03 -+ -+Bug fixes: NTR. -+ -+New features: 1) AAL5 Send() has been modified to accept an ATM Header either in the first -+ fragment by itself, or in the first fragment directly in front of payload data. -+ The API() does not change. -+ 2) Documentation updates throughout, reflected in latest version of CPHAL user's -+ guide. -+ 3) AAL5 MaxFrags default value is now 46. This is based upon the default AAL5 -+ RxBufSize of 1518 (MaxFrags = (65568/1518) + 2). IF THE OS CHOOSES A SMALLER -+ RxBufSize, IT MUST INCREASE THE VALUE OF MaxFrags ACCORDINGLY. This is done -+ via halControl(), prior to Open(). -+ -+Known issues not addressed in this release: -+ 1) The Linux SAR driver is seeing an issue in which it cannot -+ reliably send traffic simultaneously on both the high and -+ low priority queues of a single AAL5 channel. (TurboDSL) -+ -+23 May 2003 CPHAL 1.5.2 (external release) -+ -+CC Labels: REL_20030523_HALdallas_cpmac_01.05.02 -+ REL_20030523_HALdallas_cpsar_01.05.02 -+ -+Bug fixes: 1) PITS #138: CPMAC flooding issue resolved. -+ 2) PITS #142: OS may now set "MaxFrags" via Control(). This controls the -+ maximum number of fragments expected by the CPHAL. The default value is 2 for -+ CPMAC and 1028 for AAL5. If the OS chooses a RxBufSize that will cause more -+ fragments than the defaults, the OS must set "MaxFrags" to a correct value -+ ((maximum packet length / RxBufSize) + 2). -+ 3) PITS #143: Fixed. -+ 4) Firmware OAM bug fixed. (new firmware release in this version) -+ -+New features: NTR. -+ -+Known issues not addressed in this release: -+ 1) The Linux SAR driver is seeing an issue in which it cannot -+ reliably send traffic simultaneously on both the high and -+ low priority queues of a single AAL5 channel. (TurboDSL) -+ -+14 May 2003 CPHAL 1.5.1 (external release) -+ -+CC Labels: REL_20030514_HALdallas_cpmac_01.05.01 -+ REL_20030514_HALdallas_cpsar_01.05.01 -+ -+Bug fixes: 1) PITS 132 - (CPMAC) Frames < 60 bytes and split into -+ multi-fragments. -+ 2) BCIL MR PSP00000353 - (CPMAC) PhyDev not free'd on halClose() -+ 3) PITS 113 - OsSetup bug in ChannelSetup fixed. -+ 4) Fixed AAL5 to check return values of InitTcb/InitRcb. -+ 5) Fixed Shutdown to properly free resources in the case of a Close -+ mode 1 followed by Shutdown. Previously, buffer and descriptor -+ resources were left unfreed in this case. -+ -+New features: 1) AAL5 Send() modified to be capable of accepting ATM header as first four -+ bytes of first fragment. This allows the OS to "override" the -+ default ATM header which is constructed from preconfigured channel -+ parameters. -+ 2) AAL5 Receive() modified to be capable of passing the received ATM header (4 bytes, no HEC) -+ in the first fragment (by itself). It also passes up the OS an indication -+ of what the received packet type was. For Host OAM and transparent mode -+ packets, the ATM header is passed in this manner, and for other types of packets -+ (AAL5, NULL AAL) no ATM header is passed currently. -+ -+Known issues not addressed in this release: -+ 1) The Linux SAR driver is seeing an issue in which it cannot -+ reliably send traffic simultaneously on both the high and -+ low priority queues of a single AAL5 channel. -+ -+30 April 2003 CPHAL 1.5.0 (external release) -+ -+CC Labels: REL_20030430_HALdallas_cpmac_01.05.00 -+ REL_20030430_HALdallas_cpsar_01.05.00 -+ -+Bug fixes: 1) Fixed AAL5 bug that rendered the low priority queue -+ unusable. -+ 2) Fixed a bug in AAL5's Oam Rate calculations. -+ 3) Fixed use of "DeviceCPID" key in AAL5's halControl(). -+ 4) Fixed RxReturn logic in HAL. The HAL now can handle -+ failing MallocRxBuffer calls when multiple fragments -+ are being used. -+ -+New features: 1) AAL5 Stats now available on a per queue basis. -+ 2) AAL5 adds two new keys to halControl() for "Set" actions: -+ RxVc_OamCh and RxVp_OamCh. -+ 3) Shutdown() has been modified for both AAL5 and CPMAC to -+ call Close() if the module is still in the Open state. -+ 4) CPMAC adds the following access keys to halControl(): -+ hcPhyAccess,hcPhyNum,hcCpmacBase,hcSize,and hcCpmacSize. -+ 5) CPHAL no longer requests an extra 15 bytes on data buffer -+ mallocs. -+ -+Known issues not addressed in this release: -+ 1) The Linux SAR driver is seeing an issue in which it cannot -+ reliably send traffic simultaneously on both the high and -+ low priority queues of a single AAL5 channel. -+ -+21 April 2003 CPHAL 1.4.1 (external release) -+ -+CC Labels: REL_20030421_HALdallas_cpmac_01.04.01 -+ REL_20030421_HALdallas_cpsar_01.04.01 -+ -+Bug fixes: 1) Fixed OAM logic in SAR portion of CPHAL. -+ -+New features: 1) OAM loopback counters exposed through halControl. -+ 2) Host OAM Send() can now use a single channel to send -+ OAM cells on unlimited number of VP's/VC's. -+ 3) CPHAL now requests "SarFreq" through osControl. -+ 4) CPHAL now calculates all OAM function rates based on -+ "SarFreq"; function OamRateConfig removed for API. -+ 5) New OAM function OamLoopbackConfig, used for configuring -+ loopback functions in firmware OAM mode. -+ -+Known issues not addressed in this release: Bug fix 1) in release 1.4 -+ (see below) does not work properly for multiple fragments. -+ -+10 April 2003 CPHAL 1.4 (external release) -+ -+CC Labels: REL_20030410_HALdallas_cpmac_01.04.00 -+ REL_20030410_HALdallas_cpsar_01.04.00 -+ -+This release is for SAR and MAC. -+ -+ Bug fixes: 1) Implemented logic in HAL to re-request buffer mallocs -+ in the case of MallocRxBuffer failing. The HAL now maintains -+ a NeedsBuffer queue of all RCB's that are without buffers. -+ On interrupts, or on Send(), the HAL checks to see if any -+ RCB's are on the queue, and if so, calls MallocRxBuffer -+ to attempt to get a new buffer and return the RCB to -+ circulation. -+ 2) SAR now properly returns all error codes from halOpen and -+ halChannelSetup. -+ -+ New features: NTR -+ -+ Known issues not addressed in this release: NTR -+ -+08 April 2003 CPHAL 1.3.1 (internal release - SAR only) -+ -+ CC Labels: REL_20030408_HALdallas_cpsar_01.03.01 -+ -+ This is a SAR only release. The current CPMAC release is still 1.3. -+ -+ Bug fixes: 1) PDSP State RAM / Scratchpad RAM is now completely cleared after reset. -+ This resolves a stability issue. -+ -+ New features: 1) OamMode is now a parameter in halControl(). Both "Set" and "Get" -+ actions are available. The value may be "0" (Host OAM), or "1" -+ (Firmware OAM). -+ -+ Known issues not addressed in this release: -+ 1) Appropriate action for HAL in the case of MallocRxBuffer failing. We -+ are investigating whether the HAL should implement a needs buffer -+ queue. -+ -+04 April 2003 CPHAL 1.3 (external release) -+ -+ CC Labels: REL_20030404_HALdallas_cpmac_01.03.00 -+ REL_20030404_HALdallas_cpsar_01.03.00 -+ REL_20030404_HALdallas_cpaal5_01.03.00 -+ REL_20030404_HALdallas_cpaal2_01.03.00 -+ -+ This release requires no changes for the ethernet end driver. The changes necessary -+ for the sar driver (firmware file name changes) have already been implemented. -+ -+ Bug fixes: 1) RxReturn now returns an error if MallocRxBuffer fails. On RxReturn error, the driver should -+ call RxReturn again at a later time (when the malloc may succeed) in order for the CPHAL -+ to maintain a full complement of Rx buffers. We recommend holding off making this driver -+ change until we verify that this condition occurs. -+ -+ New features: 1) Removed benign compiler warnings. -+ 2) PITS 122: http://www.nbu.sc.ti.com/cgi-bin/pits/redisplay_archive?product=cphal_dev&report=122 -+ 3) Cpsar label (above) now is applied to everything -+ beneath /cpsar. -+ 4) PITS 14: http://www.nbu.sc.ti.com/cgi-bin/pits/redisplay_archive?product=cphal_dev&report=14 -+ Transferred to MR PSP 00000089. -+ 5) PITS 120: http://www.nbu.sc.ti.com/cgi-bin/pits/redisplay_archive?product=cphal_dev&report=120 -+ -+ Known issues not addressed in this release: -+ 1) PITS 102 (as relating to OamMode configuration): -+ http://www.nbu.sc.ti.com/cgi-bin/pits/redisplay_archive?product=cphal_dev&report=102 -+ Future release will make OamMode configurable -+ through halControl(), not on per channel basis. -+ -+20 March 2003 CPHAL 1.2.1 (internal release) -+ -+ CC Labels: REL_20030320_HALdallas_cpmac_01.02.01 -+ REL_20030320_HALdallas_cpsar_01.02.01 -+ REL_20030320_HALdallas_cpaal5_01.02.01 -+ REL_20030320_HALdallas_cpaal2_01.02.01 -+ -+ Bug fixes: 1. Fixed modification of buffer pointer following -+ MallocRxBuffer in cppi.c. -+ 2. Removed extra firmware files from /cpsar. -+ -+ New features: NTR. -+ -+ Known issues not addressed in this release: NTR. -+ -+07 March 2003 CPHAL 1.2 (external release) -+ -+ CPMAC/CPSAR feature complete release. SAR added -+ several features including full OAM support and various -+ other features and bug fixes to address PITS 99-106, and -+ 114. CPMAC cleaned up details raised by India PSP -+ team. -+ -+29 January 2003 CPHAL RC 3.01a (external release) -+ -+ Corrects non-static functions to be static in cppi.c. -+ -+09 Janurary 2003 CPHAL RC 3.01 (external release) -+ -+ PITS 88: Fixed MDIO re-connection problem (hcpmac.c) -+ PITS 90: Corrected Rx Buffer Pointer modification (cppi.c) -+ -+ Corrected error in cpremap.c -+ -+20 December 2002 CPHAL RC 3 (external release) -+ -+ Statistics support via halControl(). See Appendix A of guide. -+ Fixed errors in ChannelTeardown/ChannelSetup CPHAL logic. -+ Added multicast support as requested. -+ Several new OS string functions added to OS_FUNCTIONS. -+ "DebugLevel" configuration parameter changed to "Debug". -+ "Stats0" changed to "StatsDump" for CPMAC. -+ -+13 December 2002 CPHAL RC 2.03 (internal release) -+ -+ Performance improvements. -+ More debug statements implemented (esp AAL5). -+ Updated makefile with "make debug" option. -+ Hbridge performance: [debug library] 15774 tps (53% line rate) -+ [non-debug library] 13700 tps (46%) -+ -+10 December 2002 CPHAL Release Candidate 2.02 (internal release) -+ -+ Much of the configuration code internal to CPMAC and AAL5 has been made common. -+ [os]Receive API had been modified to remove OsReceiveInfo. This information is now -+ available as third member of the FRAGLIST structure, on a per buffer basis. -+ Successfully tested multi-fragment support on CPMAC, using 32 byte buffers. -+ Code is now Emerald compliant - all buffer descriptors now aligned to cache-line -+ boundaries. -+ -+2 December 2002 CPHAL Release Candidate 2.01 -+ -+ Updates to comments in hcpmac.c, cpmdio.c, hcpmac.h -+ Nested comment in hcpmac.c in RC2 can cause compile errors. -+ -+25 November 2002 CPHAL Release Candidate 2 -+ -+Project Items not completed for RC2 -+#6 Ship as Library - Once under CC. Moved to RC3 -+#8 Under Clearcase - Moved to RC3 -+#25 Emerald compliant - Moved to RC3 -+#26 Statistics support - Moved to RC3 (some support in RC2) -+#36 Debug scheme implemented - Moved to RC3 (some support in RC2) -+ -+8 November 2002 CPHAL Release Candidate 1 -+ -+Notes: -+ -+Project Items not completed for RC1 -+ -+#8 Under Clearcase - Clearcase server failure this week. Moved to RC2 -+#6 Ship as Library - Once under CC. Moved to RC2 -+#13 Verify Datatypes. Moved to RC2 -+#14 Review APIs. Moved to RC2 -+ -+APIs under review for RC2 -+ -+halIsr() -+hslRxReturn() -+halSend() -+osSendComplete() -+osReceive() -+ -+ -+CPMAC Build Instructions -+ -+Compile the file 'hcpmac.c'. -+ -+ -+AAL5 Build Instructions -+ -+The AAL5 build is composed of the source files aal5sar.c and cpsar.c. -+Refer to the provided makefile for an example of compiling these files -+into a library. -+ -+Example CPHAL Code -+ -+CPMAC: -+ -+Example CPMAC code is provided in the file hbridge.c. -+This program is provided simply as an example of using the CPHAL API. -+It is not intended to be compiled and executed in your environment. -+ -+AAL5: -+ -+Example AAL5 code is provided in the file loopback.c. This program -+is provided simply as an example of using the CPHAL API. It is not -+intended to be compiled and executed in your environment. -+ -+ -+Performance Baseline -+ -+ -+Cpmac -+ -+RC1: hbridge.bin, running with IXIA cpahl_1.cfg. -+ This sends 64-byte packets from each Ixia port, with mac destination the other Ixia port. -+ MIPS core 4Kc. -+ -+RC2: hbridge.bin, running with IXIA cpahl_1.cfg. -+ This sends 64-byte packets from each Ixia port, with mac destination the other Ixia port. -+ MIPS core 4Ke. -+ CPHAL now includes Emerald support, but this has been disabled by using 'cache -wt' to emulate 4Kc. -+ -+RC3: hbridge.bin, running with IXIA cpahl_1.cfg. -+ This sends 64-byte packets from each Ixia port, with mac destination the other Ixia port. -+ MIPS core 4Ke. -+ Running as Emerald processor. -+ -+Release Total Receive Rate Throughput Setting -+ -+RC1 11300 38% -+RC2 9524 32% -+RC3 15190 51% -diff -urN linux.old/drivers/net/Config.in linux.dev/drivers/net/Config.in ---- linux.old/drivers/net/Config.in 2005-07-12 03:20:45.726149872 +0200 -+++ linux.dev/drivers/net/Config.in 2005-07-12 02:48:42.180573000 +0200 -@@ -25,6 +25,24 @@ - comment 'Ethernet (10 or 100Mbit)' - bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET - if [ "$CONFIG_NET_ETHERNET" = "y" ]; then -+ if [ "$CONFIG_MIPS_TITAN" = "y" -o "$CONFIG_AR7" = "y" ]; then -+ tristate ' Texas Instruments Avalanche CPMAC support' CONFIG_MIPS_AVALANCHE_CPMAC -+ fi -+ if [ "$CONFIG_MIPS_AVALANCHE_CPMAC" != "n" ]; then -+ if [ "$CONFIG_AR7WRD" = "y" -o "$CONFIG_AR7VWI" = "y" -o "$CONFIG_AR7VW" = "y" ]; then -+ define_bool CONFIG_MIPS_CPMAC_INIT_BUF_MALLOC y -+ define_int CONFIG_MIPS_CPMAC_PORTS 1 -+ if [ "$CONFIG_MIPS_AVALANCHE_MARVELL" = "y" ]; then -+ define_bool CONFIG_AVALANCHE_LOW_CPMAC n -+ define_bool CONFIG_AVALANCHE_HIGH_CPMAC y -+ else -+ define_bool CONFIG_AVALANCHE_CPMAC_AUTO y -+ define_bool CONFIG_AVALANCHE_LOW_CPMAC n -+ define_bool CONFIG_AVALANCHE_HIGH_CPMAC n -+ fi -+ fi -+ fi -+ - if [ "$CONFIG_ARM" = "y" ]; then - dep_bool ' ARM EBSA110 AM79C961A support' CONFIG_ARM_AM79C961A $CONFIG_ARCH_EBSA110 - tristate ' Cirrus Logic CS8900A support' CONFIG_ARM_CIRRUS -diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile ---- linux.old/drivers/net/Makefile 2005-07-12 03:20:45.726149872 +0200 -+++ linux.dev/drivers/net/Makefile 2005-07-12 02:48:42.181573000 +0200 -@@ -56,6 +56,16 @@ - subdir-$(CONFIG_BONDING) += bonding - - # -+# Texas Instruments AVALANCHE CPMAC driver -+# -+ -+subdir-$(CONFIG_MIPS_AVALANCHE_CPMAC) += avalanche_cpmac -+#obj-$(CONFIG_MIPS_AVALANCHE_CPMAC) += avalanche_cpmac/avalanche_cpmac.o -+ifeq ($(CONFIG_MIPS_AVALANCHE_CPMAC),y) -+ obj-y += avalanche_cpmac/avalanche_cpmac.o -+endif -+ -+# - # link order important here - # - obj-$(CONFIG_PLIP) += plip.o ---- linux.old/drivers/net/avalanche_cpmac/cpmac.c 2005-08-25 10:56:33.702931008 +0200 -+++ linux.dev/drivers/net/avalanche_cpmac/cpmac.c 2005-08-25 11:08:45.027451520 +0200 -@@ -2158,17 +2158,16 @@ - CPMAC_PRIVATE_INFO_T *p_cpmac_priv = p_dev->priv; - CPMAC_DRV_HAL_INFO_T *p_drv_hal = p_cpmac_priv->drv_hal; - struct sk_buff *p_skb = fragList[0].OsInfo; -- p_skb->len = fragList[0].len; - - /* invalidate the cache. */ - dma_cache_inv((unsigned long)p_skb->data, fragList[0].len); - #ifdef CPMAC_TEST -- xdump(p_skb->data, p_skb->len, "recv"); -+ xdump(p_skb->data, fragList[0].len, "recv"); - #endif - #ifdef CPMAC_8021Q_SUPPORT - /* 802.1q stuff, just does the basic checking here. */ - if(!p_cpmac_priv->enable_802_1q && -- p_skb->len > TCI_END_OFFSET && -+ fragList[0].len > TCI_END_OFFSET && - IS_802_1Q_FRAME(p_skb->data + TPID_START_OFFSET)) - { - goto cpmac_hal_recv_frame_mismatch; |