diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/Config.in uClinux-2.4.27-uc1/drivers/net/Config.in
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/Config.in	2004-12-12 21:48:47.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/Config.in	2005-01-22 16:04:00.000000000 +0100
@@ -296,6 +296,20 @@
       dep_tristate '    D-Link DE600 pocket adapter support' CONFIG_DE600 $CONFIG_ISA
       dep_tristate '    D-Link DE620 pocket adapter support' CONFIG_DE620 $CONFIG_ISA
    fi
+   tristate '  CNXT Emac support' CONFIG_CNXT_EMAC
+   if [ "$CONFIG_CNXT_EMAC" != "n" ]; then
+      if [ "$CONFIG_ARCH_CX821XX" = "y" ]; then
+         define_bool CONFIG_CNXT_EMAC_82 y
+      fi
+      choice '    Number of Ethernet Ports'  " \
+         1   CONFIG_NUM_ETHERNET_IS_1 \
+         2   CONFIG_NUM_ETHERNET_IS_2 \
+         3   CONFIG_NUM_ETHERNET_IS_3 \
+         4   CONFIG_NUM_ETHERNET_IS_4 \
+         "  1
+   else
+      define_bool CONFIG_NUM_ETHERNET_IS_0 y
+   fi
    bool '  FEC ethernet controller (of ColdFire 5272/5282/5280)' CONFIG_FEC
    if [ "$CONFIG_FEC" = "y" ]; then
 	dep_mbool '   enable IOCTL (EXPERIMENTAL)'  CONFIG_FEC_IOCTL $CONFIG_EXPERIMENTAL
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/Makefile uClinux-2.4.27-uc1/drivers/net/Makefile
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/Makefile	2004-12-12 21:48:47.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/Makefile	2005-01-22 16:04:00.000000000 +0100
@@ -285,6 +285,12 @@
 obj-y		+= ../acorn/net/acorn-net.o
 endif
 
+subdir-$(CONFIG_CNXT_EMAC_82)	+= cnxt_emac
+obj-$(CONFIG_CNXT_EMAC_82)	+= cnxt_emac/emac_drv.o
+ifeq ($(CONFIG_CNXT_EMAC_82),m)
+	mod-subdirs	+= cnxt_emac
+endif
+
 #
 # HIPPI adapters
 #
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/Space.c uClinux-2.4.27-uc1/drivers/net/Space.c
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/Space.c	2004-12-12 21:48:47.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/Space.c	2005-01-22 16:04:00.000000000 +0100
@@ -92,6 +92,7 @@
 extern int bionet_probe(struct net_device *);
 extern int pamsnet_probe(struct net_device *);
 extern int cs89x0_probe(struct net_device *dev);
+extern int emac_probe(struct net_device *dev);
 extern int ep93xxEth_probe(struct net_device *dev);
 extern int ethertap_probe(struct net_device *dev);
 extern int hplance_probe(struct net_device *dev);
@@ -413,6 +414,9 @@
 #ifdef CONFIG_C5471_NET
 	{c5471_net_probe, 0},
 #endif
+#ifdef CONFIG_CNXT_EMAC				/* CX821xx      */
+	{emac_probe, 0},
+#endif
 
         {NULL, 0},
 };
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/Makefile uClinux-2.4.27-uc1/drivers/net/cnxt_emac/Makefile
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/Makefile	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,17 @@
+# File: drivers/net/cnxt_emac/Makefile
+#
+# Makefile for the Linux Conexant emac driver.
+#
+
+O_TARGET := emac_drv.o
+
+EXTRA_CFLAGS += -DOS_LINUX -DLINUX_EMBEDDED	-DLINUX_DRIVER
+
+obj-y += cnxtEmac.o \
+	 phy.o \
+	 mii.o
+# JH: does not compile, disabled:	 tesla.o
+
+obj-m := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac.c uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac.c
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac.c	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac.c	2005-01-20 21:45:59.000000000 +0100
@@ -0,0 +1,3295 @@
+/****************************************************************************
+*
+*	Name:			cnxtEmac.c
+*
+*	Description:	Emac driver for CX821xx products
+*
+*	Copyright:		(c) 2001,2002 Conexant Systems Inc.
+*					Personal Computing Division
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************
+*  $Author:   richarjc  $
+*  $Revision:   1.14  $
+*  $Modtime:   Aug 08 2003 08:13:00  $
+****************************************************************************/
+
+static char *version =
+"EMAC Network Driver Cnxt 2003/07/16";
+
+/* Always include 'config.h' first in case the user wants to turn on
+   or override something. */
+#define __KERNEL_SYSCALLS__
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/unistd.h>
+#include <linux/config.h>
+
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <linux/errno.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/arch/bspcfg.h>
+#include <asm/hardware.h>
+#include "osutil.h"
+#include <asm/arch/irq.h>
+#include <asm/arch/sysmem.h>
+#include "cnxtEmac.h"
+#include <asm/delay.h>
+
+#if HOMEPLUGPHY
+#include "tesla.h"
+#endif
+
+#define SDRAM_TX_MEM			1
+#define HW_RESET_EVENT			1
+#define EMAC_TX_WD_TIMER		1
+#define EMAC_MUTUALLY_EX_OPR	1
+#define EMAC_CHK_HW_4_MUTEX_OPR	0
+#define	TX_FULL_DUPLEX			1
+#define RX_SKB_DEBUG			0
+#define SETUP_FRAME_VERIFY		0
+#define RX_TASKLET				1
+#define TX_TASKLET				0
+#define	TX_DMA_INT				0
+#define	RX_DMA_INT				1
+#define USE_TU_INTERRUPT		1
+#define USE_HASHTABLE			0
+#define	EMAC_ISR_ERR_MSG_PRINT	1
+#define EMAC_DISABLE_CHK		1
+#define EMAC_TX_UDELAY			1
+
+#define RX_COPY_MEMORY( pDest, pSrc, size ) memcpy( pDest, pSrc, size )
+#define TX_COPY_MEMORY( pDest, pSrc, size ) memcpy( pDest, pSrc, size )
+
+#if CONFIG_CPU_ARM940_D_CACHE_ON
+#define EMAC_KMALLOC(s,flg)     emac_AllocNonCachedMem((s),(flg))
+#define	EMAC_KFREE(p)			
+#else
+#define EMAC_KMALLOC(s,flg)     kmalloc((s),(flg))
+#define	EMAC_KFREE(p)			kfree(p)
+#endif
+
+#define	DWORD_ALIGN_IP_HDR	2
+#define TX_TIMEOUT_DELAY	15		// 150 ms delay
+//#define TX_TIMEOUT_DELAY	10		// 100 ms delay
+#define	TX_MSG_Q_THRESHOLD			4
+#define	TX_MSG_Q_AWAKE_THRESHOLD	TX_MSG_Q_THRESHOLD + 0
+//#define	TX_MSG_Q_THRESHOLD	TX_RING_SIZE
+#define LOW_QWORD_MASK		0xFFFFFFF0
+
+#define SLAVE_ADDRESS		0xA0	// bit 1 is page block number
+#define CLOSED				FALSE
+#define	OPEN				TRUE
+#define	DRAM_8M_SIZE		0x800000
+#define	ENABLED				1
+
+#if CONFIG_NUM_ETHERNET_IS_1
+	#define MAX_ETH_PORTS	1
+#endif
+
+#if CONFIG_NUM_ETHERNET_IS_2
+	#define MAX_ETH_PORTS	2
+#endif
+
+#if CONFIG_NUM_ETHERNET_IS_3
+	#define MAX_ETH_PORTS	3
+#endif
+
+#if CONFIG_NUM_ETHERNET_IS_4
+	#define MAX_ETH_PORTS	4
+#endif
+
+// NOTE: EMAC_tx_pkt_q2 will be the common tx queue for
+// mutually exclusive transmitter operation.
+DATA_QUEUE_T	*EMAC_tx_pkt_q1;
+DATA_QUEUE_T	*EMAC_tx_pkt_q2;	
+
+DWORD			EMAC_num_in_operation = NONE;
+DWORD			EMAC_hdw_cntr = 0;
+DWORD			unhandled_emac_tx_error = 0;
+DWORD			emac_rx_proc_no_skb;
+struct net_device	*emac_dev[MAX_ETH_PORTS];
+BOOLEAN			emac_mutually_ex_opr;
+
+#define RX_LOOKBACK_THRESHOLD	20
+WORD	rx_lookback_idx[RX_RING_SIZE];
+
+#if SETUP_FRAME_VERIFY
+BOOLEAN		sf_verify;
+#endif
+
+// Emac 1 registers
+volatile unsigned long* DMAC_1_Ptr1 = (unsigned long*)0x00300000;
+volatile unsigned long* DMAC_1_Ptr2 = (unsigned long*)0x00300030;
+volatile unsigned long* DMAC_2_Ptr2 = (unsigned long*)0x00300034;
+volatile unsigned long* DMAC_1_Cnt1 = (unsigned long*)0x00300060;
+volatile unsigned long* DMAC_2_Cnt1 = (unsigned long*)0x00300064;
+volatile unsigned long* DMAC_2_Cnt2 = (unsigned long*)0x00300094;
+
+// Emac 2 registers
+volatile unsigned long* DMAC_3_Ptr1 = (unsigned long*)0x00300008;
+volatile unsigned long* DMAC_3_Ptr2 = (unsigned long*)0x00300038;
+volatile unsigned long* DMAC_4_Ptr2 = (unsigned long*)0x0030003C;
+volatile unsigned long* DMAC_3_Cnt1 = (unsigned long*)0x00300068;
+volatile unsigned long* DMAC_4_Cnt1 = (unsigned long*)0x0030006C;
+volatile unsigned long* DMAC_4_Cnt2 = (unsigned long*)0x0030009C;
+
+volatile unsigned long* INT_Stat = (unsigned long*)0x00350044;
+volatile unsigned long* INT_Msk = (unsigned long*)0x0035004c;
+volatile unsigned long* INT_MStat = (unsigned long*)0x00350090;
+
+volatile unsigned long* E_STAT_1_reg	= (volatile unsigned long*)0x00310008;
+volatile unsigned long* E_NA_1_reg  	= (volatile unsigned long*)0x00310004;
+volatile unsigned long* E_IE_1_reg	 	= (volatile unsigned long*)0x0031000C;
+volatile unsigned long* E_LP_1_reg	 	= (volatile unsigned long*)0x00310010;
+
+volatile unsigned long* E_STAT_2_reg	= (volatile unsigned long*)0x00320008;
+volatile unsigned long* E_NA_2_reg  	= (volatile unsigned long*)0x00320004;
+volatile unsigned long* E_IE_2_reg		= (volatile unsigned long*)0x0032000C;
+volatile unsigned long* E_LP_2_reg		= (volatile unsigned long*)0x00320010;
+
+volatile unsigned long* M2M_Cnt   = (volatile unsigned long* ) 0x00350004;
+volatile unsigned long* DMA7_Ptr1 = (volatile unsigned long* ) 0x00300018;
+volatile unsigned long* DMA8_Ptr1 = (volatile unsigned long* ) 0x0030001C;
+
+#define NUM_EMACS		2
+#define	MAC_ADDR_OFFSET_SIZE	1
+#define ADDRESS_FILTER_SIZE   192
+
+extern void CnxtBsp_Get_Mac_Address( int emac_num, char *mac_addr_array );
+extern int cnxt_irq_mask_state_chk( unsigned int irq_num );
+extern PHY_STATUS PhyConnectSet(PHY *phy, DWORD connect);
+extern void TaskDelayMsec(UINT32 TimeDuration);
+extern BOOLEAN CnxtBsp_Mac_MutEx_Chk( void );
+
+static int EMAC_restart_hw( struct net_device *dev, BOOLEAN flush_txq, BOOLEAN flush_rxq );
+static int EMAC_restart_rx( struct net_device *dev, BOOLEAN flush_rxq );
+
+/* Index to functions, as function prototypes. */
+int emac_probe(struct net_device *dev);
+#if USE_HASHTABLE
+	static void SetupHashTable(struct net_device *dev);
+#endif
+void ResetChip( EMAC_DRV_CTRL *thisadapter );
+
+static int emac_open(struct net_device *dev);
+static int emac_send_packet(struct sk_buff *skb, struct net_device *dev);
+static int emac_close(struct net_device *dev);
+static struct net_device_stats *emac_get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+
+void EMAC_Linkcheck(EMAC_DRV_CTRL *thisadapter, BOOLEAN force_update );
+BOOLEAN emac_SetupFrame ( struct net_device *dev );
+
+#if RX_SKB_DEBUG
+	static void skb_debug(const struct sk_buff *skb)
+	{
+	#define NUM2PRINT 80
+		char buf[NUM2PRINT * 3 + 1];	/* 3 chars per byte */
+		int i = 0;
+		for (i = 0; i < skb->len && i < NUM2PRINT; i++) {
+			sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
+		}
+		printk("skb->data: %s\n", buf);
+	}
+#endif
+
+#if CONFIG_CPU_ARM940_D_CACHE_ON
+
+/******************************************************************************
+|
+|  Function:    emacAllocNonCachedMem
+|
+|  Description: This function emulate the calloc () call to allocate a block
+|               of memory space from the non-cached memory space.  When DATA
+|               Cache is turned on, EMAC must use the non-cached memory space
+|               for its Tx descriptors, Rx descriptors, and data buffers which
+|               will be accessed by DMA.
+|
+|  Parameters:  size_t  n       number of memory elements
+|               size_t  size    number of bytes for each memory elements
+|
+|  Returns:     void    *pMem   pointer to the start of the memory allocated
+|               NULL            don't have enough room for the requested space
+|
+*******************************************************************************/
+
+void *emac_AllocNonCachedMem ( size_t size, int flags )
+{
+	// Request non-cached SDRAM memory
+	return SYSMEM_Allocate_BlockMemory( 0, (int) size, 16);
+}
+#endif
+
+DWORD	emac1_tx_reset = 0;
+DWORD	emac2_tx_reset = 0;
+DWORD	emac1_rx_reset = 0;
+DWORD	emac2_rx_reset = 0;
+
+void EMAC_Disabled_Check( struct net_device *dev )
+{
+	EMAC_DRV_CTRL *thisadapter = ( EMAC_DRV_CTRL *)dev->priv; 
+
+	if
+	(		
+		//	thisadapter->phyState.duplexMode == PHY_STAT_DUPLEX_HALF
+		//&&	thisadapter->emac_state == OPEN
+			thisadapter->emac_state == OPEN
+		&&	thisadapter->hw_reset_required == TRUE
+	)
+	{
+		thisadapter->hw_reset_required = FALSE;
+		switch( thisadapter->emac_num )
+		{
+			// emac1
+			case 1:
+				emac1_tx_reset++;
+				break;
+
+			case 2:
+				emac2_tx_reset++;
+				break;
+		}
+
+		// Tell the OS we are closed
+		netif_stop_queue(dev);
+
+		// Restart the hardware to bring it into a known state
+		EMAC_restart_hw( dev, TRUE, TRUE );
+	}
+}
+
+
+/*
+	 Parameters :
+		BOOLEAN Port_Mii: 
+			TRUE: configure MAC MII interface
+			FALSE: configure MAC 7WS interface 
+		BOOLEAN Speed100m: 
+			TRUE: configure MAC device speed 100M
+			FALSE: configure MAC device speed 1/10M
+		BOOLEAN Full_Duplex:
+			TRUE: configure MAC full duplex
+			FALSE: configure MAC half duplex
+*/
+void EMACHW_Configure_Mac
+(
+	EMAC_DRV_CTRL	*thisadapter,
+	int 			Port_Mii,
+	int 			Speed100m,
+	int 			Full_Duplex
+)
+{
+	unsigned long E_NA_settings ;
+
+	// don't care Port_Mii, CX82100 do not support 7WS mode
+	E_NA_settings = *thisadapter->emac_na_reg;
+
+	// Set default conditions
+	E_NA_settings &= ~(E_NA_NS|E_NA_FD);
+
+	if( !Speed100m)
+	{ 
+		E_NA_settings |= E_NA_NS;	// 10m
+	}
+
+	if( Full_Duplex )
+	{
+		E_NA_settings |= E_NA_FD;   // Full Duplex 
+	}
+
+	*thisadapter->emac_na_reg = E_NA_settings;
+	thisadapter->E_NA_settings = E_NA_settings;
+
+// related to ADI DSLAM/>6 Mbps/Win XP/FTP issue.  During FTP transfer, session dies but
+// it will work if we force 10 HDX
+	if ( thisadapter->phyState.linkStatus == PHY_STAT_LINK_UP )
+	{
+		if( !Speed100m && !Full_Duplex )
+		{
+			PhyConnectSet( thisadapter->pPhy, PHY_CONN_10BASE_T );
+		}
+	}
+	else
+	{
+		PhyConnectSet( thisadapter->pPhy, PHY_CONN_AUTONEG_ALL_MEDIA );
+	}
+
+#if 0
+	if( thisadapter->emac_num == 1)
+	{
+		printk("\neth0 hw update: ");
+		if( !Speed100m)
+		{ 
+			printk(" 10M");
+		}
+		else
+		{
+			printk(" 100M");
+		}
+		if( Full_Duplex )
+		{ 
+			printk(" FULL\n");
+		}
+		else
+		{
+			printk(" HALF\n");
+		}
+		if( emac_mutually_ex_opr == FALSE )
+		{
+			printk("emac_mutually_ex_opr = FALSE\n");
+		}
+		else
+		{
+			printk("emac_mutually_ex_opr = TRUE\n");
+		}
+		if(thisadapter->phyState.linkStatus == PHY_STAT_LINK_UP)
+		{
+			printk("PHY_LINK_UP\n");
+		}
+		else
+		{
+			printk("PHY_LINK_DOWN\n");
+		}
+	}
+#endif
+}
+
+
+BOOL EMAC_GetPortConfig( int dev_num,  EMAC_DRV_CTRL *pthisadapter )
+{
+    pthisadapter->MacFilteringMode = 2; 		// Not sure if we need this
+    pthisadapter->phyState.autoNegotiate = 1;	// 0: disable,  1: enable
+    pthisadapter->phyState.networkSpeed = 1; 	// 0: 10M,  1: 100M
+    pthisadapter->phyState.duplexMode = 1;		// 0: HDX,  1: FDX
+
+    return TRUE;
+}
+
+
+/******************************************************************************
+|
+|  Function:    EMAC_MapToPhyConn
+|
+|  Description: Convert PHY settings to PHY_CONN_XXXX as defined in phy.h
+|               established link rate
+|
+|  Parameters:  *pPhySettings - pointer to PHY_SETTING structure containing
+|                               speed/duplex configurations
+|
+|  Returns:     The PHY_CONN_XXXX corresponds to the specified PHY configurations
+|
+*******************************************************************************/
+
+UINT32 EMAC_MapToPhyConn ( PHY_SETTING *pPhySettings )
+{
+    UINT32  conn;
+
+    if ( pPhySettings->autoNegotiate == PHY_AUTONEGOTIATE )
+	{
+        conn = PHY_CONN_AUTONEG_ALL_MEDIA;
+	}
+    else
+    {
+        if ( pPhySettings->networkSpeed == PHY_STAT_SPEED_100 )
+        {
+            if ( pPhySettings->duplexMode == PHY_STAT_DUPLEX_FULL )
+			{
+                conn = PHY_CONN_100BASE_TXFD | PHY_CONN_AUTONEG;
+			}
+            else
+			{
+                conn = PHY_CONN_100BASE_TX;
+			}
+        }
+        else
+        {
+            if ( pPhySettings->duplexMode == PHY_STAT_DUPLEX_FULL )
+			{
+                conn = PHY_CONN_10BASE_TFD | PHY_CONN_AUTONEG;
+            }
+            else
+            {
+                conn = PHY_CONN_10BASE_T;
+			}
+        }
+    }
+    return ( conn );
+}
+
+	
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Queue_Data
+		
+ABSTRACT:
+		Places data on the queue of the data queue context
+		Returns TRUE if successful.  FALSE if not.
+
+  		This function is intended to be called from within an interrupt handler
+		therefor it does not wrap the checking of the queue status with IRQ protection.
+		
+DETAILS:
+		Returns TRUE if the data queueing operation was successful.
+
+*******************************************************************************/
+
+static BOOLEAN EMAC_Queue_Data
+(
+	DATA_QUEUE_T	*QueueCtx,	// Data queue context
+	DWORD			Data1,		// Data1 value to be queued
+	DWORD			Data2		// Data2 value to be queued
+)
+{
+
+	DATA_REG_T *data_q_entry;
+	
+	// Is there room for the data on the queue?
+	if ( QueueCtx->entry_cnt < SIZE_OF_DATA_QUEUES )
+	{
+		// Put the data on the queue context given to us
+		data_q_entry = &QueueCtx->queue[ QueueCtx->put_idx++ ];
+		data_q_entry->Data2 = Data2;
+		data_q_entry->Data1 = Data1;
+
+		// Process the put index to account for queue wrapping
+		QueueCtx->put_idx %= SIZE_OF_DATA_QUEUES;
+
+		// Indicate an entry was placed on the queue
+		QueueCtx->entry_cnt++;
+
+		// Response successfully put on queue
+		return TRUE;
+
+	}
+	else
+	{
+		// Response was not put on queue because it was full.
+		return FALSE;
+	}
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Dequeue_Data
+		
+ABSTRACT:
+		Removes data from the queue of the data queue context
+		Returns TRUE if successful.  FALSE if not.
+
+  		This function is intended to be called from within an interrupt handler
+		therefor it does not wrap the checking of the queue status with IRQ protection.
+		
+DETAILS:
+		Returns TRUE if the data dequeueing operation was successful.
+
+*******************************************************************************/
+
+static BOOLEAN EMAC_Dequeue_Data
+(
+	DATA_QUEUE_T	*QueueCtx,	// Data queue context
+	DWORD           *Data1,		// Pointer to variable to be filled with dequeued Data1 value
+	DWORD 			*Data2		// Pointer to variable to be filled with dequeued Data2 value
+)
+{
+	DATA_REG_T *data_q_entry;
+	
+	// Is there data on the queue?
+	if ( QueueCtx->entry_cnt > 0 )
+	{
+		// Get data entries from the queue context given to us
+		data_q_entry = &QueueCtx->queue[ QueueCtx->get_idx++ ];
+		*Data2 = data_q_entry->Data2;
+		*Data1 = data_q_entry->Data1;
+
+		// Process the get index to account for queue wrapping
+		QueueCtx->get_idx %= SIZE_OF_DATA_QUEUES;
+
+		// Indicate an entry was removed from the queue
+		QueueCtx->entry_cnt--;
+
+		// Response successfully dequeued
+		return TRUE;
+
+	}
+	else
+	{
+		// No response to remove from the queue.
+		return FALSE;
+	}
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Queue_Count
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+static DWORD EMAC_Queue_Count( DATA_QUEUE_T *QueueCtx )
+{
+	return	QueueCtx->entry_cnt;	
+}
+	
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Queue_Tx_Pkt
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+static void EMAC_Queue_Tx_Pkt
+(
+	struct net_device	*dev,
+	DWORD				tx_entry
+)
+{
+	EMAC_DRV_CTRL	*thisadapter=(EMAC_DRV_CTRL*)dev->priv;
+
+	// Always queue the ethernet tx packet to be sent
+	if( EMAC_Queue_Data( thisadapter->emac_tx_q, (DWORD)dev, tx_entry ) == FALSE )
+	{
+		// Queuing of data failed!!
+		printk( KERN_DEBUG "%s transmit queue full!\n", dev->name );
+	}
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Tx_Pkt_Transmit
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+static void EMAC_Tx_Pkt_Transmit( struct net_device *pdevice )
+{
+	EMAC_DRV_CTRL	*pthisadapter;
+	DWORD			tx_entry_num;
+	DWORD			buf_ptr;
+	DWORD			buf_len;
+    ULONG			*pL;
+    unsigned int	idx;
+	unsigned long	flags;
+
+	pthisadapter = ( EMAC_DRV_CTRL *)pdevice->priv;
+
+#if EMAC_MUTUALLY_EX_OPR
+	// Check for transmission of an ethernet packet already in progress.
+	// The value contained in EMAC_num_in_operation represents the emac
+	// device that currently is in operation in mutually exclusive operation.
+	
+	if
+	(
+			( emac_mutually_ex_opr == FALSE && pthisadapter->tx_pkt_in_progress == FALSE )
+		||	( emac_mutually_ex_opr == TRUE && EMAC_num_in_operation == NONE )
+	)
+	{
+		// Get the next tx ethernet packet to be sent
+		if( EMAC_Dequeue_Data( pthisadapter->emac_tx_q, (DWORD *)&pdevice, &tx_entry_num ) == FALSE )
+		{
+			// No more ethernet tx data to send on either emac
+			return;
+		}
+		
+		pthisadapter = (EMAC_DRV_CTRL*)pdevice->priv;
+		
+		// Indicate which EMAC is currently in operation 
+		//  AND
+		// that it has a transmit packet in progress.
+		EMAC_num_in_operation = pthisadapter->emac_num;
+		pthisadapter->tx_pkt_in_progress = TRUE;
+		
+		buf_ptr = (DWORD)(pthisadapter->tx_msg_q[ tx_entry_num ]).Data;
+		buf_len = (DWORD)(pthisadapter->tx_msg_q[ tx_entry_num ]).ulLength;
+		
+		// Program the DMA registers to transfer the ethernet packet into the TMAC.
+		*pthisadapter->emac_tx_dma_ptr = (ULONG) buf_ptr;
+		*pthisadapter->emac_tx_dma_cnt = (ULONG) buf_len;		// # of QWORDs to transfer
+
+		if(	emac_mutually_ex_opr == TRUE )
+		{
+			*pthisadapter->emac_tx_dma_ptrx = (ULONG) buf_ptr;
+		}
+
+		// Compute dword (UINT32) offset to the end of the data in the txd buffer.
+		// Since ulLength is in QWORDS, the number of DWORDS is 2 times ulLength.
+		idx = (unsigned int)( buf_len << 1 );
+
+		// Add the END TMAC TRANSMIT DESCRIPTOR pointer and qword count
+		// to the end of the txd message buffer.
+
+		// Get the txd buffer starting address.
+		pL          = (ULONG*)buf_ptr;
+		
+		// Write the pointer to the END transmit frame structure.
+	    pL[idx]		= (ULONG)(pthisadapter->TxD_end);
+
+		// Initialize the QWORD count used by the DMA to xfer
+		// the END transmit frame structure to the TMAC.
+		pL[idx + 1]	= (ULONG) 3;
+
+		// Indicate which tx_msg we are currently sending
+		pthisadapter->tx_msg_q_current = tx_entry_num;
+		
+		// Indicate there is one less message in the tx queue
+		if( pthisadapter->tx_msg_q_size > 0 )
+		{
+			pthisadapter->tx_msg_q_size--;
+		}
+		
+		// Put a time stamp on the message
+		pdevice->trans_start = jiffies;
+
+		// Begin the DMA transfer of the START transmit descriptor into the TMAC.
+		*pthisadapter->emac_na_reg = (pthisadapter->E_NA_settings | E_NA_STRT);
+	#if EMAC_TX_WD_TIMER
+		#if 1
+		// Disable interrupts
+		local_irq_save(flags);
+
+		#endif
+		// Start the timer that will check for missed emac tx dma interrupts
+		mod_timer(&pthisadapter->wd_timer, jiffies + TX_TIMEOUT_DELAY );
+		#if 1
+
+		// Reenable interrupts
+		local_irq_restore(flags);
+		#endif
+	#endif
+	}
+#else
+
+	if( pthisadapter->tx_pkt_in_progress == FALSE )
+	{
+		// Get the next tx ethernet packet to be sent
+		if( EMAC_Dequeue_Data( pthisadapter->emac_tx_q, (DWORD *)&pdevice, &tx_entry_num ) == FALSE )
+		{
+			// No more ethernet tx data to send on either emac
+			return;
+		}
+		
+		pthisadapter = (EMAC_DRV_CTRL*)pdevice->priv;
+		
+		// Indicate which EMAC is currently in operation 
+		//  AND
+		// that it has a transmit packet in progress.
+		EMAC_num_in_operation = pthisadapter->emac_num;
+		pthisadapter->tx_pkt_in_progress = TRUE;
+		
+		buf_ptr = (DWORD)(pthisadapter->tx_msg_q[ tx_entry_num ]).Data;
+		buf_len = (DWORD)(pthisadapter->tx_msg_q[ tx_entry_num ]).ulLength;
+		
+		// Program the DMA registers to transfer the ethernet packet into the TMAC.
+		*pthisadapter->emac_tx_dma_ptr = (ULONG) buf_ptr;
+		*pthisadapter->emac_tx_dma_cnt = (ULONG) buf_len;		// # of QWORDs to transfer
+
+		// Compute dword (UINT32) offset to the end of the data in the txd buffer.
+		// Since ulLength is in QWORDS, the number of DWORDS is 2 times ulLength.
+		idx = (unsigned int)( buf_len << 1 );
+
+		// Add the END TMAC TRANSMIT DESCRIPTOR pointer and qword count
+		// to the end of the txd message buffer.
+
+		// Get the txd buffer starting address.
+		pL          = (ULONG*)buf_ptr;
+		
+		// Write the pointer to the END transmit frame structure.
+	    pL[idx]		= (ULONG)(pthisadapter->TxD_end);
+
+		// Initialize the QWORD count used by the DMA to xfer
+		// the END transmit frame structure to the TMAC.
+		pL[idx + 1]	= (ULONG) 3;
+
+		// Indicate which tx_msg we are currently sending
+		pthisadapter->tx_msg_q_current = tx_entry_num;
+		
+		// Indicate there is one less message in the tx queue
+		if( pthisadapter->tx_msg_q_size > 0 )
+		{
+			pthisadapter->tx_msg_q_size--;
+		}
+
+		// Begin the DMA transfer of the START transmit descriptor into the TMAC.
+		*pthisadapter->emac_na_reg = (pthisadapter->E_NA_settings | E_NA_STRT);
+
+		// Put a time stamp on the message
+		pdevice->trans_start = jiffies;
+	}
+#endif
+}	
+
+void EMAC_Tx_Err_Cnt( EMAC_DRV_CTRL *thisadapter )
+{
+    register unsigned long 	estatus;
+    	
+	estatus = *thisadapter->emac_stat_reg;
+	*thisadapter->emac_stat_reg = estatus;
+
+    if ( estatus & E_S_TOF )	
+    {
+		#if EMAC_ISR_ERR_MSG_PRINT
+		printk( KERN_DEBUG "ETH%d: TX FIFO overflow\n", thisadapter->unit);  
+		#endif
+		thisadapter->stats.tx_fifo_errors++;
+		thisadapter->stats.tx_errors++;
+    }
+    if ( estatus & E_S_TUF )	
+    {
+		#if EMAC_ISR_ERR_MSG_PRINT
+		printk( KERN_DEBUG "ETH%d: TX FIFO underflow\n", thisadapter->unit);  
+		#endif
+		thisadapter->stats.tx_fifo_errors++;
+		thisadapter->stats.tx_errors++;
+    }
+
+	if ( estatus & E_S_RLD )
+	{
+		thisadapter->stats.collisions += (estatus & TSTAT_CC);	
+	}
+    if ( estatus & E_S_ED )	
+    {
+    }
+    if ( estatus & E_S_DF )	
+    {
+    }
+    if ( estatus & E_S_TF )	
+    {
+    }
+    if ( estatus & E_S_TJT )	
+    {
+    }
+}
+
+/******************************************************************************
+|
+|  Function:  EMAC_Tx_Pkt_Done
+|
+|  Description:  
+
+|  Parameters:  
+|
+|  Returns:
+*******************************************************************************/
+
+static BOOLEAN	EMAC_Tx_Pkt_Done(struct net_device *dev )
+{
+    TX_MSG_QUEUE	tx_msg;
+	unsigned long	flags;
+	BOOLEAN			status = FALSE;
+
+	EMAC_DRV_CTRL 	*thisadapter=( EMAC_DRV_CTRL *)dev->priv; 
+
+#if EMAC_MUTUALLY_EX_OPR
+	// Disable interrupts
+	local_irq_save(flags);
+
+	// Did this EMAC really have a tx packet transmission in progress?
+	if( emac_mutually_ex_opr == FALSE || EMAC_num_in_operation == thisadapter->emac_num )
+	{
+		EMAC_num_in_operation = NONE;
+		thisadapter->tx_pkt_in_progress = FALSE;
+				
+		if( netif_queue_stopped(dev))
+		{
+			if ( (TX_RING_SIZE - thisadapter->tx_msg_q_size) > TX_MSG_Q_AWAKE_THRESHOLD )
+			{
+				netif_wake_queue( dev );
+			}
+		}
+
+		tx_msg = thisadapter->tx_msg_q[ thisadapter->tx_msg_q_current ];
+
+		// Reenable interrupts
+		local_irq_restore(flags);
+
+		if( ((EMAC_TXD *)tx_msg.Data)->status & (TSTAT_TDN | TSTAT_CD) )
+		{
+			status = TRUE;
+			thisadapter->stats.tx_packets++;
+			thisadapter->stats.tx_bytes += (DWORD)tx_msg.ulLength;
+		#if 1
+		// DOES THIS NEED TO BE MOVED OUTSIDE OF THE IF-ELSE STATEMENT
+		// TO THE END OF THE FUNCTION ????
+			// Disable interrupts
+			local_irq_save(flags);
+
+			EMAC_Tx_Pkt_Transmit( dev );
+
+			// Reenable interrupts
+			local_irq_restore(flags);
+		#endif
+		}
+		else
+		{
+			EMAC_Tx_Err_Cnt( thisadapter );
+		}
+	}
+	else
+	{
+		// Reenable interrupts
+		local_irq_restore(flags);
+	}
+#else
+	thisadapter->tx_pkt_in_progress = FALSE;
+			
+	tx_msg = thisadapter->tx_msg_q[ thisadapter->tx_msg_q_current ];
+
+	if( netif_queue_stopped(dev))
+	{
+		netif_wake_queue( dev );
+	}
+
+	if( ((EMAC_TXD *)tx_msg.Data)->status & (TSTAT_TDN | TSTAT_CD) )
+	{
+		status = TRUE;
+		thisadapter->stats.tx_packets++;
+		thisadapter->stats.tx_bytes += (DWORD)tx_msg.ulLength;
+		// Disable interrupts
+		local_irq_save(flags);
+
+		EMAC_Tx_Pkt_Transmit( dev );
+
+		// Reenable interrupts
+		local_irq_restore(flags);
+	}
+	else
+	{
+		EMAC_Tx_Err_Cnt( thisadapter );
+	}
+
+#endif
+	return status;
+}
+
+
+#if (TX_FULL_DUPLEX && EMAC_MUTUALLY_EX_OPR)
+
+/******************************************************************************
+|
+|  Function:  EMAC_Mutually_Ex_Op_Chk
+|
+|  Description:
+|			   
+|  Parameters:  
+|
+|  Returns:
+*******************************************************************************/
+
+static void EMAC_Mutually_Ex_Op_Chk( struct net_device *dev )
+{
+	unsigned int		idx;
+	DWORD				tx_entry_num;
+	struct net_device	*pdevice;	
+	unsigned long		flags;
+	
+
+	EMAC_DRV_CTRL	*thisadapter= (EMAC_DRV_CTRL *)dev->priv;
+
+	// Check for emac mutually exclusive transmitter operation
+	if(	thisadapter->emac_num == 1 )
+	{
+		// Disable interrupts
+		local_irq_save(flags);
+
+		// Half Duplex
+		if(		(thisadapter->phyState.duplexMode == PHY_STAT_DUPLEX_HALF)
+#if EMAC_CHK_HW_4_MUTEX_OPR
+			&&	(thisadapter->tx_mutex_part)
+#endif
+			&&	(emac_mutually_ex_opr == FALSE) )
+		{
+			printk( KERN_DEBUG "eth0 changing to half duplex mutually exclusive operation.\n");
+			emac_mutually_ex_opr = TRUE;
+			thisadapter->emac_tx_q = EMAC_tx_pkt_q2;
+			
+			// Clear out the emac 1 transmit packet queue of 
+			// any queued transmit packets and put them	on
+			// the common emac transmit queue.
+			idx = EMAC_Queue_Count( EMAC_tx_pkt_q1 );
+			if( idx != 0 )
+			{
+				do
+				{
+					// Get an entry from the emac 1 tx pkt q
+					EMAC_Dequeue_Data( EMAC_tx_pkt_q1, (DWORD *)&pdevice, &tx_entry_num );
+
+					// Now put it on the common transmit queue
+					if( EMAC_Queue_Data( EMAC_tx_pkt_q2, (DWORD)pdevice, tx_entry_num ) == FALSE )
+					{
+						// Queuing of data failed!!
+						printk("EMAC2 transmit queue full!\n");
+						break;
+					}
+					idx--;		
+				} while( idx != 0 );	
+			}
+		}
+		
+		// Full Duplex
+		if( (thisadapter->phyState.duplexMode == PHY_STAT_DUPLEX_FULL) && emac_mutually_ex_opr == TRUE )
+		{
+			printk( KERN_DEBUG "eth0 changing to full duplex simultaneous operation.\n");
+			// When leaving mutually exclusive transmitter operation
+			// flush the common emac transmitter queue of any
+			// tx packets for emac 1 and put them on the emac 1 queue.
+			emac_mutually_ex_opr = FALSE;
+			thisadapter->emac_tx_q = EMAC_tx_pkt_q1;
+			
+			idx = EMAC_Queue_Count( EMAC_tx_pkt_q2 );
+			if( idx != 0 )
+			{
+				do
+				{
+					// Get an entry from the common tx pkt q
+					EMAC_Dequeue_Data( EMAC_tx_pkt_q2, (DWORD *)&pdevice, &tx_entry_num );
+
+					// If it is not emac 1 then return it to the common tx pkt q 
+					if( pdevice != dev )
+					{
+						if( EMAC_Queue_Data( EMAC_tx_pkt_q2, (DWORD)pdevice, tx_entry_num ) == FALSE )
+						{
+							// Queuing of data failed!!
+							printk("EMAC2 transmit queue full!\n");
+							break;
+						}
+					}
+					else
+					{
+						if( EMAC_Queue_Data( EMAC_tx_pkt_q1, (DWORD)pdevice, tx_entry_num ) == FALSE )
+						{
+							// Queuing of data failed!!
+							printk("EMAC1 transmit queue full!\n");
+							break;
+						}
+					}
+					idx--;		
+				} while( idx != 0 );	
+			}
+		}
+		
+		// Reenable interrupts
+		local_irq_restore(flags);
+	}
+}	
+#endif
+
+
+/******************************************************************************
+|
+|  Function:  EMAC_stop_hw
+|
+|  Description:  restarts the hardware and attempts to retransmit the
+|				last ethernet packet
+|  Parameters:  
+|
+|  Returns:    OK on success, ERROR otherwise.
+*******************************************************************************/
+
+void EMAC_stop_hw( struct net_device *dev)
+{
+
+ 	EMAC_DRV_CTRL	*thisadapter= (EMAC_DRV_CTRL *)dev->priv;
+
+    cnxt_mask_irq( dev->irq );
+
+#if TX_DMA_INT
+    cnxt_mask_irq( thisadapter->tx_dma_int );	
+#endif
+#if RX_DMA_INT
+    cnxt_mask_irq( thisadapter->rx_dma_int );	
+#endif
+	
+	netif_stop_queue(dev);
+
+	/* Clear the status registers  */
+	*INT_Stat = thisadapter->int_stat_clr_dev_irq;
+
+#if TX_DMA_INT
+	/* Clear the INT1_Stat register of pending TX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_tx;
+#endif
+#if RX_DMA_INT
+	/* Clear the INT1_Stat register of pending RX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_rx;
+#endif
+
+	// Stop the transmitter and receiver
+
+	// NOTE: The transmitter does not stop immediately when the stop
+	// bit is set.  Depending upon where the dma engine may be in
+	// the tranferring of a TX frame to the emac, it may take up to a maximum
+	// time interval that is equal to the value of a 1514 MTU in bits times the
+	// period of the networkspeed clock period.  Since there is no hardware
+	// indication of when the dma has stopped, all you can do is delay
+	// for this maximum time interval and hope for the best. 
+
+    thisadapter->E_NA_settings = 0;
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+}
+
+
+/******************************************************************************
+|
+|  Function:  EMAC_restart_hw
+|
+|  Description:  restarts the hardware and attempts to retransmit the
+|				last ethernet packet
+|  Parameters:  
+|
+|  Returns:    OK on success, ERROR otherwise.
+*******************************************************************************/
+
+static int EMAC_restart_hw( struct net_device *dev, BOOLEAN flush_txq, BOOLEAN flush_rxq )
+{
+	EMAC_RXD_HW_QTYPE	*rxd_hw;
+	BYTE				*rxd_buf;
+	unsigned int		idx;
+    unsigned long 		estatus;	/* contains the status of the ethernet hardware */
+    unsigned long 		lstatus;	/* contains the status of the last packet register */
+	DWORD				tx_entry_num;
+	struct net_device	*pdevice;	
+	
+	EMAC_DRV_CTRL	*thisadapter= (EMAC_DRV_CTRL *)dev->priv;
+
+    cnxt_mask_irq( dev->irq );
+
+#if TX_DMA_INT
+    cnxt_mask_irq( thisadapter->tx_dma_int );	
+#endif
+#if RX_DMA_INT
+    cnxt_mask_irq( thisadapter->rx_dma_int );	
+#endif
+	
+	netif_stop_queue(dev);
+
+	/* Clear the status registers  */
+	*INT_Stat = thisadapter->int_stat_clr_dev_irq;
+
+#if TX_DMA_INT
+	/* Clear the INT1_Stat register of pending TX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_tx;
+#endif
+#if RX_DMA_INT
+	/* Clear the INT1_Stat register of pending RX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_rx;
+#endif
+
+	// Clear the EMAC exception condition registers
+	estatus = *thisadapter->emac_stat_reg;
+	*thisadapter->emac_stat_reg = estatus;
+
+    lstatus = *thisadapter->emac_lp_reg;
+    *thisadapter->emac_lp_reg = lstatus;
+
+	// Stop the transmitter and receiver
+
+	// NOTE: The transmitter does not stop immediately when the stop
+	// bit is set.  Depending upon where the dma engine may be in
+	// the tranferring of a TX frame to the emac, it may take up to a maximum
+	// time interval that is equal to the value of a 1514 MTU in bits times the
+	// period of the networkspeed clock period.  Since there is no hardware
+	// indication of when the dma has stopped, all you can do is delay
+	// for this maximum time interval and hope for the best. 
+
+    thisadapter->E_NA_settings = 0;
+//	*thisadapter->emac_na_reg = (thisadapter->E_NA_settings | E_NA_STOP);
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+	if( thisadapter->phyState.networkSpeed == PHY_STAT_SPEED_100 )
+	{
+		TaskDelayMsec(10);
+	}
+	else
+	{
+		TaskDelayMsec(10);
+	}
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+    
+    ResetChip( thisadapter ); 
+    
+	rxd_hw = thisadapter->rxd_hw;
+
+	if( flush_rxq == TRUE )
+	{
+		// Reset the entire receive packet mess
+		rxd_buf = thisadapter->rxd_buf;
+	    QWORD_ALIGN_PTR(rxd_buf);
+
+		for( idx = 0; idx < RXD_NUM; idx++ ) 
+		{
+			rxd_hw->q[idx].mData = rxd_buf + (ETH_PKT_BUF_SZ * idx);
+			rxd_hw->q[idx].reserved = 0;
+			rxd_hw->q[idx].status = 0;
+			rxd_hw->q[idx].mib = 0;
+		}
+		rxd_hw->qndx = 0;	
+
+	}
+
+	*thisadapter->emac_rx_dma_ptr2 = (unsigned long)(&rxd_hw->q[0]); /* address of descriptor list */
+	*thisadapter->emac_rx_dma_cnt1 = (unsigned long)((CL_SIZ/8)-4);/* size of cluster in qwords */
+	*thisadapter->emac_rx_dma_cnt2 = (unsigned long)(2 * RXD_NUM);   /* number of descriptors * 2 */
+  	
+	if( flush_txq == TRUE )
+	{
+		// Clear out the emac transmit packet queue of 
+		// any queued transmit packets for this emac.
+		idx = EMAC_Queue_Count( thisadapter->emac_tx_q );
+		if( idx != 0 )
+		{
+			do
+			{
+				// Get an entry from the tx pkt q
+				EMAC_Dequeue_Data( thisadapter->emac_tx_q, (DWORD *)&pdevice, &tx_entry_num );
+
+				// If it is not this device then return it to the tx pkt q 
+				if( pdevice != dev )
+				{
+					if( EMAC_Queue_Data( thisadapter->emac_tx_q, (DWORD)pdevice, tx_entry_num ) == FALSE )
+					{
+						// Queuing of data failed!!
+						printk("EMAC transmit queue full!\n");
+						break;
+					}
+				}
+				idx--;		
+			} while( idx != 0 );	
+		}
+		
+	    //	Initialize the tx msg queue.
+	    thisadapter->tx_msg_q_next = 0;
+	    thisadapter->tx_msg_q_current = 0;
+	    thisadapter->tx_msg_q_size = 0;
+	}
+
+	*thisadapter->emac_tx_dma_ptr = 0;
+	*thisadapter->emac_tx_dma_cnt = 0;
+	thisadapter->tx_pkt_in_progress = FALSE;
+
+#if EMAC_MUTUALLY_EX_OPR
+	// Release the EMAC operation lock if we had it
+	// and allow the other EMAC to run if it needs to.
+	if(	emac_mutually_ex_opr == FALSE || EMAC_num_in_operation == thisadapter->emac_num  )
+	{
+		EMAC_num_in_operation = NONE;		
+	}		
+#endif
+	if( thisadapter->emac_state == OPEN )
+	{
+		// Get the current emac line state
+		thisadapter->E_NA_settings = 0;
+		EMAC_Linkcheck( thisadapter, TRUE );
+
+		// Set up the emac hardware filtering for perfect address filtering 
+		thisadapter->E_NA_settings |= E_NA_FILTER_MC1PERFECT;	
+		*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+		// Configure the emac hardware filtering 
+		emac_SetupFrame ( dev );
+
+#if 0
+	#if HOMEPLUGPHY
+	    if( PhyActiveHOMEPLUG( thisadapter->pPhy) )
+	    {
+		    TeslaControl_Str TeslaControl ;
+
+	        Emac_TeslaConfigRead( &TeslaControl ) ;
+	        Emac_TeslaSetup( (PVOID)thisadapter, &TeslaControl) ;
+	    }
+	#endif
+#endif	
+		*thisadapter->emac_ie_reg = thisadapter->E_IE_settings;
+	    
+		// Start the receiver operating now
+	    thisadapter->E_NA_settings |= (E_NA_SR|E_NA_SB);
+		*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+	    cnxt_unmask_irq( dev->irq );
+	#if TX_DMA_INT
+	    cnxt_unmask_irq( thisadapter->tx_dma_int );	
+	#endif
+	#if RX_DMA_INT
+	    cnxt_unmask_irq( thisadapter->rx_dma_int );	
+	#endif
+
+	}
+
+	if( netif_queue_stopped(dev))
+	{
+		netif_wake_queue( dev );
+	}
+
+    return 0;
+}
+
+
+static int EMAC_restart_rx( struct net_device *dev, BOOLEAN flush_rxq )
+{
+	EMAC_RXD_HW_QTYPE	*rxd_hw;
+	BYTE				*rxd_buf;
+	unsigned int		idx;
+	
+	EMAC_DRV_CTRL	*thisadapter= (EMAC_DRV_CTRL *)dev->priv;
+
+    cnxt_mask_irq( dev->irq );
+
+#if RX_DMA_INT
+    cnxt_mask_irq( thisadapter->rx_dma_int );	
+#endif
+	
+	netif_stop_queue(dev);
+
+	/* Clear the status registers  */
+	*INT_Stat = thisadapter->int_stat_clr_dev_irq;
+
+#if RX_DMA_INT
+	/* Clear the INT1_Stat register of pending RX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_rx;
+#endif
+
+	// Stop the receiver
+
+    thisadapter->E_NA_settings &= ~E_NA_SR;
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+	if( thisadapter->phyState.networkSpeed == PHY_STAT_SPEED_100 )
+	{
+		TaskDelayMsec(10);
+	}
+	else
+	{
+		TaskDelayMsec(10);
+	}
+    
+    EMAC_REG_WRITE( E_NA, E_NA_RRX, thisadapter->emac_hdw_num );
+	udelay( 100 );
+	udelay( 100 );
+	udelay( 50 );
+    EMAC_REG_WRITE( E_NA, 0, thisadapter->emac_hdw_num );
+	udelay( 100 );
+	udelay( 100 );
+	udelay( 50 );
+    EMAC_REG_WRITE( E_NA, 0, thisadapter->emac_hdw_num );
+	udelay( 100 );
+	udelay( 100 );
+	udelay( 50 );
+    
+	rxd_hw = thisadapter->rxd_hw;
+
+	if( flush_rxq == TRUE )
+	{
+		// Reset the entire receive packet mess
+		rxd_buf = thisadapter->rxd_buf;
+	    QWORD_ALIGN_PTR(rxd_buf);
+
+		for( idx = 0; idx < RXD_NUM; idx++ ) 
+		{
+			rxd_hw->q[idx].mData = rxd_buf + (ETH_PKT_BUF_SZ * idx);
+			rxd_hw->q[idx].reserved = 0;
+			rxd_hw->q[idx].status = 0;
+			rxd_hw->q[idx].mib = 0;
+		}
+		rxd_hw->qndx = 0;	
+	}
+
+	*thisadapter->emac_rx_dma_ptr2 = (unsigned long)(&rxd_hw->q[0]); /* address of descriptor list */
+	*thisadapter->emac_rx_dma_cnt1 = (unsigned long)((CL_SIZ/8)-4);/* size of cluster in qwords */
+	*thisadapter->emac_rx_dma_cnt2 = (unsigned long)(2 * RXD_NUM);   /* number of descriptors * 2 */
+  	
+	// Start the receiver operating now
+    thisadapter->E_NA_settings |= E_NA_SR;
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+    cnxt_unmask_irq( dev->irq );
+#if RX_DMA_INT
+    cnxt_unmask_irq( thisadapter->rx_dma_int );	
+#endif
+
+	if( netif_queue_stopped(dev))
+	{
+		netif_wake_queue( dev );
+	}
+
+    return 0;
+}
+
+
+/******************************************************************************
+|
+|  Function:  EMAC_Linux_tx_timeout
+|
+|  Description:  
+
+|  Parameters:  
+|
+|  Returns:
+*******************************************************************************/
+
+static void EMAC_Linux_tx_timeout(struct net_device *dev)
+{
+
+	EMAC_DRV_CTRL *thisadapter = ( EMAC_DRV_CTRL *)dev->priv; 
+
+	thisadapter->stats.tx_errors++;
+	thisadapter->stats.tx_aborted_errors++;
+	if( netif_queue_stopped(dev))
+	{
+		netif_wake_queue( dev );
+	}
+	printk( KERN_DEBUG "%s tx timeout\n", dev->name);
+
+	thisadapter->hw_reset_required = TRUE;
+}
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_tx_timeout
+		
+ABSTRACT:
+		
+DETAILS:
+
+RETURNS:
+		
+NOTES:
+*******************************************************************************/
+
+static void EMAC_tx_timeout(struct net_device *dev)
+{
+	unsigned long		flags;
+	EMAC_DRV_CTRL *thisadapter = ( EMAC_DRV_CTRL *)dev->priv; 
+
+	// Check to see if this was a case of us failing to detect
+	// the completion of a valid transmit frame or that there
+	// was an emac lockup or something else.
+#if 0
+	if( EMAC_Tx_Pkt_Done( dev ) == FALSE )
+#endif
+	{
+		printk( KERN_DEBUG "%s tx_timeout\n", dev->name );		
+#if 1
+		// Disable interrupts
+		local_irq_save(flags);
+
+		netif_stop_queue( dev );
+#endif
+		EMAC_Tx_Err_Cnt( thisadapter );
+		thisadapter->stats.tx_errors++;
+		thisadapter->stats.tx_aborted_errors++;
+		thisadapter->hw_reset_required = TRUE;
+#if 1
+
+		// Reenable interrupts
+		local_irq_restore(flags);
+#endif
+	#if HW_RESET_EVENT
+		SET_EVENT( thisadapter->hw_reset_event );
+	#endif
+	}
+}
+
+	 
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Tx_Pkt_Process
+		
+ABSTRACT:
+		
+DETAILS:
+
+RETURNS:
+		
+NOTES:
+To transmit an ethernet packet, three items are necessary.  Two TMAC
+TRANSMIT DESCRIPTORS and a transmit message buffer.   In this particular
+implementation the START transmit descriptor is not prepended to the
+buffer to be transmitted so the first DWORD of the buffer must be copied
+into this transmit descriptor. 
+
+See section 7.7 of the CX82100 HNP data sheet for more details on how the 
+ethernet TMAC function operates.	In particular see figures 7.5 EMAC Transmit
+Frame Structure and 7.6 TMAC DMA Operation for Channel {x} = 1 or 3.
+
+Also see section 4.6.3 Linked List Mode for an explanation of the Embedded Tail
+Linked List mode of DMA operation.
+
+The START ethernet TMAC TRANSMIT DESCRIPTOR consists of the following
+DWORD (32 bit) sized variables:
+
+	Relative 		Variable
+	Byte Address	Name			Notes
+	--------------	------------	----------------------------------------------
+	0x00			STATUS			Status of transmitted message. Updated by TMAC
+	0x04			STATUS_ZERO		Always all zeros
+	0x08			DESCRIPTOR		Contains bit fields that indicate readiness of
+									the frame, frame size and other items.  Set by
+									ARM CPU.
+	0x0C			DATA			First DWORD of data from the transmit message buffer.
+	 	.
+		.
+		.
+	0x0C + n		DATA			Last DWORD of data in transmit message buffer.
+	0x0C + n + 4	PAD				Optional padding to QWORD align POINTER and COUNT
+	0x0C + n + 4(8)	POINTER			Pointer to the END transmit descriptor structure.
+									The END transmit descriptor is used to terminate
+									the transmission of this transmit message buffer.
+	0x0C + n + 8(12)	COUNT		Size in QWORDS of the END transmit descriptor structure.
+
+The END ethernet TMAC TRANSMIT DESCRIPTOR consists of the following
+DWORD (32 bit) sized variables:
+
+	Relative 		Variable
+	Byte Address	Name			Notes
+	--------------	------------	----------------------------------------------
+	0x00			STATUS			Set to zero.
+	0x04			STATUS_ZERO		Set to zero.
+	0x08			DESCRIPTOR		Set to zero.
+	0x0C			DATA			Set to zero.
+	0x10			POINTER			Set to zero.
+	0x14			COUNT			Set to zero.
+
+*******************************************************************************/
+
+static int	EMAC_Tx_Pkt_Process
+(
+	EMAC_DRV_CTRL	*thisadapter,
+	TX_PKT_INFO		*tx_pkt_info,
+	DWORD			*entry
+)
+{
+    TX_MSG_QUEUE	tx_msg;
+	BYTE            *txd_buf;
+
+	// Determine if the transmitter has any buffers left
+	if( thisadapter->tx_msg_q_size < TX_RING_SIZE )
+	{
+		// Get a buffer from the transmitter message queue to copy the data into.
+		*entry = thisadapter->tx_msg_q_next++ % TX_RING_SIZE;
+		thisadapter->tx_msg_q_next %= TX_RING_SIZE;
+		txd_buf = thisadapter->txd_buf[*entry];
+			
+		// Copy the transmit data into our own buffer so that we can
+		// prepend the START transmit descriptor to the data.
+		TX_COPY_MEMORY
+		(
+		 	txd_buf + EMAC_TXD_SIZE,
+	        tx_pkt_info->tx_pkt_data,
+	        tx_pkt_info->tx_pkt_len
+		);
+
+		tx_msg.Data = txd_buf;
+
+		tx_msg.ulControl = TX_FRM_LEN_SET(tx_pkt_info->tx_pkt_len) | (TCTRL_RDY);
+
+		// Determine the length of the tx message in QWORDS
+		// NOTE: This length must also include the START TMAC
+		// TRANSMIT DESCRIPTOR fields.
+		tx_msg.ulLength =  ((tx_pkt_info->tx_pkt_len + EMAC_TXD_SIZE + QWORD_ROUND_UP_FACTOR ) / SIZEOF_QWORD );
+
+		// Initialize START TMAC TRANSMIT DESCRIPTOR
+		((EMAC_TXD *)tx_msg.Data)->status = 0;
+		((EMAC_TXD *)tx_msg.Data)->status_zero = 0;
+		((EMAC_TXD *)tx_msg.Data)->control = tx_msg.ulControl;
+
+		/* insert tx_msg into queue  */
+		thisadapter->tx_msg_q[ *entry ] = tx_msg; /* this is a copy*/
+		thisadapter->tx_msg_q_size++;
+	}
+
+	// Return number of empty buffers left in our ring
+	return (TX_RING_SIZE - thisadapter->tx_msg_q_size);
+}	
+
+
+/******************************************************************************
+|
+|  Function:    emac_SetupFrame
+|
+|  Description: This routine sets up the EMAC Setup Frame based on the 
+|               filtering mode configuration.  This is to configure the 
+|               hardware assisted address filtering.  
+|
+|               Currently it only supports All Multicast plus One Perfect mode.
+|               No setting is needed for promiscuous mode.
+|
+|  Returns:     OK/ERROR
+*******************************************************************************/
+
+BOOLEAN emac_SetupFrame ( struct net_device *dev )
+{
+    UINT8       		index;
+    char        		*macaddr;
+    EMAC_SETUP_FRAME  	*cam;
+    ULONG				*pL;
+    unsigned int		idx;
+    TX_MSG_QUEUE		tx_msg;
+
+	EMAC_DRV_CTRL	*thisadapter = (EMAC_DRV_CTRL*)dev->priv;
+	
+#if SETUP_FRAME_VERIFY
+	if(	sf_verify == FALSE )
+	{
+		return FALSE;
+	}
+#endif
+
+	// Check to see if we are configured for something 
+	// other than perfect MAC address filtering.
+    if 
+	(
+			( thisadapter->E_NA_settings & E_NA_FILTER_MODE ) != E_NA_FILTER_MC1PERFECT
+		||	( dev->flags & IFF_PROMISC )
+	)
+    {
+        return FALSE;
+    }
+        
+    /*
+		Prepare the setup frame with the unicast addresses.  CX821xx specifies that each entry 
+		occupies 3 double words (12 bytes) and the address data go into the low word of each 
+		double words.  CX821xx also requires the empty entries in the setup frame be filled with 
+		the last valid entry.
+    */
+		
+	memset( &thisadapter->setup_frame_buf[0], 0, sizeof ( thisadapter->setup_frame_buf ));
+
+    cam = ( EMAC_SETUP_FRAME * )((BYTE *) &thisadapter->setup_frame_buf[0] + EMAC_TXD_SIZE);
+    
+    macaddr = ( char * ) &thisadapter->PortNetAddress[0];
+
+    for (index = 0; index < EMAC_SETUP_PERFECT_ENTRIES; index++)
+    {
+        *(UINT16 *) & cam->Perfect.PhysicalAddress[index][0] = (UINT16)((macaddr[0] & 0xff) + ((macaddr[1] & 0xff) <<8));
+        *(UINT16 *) & cam->Perfect.PhysicalAddress[index][1] = (UINT16)((macaddr[2] & 0xff) + ((macaddr[3] & 0xff) <<8));
+        *(UINT16 *) & cam->Perfect.PhysicalAddress[index][2] = (UINT16)((macaddr[4] & 0xff) + ((macaddr[5] & 0xff) <<8));
+    }
+    
+	tx_msg.Data = &thisadapter->setup_frame_buf[0];
+	tx_msg.ulControl = TX_FRM_LEN_SET(ADDRESS_FILTER_SIZE) | (TCTRL_RDY | TCTRL_SET );
+
+	// Determine the length of the tx message in QWORDS
+	// NOTE: This length must also include the START TMAC
+	// TRANSMIT DESCRIPTOR fields.
+	tx_msg.ulLength =  ((ADDRESS_FILTER_SIZE + EMAC_TXD_SIZE + QWORD_ROUND_UP_FACTOR ) / SIZEOF_QWORD );
+
+	// Initialize START TMAC TRANSMIT DESCRIPTOR
+	((EMAC_TXD *)tx_msg.Data)->status = 0;
+	((EMAC_TXD *)tx_msg.Data)->status_zero = 0;
+	((EMAC_TXD *)tx_msg.Data)->control = tx_msg.ulControl;
+
+	// Compute dword (UINT32) offset to the end of the data in the txd buffer.
+	// Since ulLength is in QWORDS, the number of DWORDS is 2 times ulLength.
+	idx = (unsigned int)(tx_msg.ulLength << 1 );
+
+	// Add the END TMAC TRANSMIT DESCRIPTOR pointer and qword count
+	// to the end of the setup frame buffer.
+
+	// Get the setup frame buffer starting address.
+	pL          = (ULONG*)tx_msg.Data;
+	
+	// Write the pointer to the END transmit frame structure.
+    pL[idx]		= (ULONG)(thisadapter->TxD_end);
+
+	// Initialize the QWORD count used by the DMA to xfer
+	// the END transmit frame structure to the TMAC.
+	pL[idx + 1]	= (ULONG)TD_DMA_SIZ;
+
+	// Initialize END TMAC TRANSMIT DESCRIPTOR
+	thisadapter->TxD_end->status		= 0;
+	thisadapter->TxD_end->status_zero	= 0;
+	thisadapter->TxD_end->control		= 0;
+	thisadapter->TxD_end->data			= 0;             
+	thisadapter->TxD_end->joint.pNext	= (BYTE *)&thisadapter->TxD_end;
+	thisadapter->TxD_end->joint.cNext	= 0;          
+
+	// Program the DMA registers to transfer the ethernet packet into the TMAC.
+	*thisadapter->emac_tx_dma_ptr = (ULONG) tx_msg.Data;
+	*thisadapter->emac_tx_dma_cnt = (ULONG) tx_msg.ulLength;
+
+	// Begin the DMA transfer of the START transmit descriptor into the TMAC.
+	*thisadapter->emac_na_reg |= E_NA_STRT;
+
+	return TRUE;
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		emac_send_packet
+		
+ABSTRACT:
+		
+DETAILS:
+
+RETURNS:
+
+*******************************************************************************/
+
+static int	emac_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	TX_PKT_INFO		tx_pkt_info;
+	unsigned long	flags;
+	DWORD			entry;
+	int				num_buf;
+
+	EMAC_DRV_CTRL	*thisadapter=(EMAC_DRV_CTRL*)dev->priv;
+
+#if 0
+	if(	thisadapter->phyState.linkStatus != PHY_STAT_LINK_UP )
+	{
+		dev_kfree_skb_any (skb);
+		return 0;
+	}
+#endif
+		
+	// Generalize the data about the transmit packet
+	tx_pkt_info.tx_pkt_data = skb->data;
+	tx_pkt_info.tx_pkt_len = skb->len;
+
+	// Disable interrupts
+	spin_lock_irqsave(&thisadapter->lock, flags);
+	 
+	// Preprocess the transmit packet data for the emac driver
+	num_buf = EMAC_Tx_Pkt_Process( thisadapter, &tx_pkt_info, &entry );
+
+	// If the number of remaining tx buffers is less than
+	// some amount then tell the OS to stop giving us more.
+	if( num_buf < TX_MSG_Q_THRESHOLD )
+	{
+		netif_stop_queue( dev );
+	}
+
+	EMAC_Queue_Tx_Pkt( dev, entry );
+	
+	// Transmit a packet now
+	EMAC_Tx_Pkt_Transmit( dev );
+
+	// Reenable interrupts
+	spin_unlock_irqrestore(&thisadapter->lock, flags);
+
+	// Return the skb back to the pool now that
+	// we have copied the data from it.
+	dev_kfree_skb_any (skb);
+	return 0;
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_task
+		
+ABSTRACT:
+		
+DETAILS:
+
+RETURNS:
+		
+NOTES:
+*******************************************************************************/
+
+BOOLEAN print_debug_msg = FALSE;
+DWORD	disabled_irq_cnt = 0;
+DWORD	enabled_irq_cnt = 0;
+
+static void EMAC_task(struct net_device *dev)
+{
+	EMAC_DRV_CTRL *thisadapter = ( EMAC_DRV_CTRL *)dev->priv; 
+
+	// Check to see if the emac has been put into
+	// promiscuious mode by the operating system.
+	
+	// NOTE: The EMAC_Linkcheck function will update
+	// the emac NA register with the promiscuity settings.
+	if( dev->flags & IFF_PROMISC )
+	{
+		thisadapter->E_NA_settings &= ~E_NA_FILTER_MODE;
+		thisadapter->E_NA_settings |= E_NA_FILTER_PROMIS;	
+	}
+	else
+	{
+		thisadapter->E_NA_settings &= ~E_NA_FILTER_MODE;
+		thisadapter->E_NA_settings |= E_NA_FILTER_MC1PERFECT;	
+	}
+	
+	// Get the current emac line state
+	EMAC_Linkcheck( thisadapter, FALSE );
+
+#if 0
+	// If the physical link is not up then blow off any transmit packets
+	if(	thisadapter->phyState.linkStatus == PHY_STAT_LINK_UP )
+	{
+		netif_carrier_on( dev );
+	}
+	else
+	{
+		netif_carrier_off( dev );
+	}
+#endif
+
+	if( thisadapter->emac_state == OPEN )
+	{
+#if 1
+		// If the physical link is not up then blow off any transmit packets
+		if(	thisadapter->phyState.linkStatus == PHY_STAT_LINK_UP )
+		{
+			netif_carrier_on( dev );
+		}
+		else
+		{
+			netif_carrier_off( dev );
+		}
+
+#endif
+		#if EMAC_DISABLE_CHK
+		EMAC_Disabled_Check( dev );
+		#endif
+
+	#if (TX_FULL_DUPLEX && EMAC_MUTUALLY_EX_OPR)
+		// Check for and configure emacs for mutally
+		// exclusive transmitter operation.
+		EMAC_Mutually_Ex_Op_Chk( dev );
+	#endif
+		
+		if( netif_queue_stopped(dev) )
+		{
+			// Inform the OS that we can accept packets now
+			netif_wake_queue(dev);
+		}
+	}
+}
+
+typedef struct
+{
+	EVENT_HNDL	taskevent;
+	
+} EMAC_EVENT_T;
+
+EMAC_EVENT_T emac1_event;
+EMAC_EVENT_T emac2_event;
+
+void EMAC1_Task( struct net_device *dev )
+{
+	EMAC_DRV_CTRL *thisadapter = ( EMAC_DRV_CTRL *)dev->priv;
+	EMAC_EVENT_T *pemac_event = &emac1_event;
+
+	// Initialize task event
+	INIT_EVENT( &pemac_event->taskevent );
+	thisadapter->hw_reset_event = &pemac_event->taskevent;
+
+	while(1)
+	{
+	#if HW_RESET_EVENT
+		RESET_EVENT( thisadapter->hw_reset_event );
+		WAIT_EVENT ( thisadapter->hw_reset_event, 1070 );
+	#else
+		TaskDelayMsec(1070);
+	#endif
+		EMAC_task( dev );
+	}
+}
+
+void EMAC2_Task( struct net_device *dev )
+{
+
+	EMAC_DRV_CTRL *thisadapter = ( EMAC_DRV_CTRL *)dev->priv;
+	EMAC_EVENT_T *pemac_event = &emac2_event;
+
+	// Initialize task event
+	INIT_EVENT( &pemac_event->taskevent );
+	thisadapter->hw_reset_event = &pemac_event->taskevent;
+
+	while(1)
+	{
+	#if HW_RESET_EVENT
+		RESET_EVENT( thisadapter->hw_reset_event );
+		WAIT_EVENT ( thisadapter->hw_reset_event, 1070 );
+	#else
+		TaskDelayMsec(1070);
+	#endif
+		EMAC_task( dev );
+	}
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		sp_emac_close
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+static int emac_close(struct net_device *dev)
+{
+
+	unsigned long	flags;
+	EMAC_DRV_CTRL *thisadapter=(EMAC_DRV_CTRL*)dev->priv;
+
+#if 1
+	// Disable interrupts
+	local_irq_save(flags);
+
+#endif
+	// Effectively disable the tx watchdog timer by setting
+	// it to a very long timeout.
+	del_timer(&thisadapter->periodic_task);
+	
+	// Tell the OS we are closed
+	netif_stop_queue(dev);
+
+	// Indicate the emac is closed
+	thisadapter->emac_state = CLOSED;
+	
+#if 0
+	// Disable interrupts
+	local_irq_save(flags);
+
+#endif
+	// Restart the hardware to bring it into a known state
+	EMAC_restart_hw( dev, TRUE, TRUE );
+
+#if 0
+	// Reenable interrupts
+	local_irq_restore(flags);
+
+#endif
+	// Zero out the statistics to start out clean when we open.
+	memset( &thisadapter->stats, 0, sizeof ( struct net_device_stats ));
+
+#if 1
+	// Reenable interrupts
+	local_irq_restore(flags);
+
+#endif
+	return 0;
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		sp_emac_get_stats
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+static struct net_device_stats *emac_get_stats(struct net_device *dev)
+{
+	EMAC_DRV_CTRL *thisadapter=(EMAC_DRV_CTRL*)dev->priv;
+
+	return &(thisadapter->stats);
+}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		set_multicast_list
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+static void set_multicast_list(struct net_device *dev)
+{}
+
+
+/*******************************************************************************
+
+FUNCTION NAME:
+		EMAC_Rx_Process
+		
+ABSTRACT:
+		
+DETAILS:
+
+*******************************************************************************/
+
+#if 0
+void EMAC_Rx_Process( unsigned long data )
+{
+	// Exists so CodeWright will so this function in its list
+}	
+#endif
+#if RX_TASKLET
+static void EMAC_Rx_Process( unsigned long data )
+#else
+static void EMAC_Rx_Process( struct net_device	*dev )
+#endif
+{
+
+	register EMAC_DRV_CTRL		*thisadapter;
+	register int				i;
+	register int				idx;
+	int							lookback_idx;
+	unsigned long	    		status;
+	unsigned long				pktlen;
+	DWORD						cdt_ptr;
+	DWORD						dma_ptr2;
+	struct sk_buff				*skb;
+	volatile EMAC_RXD_HW_QTYPE	*rxd_hw;
+	BOOLEAN						rx_drop_pkts;	
+	BOOLEAN						rx_disabled;
+#if RX_TASKLET
+	struct net_device	*dev;
+	dev	= (struct net_device *)*((unsigned long *)data);
+#endif
+	thisadapter = ( EMAC_DRV_CTRL *)dev->priv;
+
+	rx_drop_pkts = FALSE;
+	rx_disabled = FALSE;
+		
+	rxd_hw = thisadapter->rxd_hw;
+	
+	i = 0;
+	while( i < (RX_RING_SIZE / 1))
+	{
+		// The 'i' variable determines the maximum entries we will check.
+		// The 'idx' variable determines where in the receive buffer CDT
+		// 	that we will begin.  When the loop finishes 'idx' points to 
+		// 	the last receive buffer that we looked at.
+    	idx = rxd_hw->qndx;
+
+		// Check to see if the DMA engine is catching up to us
+		// and if so disable the receiver so that we do not overrun
+		lookback_idx = rx_lookback_idx[ idx ];
+		if(( rxd_hw->q[lookback_idx].status != 0 ) && (	rx_disabled == FALSE ))
+		{
+		    thisadapter->E_NA_settings &= ~E_NA_SR;
+			*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+			rx_disabled = TRUE;
+		#if 0
+			printk(KERN_DEBUG "%s rx lookback threshold limit\n", dev->name );
+		#else
+			thisadapter->stats.rx_over_errors++;
+		#endif
+		}
+
+		i++;
+
+		// Check to see if we have reached the CDT entry that
+		// the dma hardware is currently working on.
+		cdt_ptr = ((DWORD)(&rxd_hw->q[idx].mData)) & LOW_QWORD_MASK;
+		dma_ptr2 = ((DWORD)(*thisadapter->emac_rx_dma_ptr2)) & LOW_QWORD_MASK;
+		
+		if(	cdt_ptr != dma_ptr2 )
+		{
+			rxd_hw->qndx = ( rxd_hw->qndx + 1 ) % RX_RING_SIZE;
+	
+			// Do we process or drop the packet?
+			if( rx_drop_pkts == FALSE )
+			{
+				status = rxd_hw->q[idx].status;
+		
+				// Check the magic status bit
+				// Always 1 for good frame?
+				if( ( status & ( RX_A1 )) != 0 ) 
+				{
+					// Get the packet length
+					pktlen = RX_FRM_LEN_GET( status );
+
+					// Make sure the frame is neither too short or too long
+					// AND that it did not have a CRC error
+					if
+					(
+							( pktlen >= MIN_ETHERNET_SIZE )
+						&&	( pktlen <= MAX_ETHERNET_SIZE )
+						&&	!( status & (RSTAT_TS | RSTAT_TL | RSTAT_CE ))
+					)
+					{
+						// Get a kernel buffer to put the data in
+						skb = dev_alloc_skb( pktlen + DWORD_ALIGN_IP_HDR );
+						if (skb != NULL)
+						{
+							skb->dev = dev;
+							skb_reserve(skb, DWORD_ALIGN_IP_HDR );	/* Align IP on 16 byte boundaries */
+
+							// Adjust the packet len pointer to remove the ethernet CRC from it
+							pktlen -= ETHERNET_CRC_SIZE;
+
+					        // NOTE: In the following memcpy the first QWORD is used by
+							// the RMAC hardware - it means nothing to us except that we
+							// must account for it in our data pointer calculations and
+							// cluster allocations.
+
+							RX_COPY_MEMORY
+							(
+							 	skb_put(skb,pktlen),
+						        (void*)rxd_hw->q[idx].mData + SIZEOF_QWORD,
+						        pktlen
+							);
+
+					  		dev->last_rx = jiffies;
+
+						#if RX_SKB_DEBUG
+							skb_debug(skb);
+						#endif
+							// Indicate to Linux that it is an ethernet packet
+							skb->protocol = eth_type_trans(skb,dev);
+
+							thisadapter->stats.rx_packets++;
+							thisadapter->stats.rx_bytes+=pktlen;
+
+							// Deliver the received packet to the protocol stack
+							switch ( netif_rx(skb) )
+							{
+								case NET_RX_SUCCESS:
+								case NET_RX_CN_LOW:
+								case NET_RX_CN_MOD:
+									break;
+									
+								case NET_RX_CN_HIGH:
+									printk( KERN_DEBUG "%s NET_RX_CN_HIGH\n", dev->name);
+									break;
+									
+								case NET_RX_DROP:
+									printk( KERN_DEBUG "%s NET_RX_DROP\n", dev->name);
+									rx_drop_pkts = TRUE;
+									break;
+									
+								default:
+									printk( KERN_DEBUG "unknown feedback return code\n");
+									break;
+							}
+						}
+						else
+						{
+							// No skbuffer to put the data into!
+							emac_rx_proc_no_skb++;
+						}
+					}
+					rxd_hw->q[idx].status = 0;
+				}
+				else
+				{
+					// Exit the loop because we have reached a receive
+					// buffer that has not had any data put into it.
+					break;
+				}
+ 			}
+			else
+			{
+				// Drop rx packets here
+ 				rxd_hw->q[idx].status = 0;
+				thisadapter->stats.rx_dropped++;
+			}
+		}
+		else
+		{
+			// Exit the loop because we are now up to the receive
+			// buffer that the dma hardware is currently working in.
+			break;
+		}
+	}
+
+    thisadapter->E_NA_settings |= E_NA_SR;
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+	// Set the receive frame interrupt mask bit so
+	// that receive frame interrupts will start
+	// occurring again.
+#if RX_DMA_INT
+    cnxt_unmask_irq( thisadapter->rx_dma_int );	
+#else
+	thisadapter->E_IE_settings |= E_IE_RI;
+	*thisadapter->emac_ie_reg = thisadapter->E_IE_settings;
+#endif
+}
+
+
+#if RX_TASKLET
+DECLARE_TASKLET( emac1_rx_tasklet, EMAC_Rx_Process, (unsigned long) &emac_dev[0]);
+DECLARE_TASKLET( emac2_rx_tasklet, EMAC_Rx_Process, (unsigned long) &emac_dev[1]);
+#endif
+
+
+#if RX_DMA_INT
+/******************************************************************************
+|
+|  Function:  EMAC_RxISR
+|
+|  Description:  handle device RX interrupts
+|				 This interrupt service routine, reads device interrupt status, acknowledges
+|				 the interrupting events, and schedules transmit when required.
+|				
+|  Parameters:  *pDrvCtrl - Pointer Driver Cntrl
+|
+|  Returns:   NONE
+*******************************************************************************/
+
+static void EMAC_RxISR(int irq, void *dev_id, struct pt_regs * regs)
+{
+	register EMAC_DRV_CTRL *thisadapter=( EMAC_DRV_CTRL *)((struct net_device *)dev_id)->priv; 
+
+	/* Clear the INT1_Stat register of pending TX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_rx;
+
+#if RX_TASKLET		
+	// Process the received frames(s) via a tasklet
+	// Clear out the receive frame interrupt mask after
+	// getting the interrupt.  The tasklet will set the
+	// mask bit again after it processes the received
+	// frames.  This keeps the system from getting more
+	// receive frame interrupts while it is already 
+	// scheduled to run the tasklet or is already running
+	// the tasklet.
+    cnxt_mask_irq( thisadapter->rx_dma_int );	
+	 
+	switch( thisadapter->emac_num )
+	{
+		case 1:
+			tasklet_schedule(&emac1_rx_tasklet);
+			break;
+
+		case 2:
+			tasklet_schedule(&emac2_rx_tasklet);
+			break;
+	}
+#else
+	EMAC_Rx_Process( dev );
+#endif
+}
+#endif
+
+#if TX_TASKLET
+static void EMAC_Tx_Process( unsigned long data )
+{
+#if EMAC_TX_UDELAY
+	udelay( 2 );
+#endif
+	EMAC_Tx_Pkt_Done((struct net_device *)*((unsigned long *)data) );
+}
+
+DECLARE_TASKLET( emac1_tx_tasklet, EMAC_Tx_Process, (unsigned long) &emac_dev[0]);
+DECLARE_TASKLET( emac2_tx_tasklet, EMAC_Tx_Process, (unsigned long) &emac_dev[1]);
+#endif
+
+#if TX_DMA_INT
+/******************************************************************************
+|
+|  Function:  EMAC_TxISR
+|
+|  Description:  handle device TX interrupts
+|				 This interrupt service routine, reads device interrupt status, acknowledges
+|				 the interrupting events, and schedules transmit when required.
+|				
+|  Parameters:  *pDrvCtrl - Pointer Driver Cntrl
+|
+|  Returns:   NONE
+*******************************************************************************/
+
+static void EMAC_TxISR(int irq, void *dev_id, struct pt_regs * regs)
+{
+	register EMAC_DRV_CTRL *thisadapter=( EMAC_DRV_CTRL *)((struct net_device *)dev_id)->priv; 
+
+	/* Clear the INT1_Stat register of pending TX interrupts */
+	*INT_Stat = thisadapter->int_stat_clr_tx;
+
+#if EMAC_TX_WD_TIMER
+	// Effectively disable the tx watchdog timer by setting
+	// it to a very long timeout.
+	del_timer(&thisadapter->wd_timer );
+#endif
+#if TX_TASKLET		
+	switch( thisadapter->emac_num )
+	{
+		case 1:
+			tasklet_schedule(&emac1_tx_tasklet);
+			break;
+
+		case 2:
+			tasklet_schedule(&emac2_tx_tasklet);
+			break;
+	}
+#else
+	// TRANSMIT FRAMES
+	// Check to see if an EMAC frame transmitted OK
+	// Perform housekeeping on the just transmitted frame
+#if EMAC_TX_UDELAY
+	udelay( 1 );
+#endif
+	EMAC_Tx_Pkt_Done( dev_id );
+#endif
+}
+#endif
+
+
+/******************************************************************************
+|
+|  Function:  EMAC_Exception_ISR
+|
+|  Description:   handle ethernet DMA device errors
+|				
+|  Returns:   None
+*******************************************************************************/
+
+static void EMAC_Exception_ISR(int irq, void *dev_id, struct pt_regs * regs)
+{
+    register unsigned long 	estatus;	/* contains the status of the ethernet hardware */
+#if (!RX_DMA_INT || !TX_DMA_INT)
+    register unsigned long 	lstatus;	/* contains the status of the last packet register */
+#endif
+	register EMAC_DRV_CTRL *thisadapter=( EMAC_DRV_CTRL *)((struct net_device *)dev_id)->priv; 
+
+	// Get the EMAC exception condition registers
+	estatus = *thisadapter->emac_stat_reg;
+#if (!RX_DMA_INT || !TX_DMA_INT)
+    lstatus = *thisadapter->emac_lp_reg;
+#endif
+
+	// Now clear out the ARM INT_Stat register interrupt that got us here
+	*thisadapter->emac_stat_reg = estatus;
+
+#if (!RX_DMA_INT || !TX_DMA_INT)
+    *thisadapter->emac_lp_reg = lstatus;
+#endif
+	*INT_Stat = thisadapter->int_stat_clr_dev_irq;
+
+#if !RX_DMA_INT
+	// RECEIVE FRAMES
+	// Check to see if an EMAC frame was received properly
+	if( lstatus & ( E_LP_RI ))
+	{
+	#if RX_TASKLET		
+		// Process the received frames(s) via a tasklet
+		// Clear out the receive frame interrupt mask after
+		// getting the interrupt.  The tasklet will set the
+		// mask bit again after it processes the received
+		// frames.  This keeps the system from getting more
+		// receive frame interrupts while it is already 
+		// scheduled to run the tasklet or is already running
+		// the tasklet.
+		thisadapter->E_IE_settings &= ~E_IE_RI;
+		*thisadapter->emac_ie_reg = thisadapter->E_IE_settings;
+		 
+		switch( thisadapter->emac_num )
+		{
+			case 1:
+				tasklet_schedule(&emac1_rx_tasklet);
+				break;
+
+			case 2:
+				tasklet_schedule(&emac2_rx_tasklet);
+				break;
+		}
+	#else
+		EMAC_Rx_Process( dev );
+	#endif
+	}
+#endif
+#if !TX_DMA_INT
+	#if USE_TU_INTERRUPT
+	// TRANSMIT FRAMES
+	// Check to see if the EMAC transmitter has stopped
+    if( estatus & (E_S_TU) )
+	{
+		#if EMAC_TX_WD_TIMER
+		del_timer(&thisadapter->wd_timer );
+		#endif
+		#if TX_TASKLET		
+		switch( thisadapter->emac_num )
+		{
+			case 1:
+				tasklet_schedule(&emac1_tx_tasklet);
+				break;
+
+			case 2:
+				tasklet_schedule(&emac2_tx_tasklet);
+				break;
+		}
+		#else
+		// TRANSMIT FRAMES
+		// Check to see if an EMAC frame transmitted OK
+		// Perform housekeeping on the just transmitted frame
+			#if EMAC_TX_UDELAY
+		udelay( 1 );
+			#endif
+		EMAC_Tx_Pkt_Done( dev_id );
+		#endif
+	}
+	#else
+	// TRANSMIT FRAMES
+	// Check to see if an EMAC frame transmitted OK
+    if
+    ( 
+    		( lstatus & ( E_LP_TI ) )
+		#if HOMEPLUGPHY
+			// The CX11656 HomePlug device uses the mii CRS bit
+			// to indicate when it has a free tx buffer.
+    	||	( PhyActiveHOMEPLUG( thisadapter->pPhy) & ( estatus & ( E_S_LCRS) ) )
+		#endif
+    )
+	{
+		// Perform housekeeping on the just transmitted frame
+		EMAC_Tx_Pkt_Done( dev ); 
+	}
+	#endif
+#endif
+
+	// Check for tx/rx frame errors
+	if(	estatus & ( E_S_LC | E_S_16 ))
+	{
+		// FATAL ERROR CONDITIONS
+		// NOTE: These error conditions must fall through to
+		// the EMAC_restart_hw at the end of the list.
+		if ( estatus & E_S_LC )
+		{
+			#if EMAC_ISR_ERR_MSG_PRINT
+			printk( KERN_DEBUG "ETH%d: TX Late Collision\n", thisadapter->unit);  
+			#endif
+		}
+
+		if( estatus &  E_S_16 )
+	    {
+			#if EMAC_ISR_ERR_MSG_PRINT
+			printk( KERN_DEBUG "ETH%d: TX Excessive Collisions\n", thisadapter->unit);  
+			#endif
+		}
+		thisadapter->stats.collisions += (estatus & TSTAT_CC);	
+
+		EMAC_stop_hw( dev_id );
+		
+		// FATAL error in mutually exclusive tx parts
+		thisadapter->hw_reset_required = TRUE;
+		
+	#if HW_RESET_EVENT
+		SET_EVENT( thisadapter->hw_reset_event );
+	#endif
+	}
+}
+
+
+/******************************************************************************
+|
+|  Function:  EMAC_Linkcheck
+|
+|  Description: Read the PHY link status and set the MAC according to the 
+|				established link rate
+|
+|  Returns:   NONE
+|
+*******************************************************************************/
+
+void EMAC_Linkcheck(EMAC_DRV_CTRL *thisadapter, BOOLEAN force_update )
+{
+    
+	unsigned long phy_settings;
+    
+	// If TRUE then clear out the adapter phySettings variable so
+	// that the logical flow of this function will cause the
+	// adapter E_NA_settings and the E_NA_x hardware register for
+	// this adapter to be updated.
+	if( force_update == TRUE )
+	{
+		thisadapter->phyState.phySettings = 0;
+	}
+
+	/*************************************************
+	* 	Read the current link settings from the PHY. *
+	*************************************************/
+    phy_settings = PhyCheck(thisadapter->pPhy);
+
+    /* Check settings and record the link state.
+	   If we are in FORCEDMODE, skip speed and duplex check.
+       If we are in auto-negotiation mode, deduce what the link speed and duplex
+       should be.  If the link is down, default it to 10 HDX.
+    */
+    if ( phy_settings != thisadapter->phyState.phySettings )
+    {
+        thisadapter->phyState.phySettings = phy_settings;
+
+        if ( phy_settings & PHY_LINK_UP )
+        {
+            if ( thisadapter->phyState.linkStatus != PHY_STAT_LINK_UP )
+            {
+                thisadapter->phyState.linkStatus = PHY_STAT_LINK_UP;
+            }
+
+        	if ( thisadapter->phyState.autoNegotiate == PHY_AUTONEGOTIATE )
+			{
+	            if ( phy_settings & PHY_LINK_100 )
+                {
+	                thisadapter->phyState.networkSpeed = PHY_STAT_SPEED_100;
+                }
+	            else
+                {
+	                thisadapter->phyState.networkSpeed = PHY_STAT_SPEED_10;
+                }
+
+	            if ( phy_settings & PHY_LINK_FDX )
+				{
+	                thisadapter->phyState.duplexMode = PHY_STAT_DUPLEX_FULL;
+	            }
+	            else
+	            {
+	                thisadapter->phyState.duplexMode = PHY_STAT_DUPLEX_HALF;
+				}
+			}
+        }
+        else
+        {
+            if ( thisadapter->phyState.linkStatus != PHY_STAT_LINK_DOWN )
+            {
+                thisadapter->phyState.linkStatus = PHY_STAT_LINK_DOWN;
+            }
+
+        	if ( thisadapter->phyState.autoNegotiate == PHY_AUTONEGOTIATE )
+			{
+	            thisadapter->phyState.networkSpeed = PHY_STAT_SPEED_100;
+	            thisadapter->phyState.duplexMode = PHY_STAT_DUPLEX_FULL;
+			}
+        }
+
+		// Update the E_NA_settings and E_NA_x hardware register
+        EMACHW_Configure_Mac
+        (
+        	thisadapter,
+        	TRUE,
+			(thisadapter->phyState.networkSpeed == PHY_STAT_SPEED_100 ),
+			(thisadapter->phyState.duplexMode == PHY_STAT_DUPLEX_FULL )
+		);
+	}
+}
+
+
+/******************************************************************************
+|
+|  Function:  EMAC_init_tx
+|
+|  Description: initializes all queues and registers necessary to begin receiving
+| 				data from the RMAC.
+|
+|  Returns:   OK on success; otherwise ERROR.
+|
+*******************************************************************************/
+
+static signed int EMAC_init_tx( EMAC_DRV_CTRL *	thisadapter )
+{
+	BYTE				*txd_buf;
+	BYTE				*txd_end;
+	unsigned int		i;
+
+#if SDRAM_TX_MEM
+    txd_end = (BYTE *)EMAC_KMALLOC(sizeof(EMAC_TD)+16, GFP_KERNEL);
+#else
+	txd_end = SYSMEM_Allocate_BlockMemory( 1, sizeof(EMAC_TD)+16, 16 );
+#endif
+    if (txd_end == NULL)
+    {
+    	printk("EMAC:TxD_end alloc() FAIL!\n");
+    }
+
+    QWORD_ALIGN_PTR( txd_end );
+	thisadapter->TxD_end = (EMAC_TD *)txd_end;
+
+	// Zero out thisadapter->TxD_end structure
+	// so that everything is at a known state
+	memset( thisadapter->TxD_end, 0, sizeof(EMAC_TD) + 16 );
+
+	// Obtain memory for the txd buffers
+#if SDRAM_TX_MEM
+	if(( txd_buf = (BYTE *) EMAC_KMALLOC((TX_RING_SIZE * ETH_PKT_BUF_SZ) + QWORD_ALIGN_PAD, GFP_KERNEL)) == NULL ) 
+#else
+	if(( txd_buf = SYSMEM_Allocate_BlockMemory( 1, (TX_RING_SIZE * ETH_PKT_BUF_SZ) + QWORD_ALIGN_PAD, 16 )) == NULL ) 
+#endif
+    {
+    	printk("EMAC:txd_buf alloc() FAIL!\n");
+    }
+
+	// Save the unaligned txd buffer pointer originally obtained
+	// from kmalloc to subsequent use in freeing the memory.
+	thisadapter->txd_buf_mem = txd_buf;
+    QWORD_ALIGN_PTR(txd_buf);
+
+	// Initialize the txd buffer array with pointers to the buffers
+	for( i = 0; i < TX_RING_SIZE; i++ ) 
+	{
+		thisadapter->txd_buf[i] = (txd_buf + (ETH_PKT_BUF_SZ * i));
+	}
+
+    //	Initialize the tx msg queue.
+    thisadapter->tx_msg_q_next = 0;
+    thisadapter->tx_msg_q_current = 0;
+    thisadapter->tx_msg_q_size = 0;
+    memset((char*)thisadapter->tx_msg_q, 0, sizeof(thisadapter->tx_msg_q));
+	
+    return 0;
+}
+
+
+/******************************************************************************
+|
+|  Function:  init_RX_EMAC
+|
+|  Description: initializes all queues and registers necessary to begin receiving
+| 				data from the RMAC.
+|
+|  Returns:   OK on success; otherwise ERROR.
+|
+*******************************************************************************/
+
+static signed int EMAC_init_rx( EMAC_DRV_CTRL	*thisadapter )
+{
+	EMAC_RXD_HW_QTYPE	*rxd_hw;
+	BYTE				*rxd_buf;
+	unsigned int		i;
+
+	/****************************************************************
+    	Obtain and clear memory for the RxD table and management 
+        information list.
+    ****************************************************************/
+    if (( rxd_hw = (EMAC_RXD_HW_QTYPE *)EMAC_KMALLOC(sizeof(EMAC_RXD_HW_QTYPE)+16,GFP_KERNEL)) == NULL )
+    {
+    	printk("EMAC:rxd_hw alloc() FAIL!\n");
+    }
+
+    QWORD_ALIGN_PTR(rxd_hw);
+	thisadapter->rxd_hw = rxd_hw;
+	
+	// Zero out thisadapter->rxd_hw structure
+	// so that everything is at a known state
+	memset( thisadapter->rxd_hw, 0, sizeof(EMAC_RXD_HW_QTYPE) + 16 );
+	
+	// Obtain memory for the rxd buffers
+	if(( rxd_buf = (BYTE *) EMAC_KMALLOC((RX_RING_SIZE * ETH_PKT_BUF_SZ) + QWORD_ALIGN_PAD, GFP_KERNEL)) == NULL ) 
+    {
+    	printk("EMAC:rxd_buf alloc() FAIL!\n");
+    }
+
+	// Save the unaligned rxd buffer pointer originally obtained
+	// from kmalloc to subsequent use in freeing the memory.
+	thisadapter->rxd_buf = rxd_buf;
+    QWORD_ALIGN_PTR(rxd_buf);
+
+	// Initialize the rxd hardware q buffer pointers with buffers
+	for( i = 0; i < RXD_NUM; i++ ) 
+	{
+		rxd_hw->q[i].mData = rxd_buf + (ETH_PKT_BUF_SZ * i);
+		rxd_hw->q[i].reserved = 0;
+		rxd_hw->q[i].status = 0;
+		rxd_hw->q[i].mib = 0;
+	}
+
+	/****************************************************************
+    	Initialize the hardware RxD Q index.
+    ****************************************************************/
+    rxd_hw->qndx = 0;
+
+	/****************************************************************
+		Initialize DMA4 to generate an interrupt at the end of 
+        receiving a packet.  Leave some space for padding at the
+        beginning and ending of the cluster.  At least seven bytes
+        are needed for cluster alignment, eight bytes are used by
+        the RMAC DMA channel, and two bytes may be used by the 
+        IP alignment copy if an in-cluster copy is performed.
+    ****************************************************************/
+	*thisadapter->emac_rx_dma_ptr2 = (unsigned long)(&rxd_hw->q[0]); /* address of descriptor list */
+    *thisadapter->emac_rx_dma_cnt1 = (unsigned long)((CL_SIZ/8)-4); /* size of cluster in qwords */
+	*thisadapter->emac_rx_dma_cnt2 = (unsigned long)(2 * RXD_NUM);  /* number of descriptors * 2 */
+
+    return 0;
+}
+
+
+static int emac_set_mac_address(struct net_device *dev, void *addr)
+{
+	int i;
+
+	if(netif_running(dev))
+	{
+    	return -EBUSY;
+	}
+
+	printk("%s : CNXT set mac address\n",dev->name);
+
+	for( i = 0; i < MAC_ADDR_LEN; i++)
+	{
+	    printk(" %2.2x",dev->dev_addr[i]=((unsigned char *)addr)[i]);
+	}
+	printk(".\n");
+	return 0;
+}
+
+
+/******************************************************************************
+|
+|  Function:  sp_emac_open
+|
+|  Returns:   OK on success; otherwise ERROR.
+|
+*******************************************************************************/
+
+static int emac_open(struct net_device *dev)
+{
+
+	EMAC_DRV_CTRL *thisadapter=(EMAC_DRV_CTRL*)dev->priv;
+
+	// Get the current emac line state
+	EMAC_Linkcheck( thisadapter, TRUE );
+
+	// If the physical link is not up then blow off any transmit packets
+	if(	thisadapter->phyState.linkStatus == PHY_STAT_LINK_UP )
+	{
+		netif_carrier_on( dev );
+	}
+	else
+	{
+		netif_carrier_off( dev );
+	}
+
+#if (TX_FULL_DUPLEX && EMAC_MUTUALLY_EX_OPR)
+	// Check for and configure emacs for mutally
+	// exclusive transmitter operation.
+	EMAC_Mutually_Ex_Op_Chk( dev );
+#endif
+	
+#if HOMEPLUGPHY
+    if( PhyActiveHOMEPLUG( thisadapter->pPhy) )
+    {
+	    TeslaControl_Str TeslaControl ;
+
+		// Pointer back to dev needed for homeplug functions
+		thisadapter->dev = dev;
+		
+        Emac_TeslaConfigRead( &TeslaControl ) ;
+        Emac_TeslaSetup( (PVOID)thisadapter, &TeslaControl) ;
+    }
+#endif
+	
+	// Set up the emac hardware filtering for perfect address filtering 
+	thisadapter->E_NA_settings |= E_NA_FILTER_MC1PERFECT;	
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+	*thisadapter->emac_stat_reg = 0;
+
+	// Configure the emac hardware filtering 
+	emac_SetupFrame ( dev );
+
+	/********************************************
+	    Set the operating modes for the EMAC
+        receiver and transmitter.
+	********************************************/
+
+	thisadapter->E_IE_settings =
+	(
+#if !RX_DMA_INT
+		E_IE_RI		|	/* Receive OK interrupt enable (masks E_LP_RI) */
+#endif	
+#if !TX_DMA_INT
+	#if USE_TU_INTERRUPT
+		E_IE_TU		|	/* Transmit process stopped interrupt enable (masks E_S_TU) */
+	#endif
+#endif	
+		E_IE_LC		|	/* Late collision interrupt enable (masks E_S_LC) */
+		E_IE_16			/* 16 collisions interrupt enable (masks E_S_16) */
+	);
+
+#if HOMEPLUGPHY
+	if( PhyActiveHOMEPLUG( thisadapter->pPhy) )
+	{
+		// The CX11656 device uses the mii CRS signal
+		//  to indicate when it has a free tx buffer
+		thisadapter->E_IE_settings |= E_IE_LCRS;
+	}
+	else
+	{
+	#if !TX_DMA_INT
+		thisadapter->E_IE_settings |= E_IE_TI;
+	#endif
+	}
+#endif
+
+	*thisadapter->emac_ie_reg = thisadapter->E_IE_settings;
+    
+	// Start the receiver operating now
+    thisadapter->E_NA_settings |= (E_NA_SR|E_NA_SB);
+	*thisadapter->emac_na_reg = thisadapter->E_NA_settings;
+
+	// Indicate the emac is open
+	thisadapter->emac_state = OPEN;
+	
+	// Enable the device irq
+    cnxt_unmask_irq( dev->irq );
+	
+#if TX_DMA_INT
+    cnxt_unmask_irq( thisadapter->tx_dma_int );	
+#endif
+#if RX_DMA_INT
+    cnxt_unmask_irq( thisadapter->rx_dma_int );	
+#endif
+
+	// Inform the OS that we can accept packets now
+	netif_start_queue(dev);
+
+	printk("%s: (CX821xx EMAC) started!\n",dev->name);
+	return 0;
+}
+
+
+/******************************************************************************
+|
+|  Function:  ResetChip
+|
+|  Description:   Reset the chip and setup E_NA register
+|				  This routine stops the transmitter and receiver, masks all interrupts, then
+|				  resets the ethernet chip. Once the device comes out of the reset state, it
+|				  initializes E_NA register.
+|
+|  Parameters:  
+|
+|  Returns:   
+*******************************************************************************/
+
+void ResetChip( EMAC_DRV_CTRL *thisadapter )	/* pointer to device control structure */
+{
+    
+	/* Delay between applying the reset condition and clearing it 
+		and then delay again after releasing the condition. Sometimes not all
+		aspects of the chip have reached their new state with a back to back
+		bit set and clear. */
+
+	// NOTE: The following delays between the register writes were empirically
+	// derived because there is no value specified in the hardware document
+	// as to how long it actually takes.
+	// Do the delays as a series of usec delays so that if an interrupt is
+	// pending it can occur between them.
+    EMAC_REG_WRITE( E_NA, E_NA_RTX, thisadapter->emac_hdw_num );
+	udelay( 100 );
+	udelay( 100 );
+	udelay( 50 );
+    EMAC_REG_WRITE( E_NA, 0, thisadapter->emac_hdw_num );
+	udelay( 100 );
+	udelay( 100 );
+	udelay( 50 );
+    EMAC_REG_WRITE( E_NA, 0, thisadapter->emac_hdw_num );
+	udelay( 100 );
+	udelay( 100 );
+	udelay( 50 );
+}
+
+
+#if USE_HASHTABLE
+HI HashIndex(unsigned char* eAddr)
+{
+    HI hi;/* hash index - return value */
+    hi  = eAddr[0];
+    hi ^= eAddr[1];
+    hi ^= eAddr[2];
+    return hi; 
+}
+
+/******************************************************************************
+|
+|  Function:  SetupHashTable
+|
+|  Description:  sets up the hash table for multicast addresses.
+|				 This routine should be called whenever there is an addition
+|				 or a deletion of multicast address. And also in endStart.
+|				 While the first call to this routine during chip 
+|				 initialization requires that the receiver be turned off, 
+|				 subsequent calls do not.
+|
+|  Returns:    OK/ERROR
+*******************************************************************************/
+static void SetupHashTable(struct net_device *dev)
+{
+    EMAC_DRV_CTRL *thisadapter = (EMAC_DRV_CTRL *)dev->priv;
+	struct dev_mc_list *dmi = dev->mc_list;
+	HI hi;
+	int i;
+
+
+#ifdef SUPPORT_BROADCAST_FILTER
+    UINT8	ethBcastAdrs[]={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+#endif /* SUPPORT_BROADCAST_FILTER */
+
+    /* 
+     * Initialize the hash table to zeroes so that the "wrong" 
+     * multicast address don't get reflected in the table this time.
+     * Here the "wrong" are the ones added/deleted between the last two
+     * consecutive calls of this function.
+     */
+    memset( (signed char*)thisadapter->hashTable,0, HASH_TABLE_SIZE );
+    
+	if (!(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) 
+	{
+		for (i = 0; i < dev->mc_count; i++)
+		{
+			hi = (HI)HASH_INDEX ((unsigned char*)dmi->dmi_addr );
+			ADD_TO_HASHTBL(thisadapter, hi);
+			dmi = dmi->next;
+		}
+	}
+	
+#ifdef SUPPORT_BROADCAST_FILTER
+    /* Install the ethernet broadcast address */
+    hi = HASH_INDEX ((unsigned char*)ethBcastAdrs);
+    ADD_TO_HASHTBL(pDrvCtrl, hi);       /* Add index to table */
+#endif /* SUPPORT_BROADCAST_FILTER */
+
+
+}
+#endif
+
+/******************************************************************************
+|
+|  Function:  sp_emac_probe
+|
+|  Description: 
+|  Parameters:  struct net_device *dev
+|
+|
+*******************************************************************************/
+
+int __init emac_probe(struct net_device *dev)
+{
+	EMAC_DRV_CTRL	*thisadapter;
+	EMAC_DRV_CTRL	*temp;
+	
+	DATA_QUEUE_T	*tx_pkt_q;
+	int				i;
+	int				j;
+	unsigned long	flags;
+	DWORD			dev_num;
+	DWORD			hdw_idx;
+	ULONG			*txd_end;
+
+	// Determine what ethernet device number we are
+	if (dev->name && (strncmp(dev->name, "eth", 3) == 0))
+	{
+		dev_num = simple_strtoul(dev->name + 3, NULL, 0);
+
+		// Do this stuff only when the first device is probed
+		if( dev_num == 0 )
+		{
+			EMAC_hdw_cntr = 0;
+
+		#if (TX_FULL_DUPLEX && EMAC_MUTUALLY_EX_OPR)
+			// Initially assume that we do not
+			// need mutually exclusive operation.
+			emac_mutually_ex_opr = FALSE;
+		#else
+			emac_mutually_ex_opr = TRUE;
+		#endif
+					
+		#if SETUP_FRAME_VERIFY
+			sf_verify = FALSE;
+		#endif
+			for( i = 0; i < RX_RING_SIZE; i++ )
+			{
+				j = ( i + (	RX_RING_SIZE - RX_LOOKBACK_THRESHOLD )) % RX_RING_SIZE;
+				rx_lookback_idx[ i ] = j;
+			}
+			
+			// Allocate space for the transmit frame queues
+			EMAC_tx_pkt_q1 = ( DATA_QUEUE_T *)(EMAC_KMALLOC( sizeof(DATA_QUEUE_T), GFP_KERNEL));
+			EMAC_tx_pkt_q2 = ( DATA_QUEUE_T *)(EMAC_KMALLOC( sizeof(DATA_QUEUE_T), GFP_KERNEL));
+		}
+
+		// NOTE: dev_num is zero relative
+		if( dev_num > ( MAX_ETH_PORTS - 1 ) || EMAC_hdw_cntr > (MAX_ETH_PORTS - 1))
+		{
+			#if 0
+			printk("emac_probe: %s is not supported by CX821xx Family BSP\n",dev->name);
+			#endif
+			return -ENODEV;
+		}
+	}
+	else
+	{
+		// Device name was not an ethernet device
+		return -ENODEV;
+	}
+
+	thisadapter=( EMAC_DRV_CTRL *)(EMAC_KMALLOC(sizeof(EMAC_DRV_CTRL)+QWORD_ALIGN_PAD, GFP_KERNEL));
+
+	if(thisadapter == NULL)
+	{
+		printk("emac_probe: Out Of Memory %s\n",dev->name);
+		return -ENODEV;
+	}
+
+	// Zero out the emac drive control structure
+	// so that everything is at a known state
+	memset( thisadapter, 0, sizeof(EMAC_DRV_CTRL)+QWORD_ALIGN_PAD);
+	
+	// Save a copy of the original adapter pointer
+	// in case we have to free the memory.
+	temp = thisadapter;
+
+	QWORD_ALIGN_PTR(thisadapter);
+	dev->priv = thisadapter;
+
+    if( !(thisadapter->pPhy = PhyAllocateMemory()) )	// PORT
+    {
+		printk("Fatal Error -- PHY OBJ Memory allocation Failure\n");
+		return -ENODEV;
+    }
+
+	// Get the configuration parameters for the emac from the flash
+    if ( EMAC_GetPortConfig( dev_num, thisadapter) == FALSE )
+    {
+        /* Error!*/
+
+        return -ENODEV;
+    }
+
+	// Probe for emac hardware now
+	for( hdw_idx = EMAC_hdw_cntr; hdw_idx <= MAX_ETH_PORTS; hdw_idx++)
+	{
+
+		EMAC_hdw_cntr = hdw_idx;
+		
+		// Fill in the emac hardware number field of the first
+		// emac hardware that we will try for use by the Phy code.
+		// NOTE: This field is zero relative.
+
+		thisadapter->emac_hdw_num = hdw_idx;
+		// Check to see if we reached the end of the list
+		// potential emac hardware ports.
+		if ( hdw_idx >= MAX_ETH_PORTS )
+		{
+			// Free up the emac adapter context memory
+			EMAC_KFREE(temp);				
+			EMAC_KFREE( thisadapter->pPhy );
+			printk("emac_probe:  PHY INIT failed.\n");
+			return -ENODEV;
+		}
+					
+		// Reset the emac hardware 
+		ResetChip( thisadapter );
+		
+		// Probe for the presence of and if found, reset
+		// and initialize the PHY and MAC layers.
+	    if( PhyInit(
+	    				(unsigned long) EMAC_REG_ADDR(E_DMA, thisadapter->emac_hdw_num ),
+						thisadapter->pPhy, 
+						EMAC_MapToPhyConn ( &thisadapter->phyState ), 
+						PHY_HWOPTS_PORT_HOPPING,
+						thisadapter->pHpna
+
+					) == PHY_STATUS_OK )
+	    {
+
+			// We found an emac device
+			hdw_idx++;
+			EMAC_hdw_cntr = hdw_idx;
+			break;
+		}
+	}
+
+	thisadapter->flags = 0;
+
+#if EMAC_TX_WD_TIMER
+	#if 1
+	// Disable interrupts
+	local_irq_save(flags);
+
+	#endif
+	init_timer(&thisadapter->wd_timer);
+	thisadapter->wd_timer.data = (unsigned long)dev;
+	thisadapter->wd_timer.function = (void *)&EMAC_tx_timeout;
+	#if 1
+
+	// Reenable interrupts
+	local_irq_restore(flags);
+	#endif
+
+#endif
+	spin_lock_init(&thisadapter->lock);
+	
+	// This is the Linux ethx number
+	thisadapter->unit = dev_num;
+
+#if EMAC_MUTUALLY_EX_OPR
+	// See if this is a mutually exclusive tx emac part
+	thisadapter->tx_mutex_part = CnxtBsp_Mac_MutEx_Chk();
+#endif
+
+	//!!! test code !!!
+	printk("emac_probe: %s found.\n",dev->name);
+	//!!! test code !!!
+
+	// Initialize the device specific stuff
+	switch( thisadapter->emac_hdw_num )
+	{
+		// emac1
+		case 0:
+			emac_dev[0] = dev;
+			thisadapter->emac_num = 1;
+
+			dev->irq = CNXT_INT_LVL_E1_ERR;
+			dev->base_addr = (ULONG)(EMAC_BASE_ADDR + ( dev_num * 0x00010000));
+			thisadapter->emac_tx_dma_ptr =	DMAC_1_Ptr1;
+		#if EMAC_MUTUALLY_EX_OPR
+			// CX82100-41 parts and above do not need this nonsense
+			if( thisadapter->tx_mutex_part == FALSE )
+			{
+				// CX82100-41
+				thisadapter->emac_tx_dma_ptrx =	DMAC_1_Ptr1;
+			}
+			else
+			{
+				thisadapter->emac_tx_dma_ptrx =	DMAC_3_Ptr1;
+			}
+		#endif
+			thisadapter->emac_rx_dma_ptr2 = DMAC_2_Ptr2;
+			thisadapter->emac_tx_dma_cnt =	DMAC_1_Cnt1;
+			thisadapter->emac_rx_dma_cnt1 = DMAC_2_Cnt1;
+			thisadapter->emac_rx_dma_cnt2 = DMAC_2_Cnt2;
+			thisadapter->emac_na_reg = E_NA_1_reg;
+			thisadapter->emac_stat_reg = E_STAT_1_reg;
+			thisadapter->emac_lp_reg = E_LP_1_reg;
+			thisadapter->emac_ie_reg = E_IE_1_reg;
+			thisadapter->tx_dma_int = CNXT_INT_LVL_DMA1;
+			thisadapter->rx_dma_int = CNXT_INT_LVL_DMA2;
+			thisadapter->int_stat_clr_dev_irq = CNXT_INT_MASK_E1_ERR;
+			thisadapter->int_stat_clr_tx = INT_DMA_EMAC_1_TX;
+			thisadapter->int_stat_clr_rx = INT_DMA_EMAC_1_RX;
+			thisadapter->tx_pkt_in_progress = FALSE;
+
+		#if TX_FULL_DUPLEX
+			thisadapter->emac_tx_q = EMAC_tx_pkt_q1;
+		#else
+			thisadapter->emac_tx_q = EMAC_tx_pkt_q2;
+		#endif
+			tx_pkt_q = thisadapter->emac_tx_q;
+			tx_pkt_q->entry_cnt = 0;
+			tx_pkt_q->get_idx = 0;
+			tx_pkt_q->put_idx = 0;
+
+			kernel_thread( (void *)EMAC1_Task, dev , CLONE_FS | CLONE_FILES  );
+			break;
+			
+		// emac2
+		case 1:
+			emac_dev[1] = dev;
+			thisadapter->emac_num = 2;
+
+			dev->irq = CNXT_INT_LVL_E2_ERR;
+			dev->base_addr = (ULONG)(EMAC_BASE_ADDR + ( dev_num * 0x00010000));
+			thisadapter->emac_tx_dma_ptr =	DMAC_3_Ptr1;
+		#if EMAC_MUTUALLY_EX_OPR
+			thisadapter->emac_tx_dma_ptrx =	DMAC_3_Ptr1;
+		#endif
+			thisadapter->emac_rx_dma_ptr2 = DMAC_4_Ptr2;
+			thisadapter->emac_tx_dma_cnt =	DMAC_3_Cnt1;
+			thisadapter->emac_rx_dma_cnt1 = DMAC_4_Cnt1;
+			thisadapter->emac_rx_dma_cnt2 = DMAC_4_Cnt2;
+			thisadapter->emac_na_reg = E_NA_2_reg;
+			thisadapter->emac_stat_reg = E_STAT_2_reg;
+			thisadapter->emac_lp_reg = E_LP_2_reg;
+			thisadapter->emac_ie_reg = E_IE_2_reg;
+			thisadapter->tx_dma_int = CNXT_INT_LVL_DMA3;
+			thisadapter->rx_dma_int = CNXT_INT_LVL_DMA4;
+			thisadapter->int_stat_clr_dev_irq = CNXT_INT_MASK_E2_ERR;
+			thisadapter->int_stat_clr_tx = INT_DMA_EMAC_2_TX;
+			thisadapter->int_stat_clr_rx = INT_DMA_EMAC_2_RX;
+			thisadapter->tx_pkt_in_progress = FALSE;
+			thisadapter->emac_tx_q = EMAC_tx_pkt_q2;
+
+		#if TX_FULL_DUPLEX
+			tx_pkt_q = thisadapter->emac_tx_q;
+			tx_pkt_q->entry_cnt = 0;
+			tx_pkt_q->get_idx = 0;
+			tx_pkt_q->put_idx = 0;
+		#endif
+
+			kernel_thread( (void *)EMAC2_Task, dev, CLONE_FS | CLONE_FILES  );
+			break;
+	}
+
+	// Retrieve the mac address for the device
+	CnxtBsp_Get_Mac_Address( dev_num, &thisadapter->PortNetAddress[0] );
+
+    /* memory Initializations.
+     * Allocation & Initialization of all the memory required by an 
+     * instance of the driver is done in the following function.
+     */
+
+	// Initialize the memory used by the transmitter
+    EMAC_init_tx( thisadapter );
+	printk("Tx DMA Ring %lx \n",(DWORD)thisadapter->txd_buf[0]);
+
+	// Initialize END TMAC TRANSMIT DESCRIPTOR
+	// NOTE: This must be done after the EMAC_init_tx function call
+	thisadapter->TxD_end->status = 0;     
+	thisadapter->TxD_end->status_zero =0;   
+	thisadapter->TxD_end->control = 0;
+
+	txd_end = (ULONG *) thisadapter->TxD_end;
+	txd_end[6] = (ULONG) txd_end;
+	txd_end[7] = 3;				/* avoids prefetch of next ptr and ctr */
+
+	// Initialize the memory used by the receiver
+    EMAC_init_rx( thisadapter );
+	printk("Rx DMA Ring %lx \n",(DWORD)thisadapter->rxd_buf);
+	
+	SET_MODULE_OWNER(dev);
+
+	dev->open				= emac_open;
+	dev->stop				= emac_close;
+	dev->hard_start_xmit	= emac_send_packet;
+	dev->get_stats			= emac_get_stats;
+	dev->set_multicast_list = &set_multicast_list;
+	dev->set_mac_address	= emac_set_mac_address;
+#if 0
+	dev->tx_timeout			= EMAC_Linux_tx_timeout;
+	dev->watchdog_timeo		= TX_TIMEOUT_DELAY + 10;
+#endif
+	
+	/* Fill in the fields of the device structure with ethernet values. */
+	ether_setup(dev);
+
+	printk("%s irq=%d ",version,dev->irq);
+	
+	for( i = 0; i < MAC_ADDR_LEN ; i++)
+	{
+		printk("%2.2x:", dev->dev_addr[i] = thisadapter->PortNetAddress[i]);
+	}
+	printk("\n");
+
+	// Connect the device irq to the OS interrupt handler
+	if (request_irq( dev->irq, &EMAC_Exception_ISR, 0, "Cnxt Ethernet Media Access Ctrl", dev))
+	{
+		return -EAGAIN;		
+	}
+
+	// Disable the device irq
+    cnxt_mask_irq( dev->irq );
+
+#if TX_DMA_INT
+	if (request_irq( thisadapter->tx_dma_int, &EMAC_TxISR, 0, "emac Tx Isr", dev))
+	{
+		return -EAGAIN;		
+	}
+	
+    cnxt_mask_irq( thisadapter->tx_dma_int );	
+#endif
+#if RX_DMA_INT
+	if (request_irq( thisadapter->rx_dma_int, &EMAC_RxISR, 0, "emac Rx Isr", dev))
+	{
+		return -EAGAIN;		
+	}
+	
+    cnxt_mask_irq( thisadapter->rx_dma_int );	
+#endif
+
+	return 0;
+}
+
+#if HOMEPLUGPHY
+
+struct sk_buff	homeplug_skb;
+BYTE			homeplug_msg_data[128];
+
+ADDR_TBL * Get_Free_Tx_Buffer( EMAC_DRV_CTRL *MACAdapter )
+{
+	homeplug_skb.data = &homeplug_msg_data[0];		
+	return &homeplug_skb;
+}
+
+void MAC_Assign_MacAddress( EMAC_DRV_CTRL *MACAdapter, UINT8 *S_Addr )
+{
+	MOVE_MEMORY( S_Addr, &MACAdapter->PortNetAddress[0], 6 ) ;
+}
+
+
+void MAC_Send_A_Frame( EMAC_DRV_CTRL *MACAdapter, UINT32 PacketSize, ADDR_TBL *PtrTxBuffer, BOOLEAN Control_Frame )
+{
+	TX_PKT_INFO		tx_pkt_info;
+	unsigned long	flags;
+	DWORD				entry;
+
+	// Generalize the data about the transmit packet
+	PtrTxBuffer->len = PacketSize;
+
+	tx_pkt_info.tx_pkt_data = PtrTxBuffer->data;
+	tx_pkt_info.tx_pkt_len = PtrTxBuffer->len;
+	tx_pkt_info.pkt_type = NORMAL;
+	
+	// Preprocess the transmit packet data for the emac driver
+	if( EMAC_Tx_Pkt_Process( MACAdapter, &tx_pkt_info, &entry ) == TRUE )
+	{
+		// Disable interrupts
+		spin_lock_irqsave(&MACAdapter->lock, flags); 
+
+		EMAC_Queue_Tx_Pkt( MACAdapter->dev, (DWORD)entry );
+		
+		// Transmit the successfully processed packet now
+		EMAC_Tx_Pkt_Transmit( MACAdapter->dev );
+		
+		// Reenable interrupts
+		spin_unlock_irqrestore(&MACAdapter->lock, flags);
+	}
+	else
+	{
+	}
+}
+#endif
+
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,612 @@
+/****************************************************************************
+*
+*	Name:			cnxtEmac.h
+*
+*	Description:	Header file for cnxtEmac.c
+*
+*	Copyright:		(c) 2001,2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.8  $
+*  $Modtime:   Jul 11 2003 07:36:44  $
+****************************************************************************/
+
+#ifndef __EMAC_END_H
+#define __EMAC_END_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+ * 
+ * includes 
+ *
+ */
+
+#include  <linux/skbuff.h>
+
+/* emac */
+#define INC_PHY
+#include "cnxtEmac_hw.h"      /* HW regs & related defines. */
+#include "filters.h"       /* Hashing, Address filtering & setup frame. */
+//#include "emac_type.h"
+#include <linux/if_ether.h>
+
+#include "phy.h"           /* Physical Layer Driver: types */
+#include <asm/arch/OsTools.h>
+
+
+/* PHY link status data structure and related #defines. */
+typedef struct phy_setting
+{
+    unsigned long   autoNegotiate;      // 0: disable,  1: enable
+    unsigned long   networkSpeed;       // 0: 10M,  1: 100M
+    unsigned long   duplexMode;         // 0: HDX,  1: FDX
+    unsigned long   linkStatus;         // 0: down, 1: up
+    unsigned long   phySettings;        // returned by PhyCheck ()
+} PHY_SETTING;
+
+#define PHY_FORCEDMODE          0
+#define PHY_AUTONEGOTIATE       1
+#define PHY_STAT_SPEED_10       0
+#define PHY_STAT_SPEED_100      1
+#define PHY_STAT_DUPLEX_HALF    0
+#define PHY_STAT_DUPLEX_FULL    1
+#define PHY_STAT_LINK_DOWN      0
+#define PHY_STAT_LINK_UP        1
+
+
+
+#if 0
+	#define	RX_RING_SIZE		64
+#else
+	#define	RX_RING_SIZE		80
+#endif
+#if 0
+	#define	TX_RING_SIZE		64
+#else
+	#define	TX_RING_SIZE		80
+#endif
+#if 1
+	#define ETH_PKT_BUF_SZ		1536
+#else
+	#define ETH_PKT_BUF_SZ		1600
+#endif
+
+
+/* Assign the appropriate number of RXD's based on the link speed. */
+#define RXD_NUM  RX_RING_SIZE
+/* Assign the mask number to allow wrap around in the RXD table. */
+#define RXD_NUM_WRAP  (RXD_NUM-1)
+
+#define SIZE_OF_DATA_QUEUES	(TX_RING_SIZE * 2)
+
+typedef struct
+{
+	DWORD	Data1;
+	DWORD	Data2;
+	DWORD	Data3;
+
+} DATA_REG_T;
+
+typedef struct
+{
+	
+	BYTE		get_idx;
+	BYTE		put_idx;
+	BYTE		entry_cnt;
+	BYTE		fill;		// Dword align the structure
+	DATA_REG_T	queue[SIZE_OF_DATA_QUEUES];
+	
+} DATA_QUEUE_T;
+
+
+#define DRV_NAME		"mac"
+#define DRV_NAME_LEN    5
+#define EDRV_DESC		"Conexant CX82100 EMAC Enhanced Network Driver"
+
+#define	NONE			0
+
+/*******************************************************************************
+ * Ethernet Standards:
+ *
+ * 1. Ethernet Frame fields - order left to right - are:
+ *    preamble[7],sfd[1],da[6],sa[6],type(or len)[2],data[var],pad[var],fcs[4].
+ *    Where, [x] = length in bytes. [var] = variable length.
+ *
+ *    da, sa & type(or len) put together is called ethernet header.
+ *
+ *    ISO802.3 has length field instead of Type field.
+ *    But in both cases ethernet & ISO802.3, the length of the 3rd field
+ *    remains 2 bytes. 
+ *
+ *    Ethernet address, Physical address & MAC address are synonymous.
+ *
+ *    ENET_HDR_REAL_SIZ: len of destination & source addr & type = 14 bytes.
+ *    ETHERMTU: max length of data & pad fields = 1500 bytes.
+ *    ETHERMIN: min length of data & pad fields (60-14) = 46 bytes.
+ *
+ * 2. MAC HW:
+ *    Preamble & sfd are removed/added by Rx/Tx MAC HW before the frame
+ *    is sent up/down to the protocols/cable. So as far as MAC SW (driver) goes, 
+ *    the frame starts from DA and ends with FCS.
+ */
+
+
+#define MAC_ADDR_LEN          ( 6 ) 
+           
+/* return value for MAC_cmp */
+#define MAC_GREATER           ( 1 )    
+#define MAC_EQUAL             ( 0 )
+#define MAC_LESS              ( -1 )
+
+/* size of multicast address and hash tables */
+#define MULTI_TABLE_SIZE      ( 256 )
+#define HASH_TABLE_SIZE       ( 32 )
+
+/* bit which defines whether a MAC Address is multi or uni cast */
+#define MULTICAST_MSK         ( 0x01 )
+
+/* hash table initialization values */
+#define FILTER_ALL            ( 0x00 )
+#define PASS_ALL              ( 0xFF )
+
+typedef enum
+{
+	NORMAL = 0,
+	SETUP
+
+} TX_PKT_TYPE;
+
+
+/****************************************************************************
+ * Structures
+ ****************************************************************************/
+
+#define EMAC_SETUP_PERFECT_ENTRIES     16
+typedef union _EMAC_SETUP_FRAME 
+{
+    struct 
+    {
+        unsigned long PhysicalAddress[EMAC_SETUP_PERFECT_ENTRIES][3];
+    } Perfect;
+} EMAC_SETUP_FRAME, *PEMAC_SETUP_FRAME;
+
+#define ADDRESS_FILTER_SIZE     192
+
+/* MAC Address */
+typedef UINT8 MAC_ADDR[MAC_ADDR_LEN];
+
+/* aligned MAC address */
+typedef struct aligned_mac_addr
+{
+   UINT16      usLSW;      /* least significant word */
+   UINT16      usCSW;      /* middle word */
+   UINT16      usMSW;      /* most significant word */
+} ALIGNED_MAC_ADDR;
+
+
+
+
+#define EMAC_CLUSTER_SZ  2048
+
+#define EADDR_LEN	        6       /* ethernet address length */
+
+#define NET_SPEED_10	10000000             /* 10 Mbps		*/
+#define NET_SPEED_100	100000000            /* 100 Mbps	*/
+
+/* Setup Frame Type */
+
+#define	MT_SETUP_FRAME	   ( NUM_MBLK_TYPES )   /* setup frame emac tx identifier */
+
+/* Call these in endMCastAddrAdd[Del] funcs. */
+#define DRV_END_DECR_MULTI(pDrvCtrl) ((pDrvCtrl)->endObj.nMulti--)
+#define DRV_END_INCR_MULTI(pDrvCtrl) ((pDrvCtrl)->endObj.nMulti++)
+
+/* 
+ * Mem alignment macros 
+ */
+
+#define QWORD_ALIGN_PTR(x) \
+	{  \
+		register unsigned int* p; \
+		p = (unsigned int*)(void*)&(x); \
+		*p=((*p)&0x7)?(((*p)|7)+1):(*p); \
+	}
+
+#define	QWORD_ALIGN_PAD		8
+#define QWORD_ALIGN_CHK		7
+#define SIZEOF_QWORD		8
+#define QWORD_ROUND_UP_FACTOR	7
+
+/* alignment sizes: always power of 2*/
+#define W_AL  2				   /* WORD alignment? */
+#define DW_AL (sizeof (DWORD))    /* DWORD alignment */
+#define QW_AL (2*sizeof (DWORD))  /* QWORD alignment */
+
+/* Align qty to forward(next) al-boundry.*/
+#define ALIGN_FW(qty,al)       (((int)(qty) + ((al)-1)) & ~((al)-1))
+
+/*******************************************************************************
+ * DMA Chain elements joining.
+ */
+
+/* Joins two dma chains. */
+typedef struct _DMA_Chain_joint
+{
+	volatile BYTE* pNext; /* Pointer to next contiguous location */
+	volatile ULONG cNext; /* # of QWORDS in next contiguous location */
+} JOINT;
+
+#define JOINT_SIZ	sizeof(JOINT)
+
+/*******************************************************************************
+ * Descriptors: definitions & defines.
+ *
+ * Note:
+ * 1 The order in which the fields are listed is important.
+ * 2 Both descriptors have status, a 64 bit qword, represented as two ULONGs.
+ *   The order in which the two ULONGs are listed in the structure definition, 
+ *   depends on the endianism: in our case little endian.
+ */
+
+/* Transmit Descriptor - hardware defined. */
+typedef struct _emac_txd
+{
+    volatile ULONG   status;         /* status - see TSTAT_XXX in emac_desc.h                    */
+    volatile ULONG   status_zero;    /* zeroes                                                   */
+    volatile ULONG   control;        /* TDES -see TCTRL_XXX in emac_desc.h (incl. len in bytes)  */
+} EMAC_TXD;
+
+#define EMAC_TXD_SIZE	sizeof( EMAC_TXD )
+
+/* Transmit Message Descriptor Entry. */
+typedef struct tDesc
+{
+    volatile ULONG	status;	     /* status				*/
+    volatile ULONG	status_zero; /* zeroes				*/
+    volatile ULONG	control;     /* control parameters	*/
+    ULONG   data;        		/* first ulong in the cluster */
+    JOINT   joint;
+} EMAC_TD;
+
+#define TD_SIZ	        ( sizeof(EMAC_TD)/ SIZEOF_QWORD ) /* 3 qwords */
+#define TD_DMA_SIZ	    (( TD_SIZ - JOINT_SIZ ) / SIZEOF_QWORD )
+
+
+typedef struct
+{
+	BYTE			*tx_pkt_data;
+	unsigned int	tx_pkt_len;
+	TX_PKT_TYPE		pkt_type;
+
+} TX_PKT_INFO;
+
+/*
+ * Tx Msg Queue 
+ */
+
+typedef struct tx_msg_queue
+{
+	char *      Data;
+    ULONG		ulControl;
+	ULONG		ulLength;
+
+} TX_MSG_QUEUE;
+
+/*********************************************************************
+	This is a hardware structure found in the CX82100
+	Design Specification. 
+*********************************************************************/
+typedef struct 
+{
+	volatile unsigned char*	mData;
+    volatile unsigned long	reserved;
+    volatile unsigned long	status;
+    volatile unsigned long	mib;
+
+}EMAC_RXD;
+
+
+/*********************************************************************
+	This structure contains the main Q information for tracking the 
+    hardware packet information and which clusters are to be
+    transferred to the MUX.  The ordering of the elements is 
+    important because the DMA channel is expecting the first
+    Q element of the EMAC_RXD to be qword aligned!
+*********************************************************************/
+typedef struct
+{
+	EMAC_RXD        q[RXD_NUM];				/* pointer to the beginning of the descriptor list */
+	struct sk_buff*	skb[RXD_NUM];
+	unsigned long   qndx;   				/* index to next available element when queue size is non-zero  */
+
+} EMAC_RXD_HW_QTYPE;
+
+typedef struct EMAC_drv_ctrl
+{
+	BYTE			*txd_buf_mem;			// Pointer to the original non-qword aligned
+											// memory block obtained from kmalloc
+
+	BYTE			*txd_buf[TX_RING_SIZE];	// Array of pointers to ethernet sized blocks
+											// of memory from the memory pointed to by
+											// txd_buf_mem
+	TX_MSG_QUEUE   	tx_msg_q [TX_RING_SIZE];
+	DATA_QUEUE_T	*emac_tx_q;
+
+   	EMAC_TD*		TxD_end;
+
+	UINT32   		tx_msg_q_next;   /* index to next available element when queue is not full */
+	UINT32   		tx_msg_q_current;  /* current transmitting TxD                               */
+	UINT32   		tx_msg_q_size;    /* if size is zero, then queue is empty                   */
+	BOOLEAN			tx_pkt_in_progress;
+	BOOLEAN			tx_mutex_part;
+	BOOLEAN			hw_reset_required;
+	EVENT_HNDL		*hw_reset_event;
+
+	BYTE			setup_frame_buf[256];
+
+	/* Tx control lock.  This protects the transmit buffer ring
+	 * state along with the "tx full" state of the driver.  This
+	 * means all netif_queue flow control actions are protected
+	 * by this lock as well.
+	 */
+	spinlock_t		lock;
+
+	struct net_device_stats	stats;
+	struct net_device_stats	prev_stats;
+
+	// Receiver hardware queue
+	EMAC_RXD_HW_QTYPE	*rxd_hw;
+	BYTE				*rxd_buf;
+	DATA_QUEUE_T		EMAC_rx_buf_q;
+
+	struct timer_list	wd_timer;
+	struct timer_list	periodic_task;
+
+   	/* Multicast Address Table is array */
+    int         multiCount;                     /* Number of multicast address in Table */
+    MAC_ADDR    multiTable[MULTI_TABLE_SIZE];   /* Multicast address table */
+    UINT8       hashTable[HASH_TABLE_SIZE];     /* Multicast hash table */
+
+    int			flags;               /* driver flags					*/
+
+	BOOLEAN		emac_dev_q_state;	// TRUE = STARTED,  FALSE = STOPPED
+	BOOLEAN		emac_state;			// TRUE = OPEN,  FALSE = CLOSED
+	DWORD		emac_num;			// emac_num = unit + 1 -> emac1 = eth0 and emac2 = eth1
+	DWORD		emac_hdw_num;		// emac_hdw_num = 0 -> emac1 and 1 -> emac2
+    int			unit;                /* unit number	*/
+
+	UINT8		PortNetAddress[MAC_ADDR_LEN];
+	   
+	volatile unsigned int	E_NA_settings;
+	volatile unsigned int	E_IE_settings;
+
+	int						tx_dma_int;
+	int						rx_dma_int;
+
+	volatile unsigned long	int_stat_clr_dev_irq;
+	volatile unsigned long	int_stat_clr_tx;
+	volatile unsigned long	int_stat_clr_rx;
+
+	volatile unsigned long*	emac_tx_dma_ptr;
+	volatile unsigned long*	emac_tx_dma_ptrx;
+	volatile unsigned long* emac_rx_dma_ptr2;
+	volatile unsigned long* emac_tx_dma_cnt;
+	volatile unsigned long* emac_rx_dma_cnt1;
+	volatile unsigned long* emac_rx_dma_cnt2;
+	volatile unsigned long* emac_na_reg;
+	volatile unsigned long* emac_stat_reg;
+	volatile unsigned long* emac_lp_reg;
+	volatile unsigned long* emac_ie_reg;
+
+	ULONG	MacFilteringMode;
+
+#ifdef INC_PHY
+
+/*
+ *  Physical Layer Driver struct-type.
+ */
+
+    PHY_SETTING     phyState;
+	
+/* # of Phys connected to the MAC via the MII bus.*/
+#ifndef MAX_SUPPORTED_PHYS
+#define MAX_SUPPORTED_PHYS	2 /* Must be < 31 */
+#endif
+
+    PHY		*pPhy;
+#endif /* INC_PHY */
+	void	*pHpna ;	//PHPNALLOBJ pHpna ;
+
+#if HOMEPLUGPHY
+	struct net_device *dev;
+		
+	#ifdef HOMEPLUG_PHYMAC_OVERFLOW_WORKAROUND
+	struct semaphore	tx_delay_sem_id;
+	int		Current_packet_Collision_cnt ;
+	#endif
+#endif
+
+
+} EMAC_DRV_CTRL;
+
+#define DRV_CTRL_SIZ	sizeof(DRV_CTRL)
+#define	DRV_CTRL	EMAC_DRV_CTRL
+
+/*******************************************************************************
+ * EMAC specific ethernet frame size & cluster size requirements.
+ */
+
+#define MIN_ETHERNET_SIZE 18        /* used in end send */
+#define MAX_ETHERNET_SIZE 1518
+#define ETHERNET_CRC_SIZE	  4
+#define CL_SIZ             2048
+
+#define	NET_SPEED_DEF	NET_SPEED_10
+
+
+/*
+ * END specific defines
+ */
+
+#define END_FLAGS_ISSET(pEnd, setBits)                                  \
+        ((pEnd)->flags & (setBits))
+
+#define END_HADDR(pEnd)                                                 \
+		((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
+
+#define END_HADDR_LEN(pEnd)                                             \
+		((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
+
+#define	END_MIB_SPEED_SET(pEndObj, speed)                               \
+	    ((pEndObj)->mib2Tbl.ifSpeed=speed)
+
+
+/*
+ * DRV_CTRL flags & access macros 
+ */
+
+#define DRV_MEMOWN		0x0001	/* TDs and RDs allocated by driver	*/
+#define EMAC_POLLING	0x0004	/* Poll mode, io mode				*/
+#define FLT_PROMISC		0x0008	/* Promiscuous, rx mode				*/
+#define FLT_MCAST		0x0010	/* Multicast, rx mode				*/
+
+#define DRV_FLAGS_SET(setBits)                                          \
+	    (pDrvCtrl->flags |= (setBits))
+
+#define DRV_FLAGS_ISSET(setBits)                                        \
+	    (pDrvCtrl->flags & (setBits))
+
+#define DRV_FLAGS_CLR(clrBits)                                          \
+	    (pDrvCtrl->flags &= ~(clrBits))
+
+#define DRV_FLAGS_GET()                                                 \
+        (pDrvCtrl->flags)
+
+        
+/* 
+ * Network Access 
+ */
+
+#define E_NA_RTX	((ULONG)((ULONG)1<<31)) /* Tx Software Reset	        [31]        */
+#define E_NA_STOP	((ULONG)((ULONG)1<<30)) /* Stop transmit		        [30]        */
+#define E_NA_HP		((ULONG)((ULONG)1<<27)) /* Hash/perfect addr filter     [27]        */
+#define E_NA_HO		((ULONG)((ULONG)1<<26)) /* Hash only			        [26]        */
+#define E_NA_IF		((ULONG)((ULONG)1<<25)) /* Inverse Filter		        [25]        */
+#define E_NA_PR		((ULONG)((ULONG)1<<24)) /* Promiscuous mode	            [24]        */
+#define E_NA_PM     ((ULONG)((ULONG)1<<23)) /* Pass all Multicast           [23]        */
+#define E_NA_PB		((ULONG)((ULONG)1<<22)) /* Pass bad packet	            [22]        */
+#define E_NA_RRX	((ULONG)((ULONG)1<<21)) /* Rx s/w reset		            [21]        */
+#define E_NA_THU	((ULONG)((ULONG)1<<20)) /* Tx test HUJ counter          [20]        */
+#define E_NA_DIS	((ULONG)((ULONG)1<<19)) /* Tx Disable backoff counter   [19]        */
+#define E_NA_RUT	((ULONG)((ULONG)1<<18)) /* Tx reset unit timer          [18]        */
+#define E_NA_IFG	((ULONG)((ULONG)3<<16)) /* Inter-frame gap	            [17:16]		*/
+#define E_NA_JBD	((ULONG)((ULONG)1<<15)) /* Jabber disable		        [15]        */
+#define E_NA_HUJ	((ULONG)((ULONG)1<<14)) /* Host Un-Jabber		        [14]        */
+#define E_NA_JCLK	((ULONG)((ULONG)1<<13)) /* Jabber clock		            [13]        */
+#define E_NA_SB		((ULONG)((ULONG)1<<12)) /* Start/Stop Backoff Counter   [12]        */
+#define E_NA_FD		((ULONG)((ULONG)1<<11)) /* Full duplex		            [11]        */
+#define E_NA_OM 	((ULONG)((ULONG)3<<9 )) /* Operating mode               [10:9]	   	*/
+#define E_NA_OM_R	((ULONG)((ULONG)3<<9 )) /* Operating mode: Reserved	    [10:9]	-GL	*/
+#define E_NA_OM_E   ((ULONG)((ULONG)2<<9 )) /* Operating mode: External LB	[10:9]  -GL	*/ 
+#define E_NA_OM_I   ((ULONG)((ULONG)1<<9 )) /* Operating mode: Internal LB	[10:9]	-GL	*/
+#define E_NA_FC		((ULONG)((ULONG)1<<8 )) /* Force Collisions	            [8]         */
+#define E_NA_HLAN	((ULONG)((ULONG)1<<7 )) /* Home LAN Enablee	            [7] 	    */
+#define E_NA_SR		((ULONG)((ULONG)1<<6 )) /* Start/Stop receive	        [6] 	    */
+#define E_NA_NS		((ULONG)((ULONG)1<<5 )) /* Network speed		        [5] 	    */
+#define E_NA_RWR	((ULONG)((ULONG)1<<4 )) /* Receive WD release	        [4]			*/
+#define E_NA_RWD	((ULONG)((ULONG)1<<3 )) /* Receive WD disable	        [3] 	    */
+#define E_NA_STRT	((ULONG)((ULONG)1    )) /* Start transmit		        [0] 	    */
+
+#define E_NA_FILTER_MODE        ( E_NA_PM | E_NA_PR | E_NA_IF | E_NA_HO | E_NA_HP )
+#define E_NA_FILTER_PROMIS      ( E_NA_PM | E_NA_PR )
+#define E_NA_FILTER_MC1PERFECT  ( E_NA_PM | E_NA_HP )
+#define E_NA_FILTER_INVERSE	    ( E_NA_IF )
+
+/*
+ * END Specific interfaces. 
+ */
+
+#define INT_DMA_EMAC_1_TX   ((unsigned long)1<<15)
+#define INT_DMA_EMAC_1_RX   ((unsigned long)1<<14)
+#define INT_DMA_EMAC_2_TX   ((unsigned long)1<<13)
+#define INT_DMA_EMAC_2_RX   ((unsigned long)1<<12)
+
+/**********************************************************/    
+/* Global shadow register for the E_NA register           */
+/**********************************************************/    
+
+
+#define E_S_TU    ((unsigned long)1<<31)
+#define E_S_RO    ((unsigned long)1<<26)
+#define E_S_RWT   ((unsigned long)1<<25)
+#define E_S_TOF   ((unsigned long)1<<16)
+#define E_S_TUF   ((unsigned long)1<<15)
+#define E_S_ED    ((unsigned long)1<<14)
+#define E_S_DF    ((unsigned long)1<<13)
+#define E_S_CD    ((unsigned long)1<<12)
+#define E_S_ES    ((unsigned long)1<<11)
+#define E_S_RLD   ((unsigned long)1<<10)
+#define E_S_TF    ((unsigned long)1<<9)
+#define E_S_TJT   ((unsigned long)1<<8)
+#define E_S_NCRS  ((unsigned long)1<<7)
+#define E_S_LCRS  ((unsigned long)1<<6)
+#define E_S_16    ((unsigned long)1<<5)
+#define E_S_LC    ((unsigned long)1<<4)
+#define E_S_CC    ((unsigned long)0xf<<0)
+
+#define BF_CRC 	   0x0ff00000
+#define BF_ALN     0x000f0000
+#define BF_LONG    0x0000f000
+#define BF_RUNT    0x00000ff0 
+#define BF_OFLW    0x0000000f
+#define BF_MASK    (BF_CRC+BF_ALN+BF_LONG+BF_RUNT+BF_OFLW)
+
+#define GF_TS      0x00000800
+#define GF_MF      0x00000400
+#define GF_TL      0x00000080
+#define GF_LC      0x00000040
+#define GF_OFT     0x00000020
+#define GF_RW      0x00000010
+#define GF_DB      0x00000004
+#define GF_CE      0x00000002
+#define GF_OF      0x00000001
+#define GF_MASK    (GF_TS+GF_MF+GF_TL+GF_LC+GF_OFT+GF_RW+GF_DB+GF_CE+GF_OF)
+#define RX_ES		0x00008000
+#define RX_A1		0x00000008
+
+
+#if HOMEPLUGPHY
+typedef	struct sk_buff ADDR_TBL ;
+
+#define Packet_Buffer_Virtual_Adr( _pBuffer )	((ADDR_TBL *)(_pBuffer))->data
+ADDR_TBL * Get_Free_Tx_Buffer( EMAC_DRV_CTRL *MACAdapter );
+
+void MAC_Assign_MacAddress( EMAC_DRV_CTRL *MACAdapter, BYTE *S_Addr );
+void MAC_Send_A_Frame( EMAC_DRV_CTRL *MACAdapter, DWORD PacketSize, ADDR_TBL *PtrTxBuffer, BOOLEAN Control_Frame );
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __EMAC_END_H */
Files uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac.o and uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac.o differ
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac_hw.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac_hw.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac_hw.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/cnxtEmac_hw.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,89 @@
+/****************************************************************************
+*
+*	Name:			cnxtEmac_hw.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2001,2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __CNXT_EMAC_HW_H
+#define __CNXT_EMAC_HW_H
+
+/*******************************************************************************
+ *
+ * This file simply INCLUDES files. 
+ * Each included file:
+ * 1) corresponds to a sub-device of the CX821xx device. 
+ * 2) It defines registers, bit masks & reg-access macros for that sub-device.
+ *
+ */
+
+/*******************************************************************************
+ * Emac: Reg base addr & Reg offset.
+ * The reg offset is same for all the sub-devices (like DMAC, EMAC & 
+ * Interrupt controller).
+ */
+
+
+#ifndef REG_BASE_ADDR
+#define REG_BASE_ADDR	 ((BYTE*)(0x00300000)) /* double word aligned */
+#endif
+
+#ifndef BE_OFST
+#define BE_OFST		 0   /* 0 for little endian, 7 for big  */
+#endif
+
+#ifndef REG_OFFSET
+#define REG_OFFSET	 (BE_OFST + 0x04) /* double word aligned */
+#endif
+
+
+/*
+ * Reg Access Macros, using Register-ADDRESS ( and not the reg number)
+ */
+
+#ifndef REG_WRITE
+#define REG_WRITE(regAddr,val)  ( (*(volatile ULONG*)(regAddr)) = (val) )
+#endif /* REG_WRITE */
+
+/*******************************************************************************
+ * Emac sub-devices: registers, bitmasks & reg access macros.
+ */
+
+
+/* M2M registers & access-macros*/
+#include "m2m_regs.h"
+
+/* Interrupt controller registers (eg int msk, intr stat) & access-macros */
+#include "intr_regs.h"
+
+/* EMAC registers & access-macros */
+#include "emac_regs.h"
+
+/* EMAC descriptors, status & access-macros */
+#include "emac_desc.h"
+
+
+#endif /* __CNXT_EMAC_HW_H */
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/dma_regs.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/dma_regs.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/dma_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/dma_regs.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,211 @@
+/****************************************************************************
+*
+*	Name:			dma_regs.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*					Personal Computing Division
+*					All Rights Reserved
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __DMA_REGS_H
+#define __DMA_REGS_H
+
+
+/*******************************************************************************
+ * CX821xx: Reg base addr & Reg offset.
+ * The reg offset is same for all the sub-devices (like DMAC, EMAC & 
+ * Interrupt controller).
+ */
+
+
+#ifndef REG_BASE_ADDR
+#define REG_BASE_ADDR	 ((BYTE*)(0x00300000)) /*  */
+#endif
+
+#ifndef BE_OFST
+#define BE_OFST		 0   /* 0 for little endian, 7 for big  */
+#endif
+
+#ifndef REG_OFFSET
+#define REG_OFFSET	 (BE_OFST + 0x04) /* double word aligned */
+#endif
+
+/*******************************************************************************
+ *
+ * Define DMAC REGs and macros to access them.
+ * To optimize REG accesses, redefine DMA_*_REG_READ and
+ * DMA_*_REG_WRITE macros in a wrapper file.
+ */
+
+/*
+ * Current pointers ( DMA{x}_Ptr1 )
+ */
+
+#define DMA_PTR1_BASE_ADDR	    REG_BASE_ADDR
+#define DMA_PTR1_REG_OFFSET	    REG_OFFSET	
+
+/* Reg numbering w.r.t base */
+
+#define DMA1_PTR1	0
+#define DMA2_PTR1	1
+#define DMA3_PTR1	2 /* EMAC Tx channel */
+#define DMA4_PTR1	3 /* EMAC Rx channel */
+#define DMA5_PTR1	4
+#define DMA6_PTR1	5
+#define DMA7_PTR1	6
+#define DMA8_PTR1	7
+#define DMA9_PTR1	8
+#define DMA10_PTR1	9
+
+/* Reg access macros */
+
+#define DMA_PTR1_REG_ADDR(regNum)   (DMA_PTR1_BASE_ADDR + \
+                                     (regNum) * DMA_PTR1_REG_OFFSET)
+
+#ifndef DMA_PTR1_REG_READ
+#define DMA_PTR1_REG_READ(regNum)   (*((volatile ULONG*)DMA_PTR1_REG_ADDR((regNum))))
+#endif /* DMA_PTR1_REG_READ */
+
+#ifndef DMA_PTR1_REG_WRITE
+#define DMA_PTR1_REG_WRITE(regNum,val)  (*((volatile ULONG*)DMA_PTR1_REG_ADDR((regNum))) = (val))
+#endif /* DMA_PTR1_REG_WRITE */
+
+
+#define DMA4_PTR1_BASE_ADDR	   	0x30000c 
+#define DMA4_PTR1_REG_ADDR(regNum)   ((volatile ULONG *)(DMA4_PTR1_BASE_ADDR + \
+                                    ((regNum) * (DMA_PTR1_REG_OFFSET))))
+
+#undef DMA4_PTR1_REG_WRITE
+#define DMA4_PTR1_REG_WRITE(regNum,val) \
+	 (*(DMA4_PTR1_REG_ADDR(regNum)) = (val))
+
+
+
+#ifndef DMA_PTR1_REG_UPDATE
+#define DMA_PTR1_REG_UPDATE(regNum,val) DMA_PTR1_REG_WRITE((regNum), \
+                                        DMA_PTR1_REG_READ((regNum)) | (val))
+#endif /* DMA_PTR1_REG_UPDATE */
+    
+#ifndef DMA_PTR1_REG_RESET
+#define DMA_PTR1_REG_RESET(regNum,val)  DMA_PTR1_REG_WRITE((regNum), \
+                                        DMA_PTR1_REG_READ((regNum)) & ~(val))
+#endif /* DMA_PTR1_REG_RESET */
+
+/*
+ * Indirect/Return pointers ( DMA{x}_Ptr2 ). 
+ */
+
+#define DMA_PTR2_BASE_ADDR	((BYTE*)0x00300030) /* Base Address */
+#define DMA_PTR2_REG_OFFSET	    REG_OFFSET	
+
+/* Reg numbering w.r.t base */
+
+#define DMA1_PTR2	0
+#define DMA2_PTR2	1
+#define DMA3_PTR2	2 /* EMAC Tx channel */
+#define DMA4_PTR2	3 /* EMAC Rx channel */
+#define DMA5_PTR2	4
+#define DMA6_PTR2	5
+#define DMA7_PTR2	6
+#define DMA8_PTR2	7
+#define DMA9_PTR2	8
+#define DMA10_PTR2	9
+
+/* Reg access macros */
+
+#define DMA_PTR2_REG_ADDR(regNum)   (DMA_PTR2_BASE_ADDR + \
+                                     (regNum) * DMA_PTR2_REG_OFFSET)
+
+#ifndef DMA_PTR2_REG_READ
+#define DMA_PTR2_REG_READ(regNum)       (*((volatile ULONG*)DMA_PTR2_REG_ADDR((regNum))))
+#endif /* DMA_PTR2_REG_READ */
+
+#ifndef DMA_PTR2_REG_WRITE
+#define DMA_PTR2_REG_WRITE(regNum,val)  (*((volatile ULONG*)DMA_PTR2_REG_ADDR((regNum))) = (val))
+#endif /* DMA_PTR2_REG_WRITE */
+
+#ifndef DMA_PTR2_REG_UPDATE
+#define DMA_PTR2_REG_UPDATE(regNum,val) DMA_PTR2_REG_WRITE((regNum), \
+                                        DMA_PTR2_REG_READ((regNum)) | (val))
+#endif /* DMA_PTR2_REG_UPDATE */
+    
+#ifndef DMA_PTR2_REG_RESET
+#define DMA_PTR2_REG_RESET(regNum,val)  DMA_PTR2_REG_WRITE((regNum), \
+                                        DMA_PTR2_REG_READ((regNum)) & ~(val))
+#endif /* DMA_PTR2_REG_RESET */
+
+/*
+ * Buffer size/Pointer mode ( DMA{x}_Cnt1 )
+ */
+
+#define DMA_CNT1_BASE_ADDR	((BYTE*)0x00300040) /* Base Address */
+#define DMA_CNT1_REG_OFFSET	REG_OFFSET	
+
+/* Reg numbering w.r.t base */
+
+#define DMA1_CNT1	0
+#define DMA2_CNT1	1
+#define DMA3_CNT1	2 /* EMAC Tx channel */
+#define DMA4_CNT1	3 /* EMAC Rx channel */
+
+/* Reg access macros */
+
+#define DMA_CNT1_REG_ADDR(regNum)   (DMA_CNT1_BASE_ADDR + \
+                                     (regNum) * DMA_CNT1_REG_OFFSET)
+
+#ifndef DMA_CNT1_REG_READ
+#define DMA_CNT1_REG_READ(regNum)       (*((volatile ULONG*)DMA_CNT1_REG_ADDR((regNum))))
+#endif /* DMA_CNT1_REG_READ */
+
+#ifndef DMA_CNT1_REG_WRITE
+#define DMA_CNT1_REG_WRITE(regNum,val)  (*((volatile ULONG*)DMA_CNT1_REG_ADDR((regNum))) = (val))
+#endif /* DMA_CNT1_REG_WRITE */
+
+#ifndef DMA_CNT1_REG_UPDATE
+#define DMA_CNT1_REG_UPDATE(regNum,val) DMA_CNT1_REG_WRITE((regNum), \
+                                        DMA_CNT1_REG_READ((regNum)) | (val))
+#endif /* DMA_CNT1_REG_UPDATE */
+    
+#ifndef DMA_CNT1_REG_RESET
+#define DMA_CNT1_REG_RESET(regNum,val)  DMA_CNT1_REG_WRITE((regNum), \
+                                        DMA_CNT1_REG_READ((regNum)) & ~(val))
+#endif /* DMA_CNT1_REG_RESET */
+
+
+
+/* 
+ * DMA addr & count reg macros
+ */
+
+/* Get dma addr from physical addr */
+#define DMA_ADDR_MASK ((ULONG)0x00ffffff)   /* [23:0] bit dma addr */
+#define DMA_ADDR(addr)\
+        (DMA_ADDR_MASK & (addr))
+
+/* Get dma cnt from byte cnt */
+#if     (MAC_HW_VER < REV_C)
+/* AD use for RevA or higher */
+#define DMA_CNT_MASK    ((ULONG)0x000007ff) /* [10:0] bit dma cnt */
+#else
+/* AD use for RevC and higher */
+#define DMA_CNT_MASK    ((ULONG)0x00001fff) /* [12:0] bit dma cnt */ 
+#endif
+
+/* Specify linked list modes used by dma */
+#define DMA_LMODE_MASK  ((ULONG)0x03000000) /* [25:24] bit dma link list mode */
+#define DMA_LMODE_TAIL  ((ULONG)0x00000000) /* ptr/cnt at buf-tail */
+#define DMA_LMODE_TBL   ((ULONG)0x01000000) /* ptr/cnt at Ptr2(table) */
+#define DMA_LMODE_RETN  ((ULONG)0x02000000) /* ptr/cnt at Ptr2(return ptr) */
+
+/* Form dma cnt reg from LMode & count - qwords - */
+#define DMA_CNT(lmode,cnt)\
+        ((DMA_LMODE_MASK & (lmode)) | (DMA_CNT_MASK & (cnt)))
+
+#endif /* __DMA_REGS_H */
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_desc.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_desc.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_desc.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_desc.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,207 @@
+/****************************************************************************
+*
+*	Name:			emac_desc.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef _EMAC_DESC_H
+#define _EMAC_DESC_H
+
+
+
+/* 
+ * receive descriptor 
+ */
+
+
+/* 
+ * Recieve status (RSTAT) - QWORD 
+ */
+
+#define RSTAT_FL	((ULONG)(0xffff0000)) /* Frame len including CRC.
+													 [31-16]			*/
+#define RSTAT_ES	((ULONG)(0x00008000)) /* Error Summary.			 
+													 [15]				*/
+/* The following Receive status defines are unused */
+#define RSTAT_OM	((ULONG)(0x00003000)) /* Operating mode.		 
+													 [13-12]			*/
+#define RSTAT_TS	((ULONG)(0x00000800)) /* Too short=1, Pkt<64 bytes.
+													 [11]				*/
+#define RSTAT_MF	((ULONG)(0x00000400)) /* Multicast frame=1.		 
+													 [10]				*/
+#define RSTAT_TL	((ULONG)(0x00000080)) /* Too long=1, Packet>1518.
+													 [7]				*/
+#define RSTAT_LC	((ULONG)(0x00000040)) /* Late collision=1.		 
+													 [6]				*/
+#define RSTAT_OFT	((ULONG)(0x00000020)) /* Frame type.			 
+													 [5]				*/
+#define RSTAT_RW	((ULONG)(0x00000010)) /* Receive watchdog=1.	 
+													 [4]				*/
+#define RSTAT_DB	((ULONG)(0x00000004)) /* Dribble bit=1.			 
+													 [2]				*/
+#define RSTAT_CE	((ULONG)(0x00000002)) /* CRC error.				 
+													 [1]				*/
+#define RSTAT_OF	((ULONG)(0x00000001)) /* RMAC Fifo overflow=1.	 
+													 [0]				*/
+/* 
+ * receive descriptor describing control information
+ */
+
+/* Ownership bit of the descriptor indicates:
+ * if reset: the packet received not yet processed.
+ * if set  : The pkt processed and now the desc is available.
+ *
+ * Note: The "processing" here is done by a function runing in tNetTask
+ * context. The netJobAdd adds the addr of this func in the tNetTask-queue.
+ * After processing a packet, the func sets it.
+ */
+#define RCTRL_OWN		0x80000000	
+#define RCTRL_RER		0x02000000	/* recv end of ring */
+
+
+/*
+ * Length of Received frame related defines.
+ */
+
+#define RX_FRM_LEN_MSK		RSTAT_FL	/* Frame length mask */
+#define RX_FRM_LEN_SHF		16			/* bit-shift required to obtain
+										   the Frame length  */
+#define RX_FRM_LEN_GET(x)	(((x) & RX_FRM_LEN_MSK) >> RX_FRM_LEN_SHF)
+#define RX_FRM_LEN_SET(x)	(((x) << RX_FRM_LEN_SHF) & RX_FRM_LEN_MSK)
+
+/*
+ * transmit descriptor 
+ */
+
+/*
+ * Transmit Descriptor describes control information.
+ */
+
+#define TCTRL_RDY		((ULONG)(0x00010000)) /* Frame ready to be transmitted
+												 when this bit is 1.
+												 [16]		*/
+#define TCTRL_TLEN		((ULONG)(0x0000fff0)) /* Transmit frame length in bytes.
+												 [15:4]		*/
+#define TCTRL_SET		((ULONG)(0x00000004)) /* Current frame is a setup frame
+												 when this bit is 1.
+												 [2]		*/
+#define TCTRL_DPD		((ULONG)(0x00000002)) /* Disable Tx padding	
+												 [1]		*/
+#define TCTRL_AC		((ULONG)(0x00000001)) /* Disable CRC append 
+												 [0]		*/
+
+#define TX_FRM_LEN_MSK		TCTRL_TLEN	/* Frame length mask */
+#define TX_FRM_LEN_SHF		4			/* bit-shift required to obtain
+										   the Frame length  */
+#define TX_FRM_LEN_SET(x)	(((x) << TX_FRM_LEN_SHF) & TX_FRM_LEN_MSK)
+
+/*
+ * Transmit Status (TSTAT) - QWORD 
+ */
+
+#define TSTAT_TDN		((ULONG)(0x80000000)) /* When set indicates transmit
+												 completed successfully
+												 (from the buffer manager)
+														[31]		*/
+#define TSTAT_TU		((ULONG)(0x40000000)) /* Transmit stopped 
+												 (descriptor not ready)
+														[30]		*/
+#define TSTAT_TOF		((ULONG)(0x00010000)) /* Transmit buffer manager
+												 FIFO Overflow when 1.
+														[16]		*/
+#define TSTAT_TUF		((ULONG)(0x00008000)) /* Transmit buffer manager
+												 FIFO underflow when 1.(MIB11)
+														[15]		*/
+#define TSTAT_ED		((ULONG)(0x00004000)) /* Excessive Tx deferral
+												 (Tx deffered longer then
+												  8192 x 400 ns.
+														[14]		*/
+#define TSTAT_DF		((ULONG)(0x00002000)) /* Frame has been defered
+												 atlease once (MIB8)
+														[13]		*/
+#define TSTAT_CD		((ULONG)(0x00001000)) /* Frame transmit completed
+												 successfully (from MII).
+														[12]		*/
+#define TSTAT_ES		((ULONG)(0x00000800)) /* Transmit Error Summary. 
+												 TF|C16|LC|NCRS|LCRS|TJT
+														[11]			*/
+#define TSTAT_RLD		((ULONG)(0x00000400)) /* Tx FIFO reload/abort during
+												 frame (includes collision)
+														[10]			*/
+#define TSTAT_TF		((ULONG)(0x00000200)) /* Tx fault (or unexpected 
+												 transmit data request during
+												 frame (from MII).
+														[9]			*/
+#define TSTAT_TJT		((ULONG)(0x00000100)) /* Transmit jabber timeout: set
+												 when the jabber timer expires.
+												 E_NA_HUJ must be configured 
+												 for this bit to function.
+														[8]			*/
+#define TSTAT_NCRS		((ULONG)(0x00000080)) /* No carrier (ECRS pin never 
+												 gone high) during the transmit
+												 of the frame.
+														[7]			*/
+#define TSTAT_LCRS		((ULONG)(0x00000040)) /* Carrier was lost (ECRS pin 
+												 gone low) at least once during
+												 the transmit of the frame. 
+												 (MIB18).
+														[6]			*/
+#define TSTAT_C16		((ULONG)(0x00000020)) /* 16 or more collisions have 
+												 occured during the frame 
+												 transmit.
+														[5]			*/
+#define TSTAT_LC		((ULONG)(0x00000010)) /* Late collision (after 64th 
+												 byte) has occured during the
+												 frame transmit (MIB16)
+														[4]			*/
+#define TSTAT_CC		((ULONG)(0x0000000F)) /* Transmit collision count of
+												 the frame. Resets after the
+												 frame is transmitted 
+												 successfully (MIB9). Increments
+												 with every collision of the 
+												 current frame.
+														[3:0]			*/
+
+
+#define TD_STAT_CC_MSK		TSTAT_CC
+#define	TD_STAT_CC_VAL(X)	(((X) & TD_STAT_CC_MSK) >> 3)    
+
+
+/* 
+ * This macro assumes that the status was 0 before Tx started for this TxD.
+ * This macro returns true if Tx was done successfully or unsuccessfully.
+ * Note in the current version, EMAC HW doesn't clear this bit.
+ */
+#ifdef HW_CLRS_TXD_RDY
+#define IS_TXD_OWNED_BY_HW(pTxD) ((pTxD)->control & (TCTRL_RDY))
+#else
+#define IS_TXD_OWNED_BY_HW(pTxD) ( ((pTxD)->status == 0) && \
+                                   ((pTxD)->control & (TCTRL_RDY)))
+#endif
+
+
+#endif  /* _EMAC_DESC_H */
Files uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_drv.o and uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_drv.o differ
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_regs.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_regs.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_regs.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,423 @@
+/****************************************************************************
+*
+*	Name:			emac_regs.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __EMAC_REGS_H
+#define __EMAC_REGS_H
+
+
+/*******************************************************************************
+ * Reg base addr & Reg offset.
+ * The reg offset is same for all the sub-devices (like DMAC, EMAC & 
+ * Interrupt controller).
+ */
+
+
+#ifndef REG_BASE_ADDR
+#define REG_BASE_ADDR	 ((BYTE*)(0x00300000)) /* double word aligned */
+#endif
+
+#ifndef BE_OFST
+#define BE_OFST		 0   /* 0 for little endian, 7 for big  */
+#endif
+
+#ifndef REG_OFFSET
+#define REG_OFFSET	 (BE_OFST + 0x04) /* double word aligned */
+#endif
+
+/*******************************************************************************
+ *
+ * Define EMAC REGs and macros to access them.
+ * To optimize REG accesses, redefine EMAC_REG_READ and
+ * EMAC_REG_WRITE macros in a wrapper file.
+ */
+
+#define EMAC_BASE_ADDR      ((UCHAR *)0x00310000)
+
+#define EMAC_REG_OFFSET		(REG_OFFSET)	/* double word aligned */
+
+/* Reg numbering w.r.t base */
+
+#define E_DMA	0		/* EMAC TxD / Rx DMA port [63:0]. NOT USED BY DRIVER */
+#define E_NA	1		/* network access [32:0]*/
+#define E_STAT	2		/* status */
+#define E_IE	3		/* enable interrupts */
+#define E_LP	4		/* Receiver Last Packet. */
+#define E_MII	6		/* MII Management Interface */
+#define E_TDMA	8		/* TxD status DMA port. NOT USED BY DRIVER */
+
+/* Reg access macros */
+
+#define EMAC_REG_ADDR(regNum,unit)  (EMAC_BASE_ADDR + (unit * 0x00010000) \
+									+ ((regNum) * EMAC_REG_OFFSET))
+
+#define EMAC_INTR_BASE_ADDR      ((volatile ULONG*)0x0031000c)
+
+#define EMAC_INTR_REG_WRITE(val,unit)  (*(EMAC_INTR_BASE_ADDR + (unit * 0x00010000)) \
+											 = (val))
+
+#define E_INTR	0	
+#define EMAC_INTR_REG_ADDR(regNum)   ((ULONG *)(EMAC_INTR_BASE_ADDR + (unit * 0x00010000)\
+                                 + ((regNum) * EMAC_REG_OFFSET)))
+
+#ifndef EMAC_INTR_REG_READ
+#define EMAC_INTR_REG_READ(unit)       (*(EMAC_INTR_BASE_ADDR + (unit * 0x00010000)))
+#endif /* EMAC_REG_READ */
+
+#ifndef EMAC_REG_READ
+#define EMAC_REG_READ(regNum,unit)       (*((volatile ULONG*)EMAC_REG_ADDR((regNum),unit)))
+#endif /* EMAC_REG_READ */
+
+#ifndef EMAC_REG_WRITE
+#define EMAC_REG_WRITE(regNum,val,unit)  (*((volatile ULONG*)EMAC_REG_ADDR((regNum),unit)) = (val))
+#endif /* EMAC_REG_WRITE */
+
+#ifndef EMAC_REG_UPDATE
+#define EMAC_REG_UPDATE(regNum,val,unit)  EMAC_REG_WRITE((regNum), \
+                                     EMAC_REG_READ((regNum),unit) | (val), unit)
+#endif /* EMAC_REG_UPDATE */
+    
+#ifndef EMAC_REG_RESET
+#define EMAC_REG_RESET(regNum,val,unit)   EMAC_REG_WRITE((regNum), \
+                                     EMAC_REG_READ((regNum),unit) & ~(val),unit)
+#endif /* EMAC_REG_RESET */
+    
+#ifndef EMAC_REG_RESET_SET
+#define EMAC_REG_RESET_SET(regNum,resetVal, setVal,unit)\
+            EMAC_REG_WRITE((regNum), \
+            (EMAC_REG_READ((regNum),unit) & ~(resetVal))|(setVal),unit)
+#endif /* EMAC_REG_RESET_SET */
+
+/*******************************************************************************
+ *
+ * Define EMAC bit masks.
+ */
+
+
+/*
+ * EMAC Register masks. 
+ */
+
+#define E_NA_MSK	((ULONG)(0xcffffff9)) /* [31:0]RW  */
+#define E_STAT_MSK	((ULONG)(0xffffffff)) /* [31:0]RW* */
+#define E_IE_MSK	((ULONG)(0x0001ffff)) /* [16:0]RW  */
+#define E_LP_MSK	((ULONG)(0x000003ff)) /* [9:0] RW  */
+#define E_MII_MSK	((ULONG)(0x0000001f)) /* [4:0]     */
+
+
+/* 
+ * EMAC Register bit masks.
+ */
+
+
+/* 
+ * Network Access 
+ */
+
+#define E_NA_RTX	((ULONG)((ULONG)1<<31)) /* Tx Software Reset	        [31]        */
+#define E_NA_STOP	((ULONG)((ULONG)1<<30)) /* Stop transmit		        [30]        */
+#define E_NA_HP		((ULONG)((ULONG)1<<27)) /* Hash/perfect addr filter     [27]        */
+#define E_NA_HO		((ULONG)((ULONG)1<<26)) /* Hash only			        [26]        */
+#define E_NA_IF		((ULONG)((ULONG)1<<25)) /* Inverse Filter		        [25]        */
+#define E_NA_PR		((ULONG)((ULONG)1<<24)) /* Promiscuous mode	            [24]        */
+#define E_NA_PM     ((ULONG)((ULONG)1<<23)) /* Pass all Multicast           [23]        */
+#define E_NA_PB		((ULONG)((ULONG)1<<22)) /* Pass bad packet	            [22]        */
+#define E_NA_RRX	((ULONG)((ULONG)1<<21)) /* Rx s/w reset		            [21]        */
+#define E_NA_THU	((ULONG)((ULONG)1<<20)) /* Tx test HUJ counter          [20]        */
+#define E_NA_DIS	((ULONG)((ULONG)1<<19)) /* Tx Disable backoff counter   [19]        */
+#define E_NA_RUT	((ULONG)((ULONG)1<<18)) /* Tx reset unit timer          [18]        */
+#define E_NA_IFG	((ULONG)((ULONG)3<<16)) /* Inter-frame gap	            [17:16]		*/
+#define E_NA_JBD	((ULONG)((ULONG)1<<15)) /* Jabber disable		        [15]        */
+#define E_NA_HUJ	((ULONG)((ULONG)1<<14)) /* Host Un-Jabber		        [14]        */
+#define E_NA_JCLK	((ULONG)((ULONG)1<<13)) /* Jabber clock		            [13]        */
+#define E_NA_SB		((ULONG)((ULONG)1<<12)) /* Start/Stop Backoff Counter   [12]        */
+#define E_NA_FD		((ULONG)((ULONG)1<<11)) /* Full duplex		            [11]        */
+#define E_NA_OM 	((ULONG)((ULONG)3<<9 )) /* Operating mode               [10:9]	   	*/
+#define E_NA_OM_R	((ULONG)((ULONG)3<<9 )) /* Operating mode: Reserved	    [10:9]	-GL	*/
+#define E_NA_OM_E   ((ULONG)((ULONG)2<<9 )) /* Operating mode: External LB	[10:9]  -GL	*/ 
+#define E_NA_OM_I   ((ULONG)((ULONG)1<<9 )) /* Operating mode: Internal LB	[10:9]	-GL	*/
+#define E_NA_FC		((ULONG)((ULONG)1<<8 )) /* Force Collisions	            [8]         */
+#define E_NA_HLAN	((ULONG)((ULONG)1<<7 )) /* Home LAN Enablee	            [7] 	    */
+#define E_NA_SR		((ULONG)((ULONG)1<<6 )) /* Start/Stop receive	        [6] 	    */
+#define E_NA_NS		((ULONG)((ULONG)1<<5 )) /* Network speed		        [5] 	    */
+#define E_NA_RWR	((ULONG)((ULONG)1<<4 )) /* Receive WD release	        [4]			*/
+#define E_NA_RWD	((ULONG)((ULONG)1<<3 )) /* Receive WD disable	        [3] 	    */
+#define E_NA_STRT	((ULONG)((ULONG)1    )) /* Start transmit		        [0] 	    */
+
+/* 
+ * Status 
+ */
+
+#define E_STAT_TU	((ULONG)(0x80000000)) /* Transmit descriptor not ready	
+                                             [31] */
+#define E_STAT_RS	((ULONG)(0x78000000)) /* Receive state					
+                                             [30:27] */
+#define E_STAT_RO	((ULONG)(0x04000000)) /* Receive FIFO overflow			
+                                             [26] */
+#define E_STAT_RWT	((ULONG)(0x02000000)) /* Receive WD timeout				
+                                             [25] */
+#define E_STAT_TDS	((ULONG)(0x01e00000)) /* Transmit buffer manager state	
+                                             [24:21] */
+#define E_STAT_TS	((ULONG)(0x001e0000)) /* Transmit state					
+                                             [20:17] */
+#define E_STAT_TOF	((ULONG)(0x00010000)) /* Transmit FIFO overflow			
+                                             [16] */
+#define E_STAT_TUF	((ULONG)(0x00008000)) /* Transmit FIFO underflow		
+                                             [15] */
+#define E_STAT_ED	((ULONG)(0x00004000)) /* Excessive Transmit deferrals	
+                                             [14] */
+#define E_STAT_DF	((ULONG)(0x00002000)) /* Tx frame differed				
+                                             [13] */
+#define E_STAT_CD	((ULONG)(0x00001000)) /* Frame transmit done from MII	
+                                             [12] */
+#define E_STAT_ES	((ULONG)(0x00000800)) /* Transmitter error summary		
+                                             [11] */
+#define E_STAT_RLD	((ULONG)(0x00000400)) /* Transmit FIFO reload/abort		
+                                             [10] */
+#define E_STAT_TF	((ULONG)(0x00000200)) /* Transmit fault					
+                                             [9] */
+#define E_STAT_TJT	((ULONG)(0x00000100)) /* Transmit Jabber Time-Out		
+                                             [8] */
+#define E_STAT_NCRS	((ULONG)(0x00000080)) /* No Carrier						
+                                             [7] */
+#define E_STAT_LCRS	((ULONG)(0x00000040)) /* Carrier was lost				
+                                             [6] */
+#define E_STAT_16	((ULONG)(0x00000020)) /* 16 or more collisions			
+                                             [5] */
+#define E_STAT_LC	((ULONG)(0x00000010)) /* Late collision					
+                                             [4] */
+#define E_STAT_CC	((ULONG)(0x0000000f)) /* Transmit collision count		
+                                             [3:0] */
+/* 
+ * Interrupt enable 
+ */
+
+#define E_IE_AU		((ULONG)(0x00020000)) /* Transmit FIFO almost underflow interrupt enable
+                                             [17] */
+#define E_IE_NI		((ULONG)(0x00010000)) /* Normal interrupt summary enable
+                                             [16] */
+#define E_IE_RW		((ULONG)(0x00008000)) /* Receive WD Timer				
+                                             [15] */
+#define E_IE_RI		((ULONG)(0x00004000)) /* Receive OK interrupt enable	
+                                             [14] */
+#define E_IE_AI		((ULONG)(0x00002000)) /* Abnormal interrupt summary 	
+                                             [13] */
+#define E_IE_LC		((ULONG)(0x00001000)) /* Late collision enable			
+                                             [12] */
+#define E_IE_16		((ULONG)(0x00000800)) /* 16 collisions interrupt enable	
+                                             [11] */
+#define E_IE_LCRS	((ULONG)(0x00000400)) /* Lost carrier interrupt enable	
+                                             [10] */
+#define E_IE_NCRS	((ULONG)(0x00000200)) /* No carrier interrupt enable	
+                                             [9] */
+#define E_IE_TF		((ULONG)(0x00000100)) /* Transmit fault enable			
+                                             [8] */
+#define E_IE_RLD	((ULONG)(0x00000080)) /* Transmit reload/abort enable	
+                                             [7] */
+#define E_IE_ED		((ULONG)(0x00000040)) /* Excessive deferral enable		
+                                             [6] */
+#define E_IE_DF		((ULONG)(0x00000020)) /* Transmit deferred enable		
+                                             [5] */
+#define E_IE_TOF	((ULONG)(0x00000010)) /* Transmit overflow enable		
+                                             [4] */
+#define E_IE_TUF	((ULONG)(0x00000008)) /* Transmit underflow enable		
+                                             [3] */
+#define E_IE_TJT	((ULONG)(0x00000004)) /* Transmit Jabber time-out enable
+                                             [2] */
+#define E_IE_TU		((ULONG)(0x00000002)) /* Transmit process stopped enable
+                                             [1] */
+#define E_IE_TI		((ULONG)(0x00000001)) /* Transmit OK interrupt			
+                                             [0] */
+
+/* 
+ * Reciever Last Packet 
+ */
+
+#define E_LP_RDMA	((ULONG)(0xf<<6)) 	/* [9:6] NOT USED by the driver */
+#define E_LP_RFIFO	((ULONG)(0xf<<2)) 	/* [5:2] NOT USED by the driver */
+#define E_LP_AU		((ULONG)(1<<10))    /* Rx Done OK from Rx buff-mgr[1] */
+#define E_LP_RI		((ULONG)(1<<1))     /* Rx Done OK from Rx buff-mgr[1] */
+#define E_LP_TI		((ULONG)(1<<0))     /* Tx Done OK from Tx buff-mgr[0] */
+
+/* 
+ * Media Independent Interface 
+ */
+
+#define E_MII_MDIP	((ULONG)(0x00000010))
+#define E_MII_MM	((ULONG)(0x00000008))
+#define E_MII_MDO	((ULONG)(0x00000004))
+#define E_MII_MDI	((ULONG)(0x00000002))
+#define E_MII_MDC	((ULONG)(0x00000001))
+
+/*
+ * Derived bit masks
+ */
+
+/* 
+ * When system error occurs, HW must be reset & driver should
+ * be restarted. Now the hw needs to be reset whenever 
+ * Tx/Rx under/over flow occurs.So these are also included in
+ * the system error.
+ *
+ * Note: 
+ * 1) Rx Overflow is sys err but there is no separate bit
+ * in the interrupt enable reg. It is absorbed in the abnormal
+ * interrupt summary bit.
+ * 2) Rx underflow is not captured in both status and intr-enable regs.
+ */
+#define E_SYS_ERR    (E_STAT_TOF|E_STAT_TUF|E_STAT_TF|E_STAT_RO)
+#define E_IE_SYS_ERR (E_IE_TOF  |E_IE_TUF  |E_IE_TF)
+
+#define IS_RX_STOPED 0x0 /* the Rx process is not stopped*/
+
+
+
+/******************************************************************************
+ * EMAC's Media Independent Interface (MII) register defines, bit masks &
+ * access macros.
+ */
+
+/*
+ * EMAC MII's Management Interface register & bit-masks.
+ */
+
+#define E_MMI_OFFSET       ((ULONG)0x18) /*offset from EMAC base addr. */
+
+/* 
+ * Active edge is the edge of the Clk - EMDC -. The sampling of the EMDIO
+ * is done, in input mode, using this edge 
+ */
+#define E_MDIP             ((ULONG)0x10) /* Active edge Mask.Bit[4].*/
+#define E_MDIP_RISING      ((ULONG)0x10) /* Active edge = rising edge  */
+#define E_MDIP_FALING      ((ULONG)0x00) /* Active edge = falling edge */
+#define E_MDIP_DEF         E_MDIP_FALING /* HW default active edge     */
+
+#define E_MM               ((ULONG)0x08) /* MDIO pin dire' mask.Bit[3] */
+#define E_MM_INPUT         ((ULONG)0x08) /* direction = input          */
+#define E_MM_OUTPUT        ((ULONG)0x00) /* direction = output         */
+#define E_MM_DEF           E_MM_INPUT    /* HW default direction       */
+
+#define E_MDO              ((ULONG)0x04) /* "Value to output" mask.Bit[2] */
+#define E_MDO_VAL1         ((ULONG)0x04) /* Value=1 to output.            */
+#define E_MDO_VAL0         ((ULONG)0x00) /* Value=0 to output.            */
+#define E_MDO_DEF          E_MDO_VAL0    /* HW default value to output.   */
+
+#define E_MDI              ((ULONG)0x02) /* "Value read" mask.Bit[1] */
+#define E_MDI_DEF          ((ULONG)0x02) /* HW default value read.   */
+
+
+#define E_MDC              ((ULONG)0x01) /* "Val to write to clk" mask.Bit[0]*/
+#define E_MDC_VAL1         ((ULONG)0x01) /* Val=1 to write to the clk, MDC   */
+#define E_MDC_VAL0         ((ULONG)0x00) /* Val=0 to write to the clk, MDC   */
+#define E_MDC_DEF          E_MDC_VAL0    /* HW default-value to write to clk.*/
+
+/*
+ * Map the bit masks as per "functional" interpretation.
+ * This mapping is used by the Phy driver.
+ * 
+ * PHY Modes:
+ * ----------
+ * Read : PHY is in read mode when it's reading data from the network cable.
+ * Write: PHY is in write mode when it's writing data to the network cable.
+ * 
+ * MAC Modes:
+ * ----------
+ * Output: MAC should output data to PHY after setting PHY in write mode.
+ * Input : MAC should input data from PHY after setting PHY in read mode.
+ *
+ * MAC & PHY Data Exchange:
+ * ------------------------
+ * 1. Data exchange between MAC & PHY is a bit (value = 0 or 1) at a time.
+ * 2. MAC controlls the PHY's mode.
+ * 3. MAC's modes are "exclusive" either input or output.
+ * 4. PHY's modes are "exclusive" either read or write.
+ */
+
+
+/* First undefined all if defined ... */
+
+#ifdef MAC_ADAPTER_ADDR
+#undef MAC_ADAPTER_ADDR
+#endif /* MAC_ADAPTER_ADDR */
+
+#ifdef MAC_MDIO_REG
+#undef MAC_MDIO_REG
+#endif /* MAC_MDIO_REG */
+
+#ifdef MDIO_CLK_MDIP
+#undef MDIO_CLK_MDIP
+#endif /* MDIO_CLK_MDIP */
+
+#ifdef MDIO_RD_ENABLE
+#undef MDIO_RD_ENABLE
+#endif /* MDIO_RD_ENABLE */
+
+#ifdef MDIO_WR_ENABLE
+#undef MDIO_WR_ENABLE
+#endif /* MDIO_WR_ENABLE */
+
+#ifdef MDIO_RD_DATA
+#undef MDIO_RD_DATA
+#endif /* MDIO_RD_DATA */
+
+#ifdef MDIO_WR_DATA_1
+#undef MDIO_WR_DATA_1
+#endif /* MDIO_WR_DATA_1 */
+
+#ifdef MDIO_WR_DATA_0
+#undef MDIO_WR_DATA_0
+#endif /* MDIO_WR_DATA_0 */
+
+#ifdef MDIO_CLK
+#undef MDIO_CLK
+#endif /* MDIO_CLK */           
+
+/* ... Now define them for Super Pipe */
+
+#define MAC_ADAPTER_ADDR  EMAC_BASE_ADDR
+#define MAC_MDIO_REG      E_MMI_OFFSET
+#define MDIO_CLK_MDIP     E_MDIP_DEF	
+#define MDIO_RD_ENABLE    (E_MM_INPUT | MDIO_CLK_MDIP) /* Set PHY in read mode.*/
+#define MDIO_WR_ENABLE    E_MM_OUTPUT /* Set PHY in write mode.*/
+#define MDIO_RD_DATA      E_MDI  /* Data read by MAC.*/
+#define MDIO_WR_DATA_1    E_MDO_VAL1  /* MAC writes 1. */
+#define MDIO_WR_DATA_0    E_MDO_VAL0  /* MAC writes 0. */
+#define MDIO_CLK          E_MDC_VAL1  /* MAC sends clock, MDC pulse.*/
+                          /* Why not E_MDC_VAL0? 
+                             While writting data to MII, the Phy driver
+                             either needs to send clk=0 or clk=1 ORed with
+                             the other flags - eg RD_ENABLE|CLK|.
+                             So clk=0 case is automatically taken care of
+                             if driver doesn't "OR" the flags with the CLK.
+                             eg. RD_ENABLE   - no "OR"ing with CLK.
+                           */
+
+
+
+#endif /* __EMAC_REGS_H */
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_type.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_type.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_type.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/emac_type.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,42 @@
+/****************************************************************************
+*
+*	Name:			emac_type.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2001,2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __EMAC_TYPE_H
+#define __EMAC_TYPE_H
+
+typedef unsigned char       UINT8;
+typedef unsigned short int  UINT16;
+typedef unsigned int        UINT32;
+
+typedef unsigned int	BOOL;
+typedef unsigned int	ULONG;
+typedef unsigned char	UCHAR;
+
+#endif /* __EMAC_TYPE_H */
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/filters.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/filters.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/filters.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/filters.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,167 @@
+/****************************************************************************
+*
+*	Name:			filters.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __FILTERS_H
+#define __FILTERS_H
+
+
+/* 
+ * Hashing & Address filtering.
+ */
+
+#include "hashIndex.h"
+
+/*
+ * Ethernet Address Filters supported by MAC HW...
+ */
+
+/* Basic filters */
+/* 16 */
+#define HW_FLT_16PER    0x0001/* 16 uni or multi perfect  */
+#define HW_FLT_16INV    0x0002/* 16 uni or multi inverse  */
+#define HW_FLT_16PER_PM 0x0004/* Pass all multi & 16 uni perfect */
+#define HW_FLT_16RES    0x0008/* reserved */
+
+/* hash */
+#define HW_FLT_1PER_HASH      0x0010/* 1 uni perfect & unlimited multi hash */
+#define HW_FLT_HASH           0x0020/* unlimited uni and/or multi hash */
+#define HW_FLT_1PER_PM        0x0040/* reserved */
+#define HW_FLT_HASH_RES2      0x0080/* reserved */
+
+/* others */
+#define HW_FLT_PM       0x0100/* Pass all multicast addrs */
+#define HW_FLT_PR       0x0200/* Promiscuous: all good pkts pass */
+#define HW_FLT_PB       0x0400/* Pass all bad pkts */
+
+/* Derived filters */
+#define HW_FLT_16ANY          (HW_FLT_16PER|HW_FLT_16INV|HW_FLT_16PER_PM|\
+                              HW_FLT_16RES)
+#define HW_FLT_HASHANY        (HW_FLT_1PER_HASH|HW_FLT_HASH|HW_FLT_1PER_PM|\
+                              HW_FLT_HASH_RES2)
+#define HW_FLT_OTHERANY       (HW_FLT_1PER_PM|HW_FLT_PM|HW_FLT_PR|\
+                              HW_FLT_PB)
+
+/* Default filter */
+#define HW_FLT_DEF            HW_FLT_16ANY/* our default */
+
+/* Default filter */
+#define HW_FLT                HW_FLT_DEF
+
+/* 
+ * Setup Frame Filtering Modes: 
+ *
+ * There are two ways of storing an ethernet address in the setup frame.
+ * 1) Directly: copying the addr, byte by byte.
+ * 2) hashing : set 1bit -per addr- of the hash table contained within setup frame.
+ *
+ * Hence, eventhough there are multiple modes available for address filtering, 
+ * as far as preparation of the setup frame goes there are only two. 
+ * 1) "Perfect": 16 addrs stored "directly".
+ * 2) "1Perfect-Hash": 1 addr stored directly & unlimited addrs stored using hashing.
+ */
+
+#define SF_FM_NONE       0x0/* No setup frame filter needed */
+#define SF_FM_PER        0x1/* 16 addrs perfect & no hash table*/
+#define SF_FM_1PER_HASH  0x2/* 1 addr perfect & a hash table */
+
+#ifdef SF_FM
+#undef SF_FM
+#endif /* SF_FM */
+
+#if (HW_FLT & HW_FLT_16ANY)
+#define SF_FM   SF_FM_PER
+#endif /* HW_FLT & HW_FLT_16ANY */
+
+#if (HW_FLT & HW_FLT_HASHANY)
+#ifdef SF_FM
+#error Setup frame filter can not support mixing of hash & 16* filters.
+#else
+#define SF_FM   SF_FM_1PER_HASH
+#endif /* SF_FM */
+#endif /* HW_FLT & HW_FLT_HASHANY */
+
+#if (HW_FLT & HW_FLT_OTHERANY)
+#ifndef SF_FM
+#define SF_FM       SF_FM_NONE
+#endif /* SF_FM */
+#endif /* HW_FLT & HW_FLT_OTHERANY */
+
+/*
+ *
+ */
+
+#if 0
+#define E_NA_HP		((ULONG)(0x08000000)) /* Hash/perfect addr filter [27]	*/
+#define E_NA_HO		((ULONG)(0x04000000)) /* Hash only			[26]		*/
+#define E_NA_IF		((ULONG)(0x02000000)) /* Inverse Filter		[25]		*/
+#define E_NA_PR		((ULONG)(0x01000000)) /* Promiscuous mode	[24]		*/
+#define E_NA_PM		((ULONG)(0x00800000)) /* Pass all Multicast [23]		*/
+#define E_NA_PB		((ULONG)(0x00400000)) /* Pass bad packet	[22]		*/
+
+#define E_NA_FM     (E_NA_IF|E_NA_PM)
+#endif
+
+#if 0
+typedef struct _FLT_FRM_EADDR_BYTE_INDEX
+{
+#if  (SF_FM==SF_FM_PER)
+int index;
+int indexOfst;
+
+#elif(SF_FM==SF_FM_1PER_HASH)
+HI hi;
+
+#elif(SF_FM==SF_FM_NONE)
+
+#else
+#error Wrong HW filter mode set.
+
+#endif /* SF_FM */
+}FLT_FRM_EADDR_BYTE_INDEX;
+#endif
+
+#define HASH_TBL_SIZ HT1_0_SIZE 
+#define IS_FILTERED_HI(pDrvCtrl, hi) HT1_0_PASS_HI((pDrvCtrl)->hashTable,hi)
+#define ADD_TO_HASHTBL(pDrvCtrl, hi) HT1_0_SET_HI((pDrvCtrl)->hashTable,hi)
+
+#define FLT_INDEX               HT_OPTY_2_2
+#define FLTR_FRM_PHY_ADRS_OFF	156   /* = FILT_INDEX(13 * 6):14th addr */
+#define FLTR_FRM_SIZE		    0xC0  /* filter frm size 192 bytes	*/
+#define FLTR_FRM_NUM_ADRS       16
+
+/* 
+ * If the LSB bit - 0th - of the first byte - byte #0 - of the
+ * ethernet address, is set - 1- then the address is a multicast one
+ * else it is unicast.
+ */
+//#define IS_MULTICAST(addrPtr) ( (*((UCHAR *)(addrPtr))) & (UCHAR *)0x01 )
+
+
+#endif /* __FILTERS_H */
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/hashIndex.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/hashIndex.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/hashIndex.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/hashIndex.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,124 @@
+/****************************************************************************
+*
+*	Name:			hashIndex.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __HASH_INDEX_H
+#define __HASH_INDEX_H
+/*
+ * 
+ *
+ *
+ */
+
+#define EADDR_LEN 6 /* Lenth of ethernet address, in bytes. */
+
+/*
+ * Hash Index (HI) methods & types.
+ */
+
+/* List of available HI methods. */
+#define HI_METHOD_CRC32        0  /* CRC32 method. */
+#define HI_METHOD_RSSCM        1  /* RSS Cable Modem (CM) HI method. */
+#define HI_METHOD_NEW          2  /* Example. */
+
+/* The default HI method. */
+#define HI_METHOD_DEF HI_METHOD_RSSCM
+
+/* No HI method specified? Choose the default one. */
+#ifndef HI_METHOD
+#define HI_METHOD HI_METHOD_DEF
+#endif
+
+
+
+#define NUM_HI_SUPPORTED 256
+typedef unsigned char HI;
+#define HT_Y(hi) ((hi)>>3)            /* byte# in the Hash Table  */
+#define HT_X(hi) (1 << ((hi) & 0x07)) /* bit position in the byte */
+
+
+/*
+ * In next two macros the interpretation of the location is as follows:
+ * L(x,y) means: nth bit in yth byte of HT. Where n is the bit # of the
+ * only bit set in x. Depending upon various HT organisation the y co-ordinate
+ * may change from plain HT_Y(hi), but x remains unchanged.
+ *
+ * HT options for Y co-ord modifications: These options decide which bytes
+ * (pattern) to be used for y co-ordinate. Commonly used options are listed
+ * below.
+ *
+ * HT_OPTY_i_j: First i bytes [0...i-1] are used for y. Next j bytes [i...i+j-1]
+ *              are not used. Then again bytes [i+j...i+j+i-1] are used & so on.
+ *
+ * HT_OPTY_1_0: All the bytes of HT are used for y co-ordinate.
+ *              Here y = HT_Y(hi);
+ *
+ * HT_OPTY_1_1: Byte# 0,2,4,6,8,...are used & 1,3,5,7... not used.
+ *              Here y = HT_OPTY_1_1(HT_Y(hi));
+ * 
+ * HT_OPTY_2_2: Byte# 0,1,4,5,8,9,...are used & 2,3,6,7,...not used.
+ *              Here y = HT_OPTY_1_1(HT_Y(hi));
+ *              This is the commonly used option when the HT is to be formed
+ *              in the Setup frame.
+ */
+
+/* Set the location (x,y), in the HT. */
+#define HT_SET_HI(ht, x, y)    (ht[(y)] |= (x))
+
+/* Check the location (x,y), in the HT.(i.e. xth bit in yth byte of HT) */
+#define HT_PASS_HI(ht, x, y)   ((ht[(y)] & (x)) ? 1:0)
+
+#define HT_OPTY_1_0(y) (y)
+#define HT_OPTY_1_1(y) TBD /* To Be Defined */
+#define HT_OPTY_2_2(y) ((((y) & ~0x1) * 2) + ((y) & 0x1))
+
+#define HT1_0_SET_HI(ht,hi) HT_SET_HI(ht,HT_X(hi),HT_OPTY_1_0(HT_Y(hi)))
+#define HT1_1_SET_HI(ht,hi) HT_SET_HI(ht,HT_X(hi),HT_OPTY_1_1(HT_Y(hi)))
+#define HT2_2_SET_HI(ht,hi) HT_SET_HI(ht,HT_X(hi),HT_OPTY_2_2(HT_Y(hi)))
+
+#define HT1_0_PASS_HI(ht,hi) HT_PASS_HI(ht,HT_X(hi),HT_OPTY_1_0(HT_Y(hi)))
+#define HT1_1_PASS_HI(ht,hi) HT_PASS_HI(ht,HT_X(hi),HT_OPTY_1_1(HT_Y(hi)))
+#define HT2_2_PASS_HI(ht,hi) HT_PASS_HI(ht,HT_X(hi),HT_OPTY_2_2(HT_Y(hi)))
+
+/* 
+ * Hash Table size: Depending on the HT_OPTY_*_*, table size required to hold
+ * HIs varies. This size is #ofbytes required to hold Hash Values (HV) for all 
+ * of the Hash Indices. Each HV is a bit: HV = value of HIth bit.
+ */
+#define HT1_0_SIZE   (NUM_HI_SUPPORTED/8) 
+#define HT1_1_SIZE   (2*HT1_0_SIZE) 
+#define HT2_2_SIZE   HT1_1_SIZE 
+
+/* Externals. */
+extern HI HashIndex(unsigned char* eAddr);
+
+/* Macros for a user of this module. */
+#define HASH_INDEX(eAddr) HashIndex((eAddr))
+
+#endif __HASH_INDEX_H
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/intr_regs.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/intr_regs.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/intr_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/intr_regs.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,143 @@
+/****************************************************************************
+*
+*	Name:			intr_regs.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __INTR_REGS_H
+#define __INTR_REGS_H
+
+/*******************************************************************************
+ * CX821xx: Reg base addr & Reg offset.
+ * The reg offset is same for all the sub-devices (like DMAC, EMAC & 
+ * Interrupt controller).
+ */
+
+
+#ifndef REG_BASE_ADDR
+#define REG_BASE_ADDR	 ((BYTE*)(0x00300000)) /* double word aligned */
+#endif
+
+#ifndef BE_OFST
+#define BE_OFST		 0   /* 0 for little endian, 7 for big  */
+#endif
+
+#ifndef REG_OFFSET
+#define REG_OFFSET	 (BE_OFST + 0x04) /* double word aligned */
+#endif
+
+/*******************************************************************************
+ *
+ * Define Interrupt REGs and macros to access them.
+ * To optimize REG accesses, redefine INTR_REG_READ and
+ * INTR_REG_WRITE macros in a wrapper file.
+ */
+
+/*
+ * ARM 1 interrupts ( indicated by INT1).
+ */
+
+#define INTR1_BASE_ADDR	    ((BYTE*)0x00350040)
+#define INTR1_REG_OFFSET	REG_OFFSET	
+
+/* Reg numbering w.r.t base */
+
+#define INT1_MSK	    0
+#define INT1_STAT	    1
+#define INT1_MSTAT	    2 
+#define INT1_SETSTAT	3 
+
+/* Reg access macros */
+
+#define INTR1_REG_ADDR(regNum)   (INTR1_BASE_ADDR + \
+                                 ((regNum) * INTR1_REG_OFFSET))
+
+#ifndef INTR1_REG_READ
+#define INTR1_REG_READ(regNum)       (*((volatile ULONG*)INTR1_REG_ADDR((regNum))))
+#endif /* INTR1_REG_READ */
+
+#ifndef INTR1_REG_WRITE
+#define INTR1_REG_WRITE(regNum,val)  (*((volatile ULONG*)INTR1_REG_ADDR((regNum))) = (val))
+#endif /* INTR1_REG_WRITE */
+
+#ifndef INTR1_REG_UPDATE
+#define INTR1_REG_UPDATE(regNum,val) INTR1_REG_WRITE((regNum), \
+                                     INTR1_REG_READ((regNum)) | (val))
+#endif /* INTR1_REG_UPDATE */
+    
+#ifndef INTR1_REG_RESET /* writing 1 resets, 0 no effect */
+#define INTR1_REG_RESET(regNum,val)  INTR1_REG_WRITE((regNum), \
+                                     INTR1_REG_READ((regNum)) | (val))
+#endif /* INTR1_REG_RESET */
+
+/* INT1_STAT Bit masks */
+
+#ifdef INT_ER_ERR
+#undef  INT_ER_ERR
+#endif
+#ifdef INT_ET_ERR
+#undef  INT_ET_ERR
+#endif
+#ifdef INT_DMA_ERR
+#undef  INT_DMA_ERR
+#endif
+#ifdef INT_DMAn_MASK
+#undef  INT_DMAn_MASK
+#endif
+#ifdef INT_DMA3
+#undef  INT_DMA3
+#endif
+#ifdef INT_DMA4
+#undef  INT_DMA4
+#endif
+
+/*#define INT_ER_ERR    ((ULONG)0x00040000)
+#define INT_ET_ERR    ((ULONG)0x00020000)
+#define INT_DMA_ERR   ((ULONG)0x00010000)
+#define INT_DMAn_MASK ((ULONG)0x000ff000)  Int_DMA{n} 
+#define INT_DMA3 ((ULONG)0x00002000)  Ethernet Tx 
+#define INT_DMA4 ((ULONG)0x00001000)  Ethernet Rx */
+
+#define INT_EMAC_TX     (INT_ET_ERR|INT_DMA3)
+#define INT_EMAC_RX     (INT_ER_ERR|INT_DMA4)
+#define INT_EMAC        (INT_EMAC_TX|INT_EMAC_RX)
+#define INT_DMA_M2M 	((ULONG)0x00000100)      
+
+/*#define MAX(x,y) ((x)>(y)?(x):(y))*/
+
+#define INT_EMAC_LVL MAX(\
+        MAX(INT_LVL_ET_ERR,INT_LVL_DMA3),\
+        MAX(INT_LVL_ER_ERR,INT_LVL_DMA4))
+/*
+ * ARM 2 interrupts ( indicated by INT2).
+ * Not listed here as they are not used by the driver.
+ */
+
+#define INTR2_BASE_ADDR	    ((BYTE*)0x00350080)
+
+
+#endif /* __INTR_REGS_H */
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/m2m_regs.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/m2m_regs.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/m2m_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/m2m_regs.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,101 @@
+/****************************************************************************
+*
+*	Name:			m2m_regs.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __M2M_REGS_H
+#define __M2M_REGS_H
+
+
+/*******************************************************************************
+ * CX821xx: Reg base addr & Reg offset.
+ * The reg offset is same for all the sub-devices (like DMAC, EMAC & 
+ * Interrupt controller).
+ */
+
+
+#ifndef REG_BASE_ADDR
+#define REG_BASE_ADDR	 ((BYTE*)(0x00300000)) /* double word aligned */
+#endif
+
+#ifndef BE_OFST
+#define BE_OFST		 0   /* 0 for little endian, 7 for big  */
+#endif
+
+#ifndef REG_OFFSET
+#define REG_OFFSET	 (BE_OFST + 0x04) /* double word aligned */
+#endif
+
+/**************************************************************
+ * M2M regs, bit masks & reg-access macros
+ */
+
+/* 
+ * Reg addresses
+ */
+
+/* M2M DMA port reg. It's 64 bit reg. Lower 32 are software writable */
+#define M2M_DMA_64BITS	  ((volatile BYTE*)0x00350000) 
+
+#if (BE_OFST==0) /* Little endian */
+#define M2M_DMA	           M2M_DMA_64BITS /* lower 32bits start here */
+#else /* big endian */
+#define M2M_DMA	          (M2M_DMA_64BITS + sizeof(DWORD)) /* Next ULONG */
+#endif /* BE_OFST == 0 */
+
+/* M2M CNT reg*/
+#define M2M_CNT	      ((volatile BYTE*)0x00350004)
+
+/* 
+ * M2M_CNT masks 
+ */
+
+#define M2M_BS_MASK       ((ULONG)(0x00600000)) /* [22:21] RW */
+
+#define M2M_BS0_MASK      ((ULONG)(0x00000000)) /* bs=0 */
+#define M2M_BS1_MASK      ((ULONG)(0x00200000)) /* bs=1 */
+#define M2M_BS2_MASK      ((ULONG)(0x00400000)) /* bs=2 */
+#define M2M_BS3_MASK      ((ULONG)(0x00600000)) /* bs=3 */
+
+#define M2M_DO_MASK       ((ULONG)(0x00100000)) /* Dst only. [20] RW */
+#define M2M_SD_MASK       ((ULONG)(0x00000000)) /* src & dst */
+
+#define M2M_COUNT_MASK    ((ULONG)(0x000fffff)) /* [19:0] RW */
+
+/* 
+ * M2M macros that form the val that may be written to M2M_CNT reg. 
+ */
+
+#define M2M_BS0_DO_CNT(num_of_qwords) \
+        (M2M_BS0_MASK|M2M_DO_MASK|(M2M_COUNT_MASK & (ULONG)(num_of_qwords)))
+
+#define M2M_BS0_SD_CNT(num_of_qwords) \
+        (M2M_BS0_MASK|M2M_SD_MASK|(M2M_COUNT_MASK & (ULONG)(num_of_qwords)))
+
+
+#endif /*__M2M_REGS_H */
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mac.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mac.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mac.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mac.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,90 @@
+/****************************************************************************
+*
+*	Name:			mac.h
+*
+*	Description:	Header file for unicast, multicast and broadcast MAC 
+*					address handling.
+*
+*	Copyright:		(c) 1999-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef __MAC_H
+#define __MAC_H
+/****************************************************************************
+ * Include Files
+ ****************************************************************************/
+
+#include <vxWorks.h>
+#include <string.h>
+
+
+/****************************************************************************
+ * Defines
+ ****************************************************************************/
+
+/* length of MAC address (in bytes) */
+#define MAC_ADDR_LEN          ( 6 ) 
+           
+/* return value for MAC_cmp */
+#define MAC_GREATER           ( 1 )    
+#define MAC_EQUAL             ( 0 )
+#define MAC_LESS              ( -1 )
+
+/* size of multicast address and hash tables */
+#define MULTI_TABLE_SIZE      ( 256 )
+#define HASH_TABLE_SIZE       ( 32 )
+
+/* bit which defines whether a MAC Address is multi or uni cast */
+#define MULTICAST_MSK         ( 0x01 )
+
+/* hash table initialization values */
+#define FILTER_ALL            ( 0x00 )
+#define PASS_ALL              ( 0xFF )
+
+
+/****************************************************************************
+ * Structures
+ ****************************************************************************/
+
+/* MAC Address */
+typedef UINT8 MAC_ADDR[MAC_ADDR_LEN];
+
+/* aligned MAC address */
+typedef struct aligned_mac_addr
+{
+   UINT16      usLSW;      /* least significant word */
+   UINT16      usCSW;      /* middle word */
+   UINT16      usMSW;      /* most significant word */
+} ALIGNED_MAC_ADDR;
+
+
+/****************************************************************************
+ * Prototypes
+ ****************************************************************************/
+
+int   MAC_cmp(const void *, const void *);
+void  MAC_SetupHashTable(MAC_ADDR *, UINT16 , UINT8 *);
+#endif /*  End of __MAC_H  */
+/*###################################################*/
+
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mii.c uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mii.c
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mii.c	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mii.c	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,953 @@
+/****************************************************************************
+*
+*	Name:			mii.c
+*
+*	Description:	MII driver for CX821xx products
+*
+*	Copyright:		(c) 1997-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+*****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+/*
+ *  Module Name: mii.c  
+ *  Author: Joe Bonaker
+ *
+ *  MII.C : OS_DEPENDENT, MAC_DEPENDENT 
+ *  100Base-T Media Independent Interface (MII)
+ *  module, which contains adapter and OS-specific support routines for
+ *  the "phy.c" PHY driver module.  This file must be tailored for each
+ *  unique adapter/operating system environment pair.
+ *
+ *  Conditional Compilation Switches:
+ *
+ *     The following conditional compilation switches apply, and may
+ *     be overridden by the user at compile-time.
+ *
+ *     DRV_OS - default DOS.  Establishes the OS-specific controller
+ *     (MAC or repeater) device I/O (or memory-mapped) access to the
+ *     PHY's serial MII plus microsecond and/or millisecond timer
+ *     support as detailed in [Step 1] of the Porting Guide below and
+ *     within this module.  DRV_OS types are defined in "phytypes.h."
+ *
+ *  Porting Guide:
+ *
+ *  There are two steps which must be performed to tailor this module
+ *  for a specific adapter (NIC) or repeater configuration.
+ *
+ *  [Step 1] entails mapping the OS_MICROSECOND_WAIT() and/or
+ *  OS_MILLISECOND_WAIT(), IO_WRITE(), IO_READ(), plus optional
+ *  OS_NANOSECOND_WAIT() macros into the PHY driver's operating system,
+ *  as defined by DRV_OS.
+ *
+ *  [Step 2] alters the adapter-specific register configuration.  At
+ *  present, only a MAC (NIC) controller interface, the RSS1161x 10/100
+ *  Mbit Fast Ethernet series, is supported.  [Step 2a] contains
+ *  MAC general purpose I/O (GPIO) settings which may vary among
+ *  different adapter configurations.  [Step 2b] contains an optional
+ *  PHY hardware reset sequence, which is dependent upon the [Step 2a]
+ *  interconnection between the MAC and PHY devices/modules.
+ *
+ *  Search this module for occurances of [Step 1] and [Step 2], editing
+ *  accordingly.
+ *
+ **********************************************************************/
+#if 0
+	#if defined(LINUX_DRIVER)
+	#include "linuxinc.h"
+	#endif
+#endif
+#define P52
+#include "phytypes.h"
+#include "mii.h"
+
+
+ /*--------------------------------------------------------------------*
+ * [Step 1] Enter DRV_OS-dependent support for OS_MICROSECOND_WAIT(),
+ *          and/or OS_MILLISECOND_WAIT(), optional OS_NANOSECOND_WAIT(),
+ *          plus 32-bit IO_WRITE()/IO_READ() services.  Edit one or
+ *          more of [Step 1a] through [Step 1h] as necessary.
+ *
+ *          Either one or both of OS_MICROSECOND_WAIT() and
+ *          OS_MILLISECOND_WAIT() must be #defined, depending on DRV_OS
+ *          environment support.  If the DRV_OS supports microsecond
+ *          granularity delays (preferred), then #define the
+ *          OS_MICROSECOND_WAIT() macro accordingly.  Otherwise,
+ *          #define OS_MILLISECOND_WAIT().  If the DRV_OS supports both
+ *          microsecond and millisecond delays, and advocates a scheme
+ *          for relinquishing the CPU during longer delays, then
+ *          OS_MILLISECOND_WAIT() may also be #defined using the more
+ *          system-friendly long delay service.  As long as at least
+ *          one of these two macros is #defined, code outside this
+ *          [Step 1] DRV_OS-specific block will ensure that the other
+ *          macro is properly derived.
+ *
+ *          Unless the DRV_OS supports nanosecond granularity (highly
+ *          unlikely), OS_NANOSECOND_WAIT() should NOT be #defined,
+ *          and will be derived from OS_MICROSECOND_WAIT() outside this
+ *          code block.  There is one exception.  Since the nanosecond
+ *          delay is only used to ensure that MiiRead() and MiiWrite()
+ *          clock timing doesn't exceed the 802.3u minimum hold time
+ *          of 200-300 nanoseconds, OS_NANOSECOND_WAIT() can be
+ *          disabled in a DRV_OS environment where IO_READ() and
+ *          IO_WRITE() take a considerable length of time to complete.
+ *          This is accomplished as follows:
+ *
+ *              #define OS_NANOSECOND_WAIT(n)           // No delay
+ *
+ *          For example, the DRV_OS=WIN32_DIAG relies on driver ioctls
+ *          to perform IO_READ() and IO_WRITE().  This, in conjunction
+ *          with a 10-millisecond delay granularity, results in
+ *          MiiRead() and MiiWrite() times approaching one second per
+ *          register!  Therein, OS_NANONSECOND_WAIT() was disabled.
+ *
+ *          Though their names imply I/O device access, the IO_READ()
+ *          and IO_WRITE() macros may also be crafted to support a
+ *          memory-mapped controller -- MAC or repeater -- device
+ *          interface.  Regardless, they also support the notion of an
+ *          <adapter> reference for DRV_OS environments requiring
+ *          abstraction to touch hardware, e.g., NDIS, WIN32_DIAG,
+ *          NOVELL_CHSM.  Other environments can ignore the <adapter>
+ *          or use it as a device base address parameter.
+ *--------------------------------------------------------------------*/
+
+#if (DRV_OS == NDIS)            /*------------------------------------*
+                                 * [Step 1a] Win95/WinNT NDIS
+                                 *
+                                 * Assumes <adapter> is the starting
+                                 * I/O port address of the MAC device
+                                 *------------------------------------*/
+#define OS_MICROSECOND_WAIT(u)          NdisStallWrapper(u)
+#ifdef P51
+ULONG P51_GlobalReadVariable;
+#define IO_WRITE(adapter, port, val) {                                         \
+    NdisWriteRegisterUlong((PULONG) ((adapter) + (port)), (ULONG) (val));      \
+    NdisReadRegisterUlong((PULONG) ((adapter) + (port)), (PULONG) &P51_GlobalReadVariable); \
+}
+#else
+#define IO_WRITE(adapter, port, val)    \
+    NdisRawWritePortUlong((PULONG) ((adapter) + (port)), (ULONG) (val))
+#endif
+#define IO_READ(adapter, port)          \
+    NdisIoReadWrapper((adapter) + (port))
+
+/***********************************************************************
+ * NdisStallWrapper() - "OS-friendly" wait in 100 uSec chunks
+ **********************************************************************/
+static void
+NdisStallWrapper(DWORD num_microseconds)
+{
+    /*
+     * Semi-hog:  relinquish the CPU every 100 microseconds to prevent
+     * other drivers (e.g., tty character devices) from starving
+     */
+    while (num_microseconds > 25) {
+        NdisStallExecution(25);
+        num_microseconds -= 25;
+    }
+//	if( num_microseconds == 1)
+//		num_microseconds = 10;
+    NdisStallExecution(num_microseconds);
+}
+
+/***********************************************************************
+ * NdisIoReadWrapper() - expected NdisRawReadPortUlong() interface
+ **********************************************************************/
+static DWORD
+NdisIoReadWrapper(DWORD port)
+{
+    ULONG       val;
+
+#ifdef P51
+    NdisReadRegisterUlong((PULONG) port, &val);
+#else
+    NdisRawReadPortUlong((PULONG) port, &val);
+#endif
+    return ((DWORD) val);
+}
+
+#elif (DRV_OS == NOVELL_CHSM)   /*------------------------------------*
+                                 * [Step 1b] Novell 32-bit ODI
+                                 *
+                                 * Assumes <adapter> has been cast as
+                                 * pointer to a PHY_ADAPTER structure
+                                 *------------------------------------*/
+
+#define OS_MICROSECOND_WAIT(u)          Odi32MicroWait(u)
+#define OS_NANOSECOND_WAIT(n)           Slow()  /* 0.5 uSec NOP */
+#ifndef IO_MAPPED               /* default:  memory-mapped device */
+#define IO_WRITE(adapter, port, val)                            \
+    Wrt32(((PHY_ADAPTER *) (adapter))->bus_tag, NULL,           \
+          (void *) (((port) + (UINT8 *)                         \
+                     ((PHY_ADAPTER *) (adapter))->dev_addr)),   \
+          (UINT32) (val))
+#define IO_READ(adapter, port)          (DWORD)                 \
+    Rd32(((PHY_ADAPTER *) (adapter))->bus_tag, NULL,            \
+         (void *) (((port) + (UINT8 *)                          \
+                   ((PHY_ADAPTER *) (adapter))->dev_addr)))
+#else                           /* non-default:  I/O-mapped device */
+#define IO_WRITE(adapter, port, val)                            \
+    Out32(((PHY_ADAPTER *) (adapter))->bus_tag,                 \
+          (void *) (((port) + (UINT8 *)                         \
+                     ((PHY_ADAPTER *) (adapter))->dev_addr)),   \
+          (UINT32) (val))
+#define IO_READ(adapter, port)          (DWORD)                 \
+    In32(((PHY_ADAPTER *) (adapter))->bus_tag,                  \
+         (void *) (((port) + (UINT8 *)                          \
+                   ((PHY_ADAPTER *) (adapter))->dev_addr)))
+#endif
+
+/***********************************************************************
+ * Odi32MicroWait() - Microsecond delay under 32-bit Novell ODI OS
+ **********************************************************************/
+static void
+Odi32MicroWait(DWORD num_microseconds)
+{
+    /*
+     * CMSMGetMicroTimer() support is suspect under some client
+     * operating systems as only 16 bits of returned 32-bit timer value
+     * may be valid.  Instead, use the (hopefully) more trustworthy
+     * Slow() service.
+     */
+    while (num_microseconds-- > 0) {
+        Slow();         /* 0.5 uSec NOP per CHSM ODI spec v1.11 */
+        Slow();
+    }
+}
+
+#elif (DRV_OS == SCO_MDI)       /*------------------------------------*
+                                 * [Step 1c] SCO Unix drivers: MDI,
+                                 * LLI, DLPI, and Gemini.
+                                 *
+                                 * Assumes <adapter> is the starting
+                                 * I/O port address of the MAC device
+                                 *------------------------------------*/
+#define OS_MICROSECOND_WAIT(u)          suspend(u)
+#define IO_WRITE(adapter, port, val)    outd((adapter) + (port), (val))
+#define IO_READ(adapter, port)          ind((adapter) + (port))
+
+#elif (DRV_OS == SCO_LLI)
+#define OS_MICROSECOND_WAIT(u)          TBD
+#define IO_WRITE(adapter, port, val)    TBD
+#define IO_READ(adapter, port)          TBD
+
+#elif (DRV_OS == SCO_DLPI)
+#define OS_MICROSECOND_WAIT(u)          TBD
+#define IO_WRITE(adapter, port, val)    TBD
+#define IO_READ(adapter, port)          TBD
+
+#elif (DRV_OS == SCO_GEMINI)
+#define OS_MICROSECOND_WAIT(u)          TBD
+#define IO_WRITE(adapter, port, val)    TBD
+#define IO_READ(adapter, port)          TBD
+
+#elif (DRV_OS == SOLARIS)       /*------------------------------------*
+                                 * [Step 1d] Sun Solaris driver
+                                 *
+                                 * Assumes <adapter> is the starting
+                                 * I/O port address of the MAC device
+                                 *------------------------------------*/
+#define OS_MICROSECOND_WAIT(u)          drv_usecwait(u)
+#define IO_WRITE(adapter, port, val)    outl((adapter) + (port), (val))
+#define IO_READ(adapter, port)          inl((adapter) + (port))
+
+#elif (DRV_OS == LINUX)         /*------------------------------------*
+                                 * [Step 1e] Linux driver support
+                                 *
+                                 * Assumes <adapter> is the starting
+                                 * I/O port address of the MAC device
+                                 *------------------------------------*/
+/*
+ * Caution:  per the outb(9) man page, the outl() arguments are the
+ * opposite of most DOS-based output routines:  outl(value, portAddr)
+ * instead of outl(portAddr, value).
+ */
+#ifdef __KERNEL__
+
+#define OS_MICROSECOND_WAIT(u)          udelay(u)
+#else
+	/* #include <unistd.h> */
+	/* #define OS_MICROSECOND_WAIT(u)          usleep(u) */
+	#define OS_MICROSECOND_WAIT(u)          LinuxMicroWait(u)
+	void LinuxMicroWait(int microseconds)
+	{
+	    do {
+	    } while (--microseconds > 0);
+	}
+#endif
+
+// Turn the requested nanosecond delay into a 20 times longer usec delay
+#define OS_NANOSECOND_WAIT(u) udelay(u/50)
+
+#ifdef P51
+	#define IO_WRITE(adapter, port, val)  { \
+		writel((val), (adapter) + (port)) ; \
+		readl( (adapter) + (port) );		\
+	}
+	#define IO_READ(adapter, port)          readl((adapter) + (port))
+#else
+	#define IO_WRITE(adapter, port, val)    outl((val), (adapter) + (port))
+	#define IO_READ(adapter, port)          inl((adapter) + (port))
+#endif
+
+#elif (DRV_OS == PKTDRV)        /*------------------------------------*
+                                 * [Step 1f] DOS/PCTCP packet driver
+                                 *
+                                 * Assumes <adapter> is the starting
+                                 * I/O port address of the MAC device
+                                 *------------------------------------*/
+#include <???.h>
+
+#define OS_MICROSECOND_WAIT(u)          TBD
+#define IO_WRITE(adapter, port, val)    TBD
+#define IO_READ(adapter, port)          TBD
+
+#elif (DRV_OS == WIN32_DIAG)    /*------------------------------------*
+                                 * [Step 1g] RSS' Win95/WinNT Diagnostic
+                                 *
+                                 * Assumes <adapter> is the adapter
+                                 * handle used by the diagnostic.  Also,
+                                 * nullifies OS_NANOSECOND_WAIT(), as
+                                 * IO_READ() and IO_WRITE() driver
+                                 * ioctl's provide sufficient clock
+                                 * spacing, i.e., >> one uSec.
+                                 *------------------------------------*/
+
+#define Unknown_OS      0
+#define Windows95_OS    1
+#define Windows98_OS    2
+#define WindowsNT4_OS   3
+
+#define OS_MILLISECOND_WAIT(m)                  SleepEx((m), FALSE)
+#define OS_NANOSECOND_WAIT(n)                   /* No delay */
+
+#define IO_WRITE(adapter, port, val)            \
+    (void) _PutCSRRegisterWrapper((ULONG) adapter, (ULONG) (port), (ULONG) (val))
+
+#define IO_READ(adapter, port)          \
+    _GetCSRRegisterWrapper((ULONG) (adapter), (ULONG) (port))
+
+/***********************************************************************
+ * _PutCSRRegisterWrapper() - expected _PutCSRRegister() interface
+ **********************************************************************/
+static DWORD
+_PutCSRRegisterWrapper(ULONG adapter, ULONG port, ULONG val)
+{
+
+    HANDLE      drvhandle;
+    DWORD       RunningOS;
+
+    RunningOS = CheckOS();
+
+    if (RunningOS != WindowsNT4_OS) {
+        _getdriverhandle(&drvhandle);   /* get handle to driver */
+        
+        if (!drvhandle)                 /* if fail, return -1 */
+            return (-1);
+    }
+
+    (void) _putcsrregister(drvhandle,adapter, port, val);
+
+    return ((DWORD) val);
+}
+
+/***********************************************************************
+ * _GetCSRRegisterWrapper() - expected _GetCSRRegister() interface
+ **********************************************************************/
+static DWORD
+_GetCSRRegisterWrapper(ULONG adapter, ULONG port)
+{
+    ULONG       val = -1;
+    HANDLE      drvhandle;
+    DWORD       RunningOS;
+
+    RunningOS = CheckOS();
+
+    if (RunningOS != WindowsNT4_OS) {
+        _getdriverhandle(&drvhandle);   /* get handle to driver */
+        
+        if (!drvhandle)                 /* if fail, return -1 */
+            return (-1);
+    }
+    
+    (void) _getcsrregister(drvhandle,adapter, port, &val);
+
+    return ((DWORD) val);
+}
+
+#elif (DRV_OS == VXWORKS)       /*------------------------------------*
+                                 * [Step 1g.1] VxWorks
+                                 *------------------------------------*/
+
+#define OS_MICROSECOND_WAIT(u)          VxWorksMicroWait(u)
+#define OS_NANOSECOND_WAIT(n)           VxWorksSlow() /* 0.5 uSec NOP */
+
+/* default:  memory-mapped device */
+#define IO_WRITE(adapter, port, val)                            \
+	* ((BYTE *) adapter + port) = val
+#define IO_READ(adapter, port)          (DWORD)                 \
+	* ((BYTE *) adapter + port)
+
+static void VxWorksSlow();
+/***********************************************************************
+ * VxWorksMicroWait() - Microsecond delay under VxWorks OS
+ **********************************************************************/
+static void
+VxWorksMicroWait(DWORD num_microseconds)
+{
+    /*
+     * Use the VxWorksSlow() function which busywaits for 0.5 microsec.
+     */
+    while (num_microseconds-- > 0) {
+        VxWorksSlow();         /* 0.5 uSec NOP loop */
+        VxWorksSlow();
+    }
+}
+
+/***********************************************************************
+ * VxWorksSlow() - Microsecond delay under VxWorks OS
+ **********************************************************************/
+static void
+VxWorksSlow()
+{
+	volatile int	iLoopCount;
+    /*
+     * Loop for 25 times to pass 0.5 micro.
+     */
+	for (iLoopCount=25; iLoopCount; iLoopCount--)
+		;
+	for (iLoopCount=25; iLoopCount; iLoopCount--)
+		;
+}
+
+
+#elif (DRV_OS == NO_OS)         /*------------------------------------*
+                                 * [Step 1g.2] No OS Services
+                                 *------------------------------------*/
+
+#define OS_MICROSECOND_WAIT(u)          NoOSMicroWait(u)
+#define OS_NANOSECOND_WAIT(n)           NoOSSlow() /* 0.5 uSec NOP */
+
+/* default:  memory-mapped device */
+#define IO_WRITE(adapter, port, val)                            \
+	* ((BYTE *) adapter + port) = val
+#define IO_READ(adapter, port)          (DWORD)                 \
+	* ((BYTE *) adapter + port)
+
+/***********************************************************************
+ * VxWorksMicroWait() - Microsecond delay under No OS Services
+ **********************************************************************/
+static void
+NoOSMicroWait(DWORD num_microseconds)
+{
+    /*
+     * Use the NoOSSlow() function which busywaits for 0.5 microsec.
+     */
+    while (num_microseconds-- > 0) {
+        NoOSSlow();         /* 0.5 uSec NOP loop */
+        NoOSSlow();
+    }
+}
+
+/***********************************************************************
+ * NoOSSlow() - Microsecond delay under VxWorks OS
+ **********************************************************************/
+static void
+NoOSSlow()
+{
+	volatile int	iLoopCount;
+    /*
+     * Loop for 25 times to pass 0.5 micro.
+     */
+	for (iLoopCount=25; iLoopCount; iLoopCount++)
+		;
+}
+
+
+#else                           /*------------------------------------*
+                                 * [Step 1h] Miscellaneous (DOS, etc.)
+                                 *
+                                 * Assumes <adapter> is the starting
+                                 * I/O port address of the MAC device
+                                 *------------------------------------*/
+#include <conio.h>
+
+#if   defined(__WATCOMC__)
+#elif defined(__BORLANDC__)
+#elif defined(_MSVC_VER)
+#endif
+
+#ifdef _MAPTEST_
+BYTE    phy_data[0x10] = {0};   /* DATA - initialized */
+BYTE    phy_bss[0x10];          /* BSS  - uninitialized */
+#endif
+
+extern DWORD    inpd(int port);
+extern DWORD    outpd(int port, DWORD val);
+#define OS_MICROSECOND_WAIT(u)          DosMicroWait(u)
+#define IO_WRITE(adapter, port, val)    \
+    (void) outpd((int) (adapter) + (port), (val))
+#define IO_READ(adapter, port)          \
+    inpd((int) (adapter) + (port))
+
+/*
+ * Convert microseconds to PC system ticks.  The 16-bit Timer0, in
+ * Mode 3 (square wave), decrements two counts per 1.1932 MHz input
+ * clock on most systems.  We round this 2.3864 ticks/uSec to integer
+ * (239 / 100) here, yielding a 32-bit unsigned range of 17.971 seconds.
+ * Warning:  Some AMI BIOSes have a bug, configuring Timer0 into Mode 2
+ * (rate generator), which only decrements one count per clock.  On
+ * such systems, we'll suffer a delay that is twice as long as
+ * expected.  This could be a problem for longer, millisecond-to-second
+ * duration delays, however, most MII related delays are microsecond
+ * or less.
+ */
+#define PC_TIMER0_TICKS(usec)           \
+    (1 + (((DWORD) (usec) * 239) / 100))
+
+/***********************************************************************
+ * DosMicroWait() - Microsecond delay under 16-bit DOS environment
+ **********************************************************************/
+static void
+DosMicroWait(DWORD count)
+{
+    DWORD       t0;
+    DWORD       t1;
+    DWORD       delta_t;
+    BYTE        timer0_lsb;
+
+    /*
+     * Writing a command value of 0x00 to Port 0x43 transfers
+     * the Timer 0 counter into the output latch register.  The value
+     * is held until read from port 0x40 (two successive byte reads,
+     * LSB followed by the MSB).  A truly bullet-proof implementation
+     * would lock interrupts prior to latching and reading the counter.
+     */
+    outp(0x43, 0x00);
+    timer0_lsb = inp(0x40);
+    t1 = ((DWORD) inp(0x40) << 8) + timer0_lsb;
+    delta_t = 0;
+    count = PC_TIMER0_TICKS(count);     /* uSec to Timer0 ticks */
+
+    do {
+        count -= delta_t;
+        t0 = t1;
+        outp(0x43, 0x00);
+        timer0_lsb = inp(0x40);
+        t1 = ((DWORD) inp(0x40) << 8) + timer0_lsb;
+        if (t1 > t0) {
+            t0 += 0x10000UL;            /* handle 16-bit rollover */
+        }
+        delta_t = t0 - t1;
+    } while (count > delta_t);
+}
+
+#ifdef UNSUPPORTED      /* Most C/C++ only support 16-bit in-line ASM */
+DWORD
+outpd(int port, DWORD val)
+{
+    __asm {
+        mov     dx, port;
+        mov     eax, val;
+        out     dx, eax;
+    }
+    return (val);
+}
+
+DWORD
+inpd(int port)
+{
+    DWORD       val;
+
+    __asm {
+        mov     dx, port;
+        in      eax, dx;
+        mov     val, eax;
+    }
+    return (val);
+}
+#endif  /* UNSUPPORTED, as most C/C++ only support 16-bit in-line ASM */
+
+#endif                          /*------------------------------------*
+                                 * [Step 1] End of first porting step
+                                 *------------------------------------*/
+
+/*
+ * Post- [Step 1] timer derivation.  OS_MICROSECOND_WAIT() and/or
+ * OS_MILLISECOND_WAIT() must be #defined for this to work....
+ */
+
+#ifndef OS_MICROSECOND_WAIT
+#define OS_MICROSECOND_WAIT(u)                  \
+    OS_MILLISECOND_WAIT((DWORD) ((u) + 999) / 1000)
+#endif
+
+#ifndef OS_MILLISECOND_WAIT
+#define OS_MILLISECOND_WAIT(m)  MICROSECOND_WAIT((DWORD) (m) * 1000)
+#endif
+
+//#if (DRV_OS == NDIS)
+//#define OS_NANOSECOND_WAIT(n)           // NO_DELAY
+//#endif
+#ifndef OS_NANOSECOND_WAIT
+#define OS_NANOSECOND_WAIT(n)   \
+    MICROSECOND_WAIT((DWORD) ((n) + 999) / 1000)
+#endif
+#define NANOSECOND_WAIT         OS_NANOSECOND_WAIT
+
+/*--------------------------------------------------------------------*
+ * [Step 2] Enter (NIC or repeater) adapter's MAC controller-specific
+ *          register information.  The MII (MDIO) and any optional
+ *          adapter-unique general purpose I/O (GPIO) settings must be
+ *          captured here.  In particular, the gpio[] table should be
+ *          modified per adapter configuration of the MAC's GPIO
+ *          interface [Step 2a].  If additional, custom configuration
+ *          is required, the low-level MiiPhyHwReset() routine may be
+ *          modifified [Step 2b].
+ *
+ *          Warning:  at present, only RSS and DEC-compatible fast
+ *          ethernet MACs are supported.  Common repeater interfaces
+ *          will be added as development (COMET?) progresses at RSS.
+ *--------------------------------------------------------------------*/
+#ifdef DEVICE_YELLOWSTONE
+
+	#define MAC_MDIO_REG            0x0c
+	#define MDIO_RD_DATA            0x8L
+	#define MDIO_RD_ENABLE          0x2L
+	#define MDIO_WR_ENABLE          0x00000L
+	#define MDIO_WR_DATA_1          0x4L
+	#define MDIO_WR_DATA_0          0x00000L        
+	#define MDIO_CLK                0x1L
+	#define MDIO_MASK               0xFL
+
+#elif defined(P51) 
+
+	#define JEDI_MII_ID			0x0032cc10		
+	#define JEDI_MII_ID_REVC	0x0032cc13
+	// bit 3:0 - revision
+
+	#define JediPhy(mii_id) (BOOLEAN)( (mii_id & 0xfffffff0) == JEDI_MII_ID)
+
+	/* P51- YUKON or ATHENS , ELAN or HLAN MII (MDIO) register offset and values */
+	// the following definition is not 100% correct but it work for all our current boards
+	#define MAC_MDIO_REG            0x30
+	#define MDIO_RD_DATA            (0x8L<< ((phy->P51_HLAN) ? 2 : 0))
+	#define MDIO_RD_ENABLE          (0x2L<< ((phy->P51_HLAN) ? 2 : 0))
+	#define MDIO_WR_ENABLE          0x00000L
+	#define MDIO_WR_DATA_1          (0x4L<< ((phy->P51_HLAN) ? 2 : 0))
+	#define MDIO_WR_DATA_0          0x00000L        
+	#define MDIO_CLK                (0x1L<<((phy->P51_HLAN) ? 2 : 0))
+	#define MDIO_MASK               (0xFL<<((phy->P51_HLAN) ? 2 : 0))
+
+#elif defined(P52) 
+	// P52- CX82100,
+	#define MAC_MDIO_REG            0x18
+	#define MDIO_RD_DATA            0x0002L
+	#define MDIO_RD_ENABLE          0x0008L
+	#define MDIO_WR_ENABLE          0x0000L
+	#define MDIO_WR_DATA_1          0x0004L        
+	#define MDIO_WR_DATA_0          0x0000L        
+	#define MDIO_CLK                0x0001L
+	#ifdef JEDIPHY		// Bright 6/8/01 test
+		#define MDIO_CLK_MDIP           0x0010L	/* bit 4 - default 0 */
+												/*		0=falling endge sample */
+												/*      1=rising endge sample */
+
+		#define MDIO_MASK               0x001FL
+	#else
+		#define MDIO_CLK_MDIP           0x0010L	/* bit 4 - default 0 */
+												/*		0=falling endge sample */
+												/*      1=rising endge sample */
+
+		#define MDIO_MASK               0x000FL
+	#endif
+
+
+#else
+
+	/* RSS 1161x MACs' CSR9 (MDIO) register offset and values */
+	#define MAC_MDIO_REG            0x48
+	#define MDIO_RD_DATA            0x80000L
+	#define MDIO_RD_ENABLE          0x40000L
+	#define MDIO_WR_ENABLE          0x00000L
+	#define MDIO_WR_DATA_1          0x20000L        
+	#define MDIO_WR_DATA_0          0x00000L        
+	#define MDIO_CLK                0x10000L
+	#define MDIO_MASK               0xF0000L
+#endif
+
+/* MII frame fields */
+#define MII_READ_ST_OP          0x6     /* MII READ start, opcode */
+#define MII_WRITE_ST_OP         0x5     /* MII WRITE start, opcode */
+#define MII_WRITE_TA            0x2     /* MII WRITE turnaround bits */
+#define MII_WRITE_FRAME         \
+    (((DWORD) MII_WRITE_ST_OP << 28) | ((DWORD) MII_WRITE_TA << 16))
+
+/* Local (static) function prototypes */
+static void     MiiPreamble(MIIOBJ *phy);
+static void     MiiIdle(MIIOBJ *phy, int num_clocks);
+
+/***********************************************************************
+ * MiiRead() - read serial data from MII register
+ **********************************************************************/
+
+WORD MiiRead(MIIOBJ *phy, BYTE reg_addr)
+{
+    DWORD 	io_data;
+    WORD	mii_data;
+    int		n;
+
+    /* Output 32-bit preamble (all ones) to re-sync the PHY */
+    MiiPreamble(phy);
+
+    /* Preserve non-MDIO bits in shared MAC_MDIO_REG (SPR) */
+    io_data = IO_READ(phy->adapter, MAC_MDIO_REG) & ~MDIO_MASK;
+
+    /* Write the first 14 <mii_data> frame bits in MSB-first order */
+    mii_data = (MII_READ_ST_OP << 10) | (phy->mii_addr << 5) | (reg_addr & 0x1F);
+    for (n = 0x2000; n > 0; n >>= 1)
+    {
+        io_data &= ~MDIO_MASK;          /* Preserve non-MDIO bits */
+        if (mii_data & n)
+        {
+            io_data |= (MDIO_WR_ENABLE | MDIO_WR_DATA_1);
+        }
+        else
+        {
+            io_data |= (MDIO_WR_ENABLE | MDIO_WR_DATA_0);
+        }
+
+		// Change output data to phy on falling edge of MDIO_CLK
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data);
+        NANOSECOND_WAIT(200);
+
+		// Input data sampled by phy on rising edge of MDIO_CLK
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data | MDIO_CLK);
+        NANOSECOND_WAIT(200);
+    }
+
+    mii_data = 0;
+    io_data &= ~MDIO_MASK;          /* Preserve non-MDIO bits */
+    io_data |= (MDIO_RD_ENABLE | MDIO_CLK_MDIP);
+
+    /*
+     * Read the next 18 bits [17:0] in MSB-first order.  The first two
+     * bits, turnaround (TA) high-Z and zero, are effectively ignored.
+     */
+    for (n = 0; n < 18; n++)
+    {
+		// NOTE: When MDIO_CLK_MDIP bit is a zero the data from 
+		// the phy is sampled on the falling edge of the MDIO_CLK.
+		// When MDIO_CLK_MDIP bit is a one the data from the phy
+		// is sampled on the rising edge of the MDIO_CLK.
+
+        // MDIO_CLK falling edge
+		IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data);	
+        NANOSECOND_WAIT(200);
+
+		// MDIO_CLK rising edge
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data | MDIO_CLK); 
+        /*
+         * ??? Shouldn't IO_READ() occur *after* MDC_CLK rising edge?
+         * The IEEE 802.3u specification -- Clause 22.3.4, "MDIO timing
+         * relationship to MDC" and Figure 22-17, "MDIO sourced by
+         * PHY" -- doesn't imply that data is latched on the falling
+         * edge of MDC.  In any case, that is what works with a National
+         * Semiconductor DP83840 PHY, but may be a source of problems
+         * with other PHY devices....
+		 *
+         * IT IS! Data must be sampled on the rising edge for the CX11656
+		 * Home Plug device.
+         */
+        mii_data <<= 1;
+        if (IO_READ(phy->adapter, MAC_MDIO_REG) & MDIO_RD_DATA) {
+            mii_data |= 0x0001;
+        }
+
+        NANOSECOND_WAIT(300);        /* [sic] 300 nSec PHY hold */
+
+    }
+
+    /* Output a single, idle (high-Z, tri-stated) clock transition */
+    MiiIdle(phy, 1);
+
+    return (mii_data & 0xFFFF);
+}
+
+/***********************************************************************
+ * MiiWrite() - write serial data to MII register
+ **********************************************************************/
+void MiiWrite(MIIOBJ *phy, BYTE reg_addr, WORD reg_value)
+{
+    DWORD       io_data;
+    DWORD       mii_frame;
+    DWORD       mask;
+
+    /* Output 32-bit preamble (ones) sequence to re-sync the PHY */
+    MiiPreamble(phy);
+
+    /* Preserve non-MDIO bits in shared MAC_MDIO_REG (SPR) */
+    io_data = IO_READ(phy->adapter, MAC_MDIO_REG) & ~MDIO_MASK;
+
+    /* Form and write 32-bit [31:0] <mii_frame> in MSB-first order */
+    mii_frame = MII_WRITE_FRAME | ((DWORD) phy->mii_addr << 23) |
+        ((DWORD) (reg_addr & 0x1F) << 18) | (DWORD) reg_value;
+    for (mask = 0x80000000UL; mask > 0; mask >>= 1) {
+        io_data &= ~MDIO_MASK;          /* Preserve non-MDIO bits */
+        if (mii_frame & mask) {
+            io_data |= (MDIO_WR_ENABLE | MDIO_WR_DATA_1);
+        } else {
+            io_data |= (MDIO_WR_ENABLE | MDIO_WR_DATA_0);
+        }
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data);
+        NANOSECOND_WAIT(200);
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data | MDIO_CLK);
+        NANOSECOND_WAIT(200);
+    }
+
+    /* Output a single, idle (high-Z, tri-stated) clock transition */
+    MiiIdle(phy, 1);
+}
+
+
+void MiiWriteMask(MIIOBJ *phy, WORD reg_addr, WORD reg_value, WORD mask_value)
+{
+
+	if( mask_value != 0xffff )
+	{
+		reg_value = (MiiRead( phy, (BYTE)reg_addr) & ~mask_value) | (reg_value & mask_value) ;
+	}
+	MiiWrite(phy, (BYTE)reg_addr, reg_value) ;
+}
+/***********************************************************************
+ * MiiPreamble() - Generate 32-bit MII preamble sequence (all ones)
+ **********************************************************************/
+static void
+MiiPreamble(MIIOBJ *phy)
+{
+    DWORD       io_data;
+    int         n;
+
+    /* Preserve non-MDIO bits in shared MAC_MDIO_REG (SPR) */
+    io_data = IO_READ(phy->adapter, MAC_MDIO_REG) & ~MDIO_MASK;
+
+    if (!phy->preamble_suppression) 
+    {
+        io_data |= (MDIO_WR_ENABLE | MDIO_WR_DATA_1);
+#if defined(JEDIPHY) && defined(P52)
+        for (n = 0; n < 64; n++)
+        {
+#else
+        for (n = 0; n < 32; n++)
+        {
+#endif
+            IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data);
+            NANOSECOND_WAIT(200);
+            IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data | MDIO_CLK);
+            NANOSECOND_WAIT(200);
+        }
+    }
+}
+
+/***********************************************************************
+ * MiiIdle() - Generate one or more bits of MII idle sequence (high-Z)
+ **********************************************************************/
+static void MiiIdle(MIIOBJ *phy, int num_clocks)
+{
+    DWORD       io_data;
+
+    /* Preserve non-MDIO bits in shared MAC_MDIO_REG (SPR) */
+    io_data = IO_READ(phy->adapter, MAC_MDIO_REG) & ~MDIO_MASK;
+#if defined(JEDIPHY) && defined(P52)
+    io_data |= (MDIO_RD_ENABLE | MDIO_CLK_MDIP);
+#else
+    io_data |= MDIO_RD_ENABLE;
+#endif
+
+	// need more delay for JEDI phy, tested under Win2K , need 5ms to make 
+	// MiiRead, Write work for JEDI, (Win98 have longer delay for the same API call)
+    do {
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data);
+//        NANOSECOND_WAIT(200);
+        MICROSECOND_WAIT(5);
+        IO_WRITE(phy->adapter, MAC_MDIO_REG, io_data | MDIO_CLK);
+//        NANOSECOND_WAIT(200);
+        MICROSECOND_WAIT(5);
+    } while (--num_clocks > 0);
+}
+
+/***********************************************************************
+ * MiiMillisecondWait() - OS-dependent busy-wait/process sleep wrapper
+ **********************************************************************/
+void
+MiiMillisecondWait(DWORD num_milliseconds)
+{
+    OS_MILLISECOND_WAIT(num_milliseconds);
+}
+
+/***********************************************************************
+ * MiiMicrosecondWait() - OS-dependent busy-wait/process sleep wrapper
+ **********************************************************************/
+void
+MiiMicrosecondWait(DWORD num_microseconds)
+{
+    OS_MICROSECOND_WAIT(num_microseconds);
+}
+
+/***********************************************************************
+ * MiiIoRead() - Export wrapper for the IO_READ() macro
+ **********************************************************************/
+DWORD MiiIoRead( DWORD mac_addr, WORD io_offset)
+{
+    return (IO_READ( mac_addr, io_offset));
+}
+
+/***********************************************************************
+ * MiiIoRead() - Export wrapper for the IO_WRITE() macro
+ **********************************************************************/
+void
+MiiIoWrite( DWORD mac_addr, WORD io_offset, DWORD io_value)
+{
+    IO_WRITE(mac_addr, io_offset, io_value);
+}
+
+#if (DRV_OS == DOS)     /* ########################################## */
+
+/***********************************************************************
+ * MiiSetBits() - Set (logical-OR) one or more bits in MII register
+ **********************************************************************/
+void
+MiiSetBits(MIIOBJ *phy, BYTE reg_addr, WORD bits)
+{
+    MiiWrite(phy, reg_addr, MiiRead(phy, reg_addr) | bits);
+}
+
+/***********************************************************************
+ * MiiClrBits() - Clear (logical-NAND) one or more bits in MII register
+ **********************************************************************/
+void
+MiiClrBits(MIIOBJ *phy, BYTE reg_addr, WORD bits)
+{
+    MiiWrite(phy, reg_addr, MiiRead(phy, reg_addr) & ~bits);
+}
+
+#endif                  /* ########################################## */
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mii.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mii.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mii.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mii.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,140 @@
+/****************************************************************************
+*
+*	Name:			mii.h
+*
+*	Description:	The 100Base-T serial Media Independent Interface (MII),
+*					which defines OS- and adapter-dependent functions imported by
+*  					the PHY driver.  The accompanying "mii.c" module must be
+*					tailored to	adhere to the implementation-dependent environment.
+*
+*	Copyright:		(c) 1997-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef _MII_H_
+#define _MII_H_
+
+#include "phytypes.h"
+
+
+typedef struct def_MIIOBJ
+{
+	DWORD	 adapter;	// beginning of MAC IO address
+   DWORD  mii_id;		// not use now 
+	WORD   mii_addr;   // Nominal value/usage here 
+	BOOLEAN   preamble_suppression;
+#ifdef P51
+	BOOLEAN P51_HLAN;	// the current mac is P51 HLAN
+#endif
+} MIIOBJ ;
+
+
+/*
+ * Special "adapter" handle for 32-bit Novell ODI drivers.  Most
+ * other drivers assume that the phy->adapter value is simply the
+ * starting I/O port (or memory-mapped) address of the MAC (or repeater)
+ * controller device.
+ */
+typedef struct {
+    void       *dev_addr;       /* MAC's I/O or memory base address */
+    void       *bus_tag;        /* CMSMSearchAdapter() busTag value */
+} PHY_ADAPTER;
+
+
+/*
+ * MII_SET_BIT, MII_SET_MASK(), MII_CLR_BIT(), MII_CLR_MASK()
+ *
+ * Macros which set or clear one or more MII register bits.  In DOS
+ * mode, a few hundred bytes can be saved by calling MiiSetBits()
+ * and MiiClearBits() instead of the in-line MiiRead() and MiiWrite()
+ * calls, as these macros are used extensively.
+ */
+#if (DRV_OS == DOS)     /* ########################################## */
+
+void             MiiSetBits(MIIOBJ *phy, BYTE reg_addr, WORD bits);
+void             MiiClrBits(MIIOBJ *phy, BYTE reg_addr, WORD bits);
+#define MII_SET_MASK    MiiSetBits
+#define MII_CLR_MASK    MiiClrBits
+
+#else                   /* ########################################## */
+
+#define MII_SET_MASK(phy, regaddr, mask)        \
+    MiiWrite((phy),                             \
+             (BYTE) (regaddr),                  \
+             (WORD) (MiiRead((phy), (BYTE) (regaddr)) | (mask)))
+#define MII_CLR_MASK(phy, regaddr, mask)        \
+    MiiWrite((phy),                             \
+             (BYTE) (regaddr),                  \
+             (WORD) (MiiRead((phy), (BYTE) (regaddr)) & ~(mask)))
+#endif                  /* ########################################## */
+
+#define MII_SET_BIT     MII_SET_MASK
+#define MII_CLR_BIT     MII_CLR_MASK
+
+/*
+ * MiiRead(), MiiWrite()
+ *
+ * (MAC or repeater) User-supplied MII read and write functions.  The
+ * PHY's serial MII registers cannot be directly addressed via the
+ * (PCI) bus, as the PHY does not implement a 16-bit parallel register
+ * interface.  Instead, the PHY's serial Media Independent Interface
+ * (MII) must be accessed and accumulated into an external, general
+ * general purpose port, e.g., an MII port on a LAN adapter MAC or
+ * or a repeater controller device.  See the "mii.c" porting file for
+ * implementation-dependent MiiRead() and MiiWrite() example code.
+ */
+WORD     MiiRead(MIIOBJ *phy, BYTE reg_addr);
+void     MiiWrite(MIIOBJ *phy, BYTE reg_addr, WORD reg_value);
+void MiiWriteMask(MIIOBJ *phy, WORD reg_addr, WORD reg_value, WORD mask_value) ;
+
+/*
+ * MILLISECOND_WAIT() and MICROSECOND_WAIT() - hook for implementation
+ * and OS-dependent delay routines defined by the user.  See "mii.c"
+ * MiiMillisecondWait() and MiiMicrosecondWait() functions for
+ * OS-specific example code.  Two functions are declared to allow the
+ * designer to deploy different wait mechanisms.  Short, microsecond
+ * delays may be implemented via a non-blocking, busy-wait mechanism
+ * whereas longer, millisecond delays might relinquish the CPU via
+ * a process or thread sleep mechanism.  Alternately, the millisecond
+ * wait function might just call the microsecond wait function.
+ */
+#ifndef MICROSECOND_WAIT
+#define MICROSECOND_WAIT        MiiMicrosecondWait
+void     MiiMicrosecondWait(DWORD num_microseconds);
+#endif
+#ifndef MILLISECOND_WAIT
+#define MILLISECOND_WAIT        MiiMillisecondWait
+void     MiiMillisecondWait(DWORD num_milliseconds);
+#endif
+
+/*
+ * MiiIoRead() and MiiIoWrite() - export IO_READ() and IO_WRITE()
+ * routines for usage by related functions, 
+ * The <io_offset> is relative to the base address of the associated
+ * MAC or repeater controller device.  The <io_value> read or
+ * written is the 32-bit DWORD I/O register value.
+ */
+DWORD    MiiIoRead( DWORD mac_address, WORD io_offset);
+void     MiiIoWrite(DWORD mac_address, WORD io_offset, DWORD io_value);
+
+#endif /* _MII_H_ */
Files uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mii.o and uClinux-2.4.27-uc1/drivers/net/cnxt_emac/mii.o differ
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/osutil.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/osutil.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/osutil.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/osutil.h	2005-01-21 17:29:45.000000000 +0100
@@ -0,0 +1,133 @@
+/****************************************************************************
+*
+*	Name:			osutil.h
+*
+*	Description:	This header file define all the OS dependent services
+*					required by HPNALL and PHY
+*
+*	Copyright:		(c) 2000-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef OSUTIL_H_
+#define	OSUTIL_H_
+
+#if defined(NDIS_MINIPORT_DRIVER)
+
+#include <ndis.h>
+//---------------------------------------------------------------
+// NIDS Data Type
+//---------------------------------------------------------------
+
+// #define HANDLE		NDIS_HANDLE			// NDIS handle 
+#define STATUS		NDIS_STATUS
+#define SUCCESS		NT_SUCCESS		// ((NT_STATUS)(Status) >= 0)
+#define FAILURE		NDIS_STATUS_FAILURE
+
+#define H20_ALLOC_MEM(_pbuffer, _length) NdisAllocateMemoryWithTag( \
+    (void *)(_pbuffer), \
+    (_length), \
+    'TXNC')
+
+#define H20_FREE_MEM(_buffer,_length) NdisFreeMemory((_buffer), (_length), 0)
+#define H20_ZERO_MEM(_buffer,_length) NdisZeroMemory((_buffer), (_length))
+
+#ifndef  MOVE_MEMORY
+#define MOVE_MEMORY(Destination,Source,Length)   \
+                         \
+    NdisMoveMemory((PVOID)(Destination),     \
+               (PVOID)(Source),      \
+               (ULONG)(Length)       \
+              )              
+
+#endif
+
+#ifndef  ZERO_MEMORY
+#define ZERO_MEMORY(_buffer,_length) NdisZeroMemory((_buffer), (_length))
+#endif
+
+#elif defined(LINUX_DRIVER)
+#include <linux/slab.h>
+#include <asm/arch/bspcfg.h>
+#include <asm/arch/bsptypes.h>
+
+
+// PORT
+#define AcquireSpinLock( pLock, flags) spin_lock_irqsave( pLock, flags) 
+#define ReleaseSpinLock( pLock, flags) spin_unlock_irqrestore( pLock, flags )
+
+// #define HANDLE		NDIS_HANDLE			// NDIS handle 
+//typedef int STATUS;
+#define SUCCESS(Status)		((STATUS)(Status) != 0)
+#define FAILURE		0
+
+#define H20_ALLOC_MEM(_pbuffer, _length) *(_pbuffer) = (void *)kmalloc( \
+    (_length), \
+    GFP_KERNEL )
+
+#define H20_FREE_MEM(_buffer,_length) kfree( _buffer ) 
+#define H20_ZERO_MEM(_buffer,_length) memset((_buffer), 0, (_length))
+
+#ifndef  MOVE_MEMORY
+#define MOVE_MEMORY(Destination,Source,Length)   \
+                         \
+    memcpy((void *)(Destination),     \
+               (void *)(Source),      \
+               (ULONG)(Length)       \
+              )              \
+
+#endif
+
+#ifndef  ZERO_MEMORY
+#define ZERO_MEMORY(_buffer,_length) memset((_buffer), 0, (_length))
+#endif
+
+#elif defined(VXWORKS_DRIVER)
+#include "vxwinc.h"
+
+// #define HANDLE		NDIS_HANDLE			// NDIS handle 
+// typedef int STATUS ;
+#define SUCCESS(Status)		((STATUS)(Status) != 0)
+#define FAILURE		0
+
+#define H20_ALLOC_MEM(_pbuffer, _length) *(_pbuffer) = (void *)malloc((_length))
+
+#define H20_FREE_MEM(_buffer,_length) free( (_buffer) ) 
+#define H20_ZERO_MEM(_buffer,_length) memset((_buffer), 0, (_length))
+
+#ifndef  MOVE_MEMORY
+#define MOVE_MEMORY(Destination,Source,Length)   \
+                         \
+    memcpy((PVOID)(Destination),     \
+               (PVOID)(Source),      \
+               (ULONG)(Length)       \
+              )              \
+
+#endif
+
+#ifndef  ZERO_MEMORY
+#define ZERO_MEMORY(_buffer,_length) memset((_buffer), 0, (_length))
+#endif
+#endif	
+
+#endif
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phy.c uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phy.c
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phy.c	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phy.c	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,1770 @@
+/****************************************************************************
+*
+*	Name:			phy.c
+*
+*	Copyright:		(c) 1997-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   richarjc  $
+*  $Revision:   1.1  $
+*  $Modtime:   Mar 27 2003 13:14:40  $
+****************************************************************************/
+
+/*
+ *  Module Name: phy.c
+ *  Author: Joe Bonaker
+ *
+ *  Copyright © Conexant Systems 1999.
+ *  Copyright © Rockwell Semiconductor Systems 1997-1998.
+ *
+ *  Module Description: 100Base-T PHY driver module.  Consists of PHY
+ *  primitives supported by underlying "mii.c" MII and adapter/OS
+ *  services.  The primary services used are PhyInit() and a periodic
+ *  PhyCheck(), the latter of which can be periodically invoked and/or
+ *  dispatched upon PHY-to-MAC generated interrupt, depending on
+ *  adapter configuration.
+ *
+ *  Conditional Compilation Switches:
+ *
+ *     The following conditional compilation switches apply, and may
+ *     be overridden by the user at compile-time.
+ *
+ *     LINK_DOWN_HOP_COUNT - default 5.  When a multiple-device (i.e.,
+ *     both HomePNA and MII PHY devices populated) PHY experiences
+ *     link down for 5 consecutive calls of PhyCheck(), this routine
+ *     may switch or "hop" ports based on the following logic:
+ *
+ *     select current, "active" port;
+ *     if (++link_down_count > LINK_DOWN_HOP_COUNT) {
+ *         clear link_down_count;
+ *         if (PHY_HWOPTS_PORT_HOPPING) {
+ *             select the other, "inactive" port;
+ *         } else if (PHY_HWOPTS_MII_PORT_PRIORITY) {
+ *             select the MII port;
+ *         } else if (PHY_HWOPTS_HPNA_PORT_PRIORITY) {
+ *             select the HomePNA port;
+ *         } else {
+ *             // retain the current, "active" port;
+ *         }
+ *     }
+ *
+ *     The PHY_HWOPTS_PORT_HOPPING option gives devices which
+ *     cannot function when isolated a chance to achieve a media link.
+ *     Some examples are the 1st generation HomePNA PHY devices plus
+ *     National, Enable and Level One MII PHY devices.  The
+ *     PHY_HWOPTS_HPNA_PORT_PRIORITY option is a good idea when using
+ *     MII PHY devices which can function isolated, such as the TDK,
+ *     QSI, GEC-Plessey, and ICS devices.  This allows the PHY
+ *     Driver to emit MAC-level link test frames on the foreground
+ *     "active" HomePNA PHY to determine a soft link indication while
+ *     the background "inactive" MII PHY attempts to establish its
+ *     hardware link indication.  The PHY_HWOPTS_MII_PORT_PRIORITY
+ *     will effectively preclude HomePNA operation unless used in
+ *     conjunction with PHY_HWOPTS_PORT_HOPPING as a way of
+ *     establishing an initial MII port state, e.g., subsequent to
+ *     DriverReset() where the initial state will be the last known
+ *     link state.
+ *
+ *     PORTABILITY_CHECK - default #undefined.  This should only be
+ *     #defined when initially porting this module to a new compiler/OS
+ *     environment.  This switch enables some simple PhyInit() sizeof()
+ *     tests of BYTE, WORD and DWORD types to ensure proper compiler
+ *     sizing of register-based fields.  Typically, most compilers
+ *     will generate "Unreachable Code" warnings which actually
+ *     indicates proper sizing.  Relaxed warnings or older compilers
+ *     may warrant a run-time check, for which the PhyInit() function
+ *     will return a PHY_STATUS_PORTABILITY_ERROR result.
+ **********************************************************************/
+
+#define PHYOBJECT_MODULE	// this is one of the PHY object module
+#define PHY_MODULE
+
+#include "osutil.h"
+
+#include "phyobj.h"
+#include "phyregs.h"
+
+#ifdef JEDIPHY	// Bright
+#include "ramse.h"
+#include "jediphy.h"
+#endif
+
+
+#define PHYID_KENDIN_KS8737(p)  (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x00221720L)
+
+/* For Kendin KS8993, KS8995 and Marvell 88E6050 which do not support MDIO interface
+ required for MII management channel. */
+#define SUPPORT_NO_MDIO_PHY 1
+
+#ifdef SUPPORT_NO_MDIO_PHY
+#define	NO_MDIO_PHY				0xA0A05050
+#define PHYID_NO_MDIO(p)		(((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == NO_MDIO_PHY)
+#else
+#define PHYID_NO_MDIO(p)		(FALSE)
+#endif
+
+#ifndef LINK_DOWN_HOP_COUNT
+#define LINK_DOWN_HOP_COUNT     5       /* 10 seconds @ 0.5 Hz */
+#endif
+
+PHY_STATUS 	 PhyReset( MIIOBJ *pMiiObj ) ;	// internal interface for jediphy
+
+static PHY_STATUS   PhyDisable(PHY *phy, PHY_PORT port);
+static PHY_STATUS   PhyEnable(PHY  *phy, PHY_PORT port);
+static DWORD        PhyConnectGet(PHY *phy);
+PHY_STATUS   PhyConnectSet(PHY *phy, DWORD connect);
+static PHY_STATUS   PhyConfigurePort(PHY *phy, DWORD link_state);
+static DWORD PhyCapabilityGet(PHY *phy);
+static DWORD PhyLastLinkUp(PHY *phy) ;
+
+#if 0
+/*
+ * PHY test and diagnostic support functions
+ *
+ * PhyLoopback() - Start/stop one of four modes of PHY loopback
+ * PhyColTest()  - Start/stop collision test via register.bit 0.7
+ * PhyIdGet()    - Read PHY Identifier registers 2-3
+ */
+static PHY_STATUS   PhyLoopback(PHY *phy, PHY_LOOPBACK mode);
+static PHY_STATUS   PhyColTest(PHY *phy, BOOLEAN enable);
+#endif
+
+
+/* Local (static) function prototypes */
+static void     ETHParsePhyHwConfig(PHY *phy);
+static void     ETHSetPhyHwOptions(PHY *phy);
+
+PHY * PhyAllocateMemory( void)
+{
+	PHY *pPhy ;
+
+	if( !SUCCESS(H20_ALLOC_MEM( &pPhy, sizeof(PHY) )) )
+		return NULL ;	// allocate fail
+	H20_ZERO_MEM( pPhy, sizeof(PHY) ) ;
+	return (void *)pPhy ;
+}
+
+void PhyFreeMemory( PHY *pPhy )
+{
+	H20_FREE_MEM( pPhy, sizeof(PHY) ) ;
+}
+
+static void Set_Active_Port( PHY *phy, PHY_PORT port )
+{
+	if( port & PHY_PORT_HPNA_DEVICES)
+	{
+		phy->active_port = phy->hpna_port ;
+		phy->inactive_port = phy->mii_port ;
+		phy->pActive_miiphy = &phy->mii_phy[JEDI_MII_PHY];
+#ifdef NON_BYPASSMODE	// test
+		phy->frame_ctl_length = 0 ;
+#else
+		phy->frame_ctl_length = 4 ;
+#endif
+	}
+	else
+	{
+		phy->inactive_port = phy->hpna_port ;
+		phy->active_port = phy->mii_port ;
+		phy->pActive_miiphy = &phy->mii_phy[ETH_MII_PHY];
+		phy->frame_ctl_length = 0 ;
+	}
+}
+
+/* 
+ * Local an_lookup[] table maps BMSR and ANAR hardware to internal,
+ * soft PHY_LINK_* (or associated PHY_CONN_* alias) bit assignments.
+ * The table is ordered in decreasing Auto-Negotiation priority per
+ * IEEE 802.3u and 802.3y, and is terminated by a null (zero) record.
+ * Searches may be keyed on any of the fields, however, <phy_link>
+ * keys should mask out non-PHY_LINK_TECHNOLOGY bits, otherwise the
+ * search may fail to achieve a match.
+ *
+ * This table may have to be extended to include an SNMP MIB field,
+ * which contains yet another enumeration of the PHY technology types.
+ */
+typedef struct {
+    WORD            bmsr;       /* BMSR HW capability bit */
+    WORD            anar;       /* ANAR/ANLPAR HW bit */
+    DWORD           phy_link;   /* internal PHY_LINK_* state */
+}                AN_LOOKUP;
+static AN_LOOKUP an_lookup[] = {
+    {BMSR_100BASE_T2FD, ANAR_100BASE_T2FD,
+     PHY_LINK_100BASE_T2FD | PHY_LINK_100 | PHY_LINK_FDX},
+
+    {BMSR_100BASE_TXFD, ANAR_100BASE_TXFD,
+     PHY_LINK_100BASE_TXFD | PHY_LINK_100 | PHY_LINK_FDX},
+
+    {BMSR_100BASE_T2,   ANAR_100BASE_T2,
+     PHY_LINK_100BASE_T2   | PHY_LINK_100},
+
+    {BMSR_100BASE_T4,   ANAR_100BASE_T4,
+     PHY_LINK_100BASE_T4   | PHY_LINK_100},
+
+    {BMSR_100BASE_TX,   ANAR_100BASE_TX,
+     PHY_LINK_100BASE_TX   | PHY_LINK_100},
+
+    {BMSR_10BASE_TFD,   ANAR_10BASE_TFD,
+     PHY_LINK_10BASE_TFD   | PHY_LINK_10  | PHY_LINK_FDX},
+
+    {BMSR_10BASE_T,     ANAR_10BASE_T,
+     PHY_LINK_10BASE_T     | PHY_LINK_10},
+
+    /* null-terminating record */
+    {0, 0, 0}
+};
+
+
+static PHY_STATUS ETHPhy_SetUp( PHY *phy )
+{
+	if(phy->hw_options & PHY_HWOPTS_NO_ETH_SEARCH)
+		return PHY_STATUS_OK ;
+
+	if (!(phy->hw_options & PHY_HWOPTS_DONT_SWRESET)) 
+		if( PhyReset( &phy->mii_phy[ETH_MII_PHY]) != PHY_STATUS_OK)
+			return PHY_STATUS_RESET_ERROR;
+
+	/* Terminate upon successful reset(s) or excess restarts */
+	phy->devices |= PHY_PORT_MII_DEVICE;
+	phy->mii_port = PHY_PORT_MII;
+
+	ETHParsePhyHwConfig( phy );
+	ETHSetPhyHwOptions( phy );
+
+	MII_CLR_MASK( &phy->mii_phy[ETH_MII_PHY], MII_BMCR, (BMCR_RESTART_AUTONEG |
+		BMCR_POWERDOWN  |
+		BMCR_LOOPBACK   |
+		BMCR_COLLISION_TEST) );
+
+	return PHY_STATUS_OK ;
+}
+
+#define MAX_PHY_NUM	2		// assume at most 1 ETH and 1 JEDI
+#define SINGLE_PHY	1			// Bright, 4/27/01, only one PHY on one EMAC (MII BUS)
+// currently this is ture
+
+#if HOMEPLUGPHY
+
+// TBD , need improvement	
+#define HOMEPLUGID 0xffffffff
+#endif
+
+PHY_STATUS
+MiiDetectPorts( PHY   *phy,             /* allocated PHY data structure space */
+        BYTE   phy_addr ) 
+{
+	BYTE        last_addr;
+	WORD        bmsr;
+	int	num_phy = 0 ;
+	int	num_of_eth_phy = 0 ;
+	DWORD  hw_options = phy->hw_options ;
+	MIIOBJ TmpMii ;
+
+    /*
+     * MII search, reset and optionally disable (isolate) PHY.  The
+     * search logic simply reads the BMSR, for which a responding PHY
+     * should return a value that is non-zero and not all one's.
+     * Otherwise, assume there isn't an MII-capable PHY at <phy_addr>.
+     * The ANAR probe is repeated after post-HW and/or software reset to
+     * guard against the PHY losing its identity (address) upon reset.
+     *
+     * If the caller specified PHY_ADDR_ANY or PHY_ADDR_NEXT(phy#), 
+     * we'll walk the list of valid PHY addresses until the first/next
+     * responding PHY is detected.  Some PHY devices have side-effects
+     * associated with PHY_ADDR_MIN (zero) -- this address is often
+     * (erroneously) treated as a broadcast by some PHYs, others
+     * won't display vendor-specific registers when reading from
+     * address-0, etc.  As such, we'll initiate a PHY_ADDR_ANY search
+     * from (PHY_ADDR_MIN + 1) on up to PHY_ADDR_MAX, concluding the
+     * search using PHY_ADDR_MIN only if no other addresses are found.
+     * This can be overriden by the PHY_HWOPTS_MII_SEARCH_0 <hw_options>
+     * switch, which initiates a search from address 0..31, rather
+     * than the default 1..31 followed by 0.
+     */
+
+#ifdef P51
+	// the driver can run on ELAN or HLAN under Yukon or Athens
+	if(hw_options & PHY_HWOPTS_P51_HLAN) 
+		TmpMii.P51_HLAN = TRUE ;
+	else
+		TmpMii.P51_HLAN = FALSE ;
+#endif
+	TmpMii.adapter = phy->mii_phy[JEDI_MII_PHY].adapter ;
+	TmpMii.preamble_suppression = FALSE ;
+	phy->pActive_miiphy = &phy->mii_phy[JEDI_MII_PHY];	// set default
+
+	if (phy_addr == PHY_ADDR_ANY) 
+	{
+		last_addr = PHY_ADDR_MAX;
+		phy_addr  = PHY_ADDR_MIN + 1;    /* start search at address-1 */
+		if (hw_options & PHY_HWOPTS_MII_SEARCH_0) 
+			--phy_addr;                 /* start search at address-0 */
+	} 
+	else if( phy_addr <= PHY_ADDR_MAX ) 
+	{
+		last_addr = phy_addr;          /* single MII search, below */
+	} 
+	else 
+	{
+		phy_addr = -phy_addr;         /* partial? MII search per */
+		last_addr  = PHY_ADDR_MAX;      /* phy.h PHY_ADDR_NEXT() */
+	}
+
+Search_Mii :
+	while (phy_addr <= last_addr) 
+	{
+		TmpMii.mii_addr = phy_addr++;
+		if (((bmsr = MiiRead(&TmpMii, MII_BMSR)) != 0x0000) &&
+			(bmsr != 0xFFFF)) 
+		{	/* Assume PHY found, so nominally perform post-SW reset */
+			num_phy++ ;
+
+			TmpMii.mii_id = (((DWORD) MiiRead(&TmpMii, MII_PHYIDR1) << 16) |
+			((DWORD) MiiRead(&TmpMii, MII_PHYIDR2)));
+
+			printk("PHY #%x = %lx\n", phy_addr,TmpMii.mii_id );
+
+#ifdef JEDIPHY	// Bright
+			if( JediPhy(TmpMii.mii_id) )
+			{	// this is Jedi Phy (HPNA2)
+				phy->mii_phy[JEDI_MII_PHY] = TmpMii ;
+				JediPhy_SetUp( phy) ;
+#ifndef SINGLE_PHY
+				if(hw_options & PHY_HWOPTS_NO_ETH_SEARCH)
+#endif
+					return PHY_STATUS_OK ;
+			}
+			else
+#endif
+			{	// assume this is Ether Phy
+				if( num_of_eth_phy == 0 )
+				{
+					phy->mii_phy[ETH_MII_PHY] = TmpMii ;
+					phy->pActive_miiphy = &phy->mii_phy[ETH_MII_PHY];
+					ETHPhy_SetUp( phy ) ;	
+
+#ifndef SINGLE_PHY
+					if(hw_options & PHY_HWOPTS_NO_HPNA_SEARCH)
+#endif
+						return PHY_STATUS_OK ;
+				}
+				num_of_eth_phy++ ;
+			}
+		}
+		if( num_phy == MAX_PHY_NUM )
+			return PHY_STATUS_OK ;
+	}
+
+	/* Go back to addr-0 once full MII search 1..31 fails */
+	if ((phy_addr == (PHY_ADDR_MAX+1)) &&
+		!(hw_options & PHY_HWOPTS_MII_SEARCH_0)) 
+	{
+		phy_addr = last_addr = PHY_ADDR_MIN ;
+		goto Search_Mii ;
+	}
+	
+	if( num_phy != 0 )
+		return PHY_STATUS_OK ;
+	else
+		return PHY_STATUS_NOT_FOUND ;
+}
+/***********************************************************************
+ * PhyInit() - Initialize PHY and attach to media (w/optional override)
+		PhyInit do not	perform hardware reset of the PHYs. 
+		Hardware reset is MAC operation, should be called before PhyInit(if required).
+ **********************************************************************/
+PHY_STATUS
+PhyInit(DWORD  adapter,         /* MAC device I/O base address */
+        PHY   *phy,             /* allocated PHY data structure space */
+        DWORD  connect,         /* PhyConnectSet() directive */
+        DWORD  hw_options,      /* zero or more PHY_HWOPTS_* values */
+        void  *LinkLayerAdapter )	// for HPNA 2.0 LL compliance
+{
+    PHY_STATUS  status;
+
+#ifdef PORTABILITY_CHECK        /* ################################## */
+    /* Not a bad idea during initial PHY driver porting effort */
+    if ((sizeof(BYTE) != 1) ||
+            (sizeof(WORD) != 2) || (sizeof(DWORD) != 4)) {
+        return (PHY_STATUS_PORTABILITY_ERROR);
+    }
+#endif  /* PORTABILITY_CHECK */ /* ################################## */
+
+
+	if( IS_PHY_INITIALIZED(phy) )
+	{	// not first time PHY Init
+		if( !(PhyCapabilityGet(phy) & PHY_LINK_MII_TECHNOLOGY ) )
+		{
+			/* No MII PHY, so don't waste time searching henceforth */
+			hw_options |= PHY_HWOPTS_NO_ETH_SEARCH;
+		}
+		else
+		{
+			if( phy->mii_phy[ETH_MII_PHY].mii_addr == PHY_ADDR_0) 
+			{
+					/*
+					 * Reduce subsequent PhyInit() MII search times by
+					 * starting at MII address zero.  The default sequence
+					 * is 1..31 then zero due to some funky side-effects
+					 * on some MII PHY devices.  This option re-orders the
+					 * search sequence to 0..31, thereby reducing
+					 * subsequent PhyInit() times by a few hundred milliseconds!
+					 */
+				hw_options |= PHY_HWOPTS_MII_SEARCH_0;
+			}
+		}
+
+		if (!(PhyCapabilityGet(phy) & PHY_LINK_HPNA_TECHNOLOGY)) 
+			/* No HomePNA PHY, so don't waste time searching henceforth */
+			hw_options |= PHY_HWOPTS_NO_HPNA_SEARCH;
+		else
+		{
+			if( phy->mii_phy[JEDI_MII_PHY].mii_addr == PHY_ADDR_0) 
+			{
+					/*
+					 * Reduce subsequent PhyInit() MII search times by
+					 * starting at MII address zero.  The default sequence
+					 * is 1..31 then zero due to some funky side-effects
+					 * on some MII PHY devices.  This option re-orders the
+					 * search sequence to 0..31, thereby reducing
+					 * subsequent PhyInit() times by a few hundred milliseconds!
+					 */
+				hw_options |= PHY_HWOPTS_MII_SEARCH_0;
+			}
+		}
+
+		if (PhyLastLinkUp(phy) & PHY_LINK_MII_TECHNOLOGY)
+		{
+			/* Last known link was MII, so pre-hop default to MII port */
+			hw_options |= (PHY_HWOPTS_MII_PORT_PRIORITY |
+						   PHY_HWOPTS_PORT_HOPPING);
+		} 
+		else if (PhyLastLinkUp(phy) & PHY_LINK_HPNA_TECHNOLOGY) 
+		{
+			/* Last known link was HLAN, so don't pre-hop default to MII port */
+			hw_options &= ~PHY_HWOPTS_MII_PORT_PRIORITY;
+		}
+	} 
+
+
+    /*
+     * Set-up <phy> data and perform optional pre-MII search HW reset,
+     * which may be required only in the case of unusual adapter design.
+     * This case has been included to satisfy the RSS11606 test adapter
+     * board, wherein a MAC general purpose I/O (GPIO) pin holds the PHY
+     * in hardware reset.  Unless programmed to release the PHY prior to
+     * searching the MII bus, the subsequent MII search will fail, as
+     * the PHY obviously cannot respond when held in hardware reset.
+     *
+     * Bug warning:  unless there's a crafty HW design, this could
+     * cause unexpected failures in a multiple-PHY environment if
+     * PHY_ADDR_ANY or PHY_ADDR_NEXT() is specified to search for a
+     * responding PHY.  For now, we'll simply do as we're told.  This
+     * should probably be moved into the search loop below, and rely
+     * upon a PHY_HWRESET() routine that parses the phy_addr argument...
+     */
+#ifdef JEDIPHY	// Bright
+	H20_ZERO_MEM( phy, sizeof(PHY)-sizeof(OSFILEOBJ) ) ;
+#else
+	H20_ZERO_MEM( phy, sizeof(PHY) ) ;
+#endif
+
+//    if (hw_options & PHY_HWOPTS_READ_ONLY) {
+//        phy->read_only = TRUE;
+//    }
+    phy->mii_phy[JEDI_MII_PHY].adapter = adapter ;
+    phy->mii_phy[ETH_MII_PHY].adapter = adapter ;
+
+    phy->LinkLayerAdapter = LinkLayerAdapter ;
+
+
+//    if ( (hw_options & PHY_HWOPTS_HWRESET_MASK) &&
+//		 (hw_options & PHY_HWOPTS_GP0_SPI_DOUT) ) 
+//        PHY_HWRESET( adapter );
+
+	phy->hw_options = hw_options;
+
+	status = MiiDetectPorts( phy, PHY_ADDR_ANY) ;
+
+	if( status != PHY_STATUS_OK )
+	{
+#ifdef SUPPORT_NO_MDIO_PHY
+		// TBD : not tested yet
+		phy->mii_phy[ETH_MII_PHY].mii_id = NO_MDIO_PHY;
+        phy->initialized = PHY_INIT_CODE;
+		phy->media.capability = PHY_LINK_100BASE_TXFD |
+								PHY_LINK_100BASE_T2FD | 
+								PHY_LINK_100 | 
+								PHY_LINK_FDX;
+		phy->media.connect = PHY_CONN_MII_TECHNOLOGY;
+		phy->devices |= PHY_PORT_MII_DEVICE;
+		phy->mii_port = PHY_PORT_MII;
+
+		Set_Active_Port( phy, phy->mii_port ) ;		
+	    status = PHY_STATUS_OK;
+#endif
+		return status ;
+	}
+
+#if HOMEPLUGPHY
+	if( phy->pActive_miiphy->mii_id == HOMEPLUGID )
+	{
+		connect = PHY_CONN_100BASE_TX ;		// HomePlug as 100 half
+	}	
+#endif
+
+	if( hw_options & PHY_HWOPTS_ISOLATE )
+		PhyDisable(phy, phy->devices);
+
+	if (phy->mii_port == PHY_PORT_NONE) 
+	{
+		/* Coerce soft non-MII Auto-Negotiation capability */
+		phy->media.capability |= PHY_LINK_AUTONEG;
+		phy->media.connect    |= PHY_CONN_AUTONEG;
+	}
+
+	if ((status = PhyConnectSet(phy, connect)) == PHY_STATUS_OK) 
+	{
+		phy->initialized = PHY_INIT_CODE;
+		phy->hw_options &= ~PHY_HWOPTS_ISOLATE;
+	}
+	return (status);
+}
+
+/***********************************************************************
+ * ParsePhyHwConfig() - Process PHY HW configuration options
+ **********************************************************************/
+static void
+ETHParsePhyHwConfig(PHY *phy)
+{
+    WORD        bmcr;
+    WORD        bmsr;
+    WORD        anar;
+    DWORD       mode;
+    AN_LOOKUP  *lookup;
+
+// no need
+//    phy->media.capability = 0;
+//    phy->media.connect = 0;
+
+    /* Determine media capabilities based on BMSR */
+    bmsr = MiiRead( &phy->mii_phy[ETH_MII_PHY], MII_BMSR);
+    if (bmsr & BMSR_AUTONEG_ABILITY) {
+        phy->media.capability |= PHY_LINK_AUTONEG;
+    }
+    for (lookup = &an_lookup[0]; lookup->bmsr != 0; lookup++) {
+        if (bmsr & lookup->bmsr)
+        {
+            phy->media.capability |= (lookup->phy_link & PHY_LINK_TECHNOLOGY);
+        }
+    }
+
+    /*
+     * Determine adapter (NIC) unique HW configuration strap
+     * settings based on BMCR (and ANAR if Auto-Negotiation is enabled).
+     */
+    bmcr = MiiRead( &phy->mii_phy[ETH_MII_PHY], MII_BMCR);
+    if (bmcr & BMCR_AUTONEG_ENABLE) {
+        /* Read default Auto-Negotiation configuration per ANAR */
+        phy->media.connect |= PHY_CONN_AUTONEG;
+        anar = MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_ANAR);
+        for (lookup = &an_lookup[0]; lookup->anar != 0; lookup++) {
+            if (anar & lookup->anar) {
+                phy->media.connect |=
+                    (lookup->phy_link & PHY_LINK_TECHNOLOGY);
+            }
+        }
+    } else {
+        /* Infer default forced mode configuration per BMCR */
+        mode = 0;
+        if (bmcr & BMCR_SPEED_100) {
+            mode |= PHY_LINK_100;
+        } else {
+            mode |= PHY_LINK_10;
+        }
+        if (bmcr & BMCR_DUPLEX_MODE) {
+            mode |= PHY_LINK_FDX;
+        }
+        for (lookup = &an_lookup[0]; lookup->phy_link != 0; lookup++) {
+            if ((phy->media.capability & lookup->phy_link) &&
+                    (mode == (lookup->phy_link &
+                              (PHY_LINK_SPEED | PHY_LINK_FDX)))) {
+                phy->media.connect |= lookup->phy_link;
+                break;
+            }
+        }
+    }
+
+    /* Check for isolated (tri-stated) MII PHY */
+    if (bmcr & BMCR_ISOLATE) {
+        phy->mii_isolated = TRUE;
+    }
+
+    /* 
+     * Finally, set <preamble_suppression> if suported by the device.
+     * This can subsequently be overriden by SetPhyHwOptions()
+     * via the PHY_HWOPTS_MII_PREAMBLE directive, which may be used
+     * in a multi-PHY environment or in case a device's BMSR register
+     * falsely indicates preamble suppression capability.
+     */
+    if (bmsr & BMSR_PREAMBLE_SUPPRESS) {
+        phy->mii_phy[ETH_MII_PHY].preamble_suppression = TRUE;
+    }
+}
+
+/***********************************************************************
+ * SetPhyHwOptions() - Configure non-default MII PHY hardware features
+ **********************************************************************/
+// ETH only
+static void
+ETHSetPhyHwOptions(PHY *phy)
+{
+    DWORD hw_opts = phy->hw_options ;
+
+    /* Force MDIO preamble, i.e., explicitly disable suppression */
+    if (hw_opts & PHY_HWOPTS_MII_PREAMBLE) {
+        phy->mii_phy[ETH_MII_PHY].preamble_suppression = FALSE;
+    }
+
+    if (PHYID_NSC_DP83840(phy)) {
+        /* Force node or repeater mode, which affects CRS signal */
+        if (hw_opts & PHY_HWOPTS_REPEATER) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_PCR, PCR_REPEATER_MODE);
+        } else {
+            MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_PCR, PCR_REPEATER_MODE);
+        }
+
+        /* Disable CLK25 output line, reducing noise when unused */
+        if (hw_opts & PHY_HWOPTS_CK25DIS) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_PCR, PCR_CLK25DIS);
+        }
+
+        /* Bypass portions of the transmitter and receiver coding */
+        if (hw_opts & PHY_HWOPTS_TX_BPALIGN) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_LBREMR, LBREMR_BP_ALIGN);
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BPSCR) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_LBREMR, LBREMR_BP_SCR);
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BP4B5B) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_LBREMR, LBREMR_BP_4B5B);
+        }
+
+        /* Assert FDX CRS during transmit, not receive (default) */
+        if (hw_opts & PHY_HWOPTS_FDX_CRS) {
+            if (PHYID_REV(phy) >= 1) {
+                /* New NSC DP83840 Rev A (revision code 1) feature */
+                MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_LBREMR, LBREMR_ALT_CRS);
+            }
+        }
+
+    } else if (PHYID_QSI_6612(phy)) {
+        /* Bypass portions of the transmitter and receiver coding */
+        if (hw_opts & PHY_HWOPTS_TX_BPALIGN) {
+            /* No QSI support for bypassing the alignment function */
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BPSCR) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R31, QSI_R31_SCR_DISABLE);
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BP4B5B) {
+            MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R31, QSI_R31_4B5BEN);
+        }
+
+    } else if (PHYID_LXT_970(phy)) {
+        /* Bypass portions of the transmitter and receiver coding */
+        if (hw_opts & PHY_HWOPTS_TX_BPALIGN) {
+            /* No Level One support for bypassing alignment function */
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BPSCR) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R19, LXT_R19_SCR_BYPASS);
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BP4B5B) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R19, LXT_R19_4B5B_BYPASS);
+        }
+
+    } else if (PHYID_GEC_NWK936(phy)) {
+        /* Bypass portions of the transmitter and receiver coding */
+        if (hw_opts & PHY_HWOPTS_TX_BPALIGN) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R24, GEC_R24_BPALIGN);
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BPSCR) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R24, GEC_R24_BPSCR);
+        }
+        if (hw_opts & PHY_HWOPTS_TX_BP4B5B) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R24, GEC_R24_BPENC);
+        }
+
+        /* Assert FDX CRS during transmit, not receive (default) */
+        if (!(hw_opts & PHY_HWOPTS_FDX_CRS)) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], 24, 0x0800);
+        }
+
+    } else if (PHYID_TDK_2120(phy)) {
+        /* Force node or repeater mode, which affects CRS signal */
+        if (hw_opts & PHY_HWOPTS_REPEATER) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_RPTR);
+        } else {
+            MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_RPTR);
+        }
+
+        /*
+         * Disable CLK25 output line, reducing noise when unused.  Due
+         * to Auto-Negotiation side-effects, the TDK RXCC option is
+         * now performed by PhyCheck() on link up and down transitions.
+         *
+         * if (hw_opts & PHY_HWOPTS_CK25DIS) {
+         *     MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_RXCC);
+         * }
+         */
+
+        /* Bypass portions of the transmitter and receiver coding */
+        if (hw_opts & (PHY_HWOPTS_TX_BPSCR | PHY_HWOPTS_TX_BP4B5B)) {
+            /* TDK PHY doesn't have separate PCS, scrambler bypass */
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_PCSBP);
+        }
+    }
+}
+
+/***********************************************************************
+ * PhyReset() - Issue PHY software reset, waiting 500 mSec to complete
+ **********************************************************************/
+PHY_STATUS 	 PhyReset( MIIOBJ *pMiiObj ) 
+{
+    PHY_STATUS  phy_status = PHY_STATUS_RESET_ERROR;
+    int         n;
+
+    /*
+     * Set BMCR Reset bit, expected to auto-clear in 500 milliseconds
+     * Some devices may require a 500-microsecond guard against serial
+     * MII access, so we'll delay after setting the reset bit and after
+     * detecting auto-clear, just to be safe.
+     */
+    MII_SET_BIT(pMiiObj, MII_BMCR, BMCR_RESET);
+    MICROSECOND_WAIT(500);
+    for (n = 0; n < 50; n++) {
+        if (!(MiiRead( pMiiObj, MII_BMCR) & BMCR_RESET)) {
+            phy_status = PHY_STATUS_OK;
+            break;
+        }
+        MILLISECOND_WAIT(10);
+    }
+    MICROSECOND_WAIT(500);
+    return (phy_status);
+}
+
+
+/***********************************************************************
+ * PhyDisable() - Disable PHY by asserting BMCR isolate command
+ **********************************************************************/
+PHY_STATUS
+PhyDisable(PHY *phy, PHY_PORT port)
+{
+
+    /* (1) Validate the selected port(s) */
+    port &= phy->devices;
+
+    /* (2) MII PMD isolation (TP tri-state) */
+    if (port & PHY_PORT_MII_PMD) {
+        if (PHYID_QSI_6612(phy)) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R31, QSI_R31_TX_ISOLATE);
+        } else if (PHYID_LXT_970(phy)) {
+            MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R19, LXT_R19_TX_DISCONNECT);
+        }
+    }
+
+    /* (3) MII data isolation (tri-state) */
+    if ((port & PHY_PORT_MII) && !phy->mii_isolated) {
+        phy->mii_isolated = TRUE;
+        MII_SET_BIT( &phy->mii_phy[ETH_MII_PHY], MII_BMCR, BMCR_ISOLATE);
+    }
+
+#ifdef JEDIPHY	// Bright
+	 JediPhyDisable( phy, port) ;
+#endif
+
+    return (PHY_STATUS_OK);
+}
+
+/***********************************************************************
+ * PhyEnable() - (Re)Enable PHY by deasserting BMCR isolate command
+ **********************************************************************/
+PHY_STATUS
+PhyEnable(PHY *phy, PHY_PORT port)
+{
+    WORD        bmcr;
+
+    /* (1) Validate the selected port(s) */
+    port &= phy->devices;
+
+    /* (2) MII PMD de-isolation (TP non tri-state) */
+    if (port & PHY_PORT_MII_PMD) {
+        if (PHYID_QSI_6612(phy)) {
+            MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R31, QSI_R31_TX_ISOLATE);
+        } else if (PHYID_LXT_970(phy)) {
+            MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R19, LXT_R19_TX_DISCONNECT);
+        }
+    }
+
+    /* (3) MII data de-isolation (no longer tri-stated) */
+    if ((port & PHY_PORT_MII) && phy->mii_isolated) {
+        phy->mii_isolated = FALSE;
+			// Bright fixed 7/18/02
+        bmcr = MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_BMCR) & 
+			~(BMCR_ISOLATE |BMCR_POWERDOWN) ;
+        if (phy->media.connect & PHY_CONN_AUTONEG) {
+            bmcr |= (BMCR_AUTONEG_ENABLE | BMCR_RESTART_AUTONEG);
+            /*
+             * Side-effect:  some PHYs (well, at least one vendor's)
+             * require the BMCR_AUTONEG_ENABLE bit (reg 0.12) be cleared
+             * then set in the case where the device is coming up out
+             * of reset or isolated state, otherwise, Auto-Negotiation
+             * won't be initiated.  We'll temporarily clear A-N bits,
+             * which will then be immediately be set, below.
+             */
+            if (PHYID_NSC_DP83840(phy) ||
+                    (phy->hw_options & PHY_HWOPTS_ACTIVE_AN_RESTART)) {
+                MiiWrite(&phy->mii_phy[ETH_MII_PHY], MII_BMCR,
+                         (WORD) (bmcr & ~(BMCR_AUTONEG_ENABLE |
+                                          BMCR_RESTART_AUTONEG)));
+            }
+        }
+        MiiWrite(&phy->mii_phy[ETH_MII_PHY], MII_BMCR, bmcr);
+    }
+
+#ifdef JEDIPHY	// Bright
+	JediPhyEnable(phy, port) ;
+#endif
+    return (PHY_STATUS_OK);
+}
+
+/***********************************************************************
+ * PhyConnectGet() - Get PHY connect setting(s)
+ **********************************************************************/
+DWORD
+PhyConnectGet(PHY *phy)
+{
+    return (phy->media.connect);
+}
+
+/***********************************************************************
+ * PhyConnectSet() - Execute PHY connect settings
+ **********************************************************************/
+PHY_STATUS
+PhyConnectSet(PHY *phy, DWORD connect)
+{
+    WORD        bmcr;
+    WORD        anar;
+    AN_LOOKUP  *lookup;
+
+    /* (1) Establish/adjust the <connect> directive */
+    switch (connect & (PHY_CONN_AUTONEG | PHY_CONN_TECHNOLOGY)) {
+        default:
+            /* Use non-zero <connect> directive as-is */
+            break;
+
+        case PHY_CONN_CURRENT:
+            /* Zero: use HW default or previous setting */
+            connect = phy->media.connect; break;
+
+        case PHY_CONN_AUTONEG:
+            /* A-N bit only: Auto-Negotiate HW default or previous */
+            connect = phy->media.connect | PHY_CONN_AUTONEG; break;
+    }
+
+    if (phy->hw_options & PHY_HWOPTS_STRICT_PARM_CHECKING) {
+        /* Strict checking:  A-N and full media agreement required */
+        if ((connect & (PHY_CONN_AUTONEG | PHY_CONN_TECHNOLOGY)) !=
+                (connect & phy->media.capability)) {
+            return (PHY_STATUS_UNSUPPORTED_MEDIA);
+        }
+
+    } else {
+        /* Relaxed checking:  A-N and partial media agreement needed */
+        if (((connect & PHY_CONN_AUTONEG)
+             && !(phy->media.capability & PHY_CONN_AUTONEG)) ||
+            ((connect & PHY_CONN_TECHNOLOGY) &&
+             !(connect & phy->media.capability &
+               PHY_CONN_TECHNOLOGY))) {
+            return (PHY_STATUS_UNSUPPORTED_MEDIA);
+        }
+        /* Truth in advertising:  shave unsupported media settings */
+        connect &= (phy->media.capability | ~PHY_CONN_TECHNOLOGY);
+    }
+
+#ifdef JEDIPHY	// Bright
+    /* (2) HomePNA device: force highest-priority setting */
+	connect = JediPhyConnectSet(phy, connect) ;
+#endif
+
+    /* (3) MII device: Auto-Negotiate or force highest capability */
+    if (connect & PHY_CONN_MII_TECHNOLOGY) {
+
+        /* Read BMCR, momentarily clearing speed and duplex bits */
+        bmcr = MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_BMCR) &
+            ~(BMCR_SPEED_100 | BMCR_DUPLEX_MODE);
+
+        if (connect & PHY_CONN_AUTONEG) {
+            /*
+             * Auto-Negotiation connection mode.  Walk the entire
+             * an_lookup[] table, latching all matching <phy_link> types
+             * into the PHY's Auto-Negotiation Advertisement Register
+             * (ANAR).  Set ANAR and BMCR when the table is exhausted.
+             */
+            bmcr |= (BMCR_AUTONEG_ENABLE | BMCR_RESTART_AUTONEG);
+            anar = MiiRead( &phy->mii_phy[ETH_MII_PHY], MII_ANAR) &
+                (ANAR_NEXT_PAGE | /* ANAR_ACKNOWLEDGE | */
+                 ANAR_PROTOCOL_SELECTOR);
+            if (connect & PHY_CONN_AUTONEG_REMOTE_FAULT)
+                anar |= ANAR_REMOTE_FAULT;
+            if (connect & PHY_CONN_AUTONEG_FDX_PAUSE)
+                anar |= ANAR_FDX_PAUSE;
+            for (lookup = &an_lookup[0]; lookup->phy_link != 0; lookup++) {
+                if (connect & lookup->phy_link & PHY_CONN_TECHNOLOGY)
+                    anar |= lookup->anar;
+            }
+            MiiWrite( &phy->mii_phy[ETH_MII_PHY], MII_ANAR, anar);
+            phy->anar = anar;       /* cached for PhyCheck() */
+            /*
+             * Side-effect:  some PHYs (well, at least one vendor's)
+             * require the BMCR_AUTONEG_ENABLE bit (reg 0.12) be cleared
+             * and then set in the case where the device is coming up out
+             * of reset or isolated state, otherwise, Auto-Negotiation
+             * won't be initiated.  We'll temporarily clear the A-N bits,
+             * which will then be immediately be set, below.
+             */
+            MiiWrite( &phy->mii_phy[ETH_MII_PHY], MII_BMCR,
+                     (WORD) (bmcr & ~(BMCR_AUTONEG_ENABLE |
+                                      BMCR_RESTART_AUTONEG)));
+
+        } else {
+            /*
+             * Forced connect mode.  Walk the an_lookup[] table until a
+             * matching <phy_link> type is found.  Set BMCR accordingly
+             * and terminate the loop.  Doesn't yet support a dual -T2/-TX
+             * device (R7145 is TBD), which likely requires an additional
+             * control to select the desired 100Base-T PMA technology.
+             */
+            bmcr &= ~(BMCR_AUTONEG_ENABLE | BMCR_RESTART_AUTONEG);
+            for (lookup = &an_lookup[0]; lookup->phy_link != 0; lookup++) {
+                if (connect & lookup->phy_link & PHY_CONN_TECHNOLOGY) {
+                    connect = lookup->phy_link & PHY_CONN_TECHNOLOGY;
+                    if (lookup->phy_link & PHY_LINK_FDX)
+                        bmcr |= BMCR_DUPLEX_MODE;
+                    if (lookup->phy_link & PHY_LINK_100)
+                        bmcr |= BMCR_SPEED_100;
+                    break;
+                }
+            }
+        }
+
+        /* Issue the MII BMCR hardware command */
+        MiiWrite(&phy->mii_phy[ETH_MII_PHY], MII_BMCR, bmcr);
+
+        /* National PHY bug:  kick (read) PHY to restart A-N (?) */
+        if ((connect & PHY_CONN_AUTONEG) && PHYID_NSC_DP83840(phy)) {
+            (void) MiiRead( &phy->mii_phy[ETH_MII_PHY], MII_BMCR);
+        }
+    }
+
+    /*
+     * (4) Select default MII/HPNA ports to activate/enable and
+     *     deactivate/disable.  If Auto-Negotiating both HomePNA
+     *     and MII ports, activate the HomePNA port unless MII
+     *     priority is specified.  If forcing or Auto-Negotiating
+     *     a single port, then activate that port.
+     */
+	 Set_Active_Port( phy, phy->hpna_port ) ;
+
+    if ((connect & PHY_CONN_MII_TECHNOLOGY) &&
+            (connect & PHY_CONN_HPNA_TECHNOLOGY)) {
+        /* Both ports active */
+        if (connect & PHY_CONN_AUTONEG) {
+            if (phy->hw_options & PHY_HWOPTS_MII_PORT_PRIORITY) {
+                /* Auto-Negotiating and MII priority option */
+                Set_Active_Port( phy, phy->mii_port ) ;
+            }
+
+        } else {
+            /* Forced connections: disable lower priority port */
+            if (phy->hw_options & PHY_HWOPTS_HPNA_PORT_PRIORITY) {
+                connect &= ~PHY_CONN_MII_TECHNOLOGY;
+            } else {
+                connect &= ~PHY_CONN_HPNA_TECHNOLOGY;
+                Set_Active_Port( phy, phy->mii_port ) ;
+            }
+        }
+
+    } else if (connect & PHY_CONN_MII_TECHNOLOGY) {
+        Set_Active_Port( phy, phy->mii_port ) ;
+    }
+
+    /* (5) Shave unused, residual <connect> settings and save */
+    connect &= (PHY_CONN_AUTONEG              |
+                PHY_CONN_AUTONEG_REMOTE_FAULT |
+                PHY_CONN_AUTONEG_FDX_PAUSE    |
+                PHY_CONN_TECHNOLOGY);
+    if (!(connect & PHY_CONN_AUTONEG) ||
+            !(connect & PHY_CONN_MII_TECHNOLOGY)) {
+        connect &= ~(PHY_CONN_AUTONEG_REMOTE_FAULT |
+                     PHY_CONN_AUTONEG_FDX_PAUSE);
+    }
+    phy->media.connect = connect;
+    phy->media.cum_link_state      =
+        phy->media.hpna_link_state =
+        phy->media.mii_link_state  = 0;
+
+    /*
+     * (6) Activate/deactivate selected ports whenever called from
+     *     PhyInit().  
+     */
+    if(!(phy->hw_options & PHY_HWOPTS_ISOLATE)) {
+        PhyConfigurePort(phy, phy->media.cum_link_state);
+    }
+    
+    return (PHY_STATUS_OK);
+}
+
+/***********************************************************************
+ * PhyConfigurePort() - Configure PHY (and optional MAC) port settings
+ **********************************************************************/
+#if 0
+	#include "macphy.h"
+#endif
+
+PHY_STATUS
+PhyConfigurePort(PHY *phy, DWORD link_state)
+{
+	BOOLEAN 			Port_Mii, Speed100m, Full_Duplex ;
+
+	if ((link_state & PHY_LINK_NEW_MEDIA) ||
+		(phy->active_port != phy->enabled_port)) 
+	{
+		/*
+		 * Upon new media and/or port change ...
+		 *
+		 * (1) Optionally stop MAC Tx/Rx, delay up to 5 maximum packet
+		 *     times (5 x 1518 bytes = 60,720 bits, yielding respective
+		 *     100/10/1 Mbit/s delays of 607.2uS/6.072mS/60.72mS)
+		 *     for the current transmit and/or receive processing to
+		 *     complete, and then disable the soon-to-be-active PHY if
+		 *     we're changing (MAC and PHY) ports.
+		 */
+#ifndef SINGLE_PHY
+		MacPhy_Stop_And_Wait_TXRX_Complete( phy->mii_phy[JEDI_MII_PHY].adapter ) ;
+#endif
+		/*
+		* Temporarily tri-state the active, soon-to-be-enabled port
+		* only upon initial or subsequent port changes.
+		*/
+		if (phy->active_port != phy->enabled_port )
+			PhyDisable(phy, phy->active_port);
+
+		/* (2) Disable the inactive PHY */
+		PhyDisable(phy, phy->inactive_port);
+
+		/* (3) reconfigure the MAC's */
+		Full_Duplex = FALSE ;
+		Port_Mii = TRUE ;
+		if (phy->active_port & PHY_PORT_HPNA_MII ) 
+		{
+			Speed100m = TRUE ;
+		}
+		else if (phy->active_port & PHY_PORT_HPNA_7WS)
+		{
+			Port_Mii = FALSE ;
+			Speed100m = FALSE ;
+		}
+		else 
+		{	// 10/100
+			Speed100m = TRUE ;
+
+			if ((link_state & PHY_LINK_UP) ||
+               ((link_state = phy->media.mii_link_state) != 0)) 
+			{
+				/* Go with current or previous MII link settings */
+				if (link_state & PHY_LINK_10) 
+					Speed100m = FALSE ;	// 10M
+
+				if (link_state & PHY_LINK_FDX) 
+					Full_Duplex = TRUE ;
+			} 
+			else 
+			{
+				/* MII link never established: go with connect */
+				link_state = phy->media.connect;
+				if (link_state & (PHY_LINK_100BASE_T2FD |
+					PHY_LINK_100BASE_TXFD)) 
+				{
+					if (!(link_state & PHY_LINK_AUTONEG))
+						/* A-N @ half-duplex, forced @ full-duplex */
+						Full_Duplex = TRUE ;
+
+				} else if (link_state & (PHY_LINK_100BASE_T2 |
+                                     PHY_LINK_100BASE_TX |
+                                     PHY_LINK_100BASE_T4)) 
+				{
+                ;       /* nada */
+
+				} 
+				else if (link_state & PHY_LINK_10BASE_TFD) 
+				{
+					Speed100m = FALSE ;
+					if (!(link_state & PHY_LINK_AUTONEG))
+					/* A-N @ half-duplex, forced @ full-duplex */
+						Full_Duplex = TRUE ;
+				} else {
+					Speed100m = FALSE ;
+				}
+			}
+		}
+#if !defined(DEVICE_YELLOWSTONE)
+	#if 0
+		MacPhy_Configure_Mac( phy->mii_phy[JEDI_MII_PHY].adapter, Port_Mii, Speed100m, Full_Duplex ) ;
+	#endif
+#endif
+
+		/* (4) Enable the active PHY */
+		PhyEnable(phy, phy->active_port) ;
+		phy->enabled_port = phy->active_port;
+	}
+	return (PHY_STATUS_OK);
+}
+
+/***********************************************************************
+ * PhyCapabilityGet() - Get PHY technology capabilities
+ **********************************************************************/
+DWORD
+PhyCapabilityGet(PHY *phy)
+{
+    return (phy->media.capability);
+}
+
+/***********************************************************************
+ * PhyCheck() - Assess link status, speed and duplex mode
+ **********************************************************************/
+static DWORD ETHPhyCheck(PHY *phy)
+{ 
+	DWORD mii_link_state  = phy->media.mii_link_state;
+	DWORD connect = phy->media.connect;
+	WORD            bmsr;
+	WORD            aner;
+	WORD            negotiation;
+	AN_LOOKUP      *table;
+	DWORD mii_link_error = 0 ;	// no checking now
+
+   if( (connect & PHY_CONN_MII_TECHNOLOGY) && (phy->mii_isolated == FALSE)){
+
+	/* For no-MDIO PHYs assume link is up, 100 Mbps, full duplex. What else?
+	 * We have no way to verify that anyway */
+        if( PHYID_NO_MDIO(phy) )
+		{
+			mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG | PHY_LINK_100 | PHY_LINK_100BASE_TX | PHY_LINK_FDX;
+	        phy->media.mii_link_state = mii_link_state;
+	        phy->media.connect = PHY_CONN_AUTONEG | PHY_LINK_UP;
+			return mii_link_state ;
+		}	
+
+        /*
+         * Important note:  must double-clutch BMSR when link status
+         * is down, since the BMSR_LINK_STATUS bit is latched LOW until
+         * read.  A second BMSR read ensures current link state.
+         */
+        bmsr = MiiRead( &phy->mii_phy[ETH_MII_PHY], MII_BMSR);
+        if (!(bmsr & BMSR_LINK_STATUS)) {
+            bmsr |= MiiRead( &phy->mii_phy[ETH_MII_PHY], MII_BMSR); /* |= retains error latches */
+
+            /*
+             * Upon "long-term" link down transition, disable power-saving
+             * TDK RXCC option (RX_CLK is held low when no data is
+             * received), as it adversely impacts Auto-Negotiation.  We'll
+             * restart Auto-Negotiation as a precautionary measure.
+             */
+            if ((phy->hw_options & PHY_HWOPTS_CK25DIS) &&
+                    PHYID_TDK_2120(phy) &&
+                    (mii_link_state & PHY_LINK_UP) &&
+                    !(bmsr & BMSR_LINK_STATUS)) {
+                MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_RXCC);
+                if (connect & PHY_CONN_AUTONEG) {
+                    MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_BMCR, BMCR_RESTART_AUTONEG);
+                }
+            }
+
+            /* Link down: report current connect state */
+            phy->media.mii_link_state &= ~PHY_LINK_UP;
+            mii_link_state = connect & (PHY_CONN_MII_TECHNOLOGY       |
+                                        PHY_CONN_AUTONEG_REMOTE_FAULT |
+                                        PHY_CONN_AUTONEG_FDX_PAUSE);
+
+        }
+
+        /*
+         * Re-evaluate link configuration for down-to-up transitions,
+         * otherwise report present (connecting or operational) link state.
+         */
+        if ((bmsr & BMSR_LINK_STATUS) && !(mii_link_state & PHY_LINK_UP)) {
+            mii_link_state = 0;
+            if (!(connect & PHY_CONN_AUTONEG)) {
+                /*
+                 * Forced connection mode:  assume the forced state,
+                 * walking the an_lookup[] table to pick up associated
+                 * PHY_LINK_FDX and PHY_LINK_100/10 status bits.
+                 */
+                for (table = &an_lookup[0]; table->phy_link != 0; table++) {
+                    if (connect & table->phy_link & PHY_LINK_TECHNOLOGY) {
+                        mii_link_state = table->phy_link | PHY_LINK_UP;
+                        break;
+                    }
+                }
+
+            } else {
+                /*
+                 * Auto-Negotiation mode:  infer link speed/mode based
+                 * on Link Control Words (LCWs) advertised and received
+                 * from our link partner.  Simply walk the negotiated
+                 * settings against the an_lookup[] table, ordered from
+                 * highest to lowest Auto-Negotiation priority, reporting
+                 * first (highest) matching capability.  Special case:
+                 * the Davicom PHY doesn't cleanse (zero) the ANLPAR link
+                 * partner register when transitioning from an A-N partner
+                 * to a non A-N partner, so check its ANER expansion
+                 * register for a new link page notification.  Not all PHYs
+                 * indicate new page in all modes, e.g., the QSI 970 and
+                 * Level One (LXT 901) PHYs' "ANLPAR spoofing" won't
+                 * indicate ANER new page when linked to a non A-N partner,
+                 * and the pre-RevA NSC 83840 apparently doesn't indicate
+                 * next page even when linked with an A-N partner.
+                 */
+                if ((bmsr & BMSR_AUTONEG_COMPLETE) &&
+                        (((aner = MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_ANER)) &
+                           ANER_PAGE_RECEIVED) ||
+                         !PHYID_DAVICOM_9101(phy))) {
+                    negotiation = (phy->anar & MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_ANLPAR));
+                    for (table = &an_lookup[0]; table->anar != 0; table++) {
+                        if (negotiation & table->anar) {
+                            mii_link_state = (PHY_LINK_UP      |
+                                              PHY_LINK_AUTONEG |
+                                              table->phy_link);
+                            break;
+                        }
+                    }
+                    if (aner & ANER_PARALLEL_DETECTION_FAULT) {
+                        mii_link_error |= PHY_LINK_PARALLEL_ERROR;
+                    }
+                }
+
+				// Bright new 9/26/01
+                if (PHYID_KENDIN_KS8737(phy)) {
+                /*
+                 * Though the Kendin PHY supports "ANLPAR spoofing,"
+                 * subsequent to link with Auto-Negotiating peer,
+                 * it fails to update its ANLPAR register, resulting
+                 * in false mode selection.  We'll correct via
+                 * vendor-specific register 31.
+                 */
+                   WORD    r31 = MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_R31);
+                   if (!(r31 & MII_BIT4)) 
+                   {
+                    /*
+                     * Not full-duplex, which can only result from
+                     * a true Auto-Negotiation handshake.
+                     */
+                    mii_link_state = (PHY_LINK_UP | PHY_LINK_AUTONEG);
+                    if (r31 & MII_BIT2) {
+                        mii_link_state |= PHY_LINK_10BASE_T;
+                    } else {
+                        mii_link_state |=
+                            (PHY_LINK_100 | PHY_LINK_100BASE_TX);
+                    }
+                   }
+                } else if (mii_link_state == 0) {
+                    /*
+                     * Parallel Detection: link but no Auto-Negotiation
+                     * match, which implies our link partner is not A-N
+                     * capable.  Determine link technology via PHY
+                     * vendor-specific status registers.
+                     */
+                    if (PHYID_NSC_DP83840(phy)) {
+                        mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG;
+                        if (MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_PAR) & PAR_SPEED_10) {
+                            mii_link_state |=
+                                (PHY_LINK_10  | PHY_LINK_10BASE_T);
+                        } else {
+                            mii_link_state |=
+                                (PHY_LINK_100 | PHY_LINK_100BASE_TX);
+                        }
+
+                    } else if (PHYID_GEC_NWK936(phy)) {
+                        /*
+                         * The GEC PHY apparently sets BMCR speed/duplex
+                         * bits based on the A-N outcome.  Though their spec
+                         * says to use extended register 25 for current
+                         * speed and duplex state, we'll stick to the
+                         * standard BMCR register, although most PHYs
+                         * don't reflect current speed/duplex state in
+                         * the BMCR when Auto-Negotiating....
+                         */
+                        mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG;
+                        if (MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_BMCR) & BMCR_SPEED_100) {
+                            mii_link_state |=
+                                (PHY_LINK_100 | PHY_LINK_100BASE_TX);
+                        } else {
+                            mii_link_state |=
+                                (PHY_LINK_10  | PHY_LINK_10BASE_T);
+                        }
+
+                    } else if (PHYID_TDK_2120(phy)) {
+                        /*
+                         * The TDK PHY's diagnostic register 18 (decimal)
+                         * MR18.RATE, bit-10 (0x400) indicates the result of
+                         * Auto-Negotiation data rate arbitration.  However,
+                         * when using their pre-production Rev 3 device,
+                         * our testing apparently revealed bit-9 (0x200) as
+                         * the RATE indicator when connecting to dumb,
+                         * non Auto-Negotiating hubs at 10 or 100 Mbit/sec,
+                         * half-duplex.  TDK support confirms that bit-10
+                         * RATE is a new feature in the Rev 7 device.  As
+                         * such, we'll go with this apparent bit-9 heuristic
+                         * on the earlier, Rev-3 device.
+                         */
+                        mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG;
+                        if (MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_R18) &
+                                ((PHYID_REV(phy) >= 7) ? TDK_R18_RATE_100
+                                                       : MII_BIT9)) {
+                            mii_link_state |=
+                                (PHY_LINK_100 | PHY_LINK_100BASE_TX);
+                        } else {
+                            mii_link_state |=
+                               (PHY_LINK_10   | PHY_LINK_10BASE_T);
+                        }
+
+                    } else if (PHYID_DAVICOM_9101(phy)) {
+                        /*
+                         * The Davicom PHY apparently (as of 21Jan98 we
+                         * have no data sheet) identifies auto-negotiation
+                         * results in bits 12-15 of register 17 (decimal).
+                         * 8nnn = 100-FDX, 4nnn = 100-HDX, 2nnn = 10-FDX,
+                         * and 1nnn = 10-HDX.  Since an A-N partner's
+                         * advertisement should be correctly reflected in
+                         * the ANLPAR (register 5), we'll only troll for
+                         * dumb, non A-N partners' half-duplex results here.
+                         */
+                        mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG;
+                        switch (MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_R17) & 0xF000) {
+                            default:
+                                mii_link_state = 0;
+                                break;
+                            case 0x4000:
+                                mii_link_state |=
+                                    (PHY_LINK_100 | PHY_LINK_100BASE_TX);
+                                break;
+                            case 0x1000:
+                                mii_link_state |=
+                                    (PHY_LINK_10  | PHY_LINK_10BASE_T);
+                                break;
+                        }
+                    } else if (PHYID_LXT_971(phy)) {
+
+                        // Unspecified, based on lab test observation 03Dec99                        */
+                        mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG;
+                        if(MiiRead(&phy->mii_phy[ETH_MII_PHY], MII_R17) & 0x4000) {
+							mii_link_state |= (PHY_LINK_100 | PHY_LINK_100BASE_TX);
+						}
+						else {
+							mii_link_state |= (PHY_LINK_10  | PHY_LINK_10BASE_T);
+                        }
+                    }
+                } /* end if - SW parallel detection logic */
+            } /* end if - Auto-Negotiating */
+
+            /* Latch 1st and subsequent PHY_LINK_NEW_MEDIA changes */
+            if (mii_link_state == 0) {
+                /* ??? Couldn't resolve link; need PHY_LINK_UNKNOWN err */
+                mii_link_state = connect & (PHY_CONN_MII_TECHNOLOGY       |
+                                            PHY_CONN_AUTONEG_REMOTE_FAULT |
+                                            PHY_CONN_AUTONEG_FDX_PAUSE);
+            } else if ((mii_link_state ^ phy->media.mii_link_state) &
+                     (PHY_LINK_SPEED | PHY_LINK_FDX |
+                      PHY_LINK_MII_TECHNOLOGY)) {
+                phy->media.mii_link_state = mii_link_state;
+                mii_link_state |= PHY_LINK_NEW_MEDIA;
+            } else {
+                phy->media.mii_link_state = mii_link_state;
+            }
+
+            /* Enable TDK RXCC option only on link down-to-up @ 100 Mbit */
+            if ((phy->hw_options & PHY_HWOPTS_CK25DIS) &&
+                    PHYID_TDK_2120(phy)) {
+                if (mii_link_state & PHY_LINK_100) {
+                    MII_SET_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_RXCC);
+                } else {
+                    MII_CLR_BIT(&phy->mii_phy[ETH_MII_PHY], MII_R16, TDK_R16_RXCC);
+                }
+            }
+        } /* endif - MII link down-to-up transition */
+
+        /* Affix newly detected errors latched by PHY hardware */
+        if ((bmsr & BMSR_JABBER_DETECT) &&
+                (mii_link_state & (PHY_LINK_10BASE_TFD |
+                                   PHY_LINK_10BASE_T))) {
+            mii_link_error |= PHY_LINK_JABBER;
+        }
+        if (bmsr & BMSR_REMOTE_FAULT) {
+            mii_link_error |= PHY_LINK_REMOTE_FAULT;
+        }
+    }
+	return mii_link_state ;
+}
+
+DWORD PhyCheck(PHY *phy)
+{
+    DWORD           connect          = phy->media.connect;
+    DWORD           hpna_link_state = 0 ;
+    DWORD           cum_link_state   = phy->media.cum_link_state;
+    DWORD           mii_link_state ;
+    PHY_PORT        port_select;
+
+    if (!IS_PHY_INITIALIZED(phy)) {
+        return (PHY_LINK_INIT_ERROR);
+    }
+
+#if HOMEPLUGPHY
+	if( PhyActiveHOMEPLUG( phy) )
+	{
+		mii_link_state = PHY_LINK_UP | PHY_LINK_AUTONEG | PHY_LINK_100 | PHY_LINK_100BASE_TX ;
+		phy->media.mii_link_state = mii_link_state;
+		phy->media.connect = PHY_CONN_AUTONEG | PHY_LINK_UP;
+		return mii_link_state ;
+	}	
+#endif
+
+    /*----------------------------------------------------------------*
+     * (1) Examine HomePNA PHY
+     *----------------------------------------------------------------*/
+#ifdef JEDIPHY	// Bright
+    hpna_link_state = JediPhyCheck(phy) ;
+#endif
+
+    /*----------------------------------------------------------------*
+     * (2) Examine MII PHY
+     *----------------------------------------------------------------*/
+    mii_link_state = ETHPhyCheck(phy) ;
+
+    /*----------------------------------------------------------------*
+     * (3) Form cumulative link state based on HomePNA and MII states
+     *----------------------------------------------------------------*/
+
+    /* Initial state indicates Auto-Negotiation directive */
+    cum_link_state = (connect & PHY_LINK_AUTONEG);
+
+    if (!(connect & PHY_CONN_HPNA_TECHNOLOGY)) {
+        /*
+         * (3a) No HomePNA connect, so infer MII-only operation
+         */
+        cum_link_state |= mii_link_state;
+        port_select = phy->mii_port;
+
+    } else if (!(connect & PHY_CONN_MII_TECHNOLOGY)) {
+        /*
+         * (3b) No MII connect, so infer HomePNA-only operation
+         */
+        cum_link_state |= hpna_link_state;
+        port_select = phy->hpna_port;
+
+        /*
+         * (3c) Simultaneous HomePNA and MII operation ...
+         */
+    } else if (!((hpna_link_state | mii_link_state) & PHY_LINK_UP)) {
+
+        /*
+         * (3c-1) Neither device reporting link: choose a port.
+         *
+         * By default, retain the current, active port.  After
+         * LINK_DOWN_HOP_COUNT (nominally 5) successive cycles of
+         * link down, we can optionally switch (hop) to the other,
+         * inactive port or lock-in on the MII or HomePNA port if
+         * the respective PHY_HWOPTS_PORT_HOPPING, PHY_HWOPTS_MII_ 
+         * PORT_PRIORITY or PHY_HWOPTS_HPNA_PORT_PRIORITY options
+         * are in effect.  Special port-hopping note:  certain
+         * tested MII PHYs such as the TDK, QSI and GEC don't require
+         * hopping to achieve link, thus we won't hop thereupon
+         * to improve our odds of achieving link on the HomePNA
+         * device.
+         */
+        cum_link_state |= (hpna_link_state | mii_link_state);
+        port_select = phy->active_port;
+        if (++phy->link_down_count >= LINK_DOWN_HOP_COUNT) {
+            phy->link_down_count = 0;
+            if ((phy->hw_options & PHY_HWOPTS_PORT_HOPPING) &&
+                    (phy->inactive_port != PHY_PORT_NONE)) {
+                port_select = phy->inactive_port;   /* (hop) */
+            } else if (phy->hw_options & PHY_HWOPTS_MII_PORT_PRIORITY) {
+                port_select = phy->mii_port;
+            } else if (phy->hw_options & PHY_HWOPTS_HPNA_PORT_PRIORITY) {
+                port_select = phy->hpna_port;
+            }
+        }
+
+    } else {
+        /*
+         * (3c-2) One or both devices reporting link: choose a port.
+         *
+         * If both devices report link, retain the active port if
+         * previously linked.  Otherwise, default to the MII link
+         * status and select the MII port, since 10/100 Mbit/s is
+         * considered a greater capability than 1 Mbit/s HomePNA.
+         * This can be overriden via the PHY_HWOPTS_HPNA_PORT_PRIORITY
+         * option.
+         *
+         * If only one device is reporting link, select that device's
+         * port and use its associated link status.
+         */
+        phy->link_down_count = 0;
+        if (hpna_link_state & mii_link_state & PHY_LINK_UP) {
+            /* Both devices reporting link: choose a winner */
+            if (phy->media.cum_link_state & PHY_LINK_UP) {
+                port_select = phy->active_port;
+                if (port_select == phy->hpna_port) {
+                    cum_link_state |= hpna_link_state;
+                } else {
+                    cum_link_state |= mii_link_state;
+                }
+
+            } else if (phy->hw_options &
+                       PHY_HWOPTS_HPNA_PORT_PRIORITY) {
+                cum_link_state |= hpna_link_state;
+                port_select = phy->hpna_port;
+
+            } else {
+                /* 10/100 Mbit/s MII > 1-Mit/s HomePNA */
+                cum_link_state |= mii_link_state;
+                port_select = phy->mii_port;
+            }
+
+        } else if (mii_link_state & PHY_LINK_UP) {
+            /* MII-only link up */
+            cum_link_state |= mii_link_state;
+            port_select = phy->mii_port;
+
+        } else {
+            /* HomePNA-only link up */
+            cum_link_state |= hpna_link_state;
+            port_select = phy->hpna_port;
+        }
+    }
+
+    /*----------------------------------------------------------------*
+     * (4) Select port and merge into cumulative link state
+     *----------------------------------------------------------------*/
+
+    switch (port_select) {
+        case PHY_PORT_HPNA_7WS:  
+           cum_link_state |= PHY_LINK_PORT_7WS;  break;
+        case PHY_PORT_HPNA_MII:  
+           cum_link_state |= PHY_LINK_PORT_MII;  break;
+        case PHY_PORT_MII:       
+           cum_link_state |= PHY_LINK_PORT_MII;  break;
+        default:                 /* ??? */                             break;
+    }
+    if (!(cum_link_state & PHY_LINK_UP)) {
+        phy->media.cum_link_state &= ~PHY_LINK_UP;
+    } else {
+        if ((cum_link_state ^ phy->media.cum_link_state) &
+                (PHY_LINK_PORT | PHY_LINK_FDX | PHY_LINK_SPEED |
+                 PHY_LINK_TECHNOLOGY)) {
+            cum_link_state |= PHY_LINK_NEW_MEDIA;
+        }
+        phy->media.cum_link_state = cum_link_state & ~PHY_LINK_NEW_MEDIA;
+    }
+
+    /*----------------------------------------------------------------*
+     * (5) Optionally reconfigure upon new-media and/or port switch
+     *----------------------------------------------------------------*/
+    if ((cum_link_state & PHY_LINK_NEW_MEDIA) ||
+            ((port_select != phy->active_port) &&
+             (port_select != PHY_PORT_NONE))) {
+        if ((port_select != phy->active_port) &&
+                (port_select != PHY_PORT_NONE)) {
+#if OLD
+            phy->inactive_port = phy->active_port;
+            phy->active_port = port_select;
+#else
+            Set_Active_Port( phy, port_select ) ;
+#endif
+        }
+        if( !(phy->hw_options & PHY_HWOPTS_ISOLATE)) 
+            PhyConfigurePort(phy, cum_link_state);
+    }
+
+    return (cum_link_state);
+}
+
+/***********************************************************************
+ * PhyLastLinkUp() - Return current or last known, valid link state
+ **********************************************************************/
+DWORD
+PhyLastLinkUp(PHY *phy)
+{
+    if (phy->media.cum_link_state != 0) {
+        return (phy->media.cum_link_state | PHY_LINK_UP);
+    }
+    return (0);         /* valid link never established */
+}
+
+/***********************************************************************
+ * PhyShutdown() - Disable (isolate) and power-down the PHY
+ **********************************************************************/
+void PhyShutdown(PHY *phy)
+{
+    (void) PhyDisable(phy, PHY_PORT_MII_DEVICE);
+    MII_SET_MASK(phy->pActive_miiphy, MII_BMCR, BMCR_POWERDOWN);
+}
+
+#if 0
+/***********************************************************************
+ * PhyLoopback() - Enable/disable PHY loopback (one of four modes)
+ **********************************************************************/
+PHY_STATUS
+PhyLoopback(PHY *phy, PHY_LOOPBACK mode)
+{
+    WORD        lbremr;
+
+    if (!IS_PHY_INITIALIZED(phy)) {
+        return (PHY_STATUS_UNINITIALIZED);
+    }
+
+    switch (mode) {
+        default:
+            mode = PHY_LOOPBACK_OFF;
+            /* fall through ... */
+        case PHY_LOOPBACK_MII:       /* MAC loopback at MII Tx/Rx */
+            lbremr = LBREMR_LB_OFF;
+            break;
+
+        case PHY_LOOPBACK_PMD:       /* Loopback at the PMD Tx/Rx */
+            lbremr = LBREMR_LB_XCVR;
+            break;
+
+        case PHY_LOOPBACK_REMOTE:    /* Media Rx Data looped onto Tx at
+                                      * MII (e.g., link BER testing) */
+            lbremr = LBREMR_LB_REMOTE;
+            break;
+
+        case PHY_LOOPBACK_10BASE_T:
+            lbremr = LBREMR_LB_10BT;
+            break;
+    }
+
+    /* Configure BMCR and LBREMR registers' loopback control bits */
+    phy->loopback = mode;
+    if (mode == PHY_LOOPBACK_MII) {
+        MII_SET_BIT(phy->pActive_miiphy, MII_BMCR, BMCR_LOOPBACK);
+    } else {
+        MII_CLR_BIT(phy->pActive_miiphy, MII_BMCR, BMCR_LOOPBACK);
+    }
+    MII_CLR_MASK(phy->pActive_miiphy, MII_LBREMR, LBREMR_LB_MASK);
+    MII_SET_MASK(phy->pActive_miiphy, MII_LBREMR, lbremr);
+
+    return (PHY_STATUS_OK);
+}
+
+/***********************************************************************
+ * PhyColTest() - Enable/disable collision test (diagnostic)
+ **********************************************************************/
+PHY_STATUS
+PhyColTest(PHY *phy, BOOLEAN enable)
+{
+    phy = phy;
+    return ((enable) ? PHY_STATUS_UNSUPPORTED_FUNCTION : PHY_STATUS_OK);
+}
+#endif
+
+/***********************************************************************
+ * PhyIdGet() - Read HW ID from registers 2 and 3
+ **********************************************************************/
+DWORD PhyIdGet(PHY *phy)
+{
+	return phy->pActive_miiphy->mii_id ;
+}
+
+BOOLEAN PhyActiveHPNA(PHY *phy)
+{
+#ifndef NON_BYPASSMODE	// test
+	if ( phy->active_port & PHY_PORT_HPNA_DEVICES )
+		return TRUE ;
+#endif
+	return FALSE ;
+}
+
+#if HOMEPLUGPHY
+
+// TBD , need improvement	
+BOOLEAN PhyActiveHOMEPLUG(PHY *phy)
+{
+
+	if ( phy->active_port & PHY_PORT_MII_DEVICE &&
+	phy->mii_phy[ETH_MII_PHY].mii_id == HOMEPLUGID )
+//	if ( phy->active_port & PHY_PORT_MII_DEVICE &&
+//	phy->mii_phy[ETH_MII_PHY].mii_id != 0x221720 )
+		return TRUE ;
+
+	return FALSE ;
+}
+#endif
+
+
+// Check if Any Phy attached to EMAC port
+// input : 
+//		Mac_Addr : beginnig of the emac mac address
+//		mii_addr : if 0xff : search 0 to 31
+//					  else search specified mii_addr (faster)
+BOOLEAN Phy_EmacPortAttached(DWORD Mac_Addr, BYTE mii_addr) 
+{
+	BYTE	last_addr;
+	WORD	bmsr;
+	MIIOBJ TmpMii ;
+
+	TmpMii.adapter = Mac_Addr ;
+	TmpMii.preamble_suppression = FALSE ;
+
+	if( mii_addr == 0xff )
+	{
+		last_addr = PHY_ADDR_MAX;
+		mii_addr  = PHY_ADDR_MIN + 1;    
+	}
+	else
+		last_addr = mii_addr ;
+
+Search_Mii_1 :
+	while(mii_addr <= last_addr) 
+	{
+		TmpMii.mii_addr = mii_addr++;
+		if (((bmsr = MiiRead(&TmpMii, MII_BMSR)) != 0x0000) &&
+			(bmsr != 0xFFFF)) 
+			return TRUE ;
+	}
+
+	/* Go back to addr-0 once full MII search 1..31 fails */
+	if( mii_addr == (PHY_ADDR_MAX+1) ) 
+	{
+		mii_addr = last_addr = PHY_ADDR_MIN ;
+		goto Search_Mii_1 ;
+	}
+	
+	return FALSE ;
+}
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phy.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phy.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phy.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phy.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,392 @@
+/****************************************************************************
+*
+*	Name:			phy.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1997-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*
+****************************************************************************
+*  $Author:   richarjc  $
+*  $Revision:   1.1  $
+*  $Modtime:   Mar 27 2003 08:01:52  $
+****************************************************************************/
+
+#ifndef _PHY_H_
+#define _PHY_H_
+
+#include "phytypes.h"
+// PHY object interfaces for other objects
+// #define NON_BYPASSMODE	1	// test
+
+#ifndef _PHYOBJ_H_
+// these definition are required for interfaces
+// the superset defined inside phyobj.h
+
+typedef enum _phy_status_ {
+    PHY_STATUS_OK = 0,
+    PHY_STATUS_NOT_FOUND,               /* PhyInit() errors ... */
+    PHY_STATUS_UNSUPPORTED_FUNCTION,
+    PHY_STATUS_PORTABILITY_ERROR,
+    PHY_STATUS_RESET_ERROR,             /* PhyReset() bit stuck */
+    PHY_STATUS_UNSUPPORTED_MEDIA,       /* PhyConnSet() error */
+    PHY_STATUS_UNINITIALIZED,
+    PHY_STATUS_ERROR_MISC 
+    /* etc. */
+} PHY_STATUS;
+
+#define PHY_LINK_UP             0x80000000L
+#define PHY_LINK_NEW_MEDIA      0x40000000L
+#define PHY_LINK_FDX            0x20000000L
+#define PHY_LINK_AUTONEG        0x10000000L
+#define PHY_LINK_100            0x04000000L
+#define PHY_LINK_10             0x02000000L
+#define PHY_LINK_HPNA_10        0x01000000L
+
+#define PHY_LINK_HPNA20         0x00000800L /* (3) PHY_LINK_TECHNOLOGY ... */
+
+#define PHY_LINK_100BASE_T2FD   0x00000080L
+#define PHY_LINK_100BASE_T2     0x00000040L
+#define PHY_LINK_FDX_PAUSE      0x00000020L
+#define PHY_LINK_100BASE_T4     0x00000010L
+#define PHY_LINK_100BASE_TXFD   0x00000008L
+#define PHY_LINK_100BASE_TX     0x00000004L
+#define PHY_LINK_10BASE_TFD     0x00000002L
+#define PHY_LINK_10BASE_T       0x00000001L
+
+
+#define PHY_LINK_SPEED          \
+    (PHY_LINK_100  | PHY_LINK_10   | PHY_LINK_HPNA_10)
+
+
+
+#define PHY_CONN_CURRENT                0
+#define PHY_CONN_AUTONEG                PHY_LINK_AUTONEG
+#define PHY_CONN_HPNA20                 PHY_LINK_HPNA20
+#define PHY_CONN_100BASE_T2FD           PHY_LINK_100BASE_T2FD
+#define PHY_CONN_100BASE_T2             PHY_LINK_100BASE_T2
+#define PHY_CONN_AUTONEG_FDX_PAUSE      PHY_LINK_FDX_PAUSE
+#define PHY_CONN_100BASE_T4             PHY_LINK_100BASE_T4
+#define PHY_CONN_100BASE_TXFD           PHY_LINK_100BASE_TXFD
+#define PHY_CONN_100BASE_TX             PHY_LINK_100BASE_TX
+#define PHY_CONN_10BASE_TFD             PHY_LINK_10BASE_TFD
+#define PHY_CONN_10BASE_T               PHY_LINK_10BASE_T
+
+/* Any (defaults to highest capability) HomePNA settting */
+#define PHY_CONN_ANY_HPNA20                                     \
+     PHY_CONN_HPNA20
+
+/* Any 10Base-T half-duplex setting */
+#define PHY_CONN_ANY_10BASE_T           PHY_CONN_10BASE_T
+
+/* Any 10Base-T full-duplex setting */
+#define PHY_CONN_ANY_10BASE_TFD         PHY_CONN_10BASE_TFD
+
+/* Any available 100Base-T half-duplex capability */
+#define PHY_CONN_ANY_100BASE_T          \
+    (PHY_CONN_100BASE_T2 | PHY_CONN_100BASE_T4 | PHY_CONN_100BASE_TX)
+
+/* Any available 100Base-T full-duplex capability */
+#define PHY_CONN_ANY_100BASE_TFD        \
+    (PHY_CONN_100BASE_T2FD | PHY_CONN_100BASE_TXFD)
+
+/* Force highest available HomePNA or 10/100 MII capability */
+#define PHY_CONN_FORCE_ANY_MEDIA        \
+    (PHY_CONN_ANY_HPNA20     |          \
+     PHY_CONN_ANY_10BASE_T   |          \
+     PHY_CONN_ANY_10BASE_TFD |          \
+     PHY_CONN_ANY_100BASE_T  |          \
+     PHY_CONN_ANY_100BASE_TFD)
+
+/* Auto-Negotiate all available HomePNA and/or 10/100 MII capabilities */
+#define PHY_CONN_AUTONEG_ALL_MEDIA      \
+    (PHY_CONN_AUTONEG | PHY_CONN_FORCE_ANY_MEDIA)
+
+/* Only Auto-Negotiate 10/100 MII capabilities: exclude HomePNA */
+#define PHY_CONN_AUTONEG_ALL_MII_MEDIA  \
+    (PHY_CONN_AUTONEG_ALL_MEDIA & ~PHY_CONN_ANY_HPNA20)
+
+/* Only Auto-Negotiate HomePNA capabilities: exclude 10/100 MII */
+#define PHY_CONN_AUTONEG_ALL_HPNA_MEDIA  \
+    (PHY_CONN_AUTONEG | PHY_CONN_ANY_HPNA20)
+
+/* Supported Options */
+#define PHY_HWOPTS_NONE                 0x00000000L
+#define PHY_HWOPTS_ISOLATE              0x00000400L
+#define PHY_HWOPTS_DONT_SWRESET         0x00002000L
+#define PHY_HWOPTS_MII_PREAMBLE         0x00008000L
+#define PHY_HWOPTS_NO_ETH_SEARCH        0x00010000L
+#define PHY_HWOPTS_NO_HPNA_SEARCH       0x00020000L
+#define PHY_HWOPTS_HPNA_PORT_PRIORITY   0x00080000L
+#define PHY_HWOPTS_MII_PORT_PRIORITY    0x00100000L
+#define PHY_HWOPTS_PORT_HOPPING         0x00200000L
+#define PHY_HWOPTS_HPNA7WS              0x20000000L
+#ifdef P51
+#define PHY_HWOPTS_P51_HLAN             0x40000000L
+#endif
+
+#define PHY void
+#endif
+
+
+PHY * PhyAllocateMemory( void) ;
+void PhyFreeMemory( PHY *pPhy ) ;
+
+PHY_STATUS   PhyInit(
+						DWORD	mac_address,
+						PHY		*phy,
+                        DWORD	connect,
+                        DWORD	hw_options, 
+						void	*pHpnaObj
+					);	// for HPNA 2.0 LL compliance
+
+DWORD PhyCheck(PHY *phy);
+BOOLEAN PhyActiveHPNA(PHY *phy) ;
+
+#if HOMEPLUGPHY
+BOOLEAN PhyActiveHOMEPLUG(PHY *phy) ;
+#endif
+
+DWORD PhyIdGet(PHY *phy) ;
+void PhyShutdown(PHY *phy) ;
+
+// Check if Any Phy attached to EMAC port
+// input : 
+//		Mac_Addr : beginnig of the emac mac address
+//		mii_addr : if 0xff : search 0 to 31
+//					  else search specified mii_addr (faster)
+BOOLEAN Phy_EmacPortAttached(DWORD Mac_Addr, BYTE mii_addr) ;
+
+/*
+	PHY * PhyAllocateMemory( void) ;
+		Allocte memory for PHY object
+	 Parameters :
+	 Return Value :
+		NULL if fail, else return a pointer to the PHY object
+	 Comment :
+		. the caller should save the returned value for other services provided 
+		by this module.
+*/
+
+/*
+	void PhyFreeMemory( PHY *pPhy ) ;
+		Free memory for PHY object
+	 Parameters :
+		PHY *pPhy: pointer to the PHY object
+	 Return Value :
+	 Comment :
+*/
+
+
+/*
+	PHY_STATUS   PhyInit(DWORD  mac_address, PHY   *phy, DWORD  connect,
+	DWORD  hw_options, PVOID pHpnaObj );	
+		Initialize PHY and attach to media (w/optional override), PhyInit do not
+		perform hardware reset of the PHYs. Hardware reset is MAC operation, should
+		be called before PhyInit(if required).
+	 Parameters :
+		DWORD  mac_address: MAC device I/O base address
+		PHY   *phy: allocated PHY data structure space 
+		DWORD  connect: used either to (a) force a selected line speed (10 or 100 Mbps)
+			) and mode (full- or half-duplex), or (b) to set a list of Auto-Negotiation
+			(A-N) options when the PHY_CONN_AUTONEG bit is set.  It can be a OR value of 
+			PHY_CONN-xxx bits defined above. The default value is PHY_CONN_AUTONEG_ALL_MEDIA.
+		DWORD  hw_options: one or more PHY_HWOPTS_* bits as follows.
+			ISOLATE - Disable (tri-state) the active HomePNA or MII device's
+				data interface and underlying PMD interface.  The
+				associated 7WS or MDC/MDIO Serial Management Interface
+				remains enabled for subsequent management commands.
+				This is equivalent to calling PhyDisable().
+			DONT_SWRESET - Don't issue (otherwise) mandatory software reset
+			MII_PREAMBLE - If this option is activated, the PHY driver will
+				always send a 32-bit MDIO preamble during MII reads
+				and writes.  Otherwise, the PHY driver will attempt
+				to suppress the 32-bit preamble, provided the device
+				hardware supports this feature as indicated by the
+				MII register 1.6 status bit.
+			PHY_HWOPTS_NO_ETH_SEARCH - do not search Ethernet PHY
+			PHY_HWOPTS_NO_HPNA_SEARCH - do not search HPNA(JEDI) PHY
+			HPNA_PORT_PRIORITY - If this option is selected, a link indication 
+				from a HPNA device will take precedence over a
+				simultaneous link indication from a ethernet 10/100 MII
+				device.  Otherwise the default case is for the higher
+				speed 10/100 MII device precedence.  This affects
+				the PhyCheck() link indication in the unlikely case
+				that both devices report link, as only the highest
+				priority capability will be reported.  It also has a
+				side-effect in that the PhyCheck() routine will switch
+				from an MII to HomePNA PHY device whenever the MII
+				link goes down (i.e., cable removed from 10/100 Ether
+				hub).
+
+			MII_PORT_PRIORITY  - Similar to HPNA_PORT_PRIORITY.  Since by default,
+				MII > HPNA, this doesn't affect the simultaneous link status. 
+				However, it does determine the default port selected (MII) 
+				at PhyInit() time and subsequent to link down.
+
+			PORT_HOPPING - If this option is selected and multi-port PHY devices
+				are present, i.e., both HomePNA and 10/100 MII
+				devices found, then the PhyCheck() routine will
+				force a port hop every LINK_DOWN_HOP_COUNT calls
+				when the link is down.  The default value of the
+				"phy.c" LINK_DOWN_HOP_COUNT is 5, which allows
+				ten seconds per port for a 2-second check period.
+				This option should not be enabled when the app/driver
+				polls PhyCheck() repeatedly in an initialization loop.
+
+				This option is recommended for broken PHY devices which
+				cannot achieve link while configured in the MII isolate
+				mode.  To date, we've found that the National
+				Semiconductor DP83840 won't work at all when isolated
+				(it also disables its twisted pair PMD interface), and
+				the Level One LXT 970 and Enable Semiconductor PHYs
+				curiously can achieve link when connected to 10 but
+				not 100 Mbit hubs and switches.
+
+				------------------------------------------------------
+
+				Note: the following truth table depicts the complex
+				interaction among the PHY_HWOPTS_PORT_HOPPING (HOP),
+				PHY_HWOPTS_HPNA_PORT_PRIORITY (HPNA) and the
+				PHY_HWOPTS_MII_PORT_PRIORITY (MII) options.  This
+				table is only applicable when BOTH devices (HomePNA and
+				MII) are present.  As can be seen, MII priority
+				primarily affects the PhyInit() default port select,
+				HPNA priority primarily affects PhyCheck() in the
+				rare (unlikely?) case that both links are up, and
+				HOP determines whether a port switch is made when
+				both links are down.  As a secondary effect when
+				HOP is disabled, MII supercedes HPNA priority when
+				both links are down, otherwise HPNA supercedes the
+				the current, active port which is retained in the
+				default case where no options are in effect.  Whew!
+
+				What's not depicted is the simple case where only one
+				port is reporting link: that port is always selected,
+				regardless of multi-port options.
+ 
+                          Multi-Port Selection Truth Table           
+ 
+                 +==================++=================+===========+
+                 |                  ||    PhyCheck()   |           |
+                 |  PHY HW option   |+---------+-------+           |
+                 |                  || Both    | Both  | PhyInit() |
+                 +=====+======+=====+| Links   | Links | Default   |
+                 | HOP | HPNA | MII || Down**  | Up    | Port      |
+                 +=====+======+=====++=========+=======+===========+
+      (default)  |  0  |   0  |  0  || current |  MII  |   HPNA    |
+                 +-----+------+-----++---------+-------+-----------+
+                 |  0  |   0  |  1  ||   MII*  |  MII  |    MII*   |
+                 +-----+------+-----++---------+-------+-----------+
+                 |  0  |   1  |  0  ||  HPNA*  | HPNA* |   HPNA    |
+                 +-----+------+-----++---------+-------+-----------+
+                 |  0  |   1  |  1  ||   MII*  | HPNA* |    MII*   |
+                 +=====+======+=====++=========+=======+===========+
+                 |  1  |   0  |  0  ||  other* |  MII  |   HPNA    |
+                 +-----+------+-----++---------+-------+-----------+
+                 |  1  |   0  |  1  ||  other* |  MII  |    MII*   |
+                 +-----+------+-----++---------+-------+-----------+
+                 |  1  |   1  |  0  ||  other* | HPNA* |   HPNA    |
+                 +-----+------+-----++---------+-------+-----------+
+                 |  1  |   1  |  1  ||  other* | HPNA* |    MII*   |
+                 +-----+------+-----++---------+-------+-----------+
+ 
+                 *  - Indicates behavior change with respect to the
+                      default action.
+ 
+                 ** - With both links down, "current" denotes the
+                      currently active port (default or last link),
+                      whereas "other" denotes a swap to the other,
+                      presently inactive port.  All port switching is
+                      governed by the nominal LINK_DOWN_HOP_COUNT
+                      value of 5, which yields a 10-second rate
+                      assuming a periodic, 2-second PhyCheck() cycle.
+                      As such, a link-down port switch won't occur
+                      for ten seconds, though a single- or dual-port
+                      link-up event will instanly effect a port switch.
+			HPNA7WS - If this option is activated, the PHY driver will support
+				HPNA(JEDI) with 7 wire istead of MII mode
+
+
+		PVOID pHpnaObj : a pointer of HPNALLOBJ
+	 Return Value
+*/
+
+/*
+	DWORD PhyCheck(PHY *phy)
+		To get the current PHY states. The driver can call this function at a timer 
+		routine to know the current PHY states from the return value to update the
+		the driver states. Beware that, if return value indicate PHY_LINK_NEW_MEDIA,
+		the PhyCheck would already reconfigure the PHY and MAC to the correct states,
+		but the current TX and RX of MAC stopped. Under this scenario, driver need to 
+		restart TX and RX of MAC if required.
+
+	 Parameters :
+		PHY *phy :
+	 Return Value : return a OR value of the following bits, please iqnore the
+		other bits not describes in this document.
+ 		PHY_LINK_SPEED - Set with PHY_LINK_UP to indicate 1/10/100
+                       Mbit/s line speed, as follows.  One and only
+                       one of the following PHY_LINK_SPEED bits will
+                       be set when PHY_LINK_UP is set.  If PHY_LINK_UP
+                       is not set, then none of the PHY_LINK_SPEED
+                       bits will be set.
+ 
+			PHY_LINK_100 - if PHY_LINK_UP && ETHERNET 100 Mbit/s
+			PHY_LINK_10  - if PHY_LINK_UP &&  ETHERNET 10 Mbit/s
+			PHY_LINK_HPNA_10  - if PHY_LINK_UP &&   HPNA 10 Mbit/s
+
+		PHY_LINK_UP        - Set when the link is operational
+		PHY_LINK_NEW_MEDIA - Set upon initial PHY_LINK_UP, and whenever
+                       PHY_LINK_UP is true and a media state change
+                       (speed and/or duplex mode) has been detected
+                       since the last PhyCheck().  This status
+                       can be used as a signal to reconfigure a MAC's
+                       speed, duplex and port select settings.
+*/
+
+/*
+	BOOLEAN PhyActiveHPNA(PHY *phy)
+		check if current active PHY is HPNA (JEDI)
+	 Parameters :
+		PHY *phy :
+	 Return Value :
+		TRUE : the current active PHY is HPNA (JEDI)
+		FLASE : the current active PHY is ETHERNET(10/100) or none
+*/
+
+/*
+	BOOLEAN PhyActiveHOMEPLUG(PHY *phy)
+		check if current active PHY is HOMEPLUG (TESLA)
+	 Parameters :
+		PHY *phy :
+	 Return Value :
+		TRUE : the current active PHY is HOMEPLUG
+		FLASE : the current active PHY is not HOMEPLUG
+*/
+
+/*
+	DWORD PhyIdGet(PHY *phy)
+		get MII ID
+	 Parameters :
+		PHY *phy :
+	 Return Value :
+		DWORD mii id from register 2 and 3
+*/
+#endif
Files uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phy.o and uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phy.o differ
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phyobj.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phyobj.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phyobj.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phyobj.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,1021 @@
+/****************************************************************************
+*
+*	Name:			phyobj.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 1997-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef _PHYOBJ_H_
+#define _PHYOBJ_H_
+
+//#include "typdef.h"
+#include "phytypes.h"
+#include "mii.h"
+#ifdef JEDIPHY	// Bright
+#include "osfile.h"
+#endif
+
+/*
+ * PHY_LINK_* -- link state information returned by PhyCheck()
+ *
+ * (1) Link summary (PHY_LINK_SUMMARY)
+ *
+ * PHY_LINK_UP        - Set when the link is operational
+ *
+ * PHY_LINK_NEW_MEDIA - Set upon initial PHY_LINK_UP, and whenever
+ *                      PHY_LINK_UP is true and a media state change
+ *                      (speed and/or duplex mode) has been detected
+ *                      since the last PhyCheck().  This status
+ *                      can be used as a signal to reconfigure a MAC's
+ *                      speed, duplex and port select settings.
+ *
+ * PHY_LINK_FDX       - Set when PHY_LINK_UP && operating Full-Duplex
+ *
+ * PHY_LINK_AUTONEG   - Set when Auto-Negotiating:  if PHY_LINK_UP,
+ *                      this indicates Auto-Negotiation complete,
+ *                      otherwise negotiation is still in progress
+ *
+ * PHY_LINK_SPEED     - Set with PHY_LINK_UP to indicate 1/10/100
+ *                      Mbit/s line speed, as follows.  One and only
+ *                      one of the following PHY_LINK_SPEED bits will
+ *                      be set when PHY_LINK_UP is set.  If PHY_LINK_UP
+ *                      is not set, then none of the PHY_LINK_SPEED
+ *                      bits will be set.
+ *
+ *                      PHY_LINK_100 - if PHY_LINK_UP && 100 Mbit/s
+ *                      PHY_LINK_10  - if PHY_LINK_UP &&  10 Mbit/s
+ *                      PHY_LINK_HPNA_10  - if PHY_LINK_UP &&   HPNA 10 Mbit/s
+ *
+ * PHY_LINK_PORT      - Set to indicate the current, active PHY port
+ *                      specific to an RSS 11617 or 11623 series
+ *                      Ethernet MAC device.  The caller should
+ *                      (carefully) reconfigure the MAC R6 Network
+ *                      Access Register (NAR, I/O offset 0x30)
+ *                      accordingly, carefully switching upon changes
+ *                      in state.  Exactly one of the following
+ *                      bits will always be set, regardless of the
+ *                      state of PHY_LINK_UP:
+ *
+ *                      PHY_LINK_PORT_MII  - Use external MII port
+ *                      PHY_LINK_PORT_7WS  - Use external 7-wire
+ *                                           serial port
+ *                      PHY_LINK_PORT_HPNA - Use internal HomePNA 
+ *                                           PHY port (not use for JEDI, RSS 11623
+ *                                           and newer devices only)
+ *                       
+ *
+ * (2) Error status (PHY_LINK_ERRORS)
+ *
+ * One or more of the following error bits are latched when ...
+ *
+ * PHY_LINK_JABBER         - Jabber condition detected (10Base-T only)
+ * PHY_LINK_PARALLEL_ERROR - Auto-Negotiation/parallel detection failure
+ * PHY_LINK_REMOTE_FAULT   - Auto-Negotiation Remote Fault received
+ *                           from the link partner
+ * PHY_LINK_INIT_ERROR     - Device not initialized
+ *
+ * (3) Media specifics (PHY_LINK_TECHNOLOGY)
+ *
+ * The PhyCheck() return code will contain exactly one of the following
+ * PHY_LINK_TECHNOLOGY bits if (PHY_LINK_UP || !PHY_LINK_AUTONEG), i.e.,
+ * whenever the link is up or if the link is down and we're trying to
+ * force a single media technology.  Otherwise, in the case that
+ * (!PHY_LINK_UP && PHY_LINK_AUTONEG), i.e., the link is down but
+ * we're advertising multiple media types, then one or more of the
+ * following bits will be set to indicate the current capability
+ * advertisement.  Depending on device capabilities, this may be a
+ * reduced subset of the <connect> argument passed via the PhyInit() or
+ * PhyConnectSet() APIs.
+ *
+ * PHY_LINK_HPNA20             - HomePNA mode 
+ *
+ * PHY_LINK_100BASE_T2FD       - 100Base-T2 Full-Duplex mode
+ * PHY_LINK_100BASE_T2         - 100Base-T2 (Half-Duplex mode)
+ * PHY_LINK_100BASE_T4         - 100Base-T4 (Half-Duplex mode)
+ * PHY_LINK_100BASE_TXFD       - 100Base-TX Full-Duplex mode
+ * PHY_LINK_100BASE_TX         - 100Base-TX (Half-Duplex mode)
+ * PHY_LINK_10BASE_TFD         - 10Base-T   Full-Duplex mode
+ * PHY_LINK_10BASE_T           - 10Base-T   (Half-Duplex mode)
+ *
+ * (4) PhyCheck()'s PHY_LINK_* Return Code Pseudo-Code
+ *
+ * The aggregate PHY_LINK_* status returned by PhyCheck() is
+ * contructed as follows:
+ *
+ * if (PHY_LINK_UP) {
+ *     One and only one PHY_LINK_1* PHY_LINK_TECHNOLOGY status bit is
+ *     set to indicate the selected link technology/speed/mode which
+ *     are currently active (PHY_LINK_TECHNOLOGY defines the
+ *     aggregation of specific technologies and maps to the 802.3u
+ *     aAutoNegLocalTechnologyAbility MIB attribute) plus some HomePNA
+ *     PHY extensions;
+ *     if (first-time PHY_LINK_UP or change in PHY_LINK_TECHNOLOGY) {
+ *         report PHY_LINK_NEW_MEDIA;
+ *     }
+ * } else { // the following should probably be ignored ... too complex
+ *     if (!PHY_LINK_AUTONEG) {
+ *         One and only one PHY_LINK_1* status bit is set to
+ *         indicate the forced mode connection attempt pending link
+ *         activation;
+ *     } else {
+ *         One or more PHY_LINK_1* status bits are set to indicate
+ *         the Auto-Negotiation advertisement pending link activation;
+ *     }
+ * }
+ *
+ * (5) PHY_LINK_DEFAULT - assume a conservative, default PHY link
+ *     state of 10 Mbit/s, half-duplex, until configured or detected
+ *     otherwise.
+ */
+#define PHY_LINK_UP             0x80000000L /* (1) PHY_LINK_SUMMARY ... */
+#define PHY_LINK_NEW_MEDIA      0x40000000L
+#define PHY_LINK_FDX            0x20000000L
+#define PHY_LINK_AUTONEG        0x10000000L
+#define PHY_LINK_SPARE1         0x08000000L
+#define PHY_LINK_100            0x04000000L // PHY_LINK_SPEED ...       
+#define PHY_LINK_10             0x02000000L
+#define PHY_LINK_HPNA_10        0x01000000L
+#define PHY_LINK_PORT_MII       0x00800000L // PHY_LINK_PORT ...
+#define PHY_LINK_PORT_7WS       0x00400000L
+//#define PHY_LINK_PORT_HPNA      0x00200000L	
+#define PHY_LINK_SPARE2         0x00100000L
+#define PHY_LINK_JABBER         0x00080000L /* (2) PHY_LINK_ERRORS ... */
+#define PHY_LINK_PARALLEL_ERROR 0x00040000L
+#define PHY_LINK_REMOTE_FAULT   0x00020000L
+#define PHY_LINK_INIT_ERROR     0x00010000L
+#define PHY_LINK_SPARE3         0x0000F000L
+#define PHY_LINK_HPNA20         0x00000800L /* (3) PHY_LINK_TECHNOLOGY ... */
+//#define PHY_LINK_1HPNA_HIPWR    0x00000400L
+//#define PHY_LINK_1HPNA_LOSPD    0x00000200L
+//#define PHY_LINK_1HPNA_HIPWR_LOSPD   0x00000100L
+#define PHY_LINK_100BASE_T2FD   0x00000080L
+#define PHY_LINK_100BASE_T2     0x00000040L
+#define PHY_LINK_FDX_PAUSE      0x00000020L
+#define PHY_LINK_100BASE_T4     0x00000010L
+#define PHY_LINK_100BASE_TXFD   0x00000008L
+#define PHY_LINK_100BASE_TX     0x00000004L
+#define PHY_LINK_10BASE_TFD     0x00000002L
+#define PHY_LINK_10BASE_T       0x00000001L
+
+#define PHY_LINK_SPEED          \
+    (PHY_LINK_100  | PHY_LINK_10   | PHY_LINK_HPNA_10)
+
+#define PHY_LINK_PORT           \
+    (PHY_LINK_PORT_MII | PHY_LINK_PORT_7WS)
+//    (PHY_LINK_PORT_MII | PHY_LINK_PORT_7WS | PHY_LINK_PORT_HPNA)
+
+#define PHY_LINK_SUMMARY        \
+    (PHY_LINK_UP       | PHY_LINK_NEW_MEDIA | PHY_LINK_FDX |    \
+     PHY_LINK_AUTONEG  | PHY_LINK_PORT      | PHY_LINK_SPEED)
+
+#define PHY_LINK_ERRORS                                 \
+    (PHY_LINK_JABBER       | PHY_LINK_PARALLEL_ERROR |  \
+     PHY_LINK_REMOTE_FAULT | PHY_LINK_INIT_ERROR)
+
+#define PHY_LINK_HPNA_TECHNOLOGY                            \
+    PHY_LINK_HPNA20
+
+#define PHY_LINK_MII_TECHNOLOGY                             \
+    (PHY_LINK_100BASE_T2FD | PHY_LINK_100BASE_T2    |       \
+     PHY_LINK_100BASE_T4   |                                \
+     PHY_LINK_100BASE_TXFD | PHY_LINK_100BASE_TX    |       \
+     PHY_LINK_10BASE_TFD   | PHY_LINK_10BASE_T)
+
+#define PHY_LINK_TECHNOLOGY                                 \
+    (PHY_LINK_MII_TECHNOLOGY | PHY_LINK_HPNA_TECHNOLOGY)
+
+#define PHY_LINK_DEFAULT        PHY_LINK_10
+
+/*
+ * PhyInit(), PhyConnectGet() and PhyConnectSet() <connect> parameters,
+ * used either to (a) force a selected line speed (10 or 100 Mbps) and
+ * mode (full- or half-duplex), or (b) to set a list of Auto-Negotiation
+ * (A-N) options when the PHY_CONN_AUTONEG bit is set.  These represent
+ * a subset of the PHY_LINK_* codes returned by PhyCheck().
+ *
+ * PHY_CONN_CURRENT - indicates that the current connection settings
+ *     are to be retained; these settings were set by a previous
+ *     PhyInit()/PhyConnSet(), otherwise they were established by the
+ *     default hardware strapping of the device's AN[2:0] pins.
+ *
+ * PHY_CONN_AUTONEG - when set, indicates that one or more
+ *     Auto-Negotiation settings are to advertised, otherwise a single
+ *     configuration mode is to be forced.  Warning:  Set by itself,
+ *     this flag directs the PHY to advertise *NO* capabilities,
+ *     which may not be the desired result.  This flag must be or-ed
+ *     with one or more of the PHY_CONN_TECHNOLOGY bits.  Optionally,
+ *     the caller can use PHY_CONN_AUTONEG_ALL_MEDIA to utilize any
+ *     available media.
+ *
+ * PHY_CONN_PORT_* - when one of [MII|7WS|HPNA] is set, indicates a
+ *     current port selection specified by the caller of PhyInit() or
+ *     PhyConnectSet().  When not set, the caller isn't indicating
+ *     the current PHY device port selection.
+ *
+ * PHY_CONN_AUTONEG_REMOTE_FAULT - a Remote Fault indication should
+ *     be advertised during Auto-Negotiation, applicable only when
+ *     accompanied by PHY_CONN_AUTONEG.
+ *
+ * PHY_CONN_AUTONEG_FDX_PAUSE - adveritise Full-Duplex Pause mode (?),
+ *     applicable only when accompanied by PHY_CONN_AUTONEG.
+ *
+ * PHY_CONN_1* - various link speeds and duplex modes whose aggregation
+ *     is defined by PHY_CONN_TECHNOLOGY.
+ *
+ * PHY_CONN_ANY_* - used to request any available 1-, 10- or 100-Mbps
+ *     technology supported by the PHY device.  Use these settings when
+ *     uncertain of the precise technology (100Base-TX, 100Base-T2, or
+ *     even the presently unsupported 100Base-T4) to be deployed.
+ *     The "FD" suffix denotes full-duplex, otherwise half-duplex applies.
+ *     PHY_CONN_FORCE_ANY_MEDIA and PHY_CONN_AUTONEG_ALL_MEDIA are
+ *     all-technology wildcards which respectively force the highest
+ *     priority technology or advertise all capabilities supported by the
+ *     device, in the following order of precedence:  100Base-T2FD,
+ *     100Base-TXFD, 100Base-T2, 100Base-T4, 100Base-TX, 10Base-TFD,
+ *     10Base-T).  Warning:  These PHY_CONN_ANY_* selections will fail if
+ *     the "phy.c" module is compiled with the non-default,
+ *     STRICT_PARAMETER_CHECKING switch #defined.
+ *
+ * PHY_CONN_DEFAULT - default connection values, dependent upon
+ *     conditional *_PHY compilation switch.
+ */
+#define PHY_CONN_CURRENT                0
+#define PHY_CONN_AUTONEG                PHY_LINK_AUTONEG
+
+#define PHY_CONN_AUTONEG_REMOTE_FAULT   PHY_LINK_REMOTE_FAULT
+
+#define PHY_CONN_HPNA20                 PHY_LINK_HPNA20
+#define PHY_CONN_100BASE_T2FD           PHY_LINK_100BASE_T2FD
+#define PHY_CONN_100BASE_T2             PHY_LINK_100BASE_T2
+#define PHY_CONN_AUTONEG_FDX_PAUSE      PHY_LINK_FDX_PAUSE
+#define PHY_CONN_100BASE_T4             PHY_LINK_100BASE_T4
+#define PHY_CONN_100BASE_TXFD           PHY_LINK_100BASE_TXFD
+#define PHY_CONN_100BASE_TX             PHY_LINK_100BASE_TX
+#define PHY_CONN_10BASE_TFD             PHY_LINK_10BASE_TFD
+#define PHY_CONN_10BASE_T               PHY_LINK_10BASE_T
+#define PHY_CONN_HPNA_TECHNOLOGY        PHY_LINK_HPNA_TECHNOLOGY
+#define PHY_CONN_MII_TECHNOLOGY         PHY_LINK_MII_TECHNOLOGY
+#define PHY_CONN_TECHNOLOGY             PHY_LINK_TECHNOLOGY
+
+/* Any (defaults to highest capability) HomePNA settting */
+#define PHY_CONN_ANY_HPNA20                                     \
+     PHY_CONN_HPNA20
+
+/* Any 10Base-T half-duplex setting */
+#define PHY_CONN_ANY_10BASE_T           PHY_CONN_10BASE_T
+
+/* Any 10Base-T full-duplex setting */
+#define PHY_CONN_ANY_10BASE_TFD         PHY_CONN_10BASE_TFD
+
+/* Any available 100Base-T half-duplex capability */
+#define PHY_CONN_ANY_100BASE_T          \
+    (PHY_CONN_100BASE_T2 | PHY_CONN_100BASE_T4 | PHY_CONN_100BASE_TX)
+
+/* Any available 100Base-T full-duplex capability */
+#define PHY_CONN_ANY_100BASE_TFD        \
+    (PHY_CONN_100BASE_T2FD | PHY_CONN_100BASE_TXFD)
+
+/* Force highest available HomePNA or 10/100 MII capability */
+#define PHY_CONN_FORCE_ANY_MEDIA        \
+    (PHY_CONN_ANY_HPNA20     |          \
+     PHY_CONN_ANY_10BASE_T   |          \
+     PHY_CONN_ANY_10BASE_TFD |          \
+     PHY_CONN_ANY_100BASE_T  |          \
+     PHY_CONN_ANY_100BASE_TFD)
+
+/* Auto-Negotiate all available HomePNA and/or 10/100 MII capabilities */
+#define PHY_CONN_AUTONEG_ALL_MEDIA      \
+    (PHY_CONN_AUTONEG | PHY_CONN_FORCE_ANY_MEDIA)
+
+/* Only Auto-Negotiate 10/100 MII capabilities: exclude HomePNA */
+#define PHY_CONN_AUTONEG_ALL_MII_MEDIA  \
+    (PHY_CONN_AUTONEG_ALL_MEDIA & ~PHY_CONN_ANY_HPNA20)
+
+/* Only Auto-Negotiate HomePNA capabilities: exclude 10/100 MII */
+#define PHY_CONN_AUTONEG_ALL_HPNA_MEDIA  \
+    (PHY_CONN_AUTONEG | PHY_CONN_ANY_HPNA20)
+
+/* Default: Auto-Negotiate HomePNA, 10Base-T and 100Base-TX */
+#define PHY_CONN_DEFAULT                           \
+    (PHY_CONN_AUTONEG    |                         \
+     PHY_CONN_ANY_HPNA20 |                         \
+     PHY_CONN_10BASE_T   | PHY_CONN_10BASE_TFD   | \
+     PHY_CONN_100BASE_TX | PHY_CONN_100BASE_TXFD   \
+    )
+
+/*
+ * The PhyInit() <phy_addr> parameter conveys either an explicit PHY
+ * address value in the range of PHY_ADDR_MIN to PHY_ADDR_MAX, or
+ * specifies PHY_ADDR_ANY which directs PhyInit() to search for
+ * the first responding PHY in the range PHY_ADDR_MIN..PHY_ADDR_MAX.
+ * Moreover, in a multiple PHY environment, the caller can use the
+ * PHY_ADDR_NEXT() macro to search for the next responding PHY
+ * starting at an address above the specified value.
+ *
+ * The following examples demonstrate search and initialization of
+ * (a) a single PHY at MII address 5, (b) the first -- and perhaps
+ * only -- PHY found on the MII bus, (c) the first PHY found on the
+ * MII bus excluding PHY 0, which may be reserved for a special
+ * purpose such as hub management.
+ * 
+ *     static PHY       phy_space[MAX_SUPPORTED_PHYS];
+ *     PHY             *phy = &phy_space[0];
+ *     DWORD            my_adapter;     // e.g., MAC register address
+ *
+ *     (a) PhyInit(my_adapter, phy, 5, ...)
+ *     (b) PhyInit(my_adapter, phy, PHY_ADDR_ANY, ...)
+ *     (c) PhyInit(my_adapter, phy, PHY_ADDR_NEXT(PHY_ADDR_MGMT), ...)
+ * 
+ * A multiple PHY (e.g., intelligent hub) search might look something
+ * like this:
+ *
+ *     static PHY       phy_space[MAX_SUPPORTED_PHYS];
+ *     PHY             *phy = &phy_space[0];
+ *     DWORD            my_adapter;     // e.g., MAC register address
+ *     BYTE             phy_addr = PHY_ADDR_ANY;
+ *     PHY_STATUS       status;
+ *
+ *     // Search (and isolate) multiple MII PHYs
+ *     do {
+ *         status = PhyInit(my_adapter, phy, phy_addr,
+ *                          PHY_CONN_CURRENT,
+ *                          PHY_HWOPTS_DONT_CONNECT);
+ *         if (status == PHY_STATUS_NOT_FOUND) {
+ *             break;
+ *         } else if (status != PHY_STATUS_OK) {
+ *             // process other PhyInit() failures ...
+ *         }
+ *         phy_addr = PHY_ADDR_NEXT(phy->addr);
+ *     } while (++phy < &phy_space[MAX_SUPPORTED_PHYS]);
+ */
+#define PHY_ADDR_MIN            ((BYTE) 0)
+#define PHY_ADDR_MAX            ((BYTE) 31)
+#define PHY_ADDR_NEXT(addr)     ((BYTE) -((addr) + 1))
+#define PHY_ADDR_ANY            PHY_ADDR_NEXT(PHY_ADDR_MAX)
+#define PHY_ADDR_MGMT           PHY_ADDR_MIN
+#define PHY_ADDR_0              ((BYTE) 0)
+
+#ifdef _H2INC_                  /* MASM H2INC.exe utility workaround */
+#undef PHY_ADDR_MIN
+#undef PHY_ADDR_MAX
+#undef PHY_ADDR_ANY
+#undef PHY_ADDR_MGMT
+#define PHY_ADDR_MIN            0       /* can't handle type cast?!! */
+#define PHY_ADDR_MAX            31
+#define PHY_ADDR_ANY            -32     /* can't handle macro func */
+#define PHY_ADDR_MGMT           PHY_ADDR_MIN
+#define PHY_ADDR_0              0
+#endif
+
+/*
+ * PhyInit() <hw_options> -- one or more PHY_HWOPTS_* bits as follows.
+ * Many HWOPTS are PHY- or adapter-dependent, and will be silently
+ * ignored if not supported.
+ *
+ * PHY_HWOPTS_* Supported Options:
+ *
+ * NONE         - Don't override any HW defaults
+ *
+ * REPEATER     - Force PHY Repeater mode such that CRS is only asserted
+ *                due to Rx activity.  The default is to force PHY Node
+ *                mode which asserts CRS due to Rx or Tx in half-duplex
+ *                mode only (802.3u CRS behavior is undefined in full-
+ *                duplex mode)
+ *
+ * READ_ONLY    - Read, but don't write to PHY devices.  Useful as a
+ *                diagnostic tool, e.g., the phyck.exe utility to query
+ *                MII and SPI registers without disturbing the
+ *                configuration maintained by a background NDIS driver.
+ *
+ * CK25DIS      - PHY dependent, use with caution.  On the NSC,
+ *                disables CLK25 pin (Hi-Z) if external clock unused.
+ *                This breaks some NICs (SMC 9332, DEC DE500) which
+ *                apparently rely on this output.  On the TDK, invokes
+ *                their R16.RXCC option, which may have adverse side
+ *                effects upon Auto-Negotiation, so the PhyCheck()
+ *                routine trys to compensate by enabling upon link up
+ *                and disabling upon link down.
+ *
+ * TX_BP4B5B    - 100Base-TX bypass 4B/5B endec (repeater applications)
+ * TX_BPSCR     - 100Base-TX bypass scrambler (100Base-FX applications)
+ * TX_BPALIGN   - 100Base-TX bypass all Tx/Rx conditioning
+ *
+ * HWRESET_MASK - Enumerated set of 15 GPIO hardware reset options:
+ *                    HWRESET_GPn     - Active-high reset using GPn
+ *                    HWRESET_GPn_NOT - Active-low  reset using GPn
+ *                    HWRESET_GPn_R12 - Active-high reset using GPn
+ *                                      via obsolete RSS 1161x MAC R12
+ *                    HWRESET_ALL     - Active-high reset using GP[3:0]
+ *                    HWRESET_ALL_NOT - Active-low  reset using GP[3:0]
+ *                    HWRESET_ALL_R12 - Active-high reset using GP[3:0]
+ *                                      via obsolete RSS 1161x MAC R12
+ *                Where GPn is LAN General Purpose I/O GP0, GP1, GP2
+ *                or GP3. The resultant hardware reset pulse is an
+ *                active-high signal, unless the _NOT suffix is
+ *                specified to generate an active-low hardware reset
+ *                pulse.  The _R12 suffix provides a backwards-
+ *                compatible option for use with pre-production devices
+ *                (RSS 11606, 11610 and 11611 and compatibles).
+ *
+ *                The _ALL suffix provides a shotgun, wildcard reset
+ *                against all GPIO signals, GP[3:0].  This is useful in
+ *                cases where none of the GPIO signals are dedicated
+ *                as inputs, and a driver is supporting multiple adapter
+ *                GPIO configurations and there's no adverse affect
+ *                from driving unused GPIO lines.  The _ALL_NOT suffix
+ *                provides an active-low signal on all GP[3:0], and the
+ *                _ALL_R12 provides an active-high signal on all GP[3:0]
+ *                using the antiquated RSS 11611 R12 register interface.
+ *
+ * ISOLATE      - Disable (tri-state) the active HomePNA or MII device's
+ *                data interface and underlying PMD interface.  The
+ *                associated SPI or MDC/MDIO Serial Management Interface
+ *                remains enabled for subsequent management commands.
+ *                This is equivalent to calling PhyDisable().
+ *
+ * HPNA_        - Allow a remote HomePNA master device to reconfigure
+ * CMD_ENABLE     the local HomePNA PHY device's speed and power mode
+ *                settings.  This is normally disabled, as the v1.0
+ *                device implementations have a bug in which noise
+ *                can be mistaken for a remote command, causing
+ *                inadvertant reconfiguration.
+ *
+ * FDX_CRS      - Set PHY-specific CRS option which alters
+ *                the CRS behavior in full-duplex mode to assert CRS
+ *                during transmission rather than during reception
+ *                (its default).  This is an RSS61x MAC SAR-26
+ *                workaround which may (?) alleviate Tx-hangs (SAR-23)
+ *                in full-duplex mode.
+ *
+ * DONT_SWRESET - Don't issue (otherwise) mandatory software reset
+ *
+ * MII_SEARCH_0 - Begin a <PHY_ADDR_ANY> MII search with address-0,
+ *                which was the pre-v1.50 PHY Driver default.
+ *                Otherwise, perform an MII search from addresses 1..31,
+ *                attempting address-0 only if no other MII PHY is
+ *                found.  (Some MII PHYs erroneously treat address-0 as
+ *                a broadcast address, others have side-effects.)
+ *                Unless this option is specified, we try 1..31 followed
+ *                by zero.  If the option is specified, we try 0..31.
+ *
+ * MII_PREAMBLE - If this option is activated, the PHY driver will
+ *                always send a 32-bit MDIO preamble during MII reads
+ *                and writes.  Otherwise, the PHY driver will attempt
+ *                to suppress the 32-bit preamble, provided the device
+ *                hardware supports this feature as indicated by the
+ *                MII register 1.6 status bit.
+ *
+ * NO_MII_      - HomePNA-only NICs can save time by eliminating a
+ * SEARCH         PhyInit() MII device search.
+ *
+ * NO_HPNA      - MII-only NICs can save time by eliminating a
+ * SEARCH         PhyInit() search for both internal (RSS 11623) and
+ *                external HomePNA devices.
+ *
+ * NO_HPNA_     - RSS 11623 NICs can save time by eliminating a
+ * EXT_SEARCH     PhyInit() search for external HomePNA devices.
+ *
+ * HPNA_PORT_   - If this option is selected, a link indication from
+ * PRIORITY       a HPNA device will take precedence over a
+ *                simultaneous link indication from a ethernet 10/100 MII
+ *                device.  Otherwise the default case is for the higher
+ *                speed 10/100 MII device precedence.  This affects
+ *                the PhyCheck() link indication in the unlikely case
+ *                that both devices report link, as only the highest
+ *                priority capability will be reported.  It also has a
+ *                side-effect in that the PhyCheck() routine will switch
+ *                from an MII to HomePNA PHY device whenever the MII
+ *                link goes down (i.e., cable removed from 10/100 Ether
+ *                hub).
+ *
+ * MII_PORT_    - Similar to HPNA_PORT_PRIORITY.  Since by default,
+ * PRIORITY       MII > HPNA, this doesn't affect the simultaneous
+ *                link status.  However, it does determine the default
+ *                port selected (MII) at PhyInit() time and subsequent
+ *                to link down.
+ *
+ * PORT_HOPPING - If this option is selected and multi-port PHY devices
+ *                are present, i.e., both 1M8 HomePNA and 10/100 MII
+ *                devices found, then the PhyCheck() routine will
+ *                force a port hop every LINK_DOWN_HOP_COUNT calls
+ *                when the link is down.  The default value of the
+ *                "phy.c" LINK_DOWN_HOP_COUNT is 5, which allows
+ *                ten seconds per port for a 2-second check period.
+ *                This option should not be enabled when the app/driver
+ *                polls PhyCheck() repeatedly in an initialization loop.
+ *
+ *                This option is recommended for broken PHY devices which
+ *                cannot achieve link while configured in the MII isolate
+ *                mode.  To date, we've found that the National
+ *                Semiconductor DP83840 won't work at all when isolated
+ *                (it also disables its twisted pair PMD interface), and
+ *                the Level One LXT 970 and Enable Semiconductor PHYs
+ *                curiously can achieve link when connected to 10 but
+ *                not 100 Mbit hubs and switches.
+ *
+ *                ------------------------------------------------------
+ *
+ *                Note: the following truth table depicts the complex
+ *                interaction among the PHY_HWOPTS_PORT_HOPPING (HOP),
+ *                PHY_HWOPTS_HPNA_PORT_PRIORITY (HPNA) and the
+ *                PHY_HWOPTS_MII_PORT_PRIORITY (MII) options.  This
+ *                table is only applicable when BOTH devices (HomePNA and
+ *                MII) are present.  As can be seen, MII priority
+ *                primarily affects the PhyInit() default port select,
+ *                HPNA priority primarily affects PhyCheck() in the
+ *                rare (unlikely?) case that both links are up, and
+ *                HOP determines whether a port switch is made when
+ *                both links are down.  As a secondary effect when
+ *                HOP is disabled, MII supercedes HPNA priority when
+ *                both links are down, otherwise HPNA supercedes the
+ *                the current, active port which is retained in the
+ *                default case where no options are in effect.  Whew!
+ *
+ *                What's not depicted is the simple case where only one
+ *                port is reporting link: that port is always selected,
+ *                regardless of multi-port options.
+ *
+ *                         Multi-Port Selection Truth Table           
+ *
+ *                +==================++=================+===========+
+ *                |                  ||    PhyCheck()   |           |
+ *                |  PHY HW option   |+---------+-------+           |
+ *                |                  || Both    | Both  | PhyInit() |
+ *                +=====+======+=====+| Links   | Links | Default   |
+ *                | HOP | HPNA | MII || Down**  | Up    | Port      |
+ *                +=====+======+=====++=========+=======+===========+
+ *     (default)  |  0  |   0  |  0  || current |  MII  |   HPNA    |
+ *                +-----+------+-----++---------+-------+-----------+
+ *                |  0  |   0  |  1  ||   MII*  |  MII  |    MII*   |
+ *                +-----+------+-----++---------+-------+-----------+
+ *                |  0  |   1  |  0  ||  HPNA*  | HPNA* |   HPNA    |
+ *                +-----+------+-----++---------+-------+-----------+
+ *                |  0  |   1  |  1  ||   MII*  | HPNA* |    MII*   |
+ *                +=====+======+=====++=========+=======+===========+
+ *                |  1  |   0  |  0  ||  other* |  MII  |   HPNA    |
+ *                +-----+------+-----++---------+-------+-----------+
+ *                |  1  |   0  |  1  ||  other* |  MII  |    MII*   |
+ *                +-----+------+-----++---------+-------+-----------+
+ *                |  1  |   1  |  0  ||  other* | HPNA* |   HPNA    |
+ *                +-----+------+-----++---------+-------+-----------+
+ *                |  1  |   1  |  1  ||  other* | HPNA* |    MII*   |
+ *                +-----+------+-----++---------+-------+-----------+
+ *
+ *                *  - Indicates behavior change with respect to the
+ *                     default action.
+ *
+ *                ** - With both links down, "current" denotes the
+ *                     currently active port (default or last link),
+ *                     whereas "other" denotes a swap to the other,
+ *                     presently inactive port.  All port switching is
+ *                     governed by the nominal LINK_DOWN_HOP_COUNT
+ *                     value of 5, which yields a 10-second rate
+ *                     assuming a periodic, 2-second PhyCheck() cycle.
+ *                     As such, a link-down port switch won't occur
+ *                     for ten seconds, though a single- or dual-port
+ *                     link-up event will instanly effect a port switch.
+ *
+ *                ------------------------------------------------------
+ *
+ * MAC_         - RSS 11617 and 11623 feature: If this option is selected,
+ * PORT_MGMT      the PHY Driver's PhyInit() and PhyCheck() routines will
+ *                assume management of the MAC Network Access Register
+ *                (NAR, R6 offset 0x30) configuration of PHY port select
+ *                bits [18:17], full-duplex mode select bit [09], and
+ *                the 10/100 speed select bit [22].  All other NAR register
+ *                bits will be retained intact, with the exception that
+ *                if the MAC's transmitter and/or receiver are currently
+ *                running, they may be temporarily stopped (this can take
+ *                up to 5-10 milliseconds) while all MII and HomePNA PHY
+ *                devices are tri-stated, the MAC port is switched, an
+ *                active MII or HomePNA PHY is enabled and then the prior
+ *                receiver and transmitter states are restored.
+ *
+ *                In addition, if a non-null <soft_nar> is passed to the
+ *                PhyInit() routine, the caller can specify the address of
+ *                its 32-bit "soft NAR" register value field which
+ *                presumably contains a driver's local, shadow copy of
+ *                the NAR register contents.  This is HIGHLY recommended
+ *                in conjunction with PHY_HWOPTS_MAC_PORT_MGMT to avoid
+ *                coherency mismatches between the hardware and shadow
+ *                software copies of the NAR register.  In this manner,
+ *                both the MAC device driver and the PhyCheck() routine
+ *                can safely manipulate the NAR register in a single-
+ *                threaded (or blocked deserialized) driver.
+ *
+ * FAST_INIT    - Avoids time consuming MII and SPI searches and device
+ *                parsing PHY devices previously initialized via
+ *                PhyInit().  Effectively re-uses the values discovered
+ *                during the initial PhyInit() call.
+ *
+ *                (Not yet supported)
+ *
+ * STRICT_      - Default unspecified provides "loose" checking by the
+ * PARM_          PhyConnectSet() routine, which is called by PhyInit().
+ * CHECKING       When specified, PhyConnectSet() will reject a
+ *                connection, reporting PHY_STATUS_UNSUPPORTED_MEDIA,
+ *                if *any* <connect> parameter media setting is not
+ *                supported by the device.  In contrast, when
+ *                unspecified, PhyConnectSet() will accept the
+ *                directive if *at least one* <connect> media setting
+ *                is supported by the device(s).  For example, assume
+ *                a 100Base-TX device supporting both full- and
+ *                half-duplex 100Base-TX and 10Base-T operation.  By
+ *                default (#undefined), a <connect> request to
+ *                Auto-Negotiate for these capabilities plus an
+ *                unsupported 100Base-T2 mode is accepted.  In contrast,
+ *                the same <connect> request is rejected due to
+ *                unsupported -T2 service, even though the other
+ *                services are available.
+ *
+ *                It's likely that NIC drivers (NDIS) won't specify
+ *                this option in order to wildcard the connect
+ *                directive to "whatever's possible" whereas diagnostic
+ *                or test utilities may use the option to verify that
+ *                expected devices are present.
+ *
+ * ACTIVE_AN_   - Restarts Auto-negotiation whenever the MII port
+ * RESTART        becomes newly active, i.e., transitions from disabled
+ *                (isolated) to enabled (de-isolated) state.  The
+ *                NSC PHY automatically gets this setting; other PHYs
+ *                may also need to be kicked when coming out of
+ *                isolation.
+ *
+ * ALT_1HZ_     - Use alternate, 1-Hz Conexant link detection algorithm
+ * HPNA_LINK      instead of the standard 0.5 Hz HomePNA algorithm.
+ *                This version only transmits a heartbeat packet if
+ *                neither a PHY-level transmit or receive indication
+ *                occurred during the previous 1-second sample interval.
+ *                This is the preferred option for the 1161x chipset
+ *                family to avoid excessive or late collision
+ *                problems.
+ *
+ * X3_DEVICE    - Force CN7221 (11625) "Ramses" X3 device version
+ *                settings.
+ *
+ * GP0_SPI_DOUT - Use alternate Ramses SPI DOUT interface such that
+ *                LAN_GPIO[0] is read in lieu of EEDO and ROM_CS#
+ *                is used in lieu of LAN_GPIO[0] for Ramses RESET#.
+ *
+ * --------------
+ *
+ * NIC_DEFAULT  - Recommended default (your implementation may vary)
+ * NIC_*        - Various adapter-specific options
+ *
+ * --------------
+ * Discontinued PHY_HWOPTS_* Options (No Longer Supported):
+ *
+ * DEFAULTS     - Replaced by PHY_HWOPTS_NONE to avoid confusion
+ * NODE         - !REPEATER implies NODE, no need for separate control
+ * LED_COL      - Obscure NSC-only option to change COL LED definition
+ * PRE_HWRESET  - Superceded by HWRESET_GP2..5* settings
+ * POST_HWRESET - No compelling need for a hardware reset subsequent
+ *                to the MII search phase of PhyInit().  The updated
+ *                HWRESET_GP2..5* options present ample flexibility for
+ *                NICs whose GPIO are tied to a PHY Reset.
+ * DONT_CONNECT - Replaced by ISOLATE
+ * ISR          - Enable PHY interrupts upon change in link state
+ */
+
+/* Supported Options */
+#define PHY_HWOPTS_NONE                 0x00000000L
+#define PHY_HWOPTS_REPEATER             0x00000001L
+#define PHY_HWOPTS_READ_ONLY            0x00000002L
+#define PHY_HWOPTS_CK25DIS              0x00000004L
+#define PHY_HWOPTS_TX_BP4B5B            0x00000008L
+#define PHY_HWOPTS_TX_BPSCR             0x00000010L
+#define PHY_HWOPTS_TX_BPALIGN           0x00000020L
+#define PHY_HWOPTS_HWRESET_MASK         0x000003C0L /* listed below */
+#define PHY_HWOPTS_ISOLATE              0x00000400L
+#define PHY_HWOPTS_HPNA_CMD_ENABLE      0x00000800L
+#define PHY_HWOPTS_FDX_CRS              0x00001000L
+#define PHY_HWOPTS_DONT_SWRESET         0x00002000L
+#define PHY_HWOPTS_MII_SEARCH_0         0x00004000L
+#define PHY_HWOPTS_MII_PREAMBLE         0x00008000L
+#define PHY_HWOPTS_NO_ETH_SEARCH        0x00010000L
+#define PHY_HWOPTS_NO_HPNA_SEARCH       0x00020000L
+#define PHY_HWOPTS_NO_HPNA_EXT_SEARCH   0x00040000L
+#define PHY_HWOPTS_HPNA_PORT_PRIORITY   0x00080000L
+#define PHY_HWOPTS_MII_PORT_PRIORITY    0x00100000L
+#define PHY_HWOPTS_PORT_HOPPING         0x00200000L
+#define PHY_HWOPTS_MAC_PORT_MGMT        0x00400000L
+#define PHY_HWOPTS_FAST_INIT            0x00800000L
+#define PHY_HWOPTS_STRICT_PARM_CHECKING 0x01000000L
+#define PHY_HWOPTS_ACTIVE_AN_RESTART    0x02000000L
+#define PHY_HWOPTS_ALT_1HZ_HPNA_LINK    0x04000000L // obsolete for JEDI
+#define PHY_HWOPTS_X3_DEVICE            0x08000000L
+#define PHY_HWOPTS_GP0_SPI_DOUT         0x10000000L
+#define PHY_HWOPTS_HPNA7WS              0x20000000L
+#ifdef P51
+#define PHY_HWOPTS_P51_HLAN             0x40000000L
+#endif
+
+/*
+ * PHY HW Reset enumerations via GPIO.  A _GP0.._GP3 suffix identifies
+ * the general purpose I/O output port used to generate a nominal
+ * one microsecond, active-high hardware reset pulse.  An additional
+ * _NOT suffix specifies an active-low reset pulse.  The QSI PHY is an
+ * example of a device requiring an active-low reset.
+ *
+ * Beginning with the production RSS 11617 devices, a.k.a. 11611
+ * version 5 (v5), the GPIO register migrated from MAC register R12 to
+ * R15.  As such, use of pre-production RSS 11611 (v3 and v4), 11610,
+ * 11606 and compatible devices is facilitated via the _R12 suffix
+ * which directs the PHY driver to access GPIO via the antiquated R12
+ * device interface.  Note that the _NOT active-low reset capability
+ * is not supported using these older, obsoleted pre-production devices.
+ * This is strictly a PHY Driver software constraint, and not a hardware
+ * restriction of the earlier devices.
+ *
+ * The _ALL suffixes provide wildcard (shotgun) resets using all four
+ * GPIO[3:0] signal lines.  _ALL and _ALL_NOT provide respective
+ * active-high and active-low reset pulses via the MAC's R15 register,
+ * whereas _ALL_R12 provides an active-high reset pulse using the
+ * antiquated MAC R12 register for older device support.
+ *
+ *      PHY_HWOPTS_HWRESET_MASK         0x03C0L
+ */
+#define PHY_HWOPTS_HWRESET_GP0          0x0040L /* Active-high resets */
+#define PHY_HWOPTS_HWRESET_GP1          0x0080L
+#define PHY_HWOPTS_HWRESET_GP2          0x00C0L
+#define PHY_HWOPTS_HWRESET_GP3          0x0100L
+#define PHY_HWOPTS_HWRESET_GP0_NOT      0x0140L /* Active-low resets */
+#define PHY_HWOPTS_HWRESET_GP1_NOT      0x0180L
+#define PHY_HWOPTS_HWRESET_GP2_NOT      0x01C0L
+#define PHY_HWOPTS_HWRESET_GP3_NOT      0x0200L
+#define PHY_HWOPTS_HWRESET_GP0_R12      0x0240L /* Obsoleted R12 GPIO */
+#define PHY_HWOPTS_HWRESET_GP1_R12      0x0280L
+#define PHY_HWOPTS_HWRESET_GP2_R12      0x02C0L
+#define PHY_HWOPTS_HWRESET_GP3_R12      0x0300L
+#define PHY_HWOPTS_HWRESET_ALL          0x0340L /* Wildcard, all GPIO */
+#define PHY_HWOPTS_HWRESET_ALL_NOT      0x0380L
+#define PHY_HWOPTS_HWRESET_ALL_R12      0x03C0L
+
+/*
+ * PHY_HWOPTS_NIC_* NIC-specific Hardware Options
+ *
+ * Usage is primarily intended for RSS test boards.  OEMs should use
+ * PHY_HWOPTS_NIC_DEFAULT or may #define their own NIC-specific set of
+ * options as necessary.  PHY_HWOPTS_NIC_EN5032 is an example of such
+ * an option.
+ * 
+ * The RSS 11617 (a.k.a. 11611 v5) is the first production LANfinity
+ * MAC device to use the newer, R15 GPIO register.  All others are
+ * pre-production or compatible devices which use the older R12 GPIO
+ * register, hence must use the _R12 suffix to direct the PHY driver
+ * to access GPIO via R12.
+ *
+ * The 11623 (RS7112) with integrated HomePNA PHY, uses GP0 as an
+ * external 10/100 PHY link LED to support the optional PC 98/99
+ * wake-on-link capability.
+ *
+ * The 11617 (RS7111A) reference board, plus pre-production 11611 and
+ * 11610 test boards have GP0 tied to PHY hardware reset.  The original
+ * 11606 test board uses GP3 as PHY hardware reset.
+ */
+#define PHY_HWOPTS_NIC_DEFAULT          PHY_HWOPTS_NONE
+/* Changed PHY_HWOPTS_NIC_RSS11623 define to support 11623/Ramses board.*/
+#define PHY_HWOPTS_NIC_RSS11623         \
+    (PHY_HWOPTS_ALT_1HZ_HPNA_LINK | PHY_HWOPTS_HWRESET_GP0_NOT)     
+#define PHY_HWOPTS_NIC_RSS11611         PHY_HWOPTS_HWRESET_GP0_R12
+#define PHY_HWOPTS_NIC_RSS11610         PHY_HWOPTS_HWRESET_GP0_R12
+#define PHY_HWOPTS_NIC_RSS11606         PHY_HWOPTS_HWRESET_GP3_R12
+#define PHY_HWOPTS_NIC_EN1207           PHY_HWOPTS_NIC_DEFAULT
+#define PHY_HWOPTS_NIC_EN5032           PHY_HWOPTS_NIC_DEFAULT
+#define PHY_HWOPTS_NIC_OEM_GP0          PHY_HWOPTS_HWRESET_GP0
+#define PHY_HWOPTS_NIC_OEM_GP0_NOT      PHY_HWOPTS_HWRESET_GP0_NOT
+
+/* Discontinued Options (no longer supported) */
+#undef PHY_HWOPTS_DEFAULTS      /* was 0x0000 */
+#undef PHY_HWOPTS_NODE          /* was 0x0002 */
+#undef PHY_HWOPTS_LED_COL       /* was 0x0008 */
+#undef PHY_HWOPTS_PRE_HWRESET   /* was 0x0080 */
+#undef PHY_HWOPTS_POST_HWRESET  /* was 0x0100 */
+#undef PHY_HWOPTS_DONT_CONNECT  /* was 0x0400 */
+#undef PHY_HWOPTS_ISR           /* was 0x0800 */
+
+/*
+ * Result codes for many PHY Driver APIs, e.g., PhyInit(), software
+ * PhyReset(), PhyDisable(), PhyEnable(), PhyConnectSet(), etc.
+ */
+typedef enum _phy_status_ {
+    PHY_STATUS_OK = 0,
+    PHY_STATUS_NOT_FOUND,               /* PhyInit() errors ... */
+    PHY_STATUS_UNSUPPORTED_FUNCTION,
+    PHY_STATUS_PORTABILITY_ERROR,
+    PHY_STATUS_RESET_ERROR,             /* PhyReset() bit stuck */
+    PHY_STATUS_UNSUPPORTED_MEDIA,       /* PhyConnSet() error */
+    PHY_STATUS_UNINITIALIZED,
+    PHY_STATUS_ERROR_MISC 
+    /* etc. */
+} PHY_STATUS;
+
+/* PhyEnable() and PhyDisable() <port_select> argument values */
+typedef enum _phy_port_ {
+    /* physical ports */
+    PHY_PORT_NONE     = 0x00,
+    PHY_PORT_MII      = 0x01,   /* 10/100 MII data signals ... */
+    PHY_PORT_MII_PMD  = 0x02,   /* and associated MDI twisted pair */
+    PHY_PORT_HPNA_7WS = 0x04,   /* HPNA 7-wire serial data */
+    PHY_PORT_HPNA_MII = 0x08   /* HPNA Mii */
+} PHY_PORT;
+#define PHY_PORT_MII_DEVICE      (PHY_PORT_MII | PHY_PORT_MII_PMD)
+#define PHY_PORT_HPNA_DEVICES    (PHY_PORT_HPNA_7WS | PHY_PORT_HPNA_MII)
+#define PHY_PORT_ALL             \
+    (PHY_PORT_MII_DEVICE | PHY_PORT_HPNA_DEVICES)
+
+/* PhyLoopback() <mode> options */
+typedef enum _phy_loopback_ {
+    PHY_LOOPBACK_OFF = 0,       /* default  - loopback disabled */
+    PHY_LOOPBACK_MII,           /* short    - MAC/PHY @ MII */
+    PHY_LOOPBACK_PMD,           /* long     - MAC/PHY @ PMD Tx/Rx */
+    PHY_LOOPBACK_REMOTE,        /* external - PMD Rx to Tx (BER test) */
+    PHY_LOOPBACK_10BASE_T       /* ???      - NSC compatibility mode */
+} PHY_LOOPBACK;
+
+
+/* PHY device descriptor */
+
+/* PHY device descriptor */
+#define MAX_MII_PHY		2
+#define JEDI_MII_PHY		0
+#define ETH_MII_PHY		1
+
+
+typedef struct _phy_ {
+#ifndef _H2INC_
+    struct _phy_       *next;   /* Nominal value/usage here */
+#else
+    DWORD              *next;   /* MASM H2INC.exe utility workaroud */
+#endif
+    void				*LinkLayerAdapter;	// HPNALLOBJ
+    int					frame_ctl_length ; // 4 bytes prefix control for JEDI phy, 0: for ethernet phy
+    PHY_PORT            devices;			// indicate what PHYS on the board
+	// set by ??Phy_SetUp can be PHY_PORT_HPNA_DEVICES [|] PHY_PORT_MII_DEVICE
+    PHY_PORT            active_port;
+    PHY_PORT            inactive_port;
+    PHY_PORT            enabled_port;   /* nominally == active_port */
+    DWORD               link_down_count;
+
+	MIIOBJ *pActive_miiphy ;		// point to active mii_phy
+	MIIOBJ mii_phy[MAX_MII_PHY] ;
+
+//	{	// for Ethernet Phy
+	PHY_PORT            mii_port;
+	BOOLEAN             mii_isolated;
+
+	PHY_LOOPBACK        loopback;		// not work for JEDI 
+	WORD                anar;			// ETHERNET only, not for JEDI
+//	}
+
+//	{	// for Jedi HPNA Phy
+	PHY_PORT            hpna_port;
+   BOOLEAN             hpna_link_pending;
+	BOOLEAN             hpna_isolated;
+
+	WORD                ramse_ctrl_reg; /* For ramses only. Shadow of control register */
+
+	int	V1_Detect_Count ;
+#ifdef H2_TX_WORKAROUND
+	DWORD JediPhy_Tx_Buffer_Len ;		
+	DWORD JediPhy_Tx_Buffer_Left ;
+#endif
+//	}
+    struct {
+        DWORD               capability;
+        DWORD               connect;
+        DWORD               mii_link_state;
+        DWORD               hpna_link_state;
+        DWORD               cum_link_state;     /* PhyCheck() report */
+    }                   media;
+    DWORD               initialized;
+
+    DWORD               hw_options;
+
+#ifdef JEDIPHY	// Bright
+    OSFILEOBJ	osfile ;	
+#endif
+} PHY;
+
+
+/* Device initialization code used by the PHY Driver */
+#define PHY_INIT_CODE           0x29FD7A64L  /* magic number */
+#define IS_PHY_INITIALIZED(p)   ((p)->initialized == PHY_INIT_CODE)
+
+/* PHY ID checks, exclusive of 4-bit vendor revision code */
+#define PHYID_RSS_20417(p)      (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x01825010L)
+#define PHYID_NSC_DP83840(p)    (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x20005C00L)
+#define PHYID_QSI_6612(p)       (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x01814400L)
+#define PHYID_LXT_970(p)        (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x78100000L)
+#define PHYID_LXT_971(p)        (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x001378E0L)
+#define PHYID_GEC_NWK936(p)     (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x02821C20L)
+#define PHYID_TDK_2120(p)       (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x0300E540L)
+#define PHYID_DAVICOM_9101(p)   (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x0181B800L)
+#define PHYID_ICS_1890(p)       (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x0015F420L)
+#define PHYID_ENABLE_5V(p)      (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x00437410L)
+#define PHYID_ENABLE_3V(p)      (((p)->mii_phy[ETH_MII_PHY].mii_id & ~0xFL) == 0x00437420L)
+
+/* PHY ID revision codes */
+#define PHYID_REV(p)            ((p)->mii_phy[ETH_MII_PHY].mii_id & 0xFL)
+
+/*
+ * PHY operational mode functions
+ *
+ * The three most commonly used PHY Driver functions are PhyInit(),
+ * PhyCheck(), and PhyWakeOnLink().  PhyInit() is called
+ * upon DriverInit() and subsequent DriverReset() routines.  PhyCheck()
+ * may be repetitively called
+ * at DriverInit() or DriverReset() time to determine an intial
+ * link status, and then periodically invoked, e.g., upon a two-second
+ * DriverCheck() interval.  PhyWakeOnLink() simply enables or disables
+ * the MII and/or HomePNA device's wake-up signals.  The caller is
+ * responsible for other set-ups (e.g., OS and 11623 dependent).
+ *
+ *
+ * PhyInit()           - Find, reset, initialize and attach PHY to
+ *                       media, PhyInit() is the first function which
+ *                       must be called before accessing a PHY device.
+ *                       Returns PHY_STATUS_OK upon successful search
+ *                       and initialization of single or combination
+ *                       10/100 MII and 1M8 HomePNA PHY devices.  The
+ *                       Parameter list is as follows:
+ *
+ *                         DWORD  adapter    - MAC device I/O base addr
+ *                         PHY   *phy        - allocated data struct space
+ *                         BYTE   phy_addr   - MII PHY address or wildcard
+ *                         DWORD  connect    - PhyConnectSet() directive
+ *                         DWORD  hw_options - zero or more PHY_HWOPTS_*
+ *                         DWORD *soft_nar   - null, or used with
+ *                                             PHY_HWOPTS_MAC_PORT_MGMT
+ *
+ * PhyReset()          - Issue PHY software reset
+ *
+ * PhyConnectGet()     - Get PHY connection parameters (Auto-Negotiation
+ *                       on/off, 10/100 Mbps speed, Full-Duplex on/off),
+ *                       plus PHY_CONN_TECHNOLOGY specific settings
+ *
+ * PhyConnectSet()     - Set PHY connection parameters
+ *
+ * PhyDisable()        - Disable/isolate MII (or SPI) and/or PMD ports
+ *
+ * PhyEnable()         - Attach (previously isolated) PHY(s) to media
+ *
+ * PhyCapbilityGet()   - Get device-dependent PHY_CONNECT_ABILITY mask
+ *
+ * PhyCheck ()         - Report operational link state (link down/up,
+ *                       1/10/100 Mbps speed, half/full-duplex mode)
+ *                       plus any error indications
+ *
+ * PhyLastLinkUp()     - Report last known link state reported by
+ *                       PhyCheck().  A zero return value indicates link
+ *                       has never been established.  Note that the link
+ *                       state is zeroed (cleared) whenever PhyInit() or
+ *                       PhyConnectSet() is invoked.
+ *
+ * PhyShutdown()       - Disables PHY and places in power-down mode
+ *
+ * PhyConfigurePort()  - Manually switches a multi-port PHY device per
+ *                       PhyCheck() <link_state>.  If the PhyInit() option
+ *                       PHY_HWOPTS_MAC_PORT_MGMT is selected, this
+ *                       function is automatically called by PhyCheck()
+ *                       upon port change, and will additionally manage
+ *                       the RSS 116xx Network Access Register (NAR)
+ *                       port/speed/duplex/heartbeat settings.  Otherwise,
+ *                       the caller must manually manage the NAR and
+ *                       call this function whenever a PHY port change
+ *                       or PHY_LINK_NEW_MEDIA is detected.  Note that a
+ *                       PHY port change can occur even when the link
+ *                       is down!
+ *
+ * PhyWakeOnLink()     - When enabled, enables the HomePNA interrupt
+ *                       (IMASK) based on receive activity and/or
+ *                       sets external, MII-based GPIO for input to
+ *                       receive a device LINK LED transition.
+ */
+#include "phy.h"
+                             
+#endif /* _PHY_H_ */
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phyregs.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phyregs.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phyregs.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phyregs.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,574 @@
+/****************************************************************************
+*
+*	Name:			phyregs.h
+
+*  Module Description: PHY device register definitions.
+
+*  Copyright © Conexant Systems 1999-2002.
+*  Copyright © Rockwell Semiconductor Systems 1997-1998.
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:20  $
+****************************************************************************/
+
+#ifndef _PHYREGS_H_
+#define _PHYREGS_H_
+
+#include "phytypes.h"
+
+/*----------------------------------------------------------------------
+ * (1) Register Map
+ *
+ * 100Base-X PHY and repeater port Media Independent Interface (MII)
+ * register offsets.  The first sixteen registers are defined by
+ * IEEE 802.3u (100Base-X) and 802.3y (100Base-T2); the next sixteen
+ * registers are reserved for vendor-specific extensions.
+ *--------------------------------------------------------------------*/
+
+/* IEEE-defined standard register set */
+#define MII_BMCR        0x00    /* Basic Mode Control Register */
+#define MII_BMSR        0x01    /* Basic Mode Status Reg */
+
+/* IEEE-defined extended register set */
+#define MII_PHYIDR1     0x02    /* PHY Identifier Register #1 */
+#define MII_PHYIDR2     0x03    /* PHY Identifier Register #2 */
+#define MII_ANAR        0x04    /* Auto-Negotiation Advertisement Reg */
+#define MII_ANLPAR      0x05    /* A-N Link Partner Availability Reg */
+#define MII_ANER        0x06    /* Auto-Negotiation Expansion Reg */
+
+/* Generic vendor extension registers (decimal) */
+#define MII_R16         16
+#define MII_R17         17
+#define MII_R18         18
+#define MII_R19         19
+#define MII_R20         20
+#define MII_R21         21
+#define MII_R22         22
+#define MII_R23         23
+#define MII_R24         24
+#define MII_R25         25
+#define MII_R26         26
+#define MII_R27         27
+#define MII_R28         28
+#define MII_R29         29
+#define MII_R30         30
+#define MII_R31         31
+
+/*----------------------------------------------------------------------
+ * (2) IEEE-defined register set
+ *--------------------------------------------------------------------*/
+
+/* Generic bit-value definitions */
+#define MII_BIT0        0x0001
+#define MII_BIT1        0x0002
+#define MII_BIT2        0x0004
+#define MII_BIT3        0x0008
+#define MII_BIT4        0x0010
+#define MII_BIT5        0x0020
+#define MII_BIT6        0x0040
+#define MII_BIT7        0x0080
+#define MII_BIT8        0x0100
+#define MII_BIT9        0x0200
+#define MII_BIT10       0x0400
+#define MII_BIT11       0x0800
+#define MII_BIT12       0x1000
+#define MII_BIT13       0x2000
+#define MII_BIT14       0x4000
+#define MII_BIT15       0x8000
+
+/* Register 0, Basic Mode Control Register (BMCR) */
+#define BMCR_RESET              0x8000
+#define BMCR_LOOPBACK           0x4000
+#define BMCR_SPEED_100          0x2000
+#define BMCR_AUTONEG_ENABLE     0x1000
+#define BMCR_POWERDOWN          0x0800
+#define BMCR_ISOLATE            0x0400
+#define BMCR_RESTART_AUTONEG    0x0200
+#define BMCR_DUPLEX_MODE        0x0100
+#define BMCR_COLLISION_TEST     0x0080
+#define BMCR_RESERVED           0x007F
+#define BMCR_HW_DEFAULT         \
+    (BMCR_SPEED_100 | BMCR_AUTONEG_ENABLE | BMCR_DUPLEX_MODE)
+
+/* Register 1, Basic Mode Status Register (BMSR) */
+#define BMSR_100BASE_T4         0x8000
+#define BMSR_100BASE_TXFD       0x4000
+#define BMSR_100BASE_TX         0x2000
+#define BMSR_10BASE_TFD         0x1000
+#define BMSR_10BASE_T           0x0800
+#define BMSR_100BASE_T2FD       0x0400
+#define BMSR_100BASE_T2         0x0200
+#define BMSR_RESERVED           0x0180
+#define BMSR_PREAMBLE_SUPPRESS  0x0040
+#define BMSR_AUTONEG_COMPLETE   0x0020
+#define BMSR_REMOTE_FAULT       0x0010
+#define BMSR_AUTONEG_ABILITY    0x0008
+#define BMSR_LINK_STATUS        0x0004
+#define BMSR_JABBER_DETECT      0x0002
+#define BMSR_EXTENDED_CAPABLE   0x0001
+#define BMSR_HW_DEFAULT                 \
+    (BMSR_100BASE_TXFD | BMSR_100BASE_TX |      \
+     BMSR_10BASE_TFD   | BMSR_10BASE_T   |      \
+     BMSR_AUTONEG_ABILITY | BMSR_EXTENDED_CAPABLE)
+
+/* Register 2-3, PHY Identifier Register 1-2 (PHYIDR1-2) */
+#define GET_OUI_OF(phyidr1, phyidr2)                            \
+    ((DWORD) ((phyidr1) << 6) | ((phyidr2) >> 10) & 0x003F))
+#define GET_CANONICAL_OUI_OF(phyidr1, phyidr2)                  \
+    ((BitSwap(((phyidr1) >> 10) & 0x003F) << 16) |              \
+     (BitSwap(((phyidr1) >> 2)  & 0x00FF) <<  8) |              \
+     (BitSwap(((phyidr1) << 6)  & 0x00C0) | (phyidr2 >> 10) & 0x003F)) 
+
+/*
+ * Register 4, Auto-Negotiation Advertisement Register (ANAR).
+ *
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * Warning!  Need to verify that the newer 802.3x and 802.3y bits
+ * match the HW register definitions, as the PHY hardware design
+ * may predate the IEEE specifications.
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+#define ANAR_NEXT_PAGE                  0x8000
+#define ANAR_ACKNOWLEDGE                0x4000
+#define ANAR_REMOTE_FAULT               0x2000
+#define ANAR_100BASE_T2FD               0x1000  /* per 802.3y -T2 */
+#define ANAR_100BASE_T2                 0x0800  /* per 802.3y -T2 */
+#define ANAR_FDX_PAUSE                  0x0400  /* per 802.3x FDX */
+#define ANAR_100BASE_T4                 0x0200
+#define ANAR_100BASE_TXFD               0x0100
+#define ANAR_100BASE_TX                 0x0080
+#define ANAR_10BASE_TFD                 0x0040
+#define ANAR_10BASE_T                   0x0020
+#define ANAR_PROTOCOL_SELECTOR          0x001F
+#define IS_ANAR_PROTOCOL_IEEE_802_3(anar)       \
+    ((anar) & ANAR_PROTOCOL_SELECTOR) == 0x0001
+
+/*
+ * Register 5, Auto-Negotiation Link Partner Ability Register (ANLPAR),
+ * which is the same format as the ANAR (Register 4)
+ */
+#define ANLPAR_NEXT_PAGE                ANAR_NEXT_PAGE
+#define ANLPAR_ACKNOWLEDGE              ANAR_ACKNOWLEDGE
+#define ANLPAR_REMOTE_FAULT             ANAR_REMOTE_FAULT
+#define ANLPAR_100BASE_T2FD             ANAR_100BASE_T2FD
+#define ANLPAR_100BASE_T2               ANAR_100BASE_T2
+#define ANLPAR_FDX_PAUSE                ANAR_FDX_PAUSE
+#define ANLPAR_100BASE_T4               ANAR_100BASE_T4
+#define ANLPAR_100BASE_TXFD             ANAR_100BASE_TXFD
+#define ANLPAR_100BASE_TX               ANAR_100BASE_TX
+#define ANLPAR_10BASE_TFD               ANAR_10BASE_TFD
+#define ANLPAR_10BASE_T                 ANAR_10BASE_T
+#define ANLPAR_PROTOCOL_SELECTOR        ANAR_PROTOCOL_SELECTOR
+#define IS_ANLPAR_PROTOCOL_IEEE_802_3   IS_ANPAR_PROTOCOL_IEEE_802_3
+
+/* Register 6, Auto-Negotiation Expansion Register (ANER) */
+#define ANER_RESERVED                           0xFFE0
+#define ANER_PARALLEL_DETECTION_FAULT           0x0010
+#define ANER_LINK_PARTNER_NEXT_PAGE_ABLE        0x0008
+#define ANER_NEXT_PAGE_ABLE                     0x0004
+#define ANER_PAGE_RECEIVED                      0x0002
+#define ANER_LINK_PARNTER_AUTONEG_ABLE          0x0001
+
+/*----------------------------------------------------------------------
+ * (3a) RSS 20417 100Base-T2 extended register set
+ *--------------------------------------------------------------------*/
+
+/* RSS vendor extension registers */
+#define MII_RSS_TBD     MII_R16
+
+/* Register TBD, TBD */
+#define RSS_RXX_BIT0    MII_BIT0
+
+/*----------------------------------------------------------------------
+ * (3b) NSC DP83840 10/100Base-TX extended register set
+ *--------------------------------------------------------------------*/
+
+/* NSC vendor extension registers */
+#define MII_DCR         0x12    /* Disconnect Counter Reg */
+#define MII_FCSCR       0x13    /* False Carrier Sense Counter Reg */
+#define MII_RECR        0x15    /* Receive Error Counter Reg */
+#define MII_SRR         0x16    /* Silicon Revision Reg */
+#define MII_PCR         0x17    /* PCS Sub-Layer Configuration Reg */
+#define MII_LBREMR      0x18    /* Loopback, Bypass & Rcvr Error Mask */
+#define MII_PAR         0x19    /* PHY Address Reg */
+#define MII_10BTSR      0x1B    /* 10Base-T Status Reg */
+#define MII_10BTCR      0x1C    /* 10Base-T Configuration Reg */
+
+/* Register 23, PCS sublayer Configuration Register (PCR) */
+#define PCR_NRZI_ENABLE         0x8000
+#define PCR_RESERVED            0x4F0B
+#define PCR_TO_DIS              0x2000
+#define PCR_REPEATER_MODE       0x1000
+#define PCR_CLK25DIS            0x0080
+#define PCR_FORCE_LINK_100      0x0040
+#define PCR_FORCE_CONNECT       0x0020
+#define PCR_TX_OFF              0x0010
+#define PCR_LED_COLLISION       0x0004
+
+/* Register 24, Loopback, Bypass & Rx Error Mask Register (LBREMR) */
+#define LBREMR_RESERVED         0x84E1
+#define LBREMR_BP_4B5B          0x4000
+#define LBREMR_BP_SCR           0x2000
+#define LBREMR_BP_ALIGN         0x1000
+#define LBREMR_LB_MASK          0x0B00
+#define LBREMR_LB_OFF           0x0000
+#define LBREMR_LB_10BT          0x0800
+#define LBREMR_LB_XCVR          0x0100
+#define LBREMR_LB_REMOTE        0x0200
+#define LBREMR_LB_UNDEFINED     0x0300
+#define LBREMR_ALT_CRS          0x0040  /* 83840 RevA device feature */
+#define LBREMR_XMT_DS           0x0020  /* 83840 RevA device feature */
+#define LBREMR_CODE_ERR         0x0010
+#define LBREMR_PE_ERR           0x0008
+#define LBREMR_LINK_ERR         0x0004
+#define LBREMR_PKT_ERR          0x0002
+
+/* Register 25, PHY Address Register (PAR) */
+#define PAR_RESERVED            0xFF80
+#define PAR_SPEED_10            0x0040
+#define PAR_CONNECT_STATUS      0x0020
+#define PAR_ADDR_MASK           0x001F
+
+/*----------------------------------------------------------------------
+ * (3c) QSI 6612 10/100Base-TX extended register set
+ *--------------------------------------------------------------------*/
+
+/* Register 17, Mode Control */
+#define QSI_R17_RESERVED_0_1   (MII_BIT0 | MII_BIT1)
+#define QSI_R17_TEST            MII_BIT2
+#define QSI_R17_PHY_ADDR       (MII_BIT3 | MII_BIT4 |           \
+                                MII_BIT5 | MII_BIT6 | MII_BIT7)
+#define QSI_R17_AN_TEST_MODE    MII_BIT8
+#define QSI_R17_RESERVED_9_10  (MII_BIT9 | MII_BIT10)
+#define QSI_R17_BTEXT           MII_BIT11
+#define QSI_R17_T4_PRESENT      MII_BIT12
+#define QSI_R17_RESERVED_13_15 (MII_BIT13 | MII_BIT14 | MII_BIT15)
+
+/* Register 29, Interrupt Source */
+#define QSI_R29_RXERR_CTR_FULL  MII_BIT0
+#define QSI_R29_AN_PAGE_RCVD    MII_BIT1
+#define QSI_R29_PARALLEL_FAULT  MII_BIT2
+#define QSI_R29_AN_LP_ACK       MII_BIT3
+#define QSI_R29_LINK_DOWN       MII_BIT4
+#define QSI_R29_REMOTE_FAULT    MII_BIT5
+#define QSI_R29_AN_COMPLETE     MII_BIT6
+#define QSI_R29_RESERVED_7_15   0xFF80
+
+/* Register 30, Interrupt Mask */
+#define QSI_R30_ENABLE_RXERR_CTR_FULL   QSI_R29_RXERR_CTR_FULL
+#define QSI_R30_ENABLE_AN_PAGE_RCVD     QSI_R29_AN_PAGE_RCVD
+#define QSI_R30_ENABLE_PARALLEL_FAULT   QSI_R29_PARALLEL_FAULT
+#define QSI_R30_ENABLE_AN_LP_ACK        QSI_R29_AN_LP_ACK
+#define QSI_R30_ENABLE_LINK_DOWN        QSI_R29_LINK_DOWN
+#define QSI_R30_ENABLE_REMOTE_FAULT     QSI_R29_REMOTE_FAULT
+#define QSI_R30_ENABLE_AN_COMPLETE      QSI_R29_AN_COMPLETE
+#define QSI_R30_RESERVED_7_14           0x7F80
+#define QSI_R30_INTERRUPT_MODE          MII_BIT15
+
+/* Register 31, BASE-TX PHY Control */
+#define QSI_R31_SCR_DISABLE     MII_BIT0
+#define QSI_R31_MLT3_DISABLE    MII_BIT1
+#define QSI_R31_OPMODE         (MII_BIT2 | MII_BIT3 | MII_BIT4)
+#define QSI_R31_TX_ISOLATE      MII_BIT5
+#define QSI_R31_4B5BEN          MII_BIT6
+#define QSI_R31_RESERVED_7      MII_BIT7
+#define QSI_R31_DCREN           MII_BIT8
+#define QSI_R31_RLBEN           MII_BIT9
+#define QSI_R31_RESERVED_10_11 (MII_BIT10 | MII_BIT11)
+#define QSI_R31_AN_COMPLETE     MII_BIT12
+#define QSI_R31_DISABLE_RXERRCT MII_BIT13
+#define QSI_R31_RESERVED_14_15 (MII_BIT14 | MII_BIT15)
+
+/*----------------------------------------------------------------------
+ * (3d) Level One LXT970 10/100Base-TX extended register set
+ *--------------------------------------------------------------------*/
+
+/* Register 17, Interrupt Enable Register */
+#define LXT_R17_TINT            MII_BIT0
+#define LXT_R17_INTEN           MII_BIT1
+
+/* Register 18, Interrupt Status Register */
+#define LXT_R18_XTALOK          MII_BIT14
+#define LXT_R18_MINT            MII_BIT15
+
+/* Register 19, Configuration Register */
+#define LXT_R19_TX_DISCONNECT   MII_BIT0
+#define LXT_R19_RESERVED_1      MII_BIT1
+#define LXT_R19_100BASE_FX      MII_BIT2
+#define LXT_R19_SCR_BYPASS      MII_BIT3
+#define LXT_R19_4B5B_BYPASS     MII_BIT4
+#define LXT_R19_ADVANCE_TXCLK   MII_BIT5
+#define LXT_R19_LEDC_BITS      (MII_BIT6 | MII_BIT7)
+#define LXT_R19_LEDC_COLLISION  0
+#define LXT_R19_LEDC_OFF        MII_BIT6
+#define LXT_R19_LEDC_ACTIVITY   MII_BIT7
+#define LXT_R19_LEDC_ON        (MII_BIT6 | MII_BIT7)
+#define LXT_R19_LINK_TEST       MII_BIT8
+#define LXT_R19_JABBER_DISABLE  MII_BIT9
+#define LXT_R19_SQE             MII_BIT10
+#define LXT_R19_TP_LPBK_DISABLE MII_BIT11
+#define LXT_R19_MDIO_INT        MII_BIT12
+#define LXT_R19_REPEATER_MODE   MII_BIT13
+#define LXT_R19_TXTEST_100      MII_BIT14
+#define LXT_R19_RESERVED_15     MII_BIT15
+
+/* Register 20, Chip Status Register */
+#define LXT_R20_PLL_LOCK        MII_BIT0
+#define LXT_R20_RESERVED_1      MII_BIT1
+#define LXT_R20_LOW_VOLTAGE     MII_BIT2
+#define LXT_R20_RESERVED_3      MII_BIT3
+#define LXT_R20_MLT3_ERROR      MII_BIT4
+#define LXT_R20_SYMBOL_ERROR    MII_BIT5
+#define LXT_R20_SCR_LOCK        MII_BIT6
+#define LXT_R20_RESERVED_7      MII_BIT7
+#define LXT_R20_PAGE_RECEIVED   MII_BIT8
+#define LXT_R20_AN_COMPLETE     MII_BIT9
+#define LXT_R20_RESERVED_10     MII_BIT10
+#define LXT_R20_SPEED_100       MII_BIT11
+#define LXT_R20_DUPLEX          MII_BIT12
+#define LXT_R20_LINK_UP         MII_BIT13
+#define LXT_R20_RESERVED_14_15 (MII_BIT14 | MII_BIT15)
+
+/*----------------------------------------------------------------------
+ * (3e) GEC Plessey NWK936 10/100Base-TX extended register set
+ *--------------------------------------------------------------------*/
+
+/* "GPS (GEC) Defined" Register 24 */
+#define GEC_R24_ERROR_CODE_0101 MII_BIT0        /* 0 = 0110, 1 = 0101 */
+#define GEC_R24_BPSCR           MII_BIT1
+#define GEC_R24_BPENC           MII_BIT2
+#define GEC_R24_BPALIGN         MII_BIT3
+#define GEC_R24_MF              MII_BIT4
+#define GEC_R24_TEST_MODES     (MII_BIT5 | MII_BIT6)
+#define GEC_R24_LEDCTL          MII_BIT7
+#define GEC_R24_LB10CTL         MII_BIT8
+#define GEC_R24_FRC_TX          MII_BIT9
+#define GEC_R24_FRC_RX          MII_BIT10
+#define GEC_R24_CRS_CTL_FDX_RX  MII_BIT11
+#define GEC_R24_JAB_DIS         MII_BIT12
+#define GEC_R24_SQE_DIS         MII_BIT13
+#define GEC_R24_UNDEF_14_15    (MII_BIT14 | MII_BIT15)
+
+/* "GPS (GEC) Defined" Register 25 */
+#define GEC_R25_AN_STATE       (MII_BIT0 | MII_BIT1 |   \
+                                MII_BIT2 | MII_BIT3)
+#define GEC_R25_AN_ABIL_MATCH   MII_BIT4
+#define GEC_R25_SPEED_100       MII_BIT5
+#define GEC_R25_DUPLEX          MII_BIT6
+#define GEC_R25_AN_COMPLETE     MII_BIT7
+#define GEC_R25_PHY_ADDR       (MII_BIT8  | MII_BIT9  | \
+                                MII_BIT10 | MII_BIT11 | MII_BIT12)
+#define GEC_R25_UNDEF_13_15    (MII_BIT13 | MII_BIT14 | MII_BIT15)
+
+/*----------------------------------------------------------------------
+ * (3f) TDK 78Q2120 10/100Base-TX extended register set
+ *--------------------------------------------------------------------*/
+
+/* Register 16, Vendor Specific Register */
+#define TDK_R16_RXCC            MII_BIT0
+#define TDK_R16_PCSBP           MII_BIT1
+#define TDK_R16_RSVD_2_3       (MII_BIT2 | MII_BIT3)
+#define TDK_R16_RVSPOL          MII_BIT4
+#define TDK_R16_APOL_DISABLE    MII_BIT5
+#define TDK_R16_GPIO0_INPUT     MII_BIT6
+#define TDK_R16_GPIO0_DAT       MII_BIT7
+#define TDK_R16_GPIO1_INPUT     MII_BIT8
+#define TDK_R16_GPIO1_DAT       MII_BIT9
+#define TDK_R16_10BT_NAT_LPBK   MII_BIT10
+#define TDK_R16_SQETEST_INHIBIT MII_BIT11
+#define TDK_R16_RSVD_12_13     (MII_BIT12 | MII_BIT13)
+#define TDK_R16_INTR_HIGH       MII_BIT14
+#define TDK_R16_RPTR            MII_BIT15
+
+/* Register 17, Interrupt Control/Status Register */
+#define TDK_R17_ANEG_COMP_INT   MII_BIT0
+#define TDK_R17_RFAULT_INT      MII_BIT1
+#define TDK_R17_LS_CHG_INT      MII_BIT2
+#define TDK_R17_LP_ACK_INT      MII_BIT3
+#define TDK_R17_PDF_INT         MII_BIT4
+#define TDK_R17_PRX_INT         MII_BIT5
+#define TDK_R17_RXER_INT        MII_BIT6
+#define TDK_R17_JABBER_INT      MII_BIT7
+#define TDK_R17_ANEG_COMP_IE    MII_BIT8
+#define TDK_R17_RFAULT_IE       MII_BIT9
+#define TDK_R17_LS_CHG_IE       MII_BIT10
+#define TDK_R17_LP_ACK_IE       MII_BIT11
+#define TDK_R17_PDF_IE          MII_BIT12
+#define TDK_R17_PRX_IE          MII_BIT13
+#define TDK_R17_RXER_IE         MII_BIT14
+#define TDK_R17_JABBER_IE       MII_BIT15
+
+/* Register 18, Diagnostic Register */
+#define TDK_R18_RSVD_0_7        0x00FF
+#define TDK_R18_RX_LOCK         MII_BIT8
+#define TDK_R18_RX_PASS         MII_BIT9
+#define TDK_R18_RATE_100        MII_BIT10
+#define TDK_R18_DPLX            MII_BIT11
+#define TDK_R18_ANEG_FAIL       MII_BIT12
+#define TDK_R18_RSVD_13_15     (MII_BIT13 | MII_BIT14 | MII_BIT15)
+
+/*----------------------------------------------------------------------
+ * (3g) Davicom 9101 10/100Base-TX extended register set
+ *--------------------------------------------------------------------*/
+
+/* No data sheet as of 04Feb98 ... */
+#define DAV_RXX_BIT0            MII_BIT0
+
+/*----------------------------------------------------------------------
+ * (3h) ICS 1890 10/100Base-TX extended register set per "ICS1890
+ *      10Base-T/100Base-TX Integrated PHYceiver(tm)" data sheet,
+ *      ICS890RevG, dated 21Oct97.
+ *--------------------------------------------------------------------*/
+
+/* Register 16, Extended Control Register */
+#define ICS_R16_CIPHER_DISABLE  MII_BIT0
+#define ICS_R16_RESERVED_1      MII_BIT1
+#define ICS_R16_INVLD_ERR_TEST  MII_BIT2
+#define ICS_R16_NRZI_ENCODING   MII_BIT3
+#define ICS_R16_RESERVED_4      MII_BIT4
+#define ICS_R16_CIPHER_TEST     MII_BIT5
+#define ICS_R16_PHY_ADDR       (MII_BIT6  | MII_BIT7  |         \
+                                MII_BIT8  | MII_BIT9  | MII_BIT10)
+#define ICS_R16_RESERVED_11_14 (MII_BIT11 | MII_BIT12 |         \
+                                MII_BIT13 | MII_BIT14)
+#define ICS_R16_CMDREG_OVERRIDE MII_BIT15
+
+/* Register 17, QuickPoll Detailed Status Register */
+#define ICS_R17_LINK_VALID      MII_BIT0
+#define ICS_R17_REMOTE_FAULT    MII_BIT1
+#define ICS_R17_JABBER_DETECT   MII_BIT2
+#define ICS_R17_SD_100BASE_TX   MII_BIT3
+#define ICS_R17_AN_COMPLETE     MII_BIT4
+#define ICS_R17_PREMATURE_END   MII_BIT5
+#define ICS_R17_HALT_SYMBOL     MII_BIT6
+#define ICS_R17_INVALID_SYMBOL  MII_BIT7
+#define ICS_R17_FALSE_CARRIER   MII_BIT8
+#define ICS_R17_PLL_LOCK_ERROR  MII_BIT9
+#define ICS_R17_RX_SIGNAL_ERROR MII_BIT10
+#define ICS_R17_AN_PROGRESS    (MII_BIT11 | MII_BIT12 | MII_BIT13)
+#define ICS_R17_DUPLEX          MII_BIT14
+#define ICS_R17_DATA_RATE_100   MII_BIT15
+
+/*----------------------------------------------------------------------
+ * (3i) <Your 10/100 MII PHY Device here>
+ *--------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------
+ * (4) HomePNA 1M8 SPI register definitions.  Registers are 8-bits
+ *     except where noted.
+ *--------------------------------------------------------------------*/
+
+/* (4a) HomePNA SPI register map */
+#define HPNA_CONTROL            0x00    /* 16-bit */
+#define HPNA_STATUS             0x02    /* 16-bit */
+#define HPNA_IMASK              0x04    /* 16-bit */
+#define HPNA_ISTAT              0x06    /* 16-bit */
+#define HPNA_TX_PCOM            0x08    /* 32-bit */
+#define HPNA_RX_PCOM            0x0C    /* 32-bit */
+#define HPNA_NOISE              0x10
+#define HPNA_PEAK               0x11
+#define HPNA_NSE_FLOOR          0x12
+#define HPNA_NSE_CEILING        0x13
+#define HPNA_NSE_ATTACK         0x14
+#define HPNA_NSE_EVENTS         0x15
+#define HPNA_AFE_CONTROL        0x16    /* 16-bit CN7221 Ramses dev */
+#define HPNA_SPARE_2            0x17
+#define HPNA_SLC_PEAK_MID       0x18	/* For Ramses only */
+#define HPNA_AID_ADDRESS        0x19
+#define HPNA_AID_INTERVAL       0x1A
+#define HPNA_AID_ISBI           0x1B
+#define HPNA_ISBI_SLOW          0x1C
+#define HPNA_ISBI_FAST          0x1D
+#define HPNA_TX_PULSE_WIDTH     0x1E
+#define HPNA_TX_PULSE_CYCLES    0x1F
+
+/* HomePNA SPI register 0x00, 16-bit HPNA_CONTROL */
+#define HPNA_CONTROL_RESERVED           0x7009
+#define HPNA_CONTROL_HIGH_POWER         0x0002
+#define HPNA_CONTROL_HIGH_SPEED         0x0004
+#define HPNA_CONTROL_POWERDOWN          0x0010
+#define HPNA_CONTROL_STOP_SLICE_ADAPT   0x0020
+#define HPNA_CONTROL_CLEAR_NSE_EVENTS   0x0040
+#define HPNA_CONTROL_STOP_AID_AUTO_ADDR 0x0080
+#define HPNA_CONTROL_CMD_HIGH_SPEED     0x0100
+#define HPNA_CONTROL_CMD_LOW_SPEED      0x0200
+#define HPNA_CONTROL_CMD_HIGH_POWER     0x0400
+#define HPNA_CONTROL_CMD_LOW_POWER      0x0800
+#define HPNA_CONTROL_IGNORE_REMOTE_CMD  0x8000
+
+/* HomePNA SPI register 0x02, 16-bit HPNA_STATUS */
+#define HPNA_STATUS_RESERVED            0x0F8F
+#define HPNA_STATUS_RX_VERSION          0x0010
+#define HPNA_STATUS_RX_SPEED            0x0020
+#define HPNA_STATUS_RX_POWER            0x0040
+#define HPNA_STATUS_INVERT_RXCLK        0x1000
+#define HPNA_STATUS_INVERT_TXCLK        0x2000
+#define HPNA_STATUS_INVERT_CLSN         0x4000
+#define HPNA_STATUS_INVERT_RXCRS        0x8000
+
+/* HomePNA SPI register 0x04, 16-bit HPNA_IMASK */
+#define HPNA_IMASK_RESERVED             0x00F0
+#define HPNA_IMASK_REMOTE_CMD_SENT      0x0001
+#define HPNA_IMASK_REMOTE_CMD_RCVD      0x0002
+#define HPNA_IMASK_PACKET_TRANSMITTED   0x0004
+#define HPNA_IMASK_PACKET_RECEIVED      0x0008
+#define HPNA_IMASK_TXPCOM_READY         0x0100
+#define HPNA_IMASK_RXPCOM_VALID         0x0200
+#define HPNA_IMASK_SW_INTERRUPTS        0xFC00
+
+/* HomePNA SPI register 0x06, 16-bit HPNA_ISTAT */
+#define HPNA_ISTAT_RESERVED             HPNA_IMASK_RESERVED
+#define HPNA_ISTAT_REMOTE_CMD_SENT      HPNA_IMASK_REMOTE_CMD_SENT
+#define HPNA_ISTAT_REMOTE_CMD_RCVD      HPNA_IMASK_REMOTE_CMD_RCVD
+#define HPNA_ISTAT_PACKET_TRANSMITTED   HPNA_IMASK_PACKET_TRANSMITTED
+#define HPNA_ISTAT_PACKET_RECEIVED      HPNA_IMASK_PACKET_RECEIVED
+#define HPNA_ISTAT_TXPCOM_READY         HPNA_IMASK_TXPCOM_READY
+#define HPNA_ISTAT_RXPCOM_VALID         HPNA_IMASK_RXPCOM_VALID         
+#define HPNA_ISTAT_SW_INTERRUPTS        HPNA_IMASK_SW_INTERRUPTS
+
+/* HomePNA SPI NSE_FLOOR register   0x12 @ 13 mV granularity */
+#define HPNA_NSE_FLOOR_HWDEFAULT        0x04
+#define HPNA_NSE_FLOOR_SWOVERRIDE       0x07
+
+/* HomePNA SPI NSE_CEILING register 0x13 @ 13 mV granularity */
+#define HPNA_NSE_CEILING_HWDEFAULT      0xD0    /* 7-bit 0x50? */
+#define HPNA_NSE_CEILING_SWOVERRIDE     0x7F
+
+/* HomePNA SPI NSE_ATTACK  register 0x14 @ 13 mV granularity */
+#define HPNA_NSE_ATTACK_HWDEFAULT       0xF4
+#define HPNA_NSE_ATTACK_SWOVERRIDE      0xF4
+
+/* 11625 Ramses (CN7221) 16-bit AFE_CONTROL test register 0x16 */
+#define HPNA_AFE_CONTROL_PD_TX          0x0001  /* powerdown Tx */
+#define HPNA_AFE_CONTROL_HPCTR          0x0002  /* Shadows reg 0.1 */
+#define HPNA_AFE_CONTROL_PD_RXIFAMP     0x0004  /* powerdown Rx amp */
+#define HPNA_AFE_CONTROL_RXGAIN         0x0008  /* 1=50, 0=30 */
+#define HPNA_AFE_CONTROL_PD_VC          0x0010  /* mid-rail current */
+#define HPNA_AFE_CONTROL_PD_RECTI       0x0020  /* Rx rectifier block */
+#define HPNA_AFE_CONTROL_PD_ENV         0x0040  /* Rx envelope amp */
+#define HPNA_AFE_CONTROL_TRI_REF        0x0080  /* tristate slice ref */
+#define HPNA_AFE_CONTROL_PD_COMP        0x0100  /* Rx slice comparatr */
+#define HPNA_AFE_CONTROL_PEAK_DELAY     0x0E00  /* Noise-to-Peak wait */
+#define HPNA_AFE_CONTROL_NOISE_SLICE    0x3000  /* Noise slice increase */
+#define HPNA_AFE_CONTROL_RESERVED       0xC000
+
+
+#endif /* _PHYREGS_H_ */
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phytypes.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phytypes.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phytypes.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/phytypes.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,173 @@
+/****************************************************************************
+*
+*	Name:			phytypes.h
+*
+*	Description:	PHY driver OS/compiler mapping of simple
+*					BYTE/WORD/DWORD types.
+*
+*	Copyright:		(c) 1997-2002 Conexant Systems Inc.
+*					Personal Computing Division
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:22  $
+****************************************************************************/
+
+#ifndef _PHYTYPES_H_
+#define _PHYTYPES_H_
+
+/*----------------------------------------------------------------------
+ * OS and compiler-specific types here, based on DRV_OS complier switch
+ *--------------------------------------------------------------------*/
+#define NDIS            1
+#define NOVELL_CHSM     2
+#define DRV_OS_UNUSED   3       /* was "SCO" ... see SCO_*, below */
+#define SOLARIS         4
+#define LINUX           5
+#define PKTDRV          6
+#define DOS             7
+#define WIN32_DIAG      8       /* RSS' Win95/NT diagnostic tool */
+#define SCO_MDI         9
+#define SCO_LLI        10
+#define SCO_DLPI       11
+#define SCO_GEMINI     12
+#define VXWORKS        13		/* VxWorks Tornado RTOS */
+#define NO_OS          14		/* No OS Services */
+
+#define DRV_OS	LINUX
+
+#ifndef DRV_OS
+#define DRV_OS  DOS     /* THE lowest common denominator :-/ */
+#endif
+
+#if (DRV_OS == NDIS)
+#include <ndis.h>
+#if !defined(_TYPDEF_H_)
+typedef ULONG DWORD;
+typedef USHORT WORD;
+typedef UCHAR BYTE;
+#endif
+
+#elif (DRV_OS == NOVELL_CHSM)
+#include <odi.h>
+#include <odi_nbi.h>
+#include <cmsm.h>
+
+#ifndef BYTE
+typedef UINT8           BYTE;
+#endif
+
+#ifndef WORD
+typedef UINT16          WORD;
+#endif
+
+#ifndef DWORD
+/* Warning:  <odi.h> UINT32 == unsigned int, not unsigned long */
+typedef unsigned long   DWORD;
+#endif
+
+#elif (DRV_OS == SCO_MDI)
+typedef int             BOOLEAN;
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned long   DWORD;
+
+#elif (DRV_OS == SCO_LLI)
+typedef int             BOOLEAN;
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned long   DWORD;
+
+#elif (DRV_OS == SCO_DLPI)
+typedef int             BOOLEAN;
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned long   DWORD;
+
+#elif (DRV_OS == SCO_GEMINI)
+typedef int             BOOLEAN;
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned long   DWORD;
+
+#elif (DRV_OS == SOLARIS)
+#include <sys/types.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+typedef int             BOOLEAN;
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned long   DWORD;
+
+#elif (DRV_OS == LINUX)
+#include <linux/delay.h>
+/* #include <asm/delay.h> */
+#include <asm/io.h>
+#include <asm/arch/bsptypes.h>
+
+#if !defined(_TYPDEF_H_) 
+	#if 0
+		typedef int             BOOLEAN;
+		typedef unsigned char   BYTE;
+		typedef unsigned short  WORD;
+		typedef unsigned long   DWORD;
+	#endif
+#endif
+
+#elif (DRV_OS == VXWORKS)	/* VxWorks Tornado RTOS */
+#if !defined(_TYPDEF_H_) && !defined(BSPTYPES_H)
+typedef int             BOOLEAN;
+typedef unsigned char   BYTE;
+typedef unsigned short  WORD;
+typedef unsigned long   DWORD;
+#endif
+
+#elif (DRV_OS == PKTDRV)
+#include <pktdrv???.h>
+
+#elif (DRV_OS == WIN32_DIAG)
+#include <windows.h>
+#include "RockDLL.h"    /* NIC diagnostics DLL */
+
+#else                   /* DOS -- Roll our own basic types */
+#if !defined(_TYPDEF_H_)
+	#if 0
+		typedef int             BOOLEAN;
+		typedef unsigned char   BYTE;
+		typedef unsigned short  WORD;
+		typedef unsigned long   DWORD;
+	#endif
+#endif
+
+#endif
+/*--------------------------------------------------------------------*/
+
+/* Be sure the essentials are in place */
+#ifndef TRUE
+#define TRUE            1
+#endif
+#ifndef FALSE
+#define FALSE           0
+#endif
+#ifndef NULL
+#define NULL            ((void *) 0)
+#endif
+
+#endif /* _PHYTYPES_H_ */
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/tesla.c uClinux-2.4.27-uc1/drivers/net/cnxt_emac/tesla.c
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/tesla.c	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/tesla.c	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,1100 @@
+/****************************************************************************
+*
+*	Name:			tesla.c
+*
+*	Description:	HomePlug support for Emac driver for CX821xx products
+*
+*	Copyright:		(c) 2001,2002 Conexant Systems Inc.
+*					Personal Computing Division
+*
+*****************************************************************************
+
+  This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+  This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+more details.
+
+  You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc., 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:22  $
+****************************************************************************/
+
+#define TESLA_MODULE
+
+#if defined(VXWORKS_DRIVER) 
+#include "protoutils.h"
+#include "JxRegSrv.h"
+#endif
+
+#include "osutil.h"
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include "cnxtEmac.h"
+#include <asm/arch/gpio.h>
+#include <asm/arch/cnxtflash.h>
+
+#include "tesla.h"
+
+#define TESLA_DEBUG	1
+
+// Tesla setupframe
+/****************************************************************************
+* int5130SendConfigPacket
+*
+* Get a transmit buffer, fill it in with configuration data and
+* send it to the card
+*
+****************************************************************************/
+#define SIZE_ETHER_ADDRESS       6              // Ethernet/IEEE addresses always 6 bytes long
+#define MIN_ETHER_PACKET_SIZE    60             // Minimum size Ethernet packet we can send (including header)
+#define MAX_ETHER_PACKET_SIZE    1514           // Maximum size Ethernet packet we can send (including header)
+#define INT5130_ENCRYPTION_KEY_LENGTH 8
+
+// Intellon Ethertype
+#define INT5130_FRAME_TYPE_OCTET_1 (0x88)
+#define INT5130_FRAME_TYPE_OCTET_2 (0x7B)
+
+#define INT5130_INIT_FRAME_ENTRY_COUNT (0x05) //Note - change to 4 if not using LCON
+#define INT5130_SET_LOCAL_PARAMETERS                     (0x19)
+#define INT5130_SET_NETWORK_ENCRYPTION_KEY (0x04)
+#define INT5130_REQUEST_PARAMETERS_AND_STATISTICS 	(0x07)
+#define INT5130_SET_TRANSMIT_CHARACTERISTICS (0x1F)
+#define INT5130_LOCAL_PARAMETER_LENGTH                   (6)
+#define INT5130_SET_TRANSMIT_CHARACTERISTICS_LENGTH (3)
+
+/* Here are the bit masks for the first transmit characteristics octet. */
+#define INT5130_LCO_MASK (0x80)
+#define INT5130_LCO_ON (0x80)
+
+#define INT5130_ENCF_MASK (0x40)
+#define INT5130_ENCF_ON (0x40)
+
+#define INT5130_TXPRIO_MASK (0x30)
+#define INT5130_CAP0 (0x00)
+#define INT5130_CAP1 (0x10)
+#define INT5130_CAP2 (0x20)
+#define INT5130_CAP3 (0x30)
+
+#define INT5130_RESPEXP_MASK           (0x08)
+#define INT5130_RESPEXP_ON             (0x08)
+
+#define INT5130_TX_CONT_FREE_MASK      (0x04)
+#define INT5130_TX_CONT_FREE_ON        (0x04)
+
+#define INT5130_CONT_FREE_TOKEN_MASK   (0x02)
+#define INT5130_CONT_FREE_TOKEN_ON		(0x02)
+
+#define INT5130_TX_WITH_TOKEN_MASK     (0x01)
+#define INT5130_TX_WITH_TOKEN_ON       (0x01)
+
+/* Here are the bit masks for the second transmit characteristics octet. */
+#define INT5130_RETRY_CTL_MASK (0xC0)
+#define INT5130_RETRY_CTL_NONE (0x00)
+
+#define INT5130_RETRY_CTL_ONE (0x40)
+#define INT5130_RETRY_CTL_ALL (0x80)
+
+#define INT5130_BUFFER_PUT(nValue) *pSendBuf++ = nValue; nSendSize +=1;
+
+#define INT5130_BUFFER_PUT_ADDR(pAddr) MOVE_MEMORY(pSendBuf, pAddr, SIZE_ETHER_ADDRESS); \
+	pSendBuf += SIZE_ETHER_ADDRESS; nSendSize += SIZE_ETHER_ADDRESS;
+
+#define INT5130_BUFFER_PUT_KEY(pKey) MOVE_MEMORY( pSendBuf, pKey, INT5130_ENCRYPTION_KEY_LENGTH); \
+	pSendBuf += INT5130_ENCRYPTION_KEY_LENGTH; nSendSize += INT5130_ENCRYPTION_KEY_LENGTH;
+
+// This is Tesla Control struct with default values, do not modify it
+TeslaControl_Str Default_TeslaControl =
+{
+	TRUE ,
+	{0x4C,0x76,0x4A,0xF8,0xE0,0x12,0xD6,0x47},
+	CA1 ,
+	TRUE ,
+	TX_NORMAL_RETRY ,
+	{"HomePlug"} ,
+	FALSE ,
+	{0,0,0,0,0,0,0,0},
+	1 ,
+	AFE_ADI ,
+	ALG_NONE ,
+	120 ,
+	{0x00,0x05,0x04,0x0c,0x06,0x80,0x12,0x69,0x13,0x69,0x14,0x69,0x00,0x00,0x00,0x00},
+	19
+} ;
+
+#if 0
+TeslaControl_Str Current_TeslaControl =
+{
+	FALSE ,
+	{0x01,0xf2,0xe3,0xd4,0xc5,0xb6,0xa7,0x98},
+	CA1 ,
+	TRUE ,
+	TX_NORMAL_RETRY ,
+	FALSE ,
+	{0,0,0,0,0,0,0,0},
+	1 ,
+	AFE_ADI ,
+	ALG_NONE ,
+	120 ,
+	{0x00,0x05,0x04,0x0c,0x06,0x80,0x12,0x69,0x13,0x69,0x14,0x69,0x00,0x00,0x00,0x00},
+	19
+} ;
+#else
+TeslaControl_Str Current_TeslaControl = {0};
+#endif
+
+
+#define MAX_BUF				256
+
+BYTE teslaflashParams[MAX_BUF];
+
+
+/*******************************************************************************
+FUNCTION NAME:
+	teslaflashGetParams
+
+ABSTRACT:	
+	Get the home plug parameters from the Tesla flash storage segment.
+
+RETURN:
+	Status
+
+DETAILS:
+*******************************************************************************/
+
+static void teslaflashGetParams( void )
+{
+
+	CNXT_FLASH_STATUS_E flashStatus;
+	CNXT_FLASH_SEGMENT_E segment = CNXT_TESLA_FLASH_SEGMENT;
+	int		i;
+	BYTE	*pteslaParams;
+
+	flashStatus = CnxtFlashOpen( segment );
+
+	switch( flashStatus )
+	{
+		case CNXT_FLASH_DATA_ERROR:
+			printk("Flash Data Error: CNXT_FLASH_SEGMENT_%d\n", segment+1 );
+
+			// Get the default home plug device parameters
+			pteslaParams = (BYTE *)&Default_TeslaControl;
+	
+			for( i = 0; i < sizeof(TeslaControl_Str); i++ )
+			{
+				teslaflashParams[i] = *pteslaParams;
+				pteslaParams++;
+			}
+
+			// Update the flash device with the default home plug parameters
+			flashStatus = CnxtFlashWriteRequest( 
+				segment, 
+				(UINT16 *)&teslaflashParams[0],
+				sizeof(TeslaControl_Str)
+			);
+			break;
+
+		case CNXT_FLASH_OWNER_ERROR:
+			printk("Wrong owner for requested Flash Segment!\n");
+			break;
+
+		default:
+
+			CnxtFlashReadRequest( 
+				segment, 
+				(UINT16 *)&teslaflashParams,
+				sizeof(TeslaControl_Str)
+			);
+
+			pteslaParams = (BYTE *)&Current_TeslaControl;
+
+			// Update the home plug device parameter structure
+			// with the values saved in the flash device.
+			for( i = 0; i < sizeof(TeslaControl_Str); i++ )
+			{
+				*pteslaParams = teslaflashParams[i];
+				pteslaParams++;
+			}
+			printk("Flash Data Success: CNXT_FLASH_SEGMENT_%d\n", segment+1 );
+			break;
+	}
+}
+
+
+static const UCHAR BroadcastAddress[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+/****************************************************************************
+* TransmitPriorities
+*
+* These bit masks are indexed by the Configured Transmit Priority setting.
+*
+****************************************************************************/
+
+static const UCHAR TransmitPriorities[] = {INT5130_CAP0, INT5130_CAP1, INT5130_CAP2, INT5130_CAP3 };
+
+/****************************************************************************
+* RetryControls
+*
+* These bit masks are indexed by the Configured Retry Control setting.
+*
+****************************************************************************/
+static UCHAR const RetryControls[]      = {INT5130_RETRY_CTL_NONE, INT5130_RETRY_CTL_ONE, INT5130_RETRY_CTL_ALL};
+
+/****************************************************************************
+* int5130SendCharacteristicsInit
+*
+* Construct the send characteristics from the supplied parameters.
+*
+* SendCharacteristics0 Bits
+*        7     (LC0)                Local Consumption only flag (not configurable)
+*        6     (ENCF)               Encryption enable flag
+*        5-4   (TxPriority)         Transmit Priority (CAP0=00b CAP1=01b CAP2=10b CAP3=11b)
+*        3     (RESP_EXP)           Response Expected Flag
+*        2     (TX_CONT_FREE)       Transmit contention free period (not configurable)
+*        1     (CONT_FREE_TOKEN)    Contention Token (not configurable)
+*        0     (TX_WITH_TOKEN)      Transmit with token (not configurable)
+*
+* SendCharacteristics1 Bits
+*        7-6   (RETRY_CTRL)         Retry Control
+*        5-0   (RESERVED)           Reserved Bits
+*
+* SendCharacteristics1 Bits
+*        7-0   (ENCRYPT_KEY_SELECT) Which Encryption Key o use (if SendChar0 Bit 7 is set)
+*                                   00000000b - Use Default Key
+*                                   00000001b - Use Network Key
+*
+****************************************************************************/
+static EMAC_DRV_CTRL *MACAdapter = NULL ;	// TBD
+
+void Emac_TeslaSetup( TESLA_HANDLE Tesla_Adapter, TeslaControl_Str *pTeslaControl )
+{
+
+	ADDR_TBL *FreeTxBuffer;
+
+	PUCHAR  pSendBuf ;
+	ULONG   nSendSize   = 0;
+	UCHAR    cfgSendCharacteristics0 ;    // 0x18,   LCO, EncryptFlag, TxPriority, ResponseExpected, TxToken Stuff
+	UCHAR    cfgSendCharacteristics1 ;    // 0x80,   Retry Control 00=NoRetry 01=OneRetry 10=All Retry?
+	short	i;
+
+	if( Tesla_Adapter )
+	{
+		MACAdapter = (EMAC_DRV_CTRL *)Tesla_Adapter ;
+	}
+
+	if (pTeslaControl->ChipSelectGpio != -1)
+	{
+		WriteGPIOData(pTeslaControl->ChipSelectGpio, 1);		// set high for Homeplug MAC select
+	}
+
+   // Setup send characteristic 0
+	cfgSendCharacteristics0 = TransmitPriorities[pTeslaControl->TransmitPriority] ;
+	if ( pTeslaControl->EncryptEnableFlag )
+	{
+		cfgSendCharacteristics0 |= INT5130_ENCF_MASK;
+	}
+	if ( pTeslaControl->ResponseExpected )
+	{
+		cfgSendCharacteristics0 |= INT5130_RESPEXP_ON;
+	}
+
+   // Setup send characteristic 1
+	cfgSendCharacteristics1 = RetryControls[pTeslaControl->RetryControl] ;
+
+	FreeTxBuffer = Get_Free_Tx_Buffer( MACAdapter) ;
+	pSendBuf = (UINT8 *)Packet_Buffer_Virtual_Adr(FreeTxBuffer) ;
+
+//     NdisStallExecution(50);
+//     NdisStallExecution(50);
+
+   // Put standard Ethernet header into buffer (dest source type)
+   INT5130_BUFFER_PUT_ADDR(BroadcastAddress);
+
+	MAC_Assign_MacAddress( MACAdapter, pSendBuf ) ;
+	pSendBuf += SIZE_ETHER_ADDRESS;
+	nSendSize += SIZE_ETHER_ADDRESS;
+
+//   INT5130_BUFFER_PUT_ADDR(MACAdapter->node_address);
+   
+   INT5130_BUFFER_PUT(INT5130_FRAME_TYPE_OCTET_1);
+   INT5130_BUFFER_PUT(INT5130_FRAME_TYPE_OCTET_2);
+                 
+   /* Indicate the number of data entries to follow. */
+   INT5130_BUFFER_PUT(INT5130_INIT_FRAME_ENTRY_COUNT);
+
+   /* Construct local parameters frame. */
+   INT5130_BUFFER_PUT(INT5130_SET_LOCAL_PARAMETERS);
+   INT5130_BUFFER_PUT(INT5130_LOCAL_PARAMETER_LENGTH);
+
+   /* Insert another copy of the MAC address. */
+	MAC_Assign_MacAddress( MACAdapter, pSendBuf ) ;
+	pSendBuf += SIZE_ETHER_ADDRESS; nSendSize += SIZE_ETHER_ADDRESS;
+
+   /* Construct xmit characteristics frame for local consumption only. */
+   INT5130_BUFFER_PUT(INT5130_SET_TRANSMIT_CHARACTERISTICS);
+   INT5130_BUFFER_PUT(INT5130_SET_TRANSMIT_CHARACTERISTICS_LENGTH);
+
+   //Tesla - need to construct cfgSendCharacteristics0 from 
+   //		RetrievedRegistryValues->EncryptFlag, TxPriority, ResponseExpected, TxToken Stuff
+   INT5130_BUFFER_PUT(INT5130_LCO_ON | cfgSendCharacteristics0);
+   INT5130_BUFFER_PUT(cfgSendCharacteristics1);
+   INT5130_BUFFER_PUT( (UCHAR)pTeslaControl->NetworkKeySelect ) ;
+
+   /* Construct two encryption key frames. */
+   /* First, put in the default key. */
+   INT5130_BUFFER_PUT(INT5130_SET_NETWORK_ENCRYPTION_KEY);
+   INT5130_BUFFER_PUT(INT5130_ENCRYPTION_KEY_LENGTH+1);
+   INT5130_BUFFER_PUT(0);  /* Default Key */
+
+	INT5130_BUFFER_PUT_KEY( pTeslaControl->DefaultKeyOverride );
+#if 0
+	MAC_Assign_MacAddress( MACAdapter, pSendBuf+2 ) ;
+	// make DefaultEncryptionKey
+	pSendBuf[0] = pSendBuf[6];
+	pSendBuf[1] = pSendBuf[7];
+	pSendBuf += INT5130_ENCRYPTION_KEY_LENGTH; nSendSize += INT5130_ENCRYPTION_KEY_LENGTH;
+#endif
+
+   /* Now the network key. */
+   INT5130_BUFFER_PUT(INT5130_SET_NETWORK_ENCRYPTION_KEY);
+   INT5130_BUFFER_PUT(INT5130_ENCRYPTION_KEY_LENGTH+1);
+   INT5130_BUFFER_PUT( (UCHAR)pTeslaControl->NetworkKeySelect ) ;
+	INT5130_BUFFER_PUT_KEY(pTeslaControl->NetworkEncryptionKey);
+
+   /* Construct xmit characteristics frame NOT for local consumption. */
+   INT5130_BUFFER_PUT(INT5130_SET_TRANSMIT_CHARACTERISTICS);
+   INT5130_BUFFER_PUT(INT5130_SET_TRANSMIT_CHARACTERISTICS_LENGTH);
+   INT5130_BUFFER_PUT(cfgSendCharacteristics0);
+   INT5130_BUFFER_PUT(cfgSendCharacteristics1);
+   INT5130_BUFFER_PUT( (UCHAR)pTeslaControl->NetworkKeySelect ) ;
+
+   // Pad out to minimum packet size
+   if (nSendSize < MIN_ETHER_PACKET_SIZE)
+   {
+      ZERO_MEMORY(pSendBuf, MIN_ETHER_PACKET_SIZE-nSendSize); /* Zero out the padded memory */
+      nSendSize = MIN_ETHER_PACKET_SIZE;
+	}
+
+	MAC_Send_A_Frame( MACAdapter, nSendSize, FreeTxBuffer, TRUE ) ;
+
+	// Set up AFE if type is defined as ADI in config.reg
+
+	if (pTeslaControl->AfeType == AFE_ADI)
+	{
+		// configure settings
+		for (i = 0; i < pTeslaControl->RegisterConfig[1]; i++)
+			Write_ADI_AFE(
+				pTeslaControl->RegisterConfig[2*(i+1)],		// reg address
+				pTeslaControl->RegisterConfig[2*(i+1)+1],	// value to program
+				pTeslaControl->ChipSelectGpio);
+	}
+}
+
+/****************************************************************************
+* End Of Tesla int5130SendConfigPacket
+****************************************************************************/
+
+#if 0	// TBD , collect code in this module
+
+//Tesla - Initialize Encryption Keys
+
+	UCHAR bNullKey[INT5130_ENCRYPTION_KEY_LENGTH] = {0};
+	UCHAR bNetworkKeyDefault[INT5130_ENCRYPTION_KEY_LENGTH] = {0x01, 0xf2, 0xe3, 0xd4, 0xc5, 0xb6, 0xa7, 0x98};
+	#define KEY_IS_NULL(key)  NdisEqualMemory(key, bNullKey, INT5130_ENCRYPTION_KEY_LENGTH)
+
+
+/****************************************************************************
+* int5130EncryptKeysInit
+*
+* Complete the initialization of our encryption keys, based on what was
+* originally read from the registry.
+*
+* This routine assumes that our network address has already been setup.
+*
+****************************************************************************/
+VOID
+EncryptKeysInit(
+	IN PULONG SourceValue, //RetrievedRegistryValues[OVERRIDE_DEFAULT_KEY_KEY]
+	IN UCHAR DefaultKey[INT5130_ENCRYPTION_KEY_LENGTH], //Adapter->DefaultEncryptionKey
+	IN UCHAR NetworkKey[INT5130_ENCRYPTION_KEY_LENGTH], //Adapter->NetworkEncryptionKey
+	IN PUCHAR RegistryNetworkAddress
+	)
+{
+	// Check to see if we need to initialize our default key
+   if (!SourceValue || KEY_IS_NULL(DefaultKey)) //pCard->cfg.cfgDefaultEncryptKey
+		{
+		//Do the hash for the default encryption key. We use the lower 16 bits of the MAC addr
+		//for the upper 16 bits of 64 and then the entire 48 bits of the MAC addr for the rest.
+		NdisMoveMemory(DefaultKey, &RegistryNetworkAddress[4], 2);
+		NdisMoveMemory(&DefaultKey[2], RegistryNetworkAddress, 6);
+		}
+DbgPrint("DefaultKey %x \n", DefaultKey);
+DbgPrint("RegistryNetAddr %x \n", RegistryNetworkAddress);
+   
+	// Check to see if we need to initialize our network key
+	if (KEY_IS_NULL(NetworkKey))
+		{
+		NdisMoveMemory(NetworkKey, bNetworkKeyDefault, INT5130_ENCRYPTION_KEY_LENGTH);
+		}
+}
+
+
+//Tesla read encryption key from registry-used in following function
+/****************************************************************************
+* UniCharToNibble
+*
+* Convert a unicode character  to a hex nibble.  Return 0xFF if its not a legal
+* hex nibble.
+*
+****************************************************************************/
+UCHAR UniCharToNibble(SHORT wNibble)
+{
+   UCHAR nNibble;
+
+   // We only care about the lower byte
+   wNibble &= 0xff;
+   
+   if (wNibble >= '0' && wNibble <= '9')
+      nNibble = wNibble - '0';
+   else if (wNibble >= 'A' && wNibble <= 'F')
+      nNibble = (wNibble - 'A') + 10;
+   else if (wNibble >= 'a' && wNibble <= 'f')
+      nNibble = (wNibble - 'a') + 10;
+   else
+      nNibble = 0xff;
+
+   return nNibble;
+}
+
+// Tesla read encryption key from registry
+/****************************************************************************
+* CfgReadEncryptKey
+*
+* Read an encryption key from the registery (as a unicode string), and
+* convert it to an 8 byte binary array.
+*
+* NOTE: NOTE: For Win 95 Gold and Win 95 OSR-1, Registry Strings are ASCII (not Unicode)
+* If you really want to support these, check if nKeyLength == INT5130_ENCRYPTION_KEY_LENGTH.
+* If it is assume its ASCII and proceed accordingly.
+*
+* All other Windows versions starting with Win 95 OSR-2 store registery strings
+* as unicode.
+*
+* This routine is good for Win 95 OSR-2 and newer versions of Windows O/S.
+*
+****************************************************************************/
+VOID
+ReadEncryptKey(
+	IN PUNICODE_STRING SourceString,
+	IN UCHAR EncryptKey[INT5130_ENCRYPTION_KEY_LENGTH]
+	)
+{
+//   PNDIS_CONFIGURATION_PARAMETER pCfgParam;
+	UCHAR	key[INT5130_ENCRYPTION_KEY_LENGTH];
+	PUSHORT	pHexString;
+	PUCHAR	pHexByte    = key;
+	BOOLEAN	bGoodHex    = TRUE;
+	UCHAR	nNibbleHi;
+	UCHAR	nNibbleLo;
+	int		nKeyUniLen;
+	int		nKeySize;
+	int		i;
+
+	{
+
+   
+	nKeyUniLen	= SourceString->Length;
+	pHexString	= (PUSHORT)(&(SourceString->Buffer[0]));
+
+	// Don't overflow our key buffer.
+	nKeySize = nKeyUniLen / 2;
+	if (nKeySize > INT5130_ENCRYPTION_KEY_LENGTH)
+		nKeySize = INT5130_ENCRYPTION_KEY_LENGTH;
+      
+		for (i=0; i<nKeySize; i++)
+		{
+			nNibbleHi = UniCharToNibble(*pHexString++);
+			nNibbleLo = UniCharToNibble(*pHexString++);
+
+			if (nNibbleHi == 0xff || nNibbleLo == 0xff)
+			{
+				bGoodHex = FALSE;
+				break;
+			}
+
+			*pHexByte++ = (nNibbleHi << 4) + nNibbleLo;
+		}
+
+	if (bGoodHex == TRUE)
+		{
+			NdisMoveMemory(EncryptKey, key, INT5130_ENCRYPTION_KEY_LENGTH);
+		}
+	}  
+	return;
+}
+
+
+{
+   if (RetrievedRegistryValues[ENCRYPT_ENABLE_FLAG_KEY])  //(Adapter->cfgEncryptEnableFlag)
+      Adapter->cfgSendCharacteristics0 |= INT5130_ENCF_MASK;
+   if (RetrievedRegistryValues[RESPONSE_EXPECTED_KEY])  //(Adapter->cfgResponseExpected)
+      Adapter->cfgSendCharacteristics0 |= INT5130_RESPEXP_ON;
+
+   // Setup send characteristic 1
+   Adapter->cfgSendCharacteristics1    = RetryControls[RetrievedRegistryValues[RETRY_CONTROL_KEY]]; //RetryControls[Adapter->cfgRetryControl];
+}
+#endif
+
+
+// return FALSE if failed (ex: Emac not started)
+
+// TBD : not worked as specified, Kludge for HomePlug only
+// TBD : need to move to emac instead of tesla
+BOOLEAN Emac_Phy_Attached( Emac_DevType *pPort1, Emac_DevType *pPort2 )
+{
+
+	if( MACAdapter )
+		*pPort1 = Emac_HomePlug_Phy ;
+	else
+		*pPort1 = Emac_Ethernet_Phy ;
+
+	*pPort2 = Emac_Ethernet_Phy ;
+	return TRUE ;
+}
+
+
+// Save Tesla control specified by TeslaControl into config.reg
+// return FALSE : if fail to write
+BOOLEAN Emac_TeslaConfigSave( TeslaControl_Str *TeslaControl ) 
+{
+	Current_TeslaControl = *TeslaControl ;
+	Emac_TeslaCurrentConfigSave( NULL) ;
+
+	return TRUE ;
+}
+
+// Read the current Tesla control into TeslaControl
+// Return TRUE :  If Emac read these settings from config.reg successfully else
+// Return FALSE : Emac would still load the default settings into TeslaControl
+BOOLEAN Emac_TeslaConfigRead( TeslaControl_Str *TeslaControl ) 
+{
+	BOOLEAN    bResult = FALSE;
+
+#if OS_FILE_SYSTEM_SUPPORTED
+	JX_REG_VAL_DESC PortConfigDesc[] =
+	{
+		{
+			"EncryptEnableFlag",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->EncryptEnableFlag),
+			&TeslaControl->EncryptEnableFlag
+		},
+		{
+			"NetworkEncryptionKey",
+			JX_REG_VAL_BINARY,
+			sizeof(TeslaControl->NetworkEncryptionKey),
+			&TeslaControl->NetworkEncryptionKey
+		},
+		{
+			"TransmitPriority",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->TransmitPriority),
+			&TeslaControl->TransmitPriority
+		},
+		{
+			"ResponseExpected",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->ResponseExpected),
+			&TeslaControl->ResponseExpected
+		},
+		{
+			"RetryControl",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->RetryControl),
+			&TeslaControl->RetryControl
+		},
+		{
+			"OverrideDefaultKey",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->OverrideDefaultKey),
+			&TeslaControl->OverrideDefaultKey
+		},
+		{
+			"DefaultKeyOverride",
+			JX_REG_VAL_BINARY,
+			sizeof(TeslaControl->DefaultKeyOverride),
+			&TeslaControl->DefaultKeyOverride
+		},
+		{
+			"NetworkKeySelect",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->NetworkKeySelect),
+			&TeslaControl->NetworkKeySelect
+		},
+		{
+			"AfeType",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->AfeType),
+			&TeslaControl->AfeType
+		},
+		{
+			"OptSettingAlgorithm",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->OptSettingAlgorithm),
+			&TeslaControl->OptSettingAlgorithm
+		},
+		{
+			"AlgorithmTime",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->AlgorithmTime),
+			&TeslaControl->AlgorithmTime
+		},
+		{
+			"RegisterConfig",
+			JX_REG_VAL_BINARY,
+			sizeof(TeslaControl->RegisterConfig),
+			&TeslaControl->RegisterConfig
+		},
+		{
+			"ChipSelectGpio",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->ChipSelectGpio),
+			&TeslaControl->ChipSelectGpio
+		}
+	};
+
+	JX_REG_KEY_HANDLE   hKey    = NULL;
+
+	*TeslaControl = Default_TeslaControl ;	// set default 
+
+	if((hKey = JxRegOpenKey(NULL, HOMEPLUG_ROOT_KEY)) != NULL)
+	{
+		bResult = JxRegQueryStruct
+		(
+			hKey,
+			NUMBER_OF_ELEMENTS(PortConfigDesc),
+			PortConfigDesc
+		);
+
+		JxRegCloseKey(hKey);
+	}
+
+	Current_TeslaControl = *TeslaControl ;
+#else
+	
+	teslaflashGetParams();
+
+	// Parameters in the Current_TeslaControl structure were
+	// loaded from the data stored in the flash device.
+	*TeslaControl = Current_TeslaControl;
+	bResult = TRUE;
+#endif
+	return bResult;
+}
+
+BOOLEAN static Emac_TeslaConfigSaveToFile( TeslaControl_Str *TeslaControl )
+{
+	BOOLEAN    bResult = FALSE;
+
+#if OS_FILE_SYSTEM_SUPPORTED
+	struct JX_REG_VAL_DESC PortConfigDesc[] =
+	{
+		{
+			"EncryptEnableFlag",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->EncryptEnableFlag),
+			&TeslaControl->EncryptEnableFlag
+		},
+		{
+			"NetworkEncryptionKey",
+			JX_REG_VAL_BINARY,
+			sizeof(TeslaControl->NetworkEncryptionKey),
+			&TeslaControl->NetworkEncryptionKey
+		},
+		{
+			"TransmitPriority",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->TransmitPriority),
+			&TeslaControl->TransmitPriority
+		},
+		{
+			"ResponseExpected",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->ResponseExpected),
+			&TeslaControl->ResponseExpected
+		},
+		{
+			"RetryControl",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->RetryControl),
+			&TeslaControl->RetryControl
+		},
+		{
+			"OverrideDefaultKey",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->OverrideDefaultKey),
+			&TeslaControl->OverrideDefaultKey
+		},
+		{
+			"DefaultKeyOverride",
+			JX_REG_VAL_BINARY,
+			sizeof(TeslaControl->DefaultKeyOverride),
+			&TeslaControl->DefaultKeyOverride
+		},
+		{
+			"NetworkKeySelect",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->NetworkKeySelect),
+			&TeslaControl->NetworkKeySelect
+		},
+		{
+			"AfeType",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->AfeType),
+			&TeslaControl->AfeType
+		},
+		{
+			"OptSettingAlgorithm",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->OptSettingAlgorithm),
+			&TeslaControl->OptSettingAlgorithm
+		},
+		{
+			"AlgorithmTime",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->AlgorithmTime),
+			&TeslaControl->AlgorithmTime
+		},
+		{
+			"RegisterConfig",
+			JX_REG_VAL_BINARY,
+			sizeof(TeslaControl->RegisterConfig),
+			&TeslaControl->RegisterConfig
+		},
+		{
+			"ChipSelectGpio",
+			JX_REG_VAL_DWORD,
+			sizeof(TeslaControl->ChipSelectGpio),
+			&TeslaControl->ChipSelectGpio
+		}
+	};
+
+	JX_REG_KEY_HANDLE   hKey    = NULL;
+
+	if((hKey = JxRegCreateKey(NULL, HOMEPLUG_ROOT_KEY)) != NULL)
+	{
+		bResult = JxRegSetStruct
+		(
+			hKey,
+			NUMBER_OF_ELEMENTS(PortConfigDesc),
+			PortConfigDesc
+		);
+
+		JxRegCloseKey(hKey);
+	}
+#endif
+	return bResult;
+}
+
+// Emac to save the current Tesla Controls into config.reg
+// 12/03/01, the function currently called by CfgMgr at Appy time to write 
+// trigger : Windweb Savesetting ... ????
+// if input Tesla_Adapter is NULL, Emac will setup whatever Homeplug Phy it detect 
+void Emac_TeslaCurrentConfigSave( TESLA_HANDLE Tesla_Adapter)
+{
+
+	// Tesla_Adapter : only one now so no need to check
+	Emac_TeslaConfigSaveToFile( &Current_TeslaControl );
+}
+
+#ifdef HOMEPLUG_PHYMAC_OVERFLOW_WORKAROUND
+
+// TBD , allow one HOMEPLUG instance only
+// TBD , how about reset 
+
+#define MAC_ADDRESSES_IDENTICAL(a1,a2) (memcmp((UCHAR *)a1,(UCHAR *)a2, 6 ) == 0)   
+
+static ULONG SendStatsRequests = 0 ;
+static ULONG StatsRequests = 0 ;
+static ULONG StatsRequestsReqDelay = 0 ;
+
+static BOOLEAN TeslaRequireTxDelay = FALSE ;
+static ULONG LastTxAck = 0;
+static ULONG LastTxCont = 0;
+
+void Emac_TeslaSendStatsRequest(
+	TESLA_HANDLE Tesla_Adapter
+)
+{
+	ADDR_TBL *FreeTxBuffer ;
+	PUCHAR  pSendBuf ;
+	ULONG   nSendSize   = 0;
+
+#if TESLA_DEBUG
+	if( MACAdapter != (PMACAPI)Tesla_Adapter )
+	{
+		printf( "TBD : support only one HOMEPLUG instance\n" ) ;
+	}
+#endif
+
+#if 0
+	if( SendStatsRequests != StatsRequests )
+	{
+		TeslaRequireTxDelay  = TRUE ;
+		SendStatsRequests = StatsRequests ;
+#if TESLA_DEBUG
+		StatsRequestsReqDelay++ ;
+#endif
+		return ;
+	}
+#endif
+
+	FreeTxBuffer = Get_Free_Tx_Buffer( MACAdapter) ;
+
+	if( !FreeTxBuffer)
+		return ;
+
+	SendStatsRequests++ ;
+
+	pSendBuf = (U8 *)Packet_Buffer_Virtual_Adr(FreeTxBuffer) ;
+
+	MAC_Assign_MacAddress( MACAdapter, pSendBuf ) ;
+
+	pSendBuf += SIZE_ETHER_ADDRESS; nSendSize += SIZE_ETHER_ADDRESS;
+
+	MAC_Assign_MacAddress( MACAdapter, pSendBuf ) ;
+
+	pSendBuf += SIZE_ETHER_ADDRESS; nSendSize += SIZE_ETHER_ADDRESS;
+
+   INT5130_BUFFER_PUT(INT5130_FRAME_TYPE_OCTET_1);
+   INT5130_BUFFER_PUT(INT5130_FRAME_TYPE_OCTET_2);
+                 
+   /* Indicate the number of data entries to follow. */
+   INT5130_BUFFER_PUT(1);
+
+   /* Construct local parameters frame. */
+   INT5130_BUFFER_PUT(INT5130_REQUEST_PARAMETERS_AND_STATISTICS) ;
+	// length 0
+   INT5130_BUFFER_PUT(0) ;
+
+	MAC_Send_A_Frame( MACAdapter, MIN_ETHER_PACKET_SIZE, FreeTxBuffer, TRUE ) ;
+}
+
+BOOLEAN Emac_TeslaRequireTxDelay( TESLA_HANDLE Tesla_Adapter )
+{
+
+#if TESLA_DEBUG
+	if( MACAdapter != (PMACAPI)Tesla_Adapter )
+	{
+		printf( "TBD : support only one HOMEPLUG instance\n" ) ;
+	}
+#endif
+
+	return TeslaRequireTxDelay  ;
+}
+
+
+BOOLEAN  Emac_TeslaIsStatsPacket
+(
+	TESLA_HANDLE	Tesla_Adapter,
+	PUCHAR 			DataPacket
+) 
+{
+	ULONG Index;
+	ULONG TxAck;
+	ULONG TxCont;
+
+#if TESLA_DEBUG
+	if( MACAdapter != (PMACAPI)Tesla_Adapter )
+	{
+		printf( "TBD : support only one HOMEPLUG instance\n" ) ;
+	}
+#endif
+
+	if ((DataPacket[12] == INT5130_FRAME_TYPE_OCTET_1) && 
+	(DataPacket[13] == INT5130_FRAME_TYPE_OCTET_2) &&
+	DataPacket[15] == 0x08 ) 	// PARAMETERS_AND_STATISTICS Response
+	{
+	char SMacAddr[SIZE_ETHER_ADDRESS] ;
+
+		MAC_Assign_MacAddress( MACAdapter, SMacAddr ) ;
+
+		if( MAC_ADDRESSES_IDENTICAL (DataPacket+6, SMacAddr )) 
+		{
+
+			StatsRequests++ ;
+			TxAck  = (DataPacket[17] << 8) + DataPacket[18];
+			TxCont = (DataPacket[23] << 8) + DataPacket[24];
+			TxAck  -= LastTxAck; 
+			TxCont -= LastTxCont;
+			TxAck  -= (TxAck >> 3); 
+			if (TxCont > TxAck) {
+				TeslaRequireTxDelay = TRUE ;
+#if 0	// TESLA_DEBUG
+				StatsRequestsReqDelay++ ;
+
+				printf( "SendStatsRequests=%ld, StatsRequests= %ld, StatsRequestsReqDelay =%ld \n",
+				SendStatsRequests, StatsRequests, StatsRequestsReqDelay ) ;
+#endif
+			}
+			else {
+				TeslaRequireTxDelay = FALSE ;
+			}
+			LastTxAck =  (DataPacket[17] << 8) + DataPacket[18];
+			LastTxCont = (DataPacket[23] << 8) + DataPacket[24];
+			return (TRUE);
+		}
+	}
+
+	// allow all other HOMEPLUG frames to upper for installation or diagnosis application
+	return (FALSE);
+}
+
+#endif	// HOMEPLUG_PHYMAC_OVERFLOW_WORKAROUND
+
+/******************************************************************************
+|
+|  Function:    TeslaState
+|
+|  Description: Sets and Gets whether Tesla exists
+|
+|  Parameters:  SetState: 1 = turns Tesla state on, 0 = do nothing
+|				Tesla state off by default
+|
+|  Returns:     TRUE (Tesla exists), FALSE (otherwise)
+*******************************************************************************/
+
+BOOLEAN TeslaState(short SetState)
+{
+	static BOOLEAN state = FALSE;
+
+	if (SetState == 1)
+	{
+		state = TRUE;
+	}
+
+	return state;
+}
+
+unsigned int *EMAC1_MDIO_REG = (unsigned int *)0x310018;
+
+#define	MDIO_MASK		0x1FL
+#define	MDIO_DEFAULT	0x08
+#define MDIO_CLK_LO		0x00
+#define MDIO_CLK_HI		0x01
+#define MDIO_READ_MODE	0x18		// rising edge for ADI + input mode
+#define MDIO_READ_BIT	0x02
+
+void Write_ADI_Byte(char RegByte)
+{
+	short	i;
+	DWORD	io_data;
+	char	data;
+	volatile int	j;
+
+	// Preserve non-MDIO bits in shared MAC_MDIO_REG
+	io_data = *EMAC1_MDIO_REG & ~MDIO_MASK;
+
+	for (i = 7; i >= 0; i--)		// sweep across byte (MSB first)
+	{
+		data = (((RegByte>>i)&1)<<2);
+		*EMAC1_MDIO_REG = io_data | MDIO_CLK_LO | data;
+		for (j = 10; j; j--);
+		*EMAC1_MDIO_REG = io_data | MDIO_CLK_HI | data;
+		for (j = 10; j; j--);
+		// These 2 for loops generate a 500 kHz clk on MDC with the processor running at 144 MHz
+	}
+}
+
+char Read_ADI_Byte(void)
+{
+	short	i;
+	DWORD	io_data;
+	char	read_data = 0;
+	volatile int	j;
+
+	// Preserve non-MDIO bits in shared MAC_MDIO_REG
+	io_data = *EMAC1_MDIO_REG & ~MDIO_MASK;
+
+	// Set for read mode
+	io_data |= MDIO_READ_MODE;
+	*EMAC1_MDIO_REG = io_data;
+
+	for (i = 7; i >= 0; i--)		// sweep across byte (MSB first)
+	{
+		*EMAC1_MDIO_REG = io_data | MDIO_CLK_LO;
+		for (j = 10; j; j--);
+		*EMAC1_MDIO_REG = io_data | MDIO_CLK_HI;
+		read_data |= ((*EMAC1_MDIO_REG & MDIO_READ_BIT) >> 1) << i;
+		for (j = 10; j; j--);
+		// These 2 for loops generate a 500 kHz clk on MDC with the processor running at 144 MHz
+	}
+
+	return read_data;
+}
+
+/******************************************************************************
+|
+|  Function:    Read_ADI_AFE
+|
+|  Description: Reads from the ADI AFE control register
+|
+|  Parameters:  RegisterAddress - register control address
+|
+|  Returns:     contents of register control at requested address
+*******************************************************************************/
+
+char Read_ADI_AFE(char RegisterAddress, short GpioEnable)
+{
+	char	returnByte;
+
+	if (GpioEnable != -1)
+		WriteGPIOData(GpioEnable, 0);
+
+	Write_ADI_Byte(RegisterAddress | 0x80);		// need bit 7 hi to let AFE know this is a read request
+	returnByte = Read_ADI_Byte();
+
+	if (GpioEnable != -1)
+		WriteGPIOData(GpioEnable, 1);
+
+	*EMAC1_MDIO_REG = (*EMAC1_MDIO_REG & ~MDIO_MASK)|MDIO_DEFAULT;
+
+	return returnByte;
+}
+
+/******************************************************************************
+|
+|  Function:    Write_ADI_AFE
+|
+|  Description: Writes to the ADI AFE control register
+|
+|  Parameters:  RegisterAddress - register control address
+|				RegisterData - register data
+|
+|  Returns:     void
+*******************************************************************************/
+
+void Write_ADI_AFE(char RegisterAddress, char RegisterData, short GpioEnable)
+{
+	if (GpioEnable != -1)
+		WriteGPIOData(GpioEnable, 0);
+
+	Write_ADI_Byte(RegisterAddress);
+	Write_ADI_Byte(RegisterData);
+
+	if (GpioEnable != -1)
+		WriteGPIOData(GpioEnable, 1);
+
+	*EMAC1_MDIO_REG = (*EMAC1_MDIO_REG & ~MDIO_MASK)|MDIO_DEFAULT;
+}
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/tesla.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/tesla.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/tesla.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/tesla.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,138 @@
+/****************************************************************************
+* $Header:   S:/Embedded/archives/Linux/BSP_CX821xx/uClinux2.4.6/linux/drivers/net/cnxt_emac/tesla.h-arc   1.0   Mar 19 2003 13:35:54   davidsdj  $
+*
+*  Copyright(c)2001  Conexant Systems
+*
+*****************************************************************************/
+
+// Bright Shih, 11/12/2001
+#if !defined(TESLA_H_)
+#define	TESLA_H_
+
+//#define HOMEPLUG_PHYMAC_OVERFLOW_WORKAROUND 1
+
+//#define HOMEPLUG_GPIO8		1
+//#define GPIO8_DEBUG			1
+
+typedef enum def_ACCESS_PRIORITY
+{
+	CA0 = 0,
+	CA1,
+	CA2,
+	CA3,
+} ACCESS_PRIORITY ;
+
+typedef enum def_TX_RETRY_CONTROL
+{
+	TX_NO_RETRY = 0,
+	TX_ONE_RETRY ,
+	TX_NORMAL_RETRY ,
+} TX_RETRY_CONTROL ;
+
+typedef enum def_AFE_TYPE
+{
+	AFE_ADI = 0,
+	AFE_INTELLON ,
+	AFE_UNKNOWN ,
+} AFE_TYPE ;
+
+typedef enum def_SETTING_ALGORITHM		// optimum setting algorithm
+{
+	ALG_NONE = 0,
+	ALG_HUNT ,
+} SETTING_ALGORITHM ;
+
+typedef struct def_TeslaControl_Str
+{
+BOOLEAN				EncryptEnableFlag ;		// default FALSE
+UCHAR				NetworkEncryptionKey[8];// default  0x01,0xf2,0xe3,0xd4,0xc5, 0xb6, 0xa7,0x98 
+
+ACCESS_PRIORITY		TransmitPriority ;		// default CA1
+BOOLEAN				ResponseExpected ;		// default TRUE
+TX_RETRY_CONTROL	RetryControl;			// default TX_NORMAL_RETRY
+
+UCHAR				PasswordPlainText[32];
+
+// below hidden from end users
+BOOLEAN				OverrideDefaultKey	;	// default FALSE ;
+UCHAR				DefaultKeyOverride[8] ;	//	default get from device driver - expose to user only if OverrideDefaultKey is TRUE
+DWORD				NetworkKeySelect ;		// 1-255, default NETWORK_KEY 1 ( 0 - use DEFAULT_KEY)
+
+AFE_TYPE			AfeType ;				// default AFE_ADI
+SETTING_ALGORITHM	OptSettingAlgorithm ;	// default ALG_HUNT
+DWORD				AlgorithmTime ;			// default 120 (seconds)
+
+UCHAR				RegisterConfig[16] ;	// default:
+											//		in pairs except for 0 and 1
+											//		pairs denote register and value to set
+											//		0: 0x00, 0x03 - denotes 3 reg to program
+											//		2: 0x04, 0x0c (Reg 0x04 = 0x0c)
+											//		4: 0x05, 0xff (Reg 0x05 = 0xff)
+											//		6: 0x06, 0x80 (Reg 0x06 = 0x80)
+											//      0x00 for the rest since only 3 reg set by default
+
+DWORD				ChipSelectGpio ;		// default 19
+} TeslaControl_Str ;
+
+#define TESLA_HANDLE void*
+
+// call Emac to get the HomePlug Handle, 
+// return NULL if no HOMEPLUG phy detected
+// TESLA_HANDLE Emac_HomePlugHandle(void) ;
+
+typedef enum def_Emac_DevType
+{
+	Emac_No_Phy = 0,
+	Emac_Ethernet_Phy ,
+	Emac_HomePlug_Phy ,
+	Emac_Hpna_Phy ,
+	// future Phy support
+} Emac_DevType ;
+
+// return FALSE if failed (ex: Emac not started)
+BOOLEAN Emac_Phy_Attached( Emac_DevType *pPort1, Emac_DevType *pPort2 ) ;
+
+
+// Save Tesla control specified by TeslaControl into config.reg
+// return FALSE : if fail to write
+BOOLEAN Emac_TeslaConfigSave( TeslaControl_Str *TeslaControl ) ;
+
+
+// Read the current Tesla control into TeslaControl
+// Return TRUE :  If Emac read these settings from config.reg successfully else
+// Return FALSE : Emac would still load the default settings into TeslaControl
+BOOLEAN Emac_TeslaConfigRead( TeslaControl_Str *TeslaControl ) ;
+
+
+// Ask Emac to setup Homeplug phy with pTeslaControl
+// if input Tesla_Adapter is NULL, Emac will setup whatever Homeplug Phy it detect
+void Emac_TeslaSetup( TESLA_HANDLE Tesla_Adapter, TeslaControl_Str *pTeslaControl ) ;
+
+
+// Emac to save the current Tesla Controls into config.reg
+// 12/03/01, the function currently called by CfgMgr at Appy time to write 
+// trigger : Windweb Savesetting ... ????
+// if input Tesla_Adapter is NULL, Emac will setup whatever Homeplug Phy it detect 
+void Emac_TeslaCurrentConfigSave( TESLA_HANDLE Tesla_Adapter) ;
+
+
+void Write_ADI_AFE(char RegisterAddress, char RegisterData, short GpioEnable);
+char Read_ADI_AFE(char RegisterAddress, short GpioEnable);
+
+#if 1		// HOMEPLUG_PHYMAC_OVERFLOW_WORKAROUND
+void Emac_TeslaSendStatsRequest(
+	TESLA_HANDLE Tesla_Adapter
+) ;
+
+BOOLEAN Emac_TeslaRequireTxDelay( TESLA_HANDLE Tesla_Adapter ) ;
+
+BOOLEAN  Emac_TeslaIsStatsPacket (
+	TESLA_HANDLE Tesla_Adapter,
+	unsigned char * DataPacket ) ;
+
+
+#define HomePlug_TX_Delay	2	// suggest 2 milli second
+
+#endif
+
+#endif
diff -uNr uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/verFeatures.h uClinux-2.4.27-uc1/drivers/net/cnxt_emac/verFeatures.h
--- uc-origs/uClinux-2.4.27-uc1/drivers/net/cnxt_emac/verFeatures.h	1970-01-01 01:00:00.000000000 +0100
+++ uClinux-2.4.27-uc1/drivers/net/cnxt_emac/verFeatures.h	2005-01-20 21:18:13.000000000 +0100
@@ -0,0 +1,168 @@
+/****************************************************************************
+*
+*	Name:			verFeatures.h
+*
+*	Description:	
+*
+*	Copyright:		(c) 2002 Conexant Systems Inc.
+*					Personal Computing Division
+*					All Rights Reserved
+*
+****************************************************************************
+*  $Author:   davidsdj  $
+*  $Revision:   1.0  $
+*  $Modtime:   Mar 19 2003 12:25:22  $
+****************************************************************************/
+
+#ifndef _VER_H
+#define _VER_H
+
+/*
+ * Version numbers
+ */
+
+/* EMAC HW versions */
+#define REV_A   1
+#define REV_B	2
+#define REV_C   3
+#define REV_D   4
+
+/* EMAC SW versions */
+#define VER_01   1
+#define VER_02   2
+#define VER_03   3
+#define VER_04   4
+#define VER_05   5
+#define VER_06   6
+#define VER_07   7
+#define VER_08   8
+#define VER_09   9
+#define VER_10   10
+#define VER_11   11
+#define VER_12   12
+#define VER_13   13
+#define VER_14   14
+#define VER_15   15
+#define VER_16   16
+#define VER_17   17
+#define VER_18   18
+#define VER_19   19
+#define VER_20   20
+
+/* EMAC versions */
+#define MAC_HW_VER      REV_C		
+#define MAC_SW_VER      VER_06     
+
+/*
+ * Version Features.
+ */
+
+/* Defines to control code generation depending on features available. */
+
+#define INC_SNMP  0 /* AD Aug18 SNMP API support: include SNMP. */
+
+#define NETPOOL_USE_DEF_FUNCTBL
+#define REMEMBER_MClBlks_CL_STARTADDR
+#define UCAST_IN_IOCTL		/* Unicast addr manipulation using IOCTL */
+/*#define USE_BSP_ENET_RTN*/	/* Use the BSP fn to get the mac addr 1st time */
+#define USE_BSP_SRAM_RTN
+/*#define USE_BSP_DMA_M2M_OBJ*/
+/*#define SUPPORT_MACADDR_FILTER*/
+#define INC_PHY
+
+
+#define USE_DMA_M2M_COPY_OP1
+#define BUG_MUX_PATCH
+
+
+/* Do rxHandling - netJobAdd - as late as possible. */
+#define RXHANDLING_AS_SOON_AS_POSSIBLE				1
+#define RXHANDLING_AS_LATE_AS_POSSIBLE				2
+#define RXHANDLING_NO_RXHANDLING					3
+#define RXHANDLING RXHANDLING_AS_LATE_AS_POSSIBLE
+
+#if     (MAC_HW_VER == REV_A)
+
+#define EMAC_TX_DMA_LMODE DMA_LMODE_TAIL
+#define BUG_HW_EMAC_RX_1   /* This bug is in REV_A & will not be in REV_B/C...*/
+#define BUG_HW_EMAC_RX_2   /* This bug is in REV_A & will not be in REV_B/C...*/
+#define ZERO_MEM_USING_DMA /* zero memory using DMA */
+
+#else   /* not MAC_HW_VER_A*/
+
+#undef  BUG_HW_EMAC_RX_1 
+#define EMAC_TX_DMA_LMODE DMA_LMODE_TAIL
+
+#endif  /*MAC_HW_VER_A*/
+
+#define TEST_PLATFORM_MODEL     1
+#define TEST_PLATFORM_HW        2
+#define TEST_PLATFORM           TEST_PLATFORM_HW
+
+
+/*
+ * Version strings.
+ */
+
+/* EMAC HW version strings */
+#if     (MAC_HW_VER == REV_A)
+#define MAC_HW_VER_STR  "A"
+#elif   (MAC_HW_VER == REV_B)
+#define MAC_HW_VER_STR  "B"
+#elif   (MAC_HW_VER == REV_C)
+#define MAC_HW_VER_STR  "C"
+#elif   (MAC_HW_VER == REV_D)
+#define MAC_HW_VER_STR  "D"
+#else
+#error Invalid EMAC HW version.
+#endif
+
+/* EMAC SW version strings */
+#if     (MAC_SW_VER == VER_01)
+#define MAC_SW_VER_STR  "0.1"
+#elif   (MAC_SW_VER == VER_02)
+#define MAC_SW_VER_STR  "0.2"
+#elif   (MAC_SW_VER == VER_03)
+#define MAC_SW_VER_STR  "0.3"
+#elif   (MAC_SW_VER == VER_04)
+#define MAC_SW_VER_STR  "0.4"
+#elif   (MAC_SW_VER == VER_05)
+#define MAC_SW_VER_STR  "0.5"
+#elif   (MAC_SW_VER == VER_06)
+#define MAC_SW_VER_STR  "0.6"
+#elif   (MAC_SW_VER == VER_07)
+#define MAC_SW_VER_STR  "0.7"
+#elif   (MAC_SW_VER == VER_08)
+#define MAC_SW_VER_STR  "0.8"
+#elif   (MAC_SW_VER == VER_09)
+#define MAC_SW_VER_STR  "0.9"
+#elif   (MAC_SW_VER == VER_10)
+#define MAC_SW_VER_STR  "1.0"
+#elif   (MAC_SW_VER == VER_11)
+#define MAC_SW_VER_STR  "1.1"
+#elif   (MAC_SW_VER == VER_12)
+#define MAC_SW_VER_STR  "1.2"
+#elif   (MAC_SW_VER == VER_13)
+#define MAC_SW_VER_STR  "1.3"
+#elif   (MAC_SW_VER == VER_14)
+#define MAC_SW_VER_STR  "1.4"
+#elif   (MAC_SW_VER == VER_15)
+#define MAC_SW_VER_STR  "1.5"
+#elif   (MAC_SW_VER == VER_16)
+#define MAC_SW_VER_STR  "1.6"
+#elif   (MAC_SW_VER == VER_17)
+#define MAC_SW_VER_STR  "1.7"
+#elif   (MAC_SW_VER == VER_18)
+#define MAC_SW_VER_STR  "1.8"
+#elif   (MAC_SW_VER == VER_19)
+#define MAC_SW_VER_STR  "1.9"
+#elif   (MAC_SW_VER == VER_20)
+#define MAC_SW_VER_STR  "2.0"
+#else
+#error Invalid EMAC SW version.
+#endif
+
+/* EMAC versions */
+#define MAC_VER_STR "v:" MAC_HW_VER_STR "," MAC_SW_VER_STR
+
+#endif _VER_H

