diff -u --recursive --new-file linux-2.4.26/Documentation/Configure.help linux-2.4.26.patch/Documentation/Configure.help
--- linux-2.4.26/Documentation/Configure.help	2004-04-14 06:05:24.000000000 -0700
+++ linux-2.4.26.patch/Documentation/Configure.help	2004-04-21 09:15:12.000000000 -0700
@@ -11935,6 +11935,16 @@
   say M here and read <file:Documentation/modules.txt>.  The module
   will be called sungem.o.
 
+Broadcom NetXtreme BCM5700 Gigabit Ethernet support
+CONFIG_NET_BROADCOM
+  Say Y here if you have a Broadcom BCM57xx, or 3Com
+  3C996/3C997/3C1000/3C940 PCI/PCIX Gigabit Ethernet adapter.
+
+  If you want to compile this driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. This is recommended.
+  The module will be called bcm5700.o.
+
 Broadcom Tigon3 support
 CONFIG_TIGON3
   This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
diff -u --recursive --new-file linux-2.4.26/drivers/net/bcm/5701rls.c linux-2.4.26.patch/drivers/net/bcm/5701rls.c
--- linux-2.4.26/drivers/net/bcm/5701rls.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.26.patch/drivers/net/bcm/5701rls.c	2004-06-22 16:07:37.000000000 -0700
@@ -0,0 +1,46 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2003 Broadcom  */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/*                                                                            */
+/******************************************************************************/
+
+#if INCLUDE_5701_AX_FIX
+
+#include "mm.h"
+#include "5701rls.h"
+
+LM_STATUS LM_LoadRlsFirmware(PLM_DEVICE_BLOCK pDevice)
+{
+  T3_FWIMG_INFO FwImgInfo;
+
+  FwImgInfo.StartAddress = t3FwStartAddr;
+  FwImgInfo.Text.Buffer = (PLM_UINT8)t3FwText;
+  FwImgInfo.Text.Offset  = t3FwTextAddr;
+  FwImgInfo.Text.Length  = t3FwTextLen;
+  FwImgInfo.ROnlyData.Buffer = (PLM_UINT8)t3FwRodata;
+  FwImgInfo.ROnlyData.Offset  = t3FwRodataAddr;
+  FwImgInfo.ROnlyData.Length  = t3FwRodataLen;
+  FwImgInfo.Data.Buffer = (PLM_UINT8)t3FwData;
+  FwImgInfo.Data.Offset  = t3FwDataAddr;
+  FwImgInfo.Data.Length  = t3FwDataLen;
+
+  if (LM_LoadFirmware(pDevice,
+                      &FwImgInfo,
+                      T3_RX_CPU_ID | T3_TX_CPU_ID,
+                      T3_RX_CPU_ID) != LM_STATUS_SUCCESS)
+    {
+      return LM_STATUS_FAILURE;
+    }
+  
+  return LM_STATUS_SUCCESS;
+}
+
+#endif /* INCLUDE_5701_AX_FIX */
diff -u --recursive --new-file linux-2.4.26/drivers/net/bcm/5701rls.h linux-2.4.26.patch/drivers/net/bcm/5701rls.h
--- linux-2.4.26/drivers/net/bcm/5701rls.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.26.patch/drivers/net/bcm/5701rls.h	2004-06-22 16:07:37.000000000 -0700
@@ -0,0 +1,198 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2003 Broadcom  */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/******************************************************************************/
+
+typedef unsigned long U32;
+int t3FwReleaseMajor = 0x0;
+int t3FwReleaseMinor = 0x0;
+int t3FwReleaseFix = 0x0;
+U32 t3FwStartAddr = 0x08000000;
+U32 t3FwTextAddr = 0x08000000;
+int t3FwTextLen = 0x9c0;
+U32 t3FwRodataAddr = 0x080009c0;
+int t3FwRodataLen = 0x60;
+U32 t3FwDataAddr = 0x08000a40;
+int t3FwDataLen = 0x20;
+U32 t3FwSbssAddr = 0x08000a60;
+int t3FwSbssLen = 0xc;
+U32 t3FwBssAddr = 0x08000a70;
+int t3FwBssLen = 0x10;
+U32 t3FwText[(0x9c0/4) + 1] = {
+0x0, 
+0x10000003, 0x0, 0xd, 0xd, 
+0x3c1d0800, 0x37bd3ffc, 0x3a0f021, 0x3c100800, 
+0x26100000, 0xe000018, 0x0, 0xd, 
+0x3c1d0800, 0x37bd3ffc, 0x3a0f021, 0x3c100800, 
+0x26100034, 0xe00021c, 0x0, 0xd, 
+0x0, 0x0, 0x0, 0x27bdffe0, 
+0x3c1cc000, 0xafbf0018, 0xaf80680c, 0xe00004c, 
+0x241b2105, 0x97850000, 0x97870002, 0x9782002c, 
+0x9783002e, 0x3c040800, 0x248409c0, 0xafa00014, 
+0x21400, 0x621825, 0x52c00, 0xafa30010, 
+0x8f860010, 0xe52825, 0xe000060, 0x24070102, 
+0x3c02ac00, 0x34420100, 0x3c03ac01, 0x34630100, 
+0xaf820490, 0x3c02ffff, 0xaf820494, 0xaf830498, 
+0xaf82049c, 0x24020001, 0xaf825ce0, 0xe00003f, 
+0xaf825d00, 0xe000140, 0x0, 0x8fbf0018, 
+0x3e00008, 0x27bd0020, 0x2402ffff, 0xaf825404, 
+0x8f835400, 0x34630400, 0xaf835400, 0xaf825404, 
+0x3c020800, 0x24420034, 0xaf82541c, 0x3e00008, 
+0xaf805400, 0x0, 0x0, 0x3c020800, 
+0x34423000, 0x3c030800, 0x34633000, 0x3c040800, 
+0x348437ff, 0x3c010800, 0xac220a64, 0x24020040, 
+0x3c010800, 0xac220a68, 0x3c010800, 0xac200a60, 
+0xac600000, 0x24630004, 0x83102b, 0x5040fffd, 
+0xac600000, 0x3e00008, 0x0, 0x804821, 
+0x8faa0010, 0x3c020800, 0x8c420a60, 0x3c040800, 
+0x8c840a68, 0x8fab0014, 0x24430001, 0x44102b, 
+0x3c010800, 0xac230a60, 0x14400003, 0x4021, 
+0x3c010800, 0xac200a60, 0x3c020800, 0x8c420a60, 
+0x3c030800, 0x8c630a64, 0x91240000, 0x21140, 
+0x431021, 0x481021, 0x25080001, 0xa0440000, 
+0x29020008, 0x1440fff4, 0x25290001, 0x3c020800, 
+0x8c420a60, 0x3c030800, 0x8c630a64, 0x8f84680c, 
+0x21140, 0x431021, 0xac440008, 0xac45000c, 
+0xac460010, 0xac470014, 0xac4a0018, 0x3e00008, 
+0xac4b001c, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x2000008, 
+0x0, 0xa0001e3, 0x3c0a0001, 0xa0001e3, 
+0x3c0a0002, 0xa0001e3, 0x0, 0xa0001e3, 
+0x0, 0xa0001e3, 0x0, 0xa0001e3, 
+0x0, 0xa0001e3, 0x0, 0xa0001e3, 
+0x0, 0xa0001e3, 0x0, 0xa0001e3, 
+0x0, 0xa0001e3, 0x0, 0xa0001e3, 
+0x3c0a0007, 0xa0001e3, 0x3c0a0008, 0xa0001e3, 
+0x3c0a0009, 0xa0001e3, 0x0, 0xa0001e3, 
+0x0, 0xa0001e3, 0x3c0a000b, 0xa0001e3, 
+0x3c0a000c, 0xa0001e3, 0x3c0a000d, 0xa0001e3, 
+0x0, 0xa0001e3, 0x0, 0xa0001e3, 
+0x3c0a000e, 0xa0001e3, 0x0, 0xa0001e3, 
+0x0, 0xa0001e3, 0x0, 0xa0001e3, 
+0x0, 0xa0001e3, 0x0, 0xa0001e3, 
+0x0, 0xa0001e3, 0x0, 0xa0001e3, 
+0x0, 0xa0001e3, 0x3c0a0013, 0xa0001e3, 
+0x3c0a0014, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x27bdffe0, 
+0x1821, 0x1021, 0xafbf0018, 0xafb10014, 
+0xafb00010, 0x3c010800, 0x220821, 0xac200a70, 
+0x3c010800, 0x220821, 0xac200a74, 0x3c010800, 
+0x220821, 0xac200a78, 0x24630001, 0x1860fff5, 
+0x2442000c, 0x24110001, 0x8f906810, 0x32020004, 
+0x14400005, 0x24040001, 0x3c020800, 0x8c420a78, 
+0x18400003, 0x2021, 0xe000182, 0x0, 
+0x32020001, 0x10400003, 0x0, 0xe000169, 
+0x0, 0xa000153, 0xaf915028, 0x8fbf0018, 
+0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0020, 
+0x3c050800, 0x8ca50a70, 0x3c060800, 0x8cc60a80, 
+0x3c070800, 0x8ce70a78, 0x27bdffe0, 0x3c040800, 
+0x248409d0, 0xafbf0018, 0xafa00010, 0xe000060, 
+0xafa00014, 0xe00017b, 0x2021, 0x8fbf0018, 
+0x3e00008, 0x27bd0020, 0x24020001, 0x8f836810, 
+0x821004, 0x21027, 0x621824, 0x3e00008, 
+0xaf836810, 0x27bdffd8, 0xafbf0024, 0x1080002e, 
+0xafb00020, 0x8f825cec, 0xafa20018, 0x8f825cec, 
+0x3c100800, 0x26100a78, 0xafa2001c, 0x34028000, 
+0xaf825cec, 0x8e020000, 0x18400016, 0x0, 
+0x3c020800, 0x94420a74, 0x8fa3001c, 0x221c0, 
+0xac830004, 0x8fa2001c, 0x3c010800, 0xe000201, 
+0xac220a74, 0x10400005, 0x0, 0x8e020000, 
+0x24420001, 0xa0001df, 0xae020000, 0x3c020800, 
+0x8c420a70, 0x21c02, 0x321c0, 0xa0001c5, 
+0xafa2001c, 0xe000201, 0x0, 0x1040001f, 
+0x0, 0x8e020000, 0x8fa3001c, 0x24420001, 
+0x3c010800, 0xac230a70, 0x3c010800, 0xac230a74, 
+0xa0001df, 0xae020000, 0x3c100800, 0x26100a78, 
+0x8e020000, 0x18400028, 0x0, 0xe000201, 
+0x0, 0x14400024, 0x0, 0x8e020000, 
+0x3c030800, 0x8c630a70, 0x2442ffff, 0xafa3001c, 
+0x18400006, 0xae020000, 0x31402, 0x221c0, 
+0x8c820004, 0x3c010800, 0xac220a70, 0x97a2001e, 
+0x2442ff00, 0x2c420300, 0x1440000b, 0x24024000, 
+0x3c040800, 0x248409dc, 0xafa00010, 0xafa00014, 
+0x8fa6001c, 0x24050008, 0xe000060, 0x3821, 
+0xa0001df, 0x0, 0xaf825cf8, 0x3c020800, 
+0x8c420a40, 0x8fa3001c, 0x24420001, 0xaf835cf8, 
+0x3c010800, 0xac220a40, 0x8fbf0024, 0x8fb00020, 
+0x3e00008, 0x27bd0028, 0x27bdffe0, 0x3c040800, 
+0x248409e8, 0x2821, 0x3021, 0x3821, 
+0xafbf0018, 0xafa00010, 0xe000060, 0xafa00014, 
+0x8fbf0018, 0x3e00008, 0x27bd0020, 0x8f82680c, 
+0x8f85680c, 0x21827, 0x3182b, 0x31823, 
+0x431024, 0x441021, 0xa2282b, 0x10a00006, 
+0x0, 0x401821, 0x8f82680c, 0x43102b, 
+0x1440fffd, 0x0, 0x3e00008, 0x0, 
+0x3c040800, 0x8c840000, 0x3c030800, 0x8c630a40, 
+0x64102b, 0x54400002, 0x831023, 0x641023, 
+0x2c420008, 0x3e00008, 0x38420001, 0x27bdffe0, 
+0x802821, 0x3c040800, 0x24840a00, 0x3021, 
+0x3821, 0xafbf0018, 0xafa00010, 0xe000060, 
+0xafa00014, 0xa000216, 0x0, 0x8fbf0018, 
+0x3e00008, 0x27bd0020, 0x0, 0x27bdffe0, 
+0x3c1cc000, 0xafbf0018, 0xe00004c, 0xaf80680c, 
+0x3c040800, 0x24840a10, 0x3802821, 0x3021, 
+0x3821, 0xafa00010, 0xe000060, 0xafa00014, 
+0x2402ffff, 0xaf825404, 0x3c0200aa, 0xe000234, 
+0xaf825434, 0x8fbf0018, 0x3e00008, 0x27bd0020, 
+0x0, 0x0, 0x0, 0x27bdffe8, 
+0xafb00010, 0x24100001, 0xafbf0014, 0x3c01c003, 
+0xac200000, 0x8f826810, 0x30422000, 0x10400003, 
+0x0, 0xe000246, 0x0, 0xa00023a, 
+0xaf905428, 0x8fbf0014, 0x8fb00010, 0x3e00008, 
+0x27bd0018, 0x27bdfff8, 0x8f845d0c, 0x3c0200ff, 
+0x3c030800, 0x8c630a50, 0x3442fff8, 0x821024, 
+0x1043001e, 0x3c0500ff, 0x34a5fff8, 0x3c06c003, 
+0x3c074000, 0x851824, 0x8c620010, 0x3c010800, 
+0xac230a50, 0x30420008, 0x10400005, 0x871025, 
+0x8cc20000, 0x24420001, 0xacc20000, 0x871025, 
+0xaf825d0c, 0x8fa20000, 0x24420001, 0xafa20000, 
+0x8fa20000, 0x8fa20000, 0x24420001, 0xafa20000, 
+0x8fa20000, 0x8f845d0c, 0x3c030800, 0x8c630a50, 
+0x851024, 0x1443ffe8, 0x851824, 0x27bd0008, 
+0x3e00008, 0x0, 0x0, 0x0 };
+U32 t3FwRodata[(0x60/4) + 1] = {
+0x35373031, 0x726c7341, 0x0, 
+0x0, 0x53774576, 0x656e7430, 0x0, 
+0x726c7045, 0x76656e74, 0x31000000, 0x556e6b6e, 
+0x45766e74, 0x0, 0x0, 0x0, 
+0x0, 0x66617461, 0x6c457272, 0x0, 
+0x0, 0x4d61696e, 0x43707542, 0x0, 
+0x0, 0x0 };
+U32 t3FwData[(0x20/4) + 1] = {
+0x0, 0x0, 0x0, 
+0x0, 0x0, 0x0, 0x0, 
+0x0, 0x0 };
diff -u --recursive --new-file linux-2.4.26/drivers/net/bcm/autoneg.c linux-2.4.26.patch/drivers/net/bcm/autoneg.c
--- linux-2.4.26/drivers/net/bcm/autoneg.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.26.patch/drivers/net/bcm/autoneg.c	2004-06-22 16:07:37.000000000 -0700
@@ -0,0 +1,438 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2003 Broadcom  */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/******************************************************************************/
+
+#if INCLUDE_TBI_SUPPORT
+#include "mm.h"
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+void
+MM_AnTxConfig(
+    PAN_STATE_INFO pAnInfo)
+{
+    PLM_DEVICE_BLOCK pDevice;
+
+    pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
+
+    REG_WR(pDevice, MacCtrl.TxAutoNeg, (LM_UINT32) pAnInfo->TxConfig.AsUSHORT);
+
+    pDevice->MacMode |= MAC_MODE_SEND_CONFIGS;
+    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+}
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+void
+MM_AnTxIdle(
+    PAN_STATE_INFO pAnInfo)
+{
+    PLM_DEVICE_BLOCK pDevice;
+
+    pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
+
+    pDevice->MacMode &= ~MAC_MODE_SEND_CONFIGS;
+    REG_WR(pDevice, MacCtrl.Mode, pDevice->MacMode);
+}
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+char
+MM_AnRxConfig(
+    PAN_STATE_INFO pAnInfo,
+    unsigned short *pRxConfig)
+{
+    PLM_DEVICE_BLOCK pDevice;
+    LM_UINT32 Value32;
+    char Retcode;
+
+    Retcode = AN_FALSE;
+
+    pDevice = (PLM_DEVICE_BLOCK) pAnInfo->pContext;
+
+    Value32 = REG_RD(pDevice, MacCtrl.Status);
+    if(Value32 & MAC_STATUS_RECEIVING_CFG)
+    {
+        Value32 = REG_RD(pDevice, MacCtrl.RxAutoNeg);
+        *pRxConfig = (unsigned short) Value32;
+
+        Retcode = AN_TRUE;
+    }
+
+    return Retcode;
+}
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+void
+AutonegInit(
+    PAN_STATE_INFO pAnInfo)
+{
+    unsigned long j;
+
+    for(j = 0; j < sizeof(AN_STATE_INFO); j++)
+    {
+        ((unsigned char *) pAnInfo)[j] = 0;
+    }
+
+    /* Initialize the default advertisement register. */
+    pAnInfo->mr_adv_full_duplex = 1;
+    pAnInfo->mr_adv_sym_pause = 1;
+    pAnInfo->mr_adv_asym_pause = 1;
+    pAnInfo->mr_an_enable = 1;
+}
+
+
+
+/******************************************************************************/
+/* Description:                                                               */
+/*                                                                            */
+/* Return:                                                                    */
+/******************************************************************************/
+AUTONEG_STATUS
+Autoneg8023z(
+    PAN_STATE_INFO pAnInfo)
+{
+    unsigned short RxConfig;
+    unsigned long Delta_us;
+    AUTONEG_STATUS AnRet;
+
+    /* Get the current time. */
+    if(pAnInfo->State == AN_STATE_UNKNOWN)
+    {
+        pAnInfo->RxConfig.AsUSHORT = 0;
+        pAnInfo->CurrentTime_us = 0;
+        pAnInfo->LinkTime_us = 0;
+        pAnInfo->AbilityMatchCfg = 0;
+        pAnInfo->AbilityMatchCnt = 0;
+        pAnInfo->AbilityMatch = AN_FALSE;
+        pAnInfo->IdleMatch = AN_FALSE;
+        pAnInfo->AckMatch = AN_FALSE;
+    }
+
+    /* Increment the timer tick.  This function is called every microsecon. */
+//    pAnInfo->CurrentTime_us++;
+
+    /* Set the AbilityMatch, IdleMatch, and AckMatch flags if their */
+    /* corresponding conditions are satisfied. */
+    if(MM_AnRxConfig(pAnInfo, &RxConfig))
+    {
+        if(RxConfig != pAnInfo->AbilityMatchCfg)
+        {
+            pAnInfo->AbilityMatchCfg = RxConfig;
+            pAnInfo->AbilityMatch = AN_FALSE;
+            pAnInfo->AbilityMatchCnt = 0;
+        }
+        else
+        {
+            pAnInfo->AbilityMatchCnt++;
+            if(pAnInfo->AbilityMatchCnt > 1)
+            {
+                pAnInfo->AbilityMatch = AN_TRUE;
+                pAnInfo->AbilityMatchCfg = RxConfig;
+            }
+        }
+
+        if(RxConfig & AN_CONFIG_ACK)
+        {
+            pAnInfo->AckMatch = AN_TRUE;
+        }
+        else
+        {
+            pAnInfo->AckMatch = AN_FALSE;
+        }
+
+        pAnInfo->IdleMatch = AN_FALSE;
+    }
+    else
+    {
+        pAnInfo->IdleMatch = AN_TRUE;
+
+        pAnInfo->AbilityMatchCfg = 0;
+        pAnInfo->AbilityMatchCnt = 0;
+        pAnInfo->AbilityMatch = AN_FALSE;
+        pAnInfo->AckMatch = AN_FALSE;
+
+        RxConfig = 0;
+    }
+
+    /* Save the last Config. */
+    pAnInfo->RxConfig.AsUSHORT = RxConfig;
+
+    /* Default return code. */
+    AnRet = AUTONEG_STATUS_OK;
+
+    /* Autoneg state machine as defined in 802.3z section 37.3.1.5. */
+    switch(pAnInfo->State)
+    {
+        case AN_STATE_UNKNOWN:
+            if(pAnInfo->mr_an_enable || pAnInfo->mr_restart_an)
+            {
+                pAnInfo->CurrentTime_us = 0;
+                pAnInfo->State = AN_STATE_AN_ENABLE;
+            }
+
+            /* Fall through.*/
+
+        case AN_STATE_AN_ENABLE:
+            pAnInfo->mr_an_complete = AN_FALSE;
+            pAnInfo->mr_page_rx = AN_FALSE;
+
+            if(pAnInfo->mr_an_enable)
+            {
+                pAnInfo->LinkTime_us = 0;
+                pAnInfo->AbilityMatchCfg = 0;
+                pAnInfo->AbilityMatchCnt = 0;
+                pAnInfo->AbilityMatch = AN_FALSE;
+                pAnInfo->IdleMatch = AN_FALSE;
+                pAnInfo->AckMatch = AN_FALSE;
+
+                pAnInfo->State = AN_STATE_AN_RESTART_INIT;
+            }
+            else
+            {
+                pAnInfo->State = AN_STATE_DISABLE_LINK_OK;
+            }
+            break;
+
+        case AN_STATE_AN_RESTART_INIT:
+            pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
+            pAnInfo->mr_np_loaded = AN_FALSE;
+
+            pAnInfo->TxConfig.AsUSHORT = 0;
+            MM_AnTxConfig(pAnInfo);
+
+            AnRet = AUTONEG_STATUS_TIMER_ENABLED;
+
+            pAnInfo->State = AN_STATE_AN_RESTART;
+
+            /* Fall through.*/
+
+        case AN_STATE_AN_RESTART:
+            /* Get the current time and compute the delta with the saved */
+            /* link timer. */
+            Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
+            if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
+            {
+                pAnInfo->State = AN_STATE_ABILITY_DETECT_INIT;
+            }
+            else
+            {
+                AnRet = AUTONEG_STATUS_TIMER_ENABLED;
+            }
+            break;
+
+        case AN_STATE_DISABLE_LINK_OK:
+            AnRet = AUTONEG_STATUS_DONE;
+            break;
+
+        case AN_STATE_ABILITY_DETECT_INIT:
+            /* Note: in the state diagram, this variable is set to */
+            /* mr_adv_ability<12>.  Is this right?. */
+            pAnInfo->mr_toggle_tx = AN_FALSE;
+
+            /* Send the config as advertised in the advertisement register. */
+            pAnInfo->TxConfig.AsUSHORT = 0;
+            pAnInfo->TxConfig.D5_FD = pAnInfo->mr_adv_full_duplex;
+            pAnInfo->TxConfig.D6_HD = pAnInfo->mr_adv_half_duplex;
+            pAnInfo->TxConfig.D7_PS1 = pAnInfo->mr_adv_sym_pause;
+            pAnInfo->TxConfig.D8_PS2 = pAnInfo->mr_adv_asym_pause;
+            pAnInfo->TxConfig.D12_RF1 = pAnInfo->mr_adv_remote_fault1;
+            pAnInfo->TxConfig.D13_RF2 = pAnInfo->mr_adv_remote_fault2;
+            pAnInfo->TxConfig.D15_NP = pAnInfo->mr_adv_next_page;
+
+            MM_AnTxConfig(pAnInfo);
+
+            pAnInfo->State = AN_STATE_ABILITY_DETECT;
+
+            break;
+
+        case AN_STATE_ABILITY_DETECT:
+            if(pAnInfo->AbilityMatch == AN_TRUE &&
+                pAnInfo->RxConfig.AsUSHORT != 0)
+            {
+                pAnInfo->State = AN_STATE_ACK_DETECT_INIT;
+            }
+
+            break;
+
+        case AN_STATE_ACK_DETECT_INIT:
+            pAnInfo->TxConfig.D14_ACK = 1;
+            MM_AnTxConfig(pAnInfo);
+
+            pAnInfo->State = AN_STATE_ACK_DETECT;
+
+            /* Fall through. */
+
+        case AN_STATE_ACK_DETECT:
+            if(pAnInfo->AckMatch == AN_TRUE)
+            {
+                if((pAnInfo->RxConfig.AsUSHORT & ~AN_CONFIG_ACK) ==
+                    (pAnInfo->AbilityMatchCfg & ~AN_CONFIG_ACK))
+                {
+                    pAnInfo->State = AN_STATE_COMPLETE_ACK_INIT;
+                }
+                else
+                {
+                    pAnInfo->State = AN_STATE_AN_ENABLE;
+                }
+            }
+            else if(pAnInfo->AbilityMatch == AN_TRUE &&
+                pAnInfo->RxConfig.AsUSHORT == 0)
+            {
+                pAnInfo->State = AN_STATE_AN_ENABLE;
+            }
+
+            break;
+
+        case AN_STATE_COMPLETE_ACK_INIT:
+            /* Make sure invalid bits are not set. */
+            if(pAnInfo->RxConfig.bits.D0 || pAnInfo->RxConfig.bits.D1 ||
+                pAnInfo->RxConfig.bits.D2 || pAnInfo->RxConfig.bits.D3 ||
+                pAnInfo->RxConfig.bits.D4 || pAnInfo->RxConfig.bits.D9 ||
+                pAnInfo->RxConfig.bits.D10 || pAnInfo->RxConfig.bits.D11)
+            {
+                AnRet = AUTONEG_STATUS_FAILED;
+                break;
+            }
+
+            /* Set up the link partner advertisement register. */
+            pAnInfo->mr_lp_adv_full_duplex = pAnInfo->RxConfig.D5_FD;
+            pAnInfo->mr_lp_adv_half_duplex = pAnInfo->RxConfig.D6_HD;
+            pAnInfo->mr_lp_adv_sym_pause = pAnInfo->RxConfig.D7_PS1;
+            pAnInfo->mr_lp_adv_asym_pause = pAnInfo->RxConfig.D8_PS2;
+            pAnInfo->mr_lp_adv_remote_fault1 = pAnInfo->RxConfig.D12_RF1;
+            pAnInfo->mr_lp_adv_remote_fault2 = pAnInfo->RxConfig.D13_RF2;
+            pAnInfo->mr_lp_adv_next_page = pAnInfo->RxConfig.D15_NP;
+
+            pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
+
+            pAnInfo->mr_toggle_tx = !pAnInfo->mr_toggle_tx;
+            pAnInfo->mr_toggle_rx = pAnInfo->RxConfig.bits.D11;
+            pAnInfo->mr_np_rx = pAnInfo->RxConfig.D15_NP;
+            pAnInfo->mr_page_rx = AN_TRUE;
+
+            pAnInfo->State = AN_STATE_COMPLETE_ACK;
+            AnRet = AUTONEG_STATUS_TIMER_ENABLED;
+
+            break;
+
+        case AN_STATE_COMPLETE_ACK:
+            if(pAnInfo->AbilityMatch == AN_TRUE &&
+                pAnInfo->RxConfig.AsUSHORT == 0)
+            {
+                pAnInfo->State = AN_STATE_AN_ENABLE;
+                break;
+            }
+
+            Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
+
+            if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
+            {
+                if(pAnInfo->mr_adv_next_page == 0 ||
+                    pAnInfo->mr_lp_adv_next_page == 0)
+                {
+                    pAnInfo->State = AN_STATE_IDLE_DETECT_INIT;
+                }
+                else
+                {
+                    if(pAnInfo->TxConfig.bits.D15 == 0 &&
+                        pAnInfo->mr_np_rx == 0)
+                    {
+                        pAnInfo->State = AN_STATE_IDLE_DETECT_INIT;
+                    }
+                    else
+                    {
+                        AnRet = AUTONEG_STATUS_FAILED;
+                    }
+                }
+            }
+
+            break;
+
+        case AN_STATE_IDLE_DETECT_INIT:
+            pAnInfo->LinkTime_us = pAnInfo->CurrentTime_us;
+
+            MM_AnTxIdle(pAnInfo);
+
+            pAnInfo->State = AN_STATE_IDLE_DETECT;
+
+            AnRet = AUTONEG_STATUS_TIMER_ENABLED;
+
+            break;
+
+        case AN_STATE_IDLE_DETECT:
+            if(pAnInfo->AbilityMatch == AN_TRUE &&
+                pAnInfo->RxConfig.AsUSHORT == 0)
+            {
+                pAnInfo->State = AN_STATE_AN_ENABLE;
+                break;
+            }
+
+            Delta_us = pAnInfo->CurrentTime_us - pAnInfo->LinkTime_us;
+            if(Delta_us > AN_LINK_TIMER_INTERVAL_US)
+            {
+//                if(pAnInfo->IdleMatch == AN_TRUE)
+//                {
+                    pAnInfo->State = AN_STATE_LINK_OK;
+//                }
+//                else
+//                {
+//                    AnRet = AUTONEG_STATUS_FAILED;
+//                    break;
+//                }
+            }
+
+            break;
+
+        case AN_STATE_LINK_OK:
+            pAnInfo->mr_an_complete = AN_TRUE;
+            pAnInfo->mr_link_ok = AN_TRUE;
+            AnRet = AUTONEG_STATUS_DONE;
+
+            break;
+
+        case AN_STATE_NEXT_PAGE_WAIT_INIT:
+            break;
+
+        case AN_STATE_NEXT_PAGE_WAIT:
+            break;
+
+        default:
+            AnRet = AUTONEG_STATUS_FAILED;
+            break;
+    }
+
+    return AnRet;
+}
+#endif /* INCLUDE_TBI_SUPPORT */
+
diff -u --recursive --new-file linux-2.4.26/drivers/net/bcm/autoneg.h linux-2.4.26.patch/drivers/net/bcm/autoneg.h
--- linux-2.4.26/drivers/net/bcm/autoneg.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.26.patch/drivers/net/bcm/autoneg.h	2004-06-22 16:07:37.000000000 -0700
@@ -0,0 +1,418 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2003 Broadcom  */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* History:                                                                   */
+/******************************************************************************/
+
+
+#ifndef AUTONEG_H
+#define AUTONEG_H
+
+
+
+/******************************************************************************/
+/* Constants. */
+/******************************************************************************/
+
+#define AN_LINK_TIMER_INTERVAL_US           12000       /* 10ms */
+
+/* TRUE, FALSE */
+#define AN_TRUE                             1
+#define AN_FALSE                            0
+
+
+
+/******************************************************************************/
+/* Main data structure for keeping track of 802.3z auto-negotation state */
+/* variables as shown in Figure 37-6 of the IEEE 802.3z specification. */
+/******************************************************************************/
+
+typedef struct
+{
+    /* Pointer to the operating system specific data structure. */
+    void *pContext;
+
+    /* Current auto-negotiation state. */
+    unsigned long State;
+    #define AN_STATE_UNKNOWN                        0
+    #define AN_STATE_AN_ENABLE                      1
+    #define AN_STATE_AN_RESTART_INIT                2
+    #define AN_STATE_AN_RESTART                     3
+    #define AN_STATE_DISABLE_LINK_OK                4
+    #define AN_STATE_ABILITY_DETECT_INIT            5
+    #define AN_STATE_ABILITY_DETECT                 6
+    #define AN_STATE_ACK_DETECT_INIT                7
+    #define AN_STATE_ACK_DETECT                     8
+    #define AN_STATE_COMPLETE_ACK_INIT              9
+    #define AN_STATE_COMPLETE_ACK                   10
+    #define AN_STATE_IDLE_DETECT_INIT               11
+    #define AN_STATE_IDLE_DETECT                    12
+    #define AN_STATE_LINK_OK                        13
+    #define AN_STATE_NEXT_PAGE_WAIT_INIT            14
+    #define AN_STATE_NEXT_PAGE_WAIT                 16
+
+    /* Link timer. */
+    unsigned long LinkTime_us;
+
+    /* Current time. */
+    unsigned long CurrentTime_us;
+
+    /* Ability, idle, and ack match functions. */
+    unsigned long AbilityMatchCnt;
+
+    /* Need these values for consistency check. */
+    unsigned short AbilityMatchCfg;
+
+    unsigned short reserved;
+
+    char AbilityMatch;
+    char IdleMatch;
+    char AckMatch;
+    char reserved1;
+
+    /* Tx config data */
+    union
+    {
+        /* The TxConfig register is arranged as follows:                      */
+        /*                                                                    */
+        /* MSB                                                           LSB  */
+        /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
+        /* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8|  */
+        /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
+        struct
+        {
+#ifdef BIG_ENDIAN_HOST
+            unsigned short D7:1;        /* PS1 */
+            unsigned short D6:1;        /* HD */
+            unsigned short D5:1;        /* FD */
+            unsigned short D4:1;
+            unsigned short D3:1;
+            unsigned short D2:1;
+            unsigned short D1:1;
+            unsigned short D0:1;
+            unsigned short D15:1;       /* NP */
+            unsigned short D14:1;       /* ACK */
+            unsigned short D13:1;       /* RF2 */
+            unsigned short D12:1;       /* RF1 */
+            unsigned short D11:1;
+            unsigned short D10:1;
+            unsigned short D9:1;
+            unsigned short D8:1;        /* PS2 */
+#else /* BIG_ENDIAN_HOST */
+            unsigned int D8:1;        /* PS2 */
+            unsigned int D9:1;
+            unsigned int D10:1;
+            unsigned int D11:1;
+            unsigned int D12:1;       /* RF1 */
+            unsigned int D13:1;       /* RF2 */
+            unsigned int D14:1;       /* ACK */
+            unsigned int D15:1;       /* NP */
+            unsigned int D0:1;
+            unsigned int D1:1;
+            unsigned int D2:1;
+            unsigned int D3:1;
+            unsigned int D4:1;
+            unsigned int D5:1;        /* FD */
+            unsigned int D6:1;        /* HD */
+            unsigned int D7:1;        /* PS1 */
+#endif
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define D8_PS2                      bits.D8
+        #define D12_RF1                     bits.D12
+        #define D13_RF2                     bits.D13
+        #define D14_ACK                     bits.D14
+        #define D15_NP                      bits.D15
+        #define D5_FD                       bits.D5
+        #define D6_HD                       bits.D6
+        #define D7_PS1                      bits.D7
+    } TxConfig;
+
+    /* Rx config data */
+    union
+    {
+        /* The RxConfig register is arranged as follows:                      */
+        /*                                                                    */
+        /* MSB                                                           LSB  */
+        /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
+        /* | D7| D6| D5| D4| D3| D2| D1| D0|D15|D14|D13|D12|D11|D10| D9| D8|  */
+        /* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+  */
+        struct
+        {
+#ifdef BIG_ENDIAN_HOST
+	    unsigned short D7:1;        /* PS1 */
+            unsigned short D6:1;        /* HD */
+	    unsigned short D5:1;        /* FD */
+            unsigned short D4:1;
+            unsigned short D3:1;
+            unsigned short D2:1;
+            unsigned short D1:1;
+            unsigned short D0:1;
+  	    unsigned short D15:1;       /* NP */
+            unsigned short D14:1;       /* ACK */
+            unsigned short D13:1;       /* RF2 */    
+            unsigned short D12:1;       /* RF1 */
+            unsigned short D11:1;
+            unsigned short D10:1;
+            unsigned short D9:1;
+            unsigned short D8:1;        /* PS2 */
+#else /* BIG_ENDIAN_HOST */
+            unsigned int D8:1;        /* PS2 */
+            unsigned int D9:1;
+            unsigned int D10:1;
+            unsigned int D11:1;
+            unsigned int D12:1;       /* RF1 */
+            unsigned int D13:1;       /* RF2 */
+            unsigned int D14:1;       /* ACK */
+            unsigned int D15:1;       /* NP */
+            unsigned int D0:1;
+            unsigned int D1:1;
+            unsigned int D2:1;
+            unsigned int D3:1;
+            unsigned int D4:1;
+            unsigned int D5:1;        /* FD */
+            unsigned int D6:1;        /* HD */
+            unsigned int D7:1;        /* PS1 */
+#endif
+        } bits;
+
+        unsigned short AsUSHORT;
+    } RxConfig;
+
+    #define AN_CONFIG_NP                            0x0080
+    #define AN_CONFIG_ACK                           0x0040
+    #define AN_CONFIG_RF2                           0x0020
+    #define AN_CONFIG_RF1                           0x0010
+    #define AN_CONFIG_PS2                           0x0001
+    #define AN_CONFIG_PS1                           0x8000
+    #define AN_CONFIG_HD                            0x4000
+    #define AN_CONFIG_FD                            0x2000
+
+
+    /* Management registers. */
+
+    /* Control register. */
+    union
+    {
+        struct
+        {
+            unsigned int an_enable:1;
+            unsigned int loopback:1;
+            unsigned int reset:1;
+            unsigned int restart_an:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_an_enable                Mr0.bits.an_enable
+        #define mr_loopback                 Mr0.bits.loopback
+        #define mr_main_reset               Mr0.bits.reset
+        #define mr_restart_an               Mr0.bits.restart_an
+    } Mr0;
+
+    /* Status register. */
+    union
+    {
+        struct
+        {
+            unsigned int an_complete:1;
+            unsigned int link_ok:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_an_complete              Mr1.bits.an_complete
+        #define mr_link_ok                  Mr1.bits.link_ok
+    } Mr1;
+
+    /* Advertisement register. */
+    union
+    {
+        struct
+        {
+            unsigned int reserved_4:5;
+            unsigned int full_duplex:1;
+            unsigned int half_duplex:1;
+            unsigned int sym_pause:1;
+            unsigned int asym_pause:1;
+            unsigned int reserved_11:3;
+            unsigned int remote_fault1:1;
+            unsigned int remote_fault2:1;
+            unsigned int reserved_14:1;
+            unsigned int next_page:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_adv_full_duplex          Mr4.bits.full_duplex
+        #define mr_adv_half_duplex          Mr4.bits.half_duplex
+        #define mr_adv_sym_pause            Mr4.bits.sym_pause
+        #define mr_adv_asym_pause           Mr4.bits.asym_pause
+        #define mr_adv_remote_fault1        Mr4.bits.remote_fault1
+        #define mr_adv_remote_fault2        Mr4.bits.remote_fault2
+        #define mr_adv_next_page            Mr4.bits.next_page
+    } Mr4;
+
+    /* Link partner advertisement register. */
+    union
+    {
+        struct
+        {
+            unsigned int reserved_4:5;
+            unsigned int lp_full_duplex:1;
+            unsigned int lp_half_duplex:1;
+            unsigned int lp_sym_pause:1;
+            unsigned int lp_asym_pause:1;
+            unsigned int reserved_11:3;
+            unsigned int lp_remote_fault1:1;
+            unsigned int lp_remote_fault2:1;
+            unsigned int lp_ack:1;
+            unsigned int lp_next_page:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_lp_adv_full_duplex       Mr5.bits.lp_full_duplex
+        #define mr_lp_adv_half_duplex       Mr5.bits.lp_half_duplex
+        #define mr_lp_adv_sym_pause         Mr5.bits.lp_sym_pause
+        #define mr_lp_adv_asym_pause        Mr5.bits.lp_asym_pause
+        #define mr_lp_adv_remote_fault1     Mr5.bits.lp_remote_fault1
+        #define mr_lp_adv_remote_fault2     Mr5.bits.lp_remote_fault2
+        #define mr_lp_adv_next_page         Mr5.bits.lp_next_page
+    } Mr5;
+
+    /* Auto-negotiation expansion register. */
+    union
+    {
+        struct
+        {
+            unsigned int reserved_0:1;
+            unsigned int page_received:1;
+            unsigned int next_pageable:1;
+            unsigned int reserved_15:13;
+        } bits;
+
+        unsigned short AsUSHORT;
+    } Mr6;
+
+    /* Auto-negotiation next page transmit register. */
+    union
+    {
+        struct
+        {
+            unsigned int code_field:11;
+            unsigned int toggle:1;
+            unsigned int ack2:1;
+            unsigned int message_page:1;
+            unsigned int reserved_14:1;
+            unsigned int next_page:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_np_tx                    Mr7.AsUSHORT
+    } Mr7;
+
+    /* Auto-negotiation link partner ability register. */
+    union
+    {
+        struct
+        {
+            unsigned int code_field:11;
+            unsigned int toggle:1;
+            unsigned int ack2:1;
+            unsigned int message_page:1;
+            unsigned int ack:1;
+            unsigned int next_page:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+        
+        #define mr_lp_np_rx                 Mr8.AsUSHORT
+    } Mr8;
+
+    /* Extended status register. */
+    union
+    {
+        struct
+        {
+            unsigned int reserved_11:12;
+            unsigned int base1000_t_hd:1;
+            unsigned int base1000_t_fd:1;
+            unsigned int base1000_x_hd:1;
+            unsigned int base1000_x_fd:1;
+        } bits;      
+
+        unsigned short AsUSHORT;
+    } Mr15;
+
+    /* Miscellaneous state variables. */
+    union
+    {
+        struct
+        {
+            unsigned int toggle_tx:1;
+            unsigned int toggle_rx:1;
+            unsigned int np_rx:1;
+            unsigned int page_rx:1;
+            unsigned int np_loaded:1;
+        } bits;
+
+        unsigned short AsUSHORT;
+
+        #define mr_toggle_tx                MrMisc.bits.toggle_tx
+        #define mr_toggle_rx                MrMisc.bits.toggle_rx
+        #define mr_np_rx                    MrMisc.bits.np_rx
+        #define mr_page_rx                  MrMisc.bits.page_rx
+        #define mr_np_loaded                MrMisc.bits.np_loaded
+    } MrMisc;
+
+} AN_STATE_INFO, *PAN_STATE_INFO;
+
+
+
+/******************************************************************************/
+/* Return code of Autoneg8023z. */
+/******************************************************************************/
+
+typedef enum
+{
+    AUTONEG_STATUS_OK               = 0,
+    AUTONEG_STATUS_DONE             = 1,
+    AUTONEG_STATUS_TIMER_ENABLED    = 2,
+//    AUTONEG_STATUS_FAILED           = 0xffffffff,
+    AUTONEG_STATUS_FAILED           = 0xfffffff
+} AUTONEG_STATUS, *PAUTONEG_STATUS;
+
+
+
+/******************************************************************************/
+/* Function prototypes. */
+/******************************************************************************/
+
+AUTONEG_STATUS Autoneg8023z(PAN_STATE_INFO pAnInfo);
+void AutonegInit(PAN_STATE_INFO pAnInfo);
+
+
+
+/******************************************************************************/
+/* The following functions are defined in the os-dependent module. */
+/******************************************************************************/
+
+void MM_AnTxConfig(PAN_STATE_INFO pAnInfo);
+void MM_AnTxIdle(PAN_STATE_INFO pAnInfo);
+char MM_AnRxConfig(PAN_STATE_INFO pAnInfo, unsigned short *pRxConfig);
+
+
+
+#endif /* AUTONEG_H */
+
diff -u --recursive --new-file linux-2.4.26/drivers/net/bcm/b57diag.c linux-2.4.26.patch/drivers/net/bcm/b57diag.c
--- linux-2.4.26/drivers/net/bcm/b57diag.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.26.patch/drivers/net/bcm/b57diag.c	2004-06-22 16:07:37.000000000 -0700
@@ -0,0 +1,706 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2004 Broadcom  */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* ethtool -t selftest code.                                                  */
+/*                                                                            */
+/******************************************************************************/
+
+#include "mm.h"
+#ifdef ETHTOOL_TEST
+
+typedef struct reg_entry
+{
+	LM_UINT16   offset;
+	LM_UINT16   flags;
+#define BCM5705_ONLY		1
+#define NOT_FOR_BCM5705		2
+#define NOT_FOR_BCM5788		4
+	LM_UINT32   read_mask;
+	LM_UINT32   write_mask;
+} reg_entry_t;
+
+typedef struct mem_entry
+{
+	LM_UINT32   offset;
+	LM_UINT32   len;
+} mem_entry_t;
+
+/* Returns 1 on success, 0 on failure */
+int
+b57_test_registers(UM_DEVICE_BLOCK *pUmDevice)
+{
+	LM_DEVICE_BLOCK *pDevice = &pUmDevice->lm_dev;
+	int ret;
+	int i, bcm5705;
+	LM_UINT32 offset, read_mask, write_mask, val, save_val, read_val;
+	static reg_entry_t reg_tbl[] = {
+		/* MAC block */
+		{ 0x0400, 0x0002, 0x00000000, 0x00ef6f8c },
+		{ 0x0400, 0x0001, 0x00000000, 0x01ef6b8c },	/* 5705 */
+		{ 0x0404, 0x0002, 0x03800107, 0x00000000 },
+		{ 0x0404, 0x0001, 0x03800100, 0x00000000 },	/* 5705 */
+		{ 0x0408, 0x0002, 0x00000000, 0x07c01400 },
+		{ 0x0408, 0x0001, 0x00000000, 0x07c01000 },	/* 5705 */
+		{ 0x040c, 0x0000, 0x00000000, 0xfff8007f },
+		{ 0x0410, 0x0000, 0x00000000, 0x0000ffff },
+		{ 0x0414, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x0418, 0x0000, 0x00000000, 0x0000ffff },
+		{ 0x041c, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x0420, 0x0000, 0x00000000, 0x0000ffff },
+		{ 0x0424, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x0428, 0x0000, 0x00000000, 0x0000ffff },
+		{ 0x042c, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x0430, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x0430, 0x0001, 0x00000000, 0x0fff03ff },	/* 5705 */
+		{ 0x0434, 0x0002, 0x00000000, 0x0fffffff },
+		{ 0x0434, 0x0001, 0x00000000, 0x000001ff },	/* 5705 */
+		{ 0x043c, 0x0000, 0x00000000, 0x0000ffff },
+		{ 0x0454, 0x0000, 0x00000000, 0x00000010 },
+		{ 0x045c, 0x0000, 0x00000000, 0x00000070 },
+		{ 0x0464, 0x0000, 0x00000000, 0x00003fff },
+		{ 0x0468, 0x0002, 0x00000000, 0x000007fc },
+		{ 0x0468, 0x0001, 0x00000000, 0x000007dc },	/* 5705 */
+		{ 0x0470, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x0474, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x0478, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x047c, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x0480, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x0480, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
+		{ 0x0484, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x0488, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x0488, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
+		{ 0x048c, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x0490, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x0490, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
+		{ 0x0494, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x0498, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x0498, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
+		{ 0x049c, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x04a0, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04a0, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
+		{ 0x04a4, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x04a8, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04a8, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
+		{ 0x04ac, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x04b0, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04b0, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
+		{ 0x04b4, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x04b8, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04b8, 0x0001, 0x00000000, 0xe7ffffff },	/* 5705 */
+		{ 0x04bc, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x04c0, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04c4, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04c8, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04cc, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04d0, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04d4, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04d8, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04dc, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04e0, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04e4, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04e8, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04ec, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04f0, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04f4, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04f8, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x04fc, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x0500, 0x0002, 0x00000000, 0x000000f8 },
+		{ 0x0500, 0x0001, 0x00000000, 0x00000008 },	/* 5705 */
+
+		/* Send Data Initiator Control Registers */
+		{ 0x0c00, 0x0000, 0x00000000, 0x00000006 },
+		{ 0x0c04, 0x0000, 0x00000004, 0x00000000 },
+		{ 0x0c08, 0x0000, 0x00000000, 0x0000001b },
+		{ 0x0c0c, 0x0002, 0x00000000, 0x00ffffff },
+		{ 0x0c0c, 0x0001, 0x00000000, 0x00000001 },
+		{ 0x0c80, 0x0000, 0x000003ff, 0x00000000 },
+		{ 0x0c84, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0c88, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0c8c, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0c90, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0c94, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0c98, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0c9c, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0ca0, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0ca4, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0ca8, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0cac, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0cb0, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0cb4, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0cb8, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0cbc, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0cc0, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0cc4, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0cc8, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0ccc, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0cd0, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0cd4, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0cd8, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0cdc, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x0ce0, 0x0001, 0x00000000, 0xffffffff },	/* 5705 */
+		{ 0x0ce4, 0x0001, 0x00000000, 0xffffffff },	/* 5705 */
+		{ 0x0ce8, 0x0001, 0x00000000, 0x00ffffff },	/* 5705 */
+		{ 0x0cec, 0x0001, 0x00000000, 0x000efcf7 },	/* 5705 */
+		{ 0x0cf0, 0x0001, 0x00000000, 0x0000ffff },	/* 5705 */
+		{ 0x0cf4, 0x0001, 0x00000000, 0x20000000 },	/* 5705 */
+
+		/* SDC Control Registers */
+		{ 0x1000, 0x0000, 0x00000000, 0x00000002 },
+		{ 0x1008, 0x0001, 0x00000000, 0x40000000 },	/* 5705 */
+
+		/* Send BD Ring Selector Control Registers. */
+		{ 0x1400, 0x0000, 0x00000000, 0x00000006 },
+		{ 0x1404, 0x0000, 0x00000004, 0x00000000 },
+		{ 0x1408, 0x0000, 0x0000ffff, 0x00000000 },
+		{ 0x1440, 0x0000, 0x0000000f, 0x00000000 },
+		{ 0x1444, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x1448, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x144c, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x1450, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x1454, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x1458, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x145c, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x1460, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x1464, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x1468, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x146c, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x1470, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x1474, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x1478, 0x0002, 0x0000000f, 0x00000000 },
+		{ 0x147c, 0x0002, 0x0000000f, 0x00000000 },
+
+		/* Send BD Inititor Control Registers.*/
+		{ 0x1800, 0x0000, 0x00000000, 0x00000006 },
+		{ 0x1804, 0x0000, 0x00000004, 0x00000000 },
+		{ 0x1808, 0x0000, 0xffffffff, 0x00000000 },
+		{ 0x180c, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x1810, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x1814, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x1818, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x181c, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x1820, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x1824, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x1828, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x182c, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x1830, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x1834, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x1838, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x183c, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x1840, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x1844, 0x0002, 0xffffffff, 0x00000000 },
+
+		/* Send BD Completion Control Registers */
+		{ 0x1c00, 0x0000, 0x00000000, 0x00000002 },
+
+		/* Receive List Placement Control Registers. */
+		{ 0x2000, 0x0000, 0x00000000, 0x0000001e },
+		{ 0x2004, 0x0000, 0x0000001c, 0x00000000 },
+		{ 0x2010, 0x0002, 0x00000000, 0x00007fff },
+		{ 0x2010, 0x0001, 0x00000000, 0x000060ff },	/* 5705 */
+		{ 0x2014, 0x0000, 0x00000000, 0x00000001 },
+		{ 0x2200, 0x0000, 0x000003ff, 0x00000000 },
+		{ 0x2204, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2208, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x220c, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2210, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2214, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2218, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x221c, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2220, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2224, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2228, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x222c, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2230, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2234, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2238, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x223c, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2240, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2244, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x2248, 0x0002, 0x000003ff, 0x00000000 },
+		{ 0x224c, 0x0000, 0x000003ff, 0x00000000 },
+		{ 0x2250, 0x0000, 0x000003ff, 0x00000000 },
+		{ 0x2254, 0x0000, 0x000003ff, 0x00000000 },
+		{ 0x2258, 0x0002, 0x000003ff, 0x00000000 },
+
+		/* Receive Data and Receive BD Initiator Control Registers. */
+		{ 0x2400, 0x0002, 0x00000000, 0x0000001e },
+		{ 0x2400, 0x0001, 0x00000000, 0x0000001a },	/* 5705 */
+		{ 0x2404, 0x0000, 0x0000001c, 0x00000000 },
+		{ 0x2408, 0x0002, 0x00000000, 0x0000ffff },
+		{ 0x2440, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x2444, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x2448, 0x0002, 0x00000000, 0x00000003 },
+		{ 0x244c, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x2450, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x2454, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x2458, 0x0000, 0x00000000, 0xffff0002 },
+		{ 0x245c, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x2470, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x2474, 0x0000, 0xffffffff, 0x00000000 },
+		{ 0x2478, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x2480, 0x0000, 0xffffffff, 0x00000000 },
+		{ 0x2484, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x2488, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x248c, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x2490, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x2494, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x2498, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x249c, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x24a0, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x24a4, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x24a8, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x24ac, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x24b0, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x24b4, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x24b8, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x24bc, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x24c0, 0x0000, 0xffffffff, 0x00000000 },
+	
+		/* Receive Data Completion Control Registers */
+		{ 0x2800, 0x0000, 0x00000000, 0x00000002 },
+
+		/* Receive BD Initiator Control Registers. */
+		{ 0x2c00, 0x0000, 0x00000000, 0x00000006 },
+		{ 0x2c04, 0x0000, 0x00000004, 0x00000000 },
+		{ 0x2c18, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x2c18, 0x0001, 0x00000000, 0x000003ff },	/* 5705 */
+		{ 0x2c1c, 0x0002, 0x00000000, 0xffffffff },
+	
+		/* Receive BD Completion Control Registers. */
+		{ 0x3000, 0x0000, 0x00000000, 0x00000006 },
+		{ 0x3004, 0x0000, 0x00000004, 0x00000000 },
+		{ 0x3008, 0x0002, 0x00000000, 0x000000ff },
+		{ 0x300c, 0x0000, 0x00000000, 0x000001ff },
+
+		/* Host Coalescing Control Registers. */
+		{ 0x3c00, 0x0002, 0x00000000, 0x00000004 },
+		{ 0x3c00, 0x0001, 0x00000000, 0x000000f6 },	/* 5705 */
+		{ 0x3c04, 0x0000, 0x00000004, 0x00000000 },
+		{ 0x3c08, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x3c08, 0x0001, 0x00000000, 0x000003ff },	/* 5705 */
+		{ 0x3c0c, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x3c0c, 0x0001, 0x00000000, 0x000003ff },	/* 5705 */
+		{ 0x3c10, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x3c10, 0x0005, 0x00000000, 0x000000ff },	/* 5705 */
+		{ 0x3c14, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x3c14, 0x0005, 0x00000000, 0x000000ff },	/* 5705 */
+		{ 0x3c18, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x3c1c, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x3c20, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x3c20, 0x0005, 0x00000000, 0x000000ff },	/* 5705 */
+		{ 0x3c24, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x3c24, 0x0005, 0x00000000, 0x000000ff },	/* 5705 */
+		{ 0x3c28, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x3c30, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x3c34, 0x0002, 0x00000000, 0xffffffff },
+		{ 0x3c38, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x3c3c, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x3c40, 0x0000, 0xffffffff, 0x00000000 },
+		{ 0x3c44, 0x0000, 0xffffffff, 0x00000000 },
+		{ 0x3c50, 0x0002, 0x00000000, 0x000000ff },
+		{ 0x3c54, 0x0000, 0x00000000, 0x000000ff },
+		{ 0x3c80, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3c80, 0x0001, 0x00000000, 0x000001ff },	/* 5705 */
+		{ 0x3c84, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3c88, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3c8c, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3c90, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3c94, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3c98, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3c9c, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3ca0, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3ca4, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3ca8, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3cac, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3cb0, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3cb4, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3cb8, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3cbc, 0x0002, 0x00000000, 0x000007ff },
+		{ 0x3cc0, 0x0000, 0x00000000, 0x000001ff },
+		{ 0x3cc4, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3cc8, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3ccc, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3cd0, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3cd4, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3cd8, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3cdc, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3ce0, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3ce4, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3ce8, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3cec, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3cf0, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3cf4, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3cf8, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x3cfc, 0x0002, 0x00000000, 0x000001ff },
+
+		/* Memory Arbiter Registers */
+		{ 0x4000, 0x0002, 0x00000000, 0x001ffffe },
+		{ 0x4000, 0x0001, 0x00000000, 0x38111e7e },
+		{ 0x4004, 0x0002, 0x001ffffc, 0x00000000 },
+		{ 0x4004, 0x0002, 0x00111dfc, 0x00000000 },
+		{ 0x4008, 0x0000, 0x00000000, 0x001fffff },
+		{ 0x400c, 0x0000, 0x00000000, 0x001fffff },
+
+		/* Buffer Manager Control Registers. */
+		{ 0x4400, 0x0000, 0x00000000, 0x0000001c },
+		{ 0x4404, 0x0000, 0x00000014, 0x00000000 },
+		{ 0x4408, 0x0000, 0x00000000, 0x007fff80 },
+		{ 0x440c, 0x0000, 0x00000000, 0x007fffff },
+		{ 0x4410, 0x0000, 0x00000000, 0x0000003f },
+		{ 0x4414, 0x0000, 0x00000000, 0x000001ff },
+		{ 0x4418, 0x0000, 0x00000000, 0x000001ff },
+		{ 0x4420, 0x0000, 0xffffffff, 0x00000000 },
+		{ 0x4428, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x442c, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x4430, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x4440, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x4448, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x444c, 0x0000, 0xffffffff, 0x00000000 },
+		{ 0x4450, 0x0000, 0xffffffff, 0x00000000 },
+		{ 0x4454, 0x0000, 0xffffffff, 0x00000000 },
+		{ 0x4458, 0x0001, 0x00000000, 0x000001ff },	/* 5705 */
+	
+		{ 0x4800, 0x0002, 0x00000000, 0x000003fe },
+		{ 0x4800, 0x0001, 0x00000000, 0xc00003fe },	/* 5705 */
+		{ 0x4804, 0x0000, 0x000003fc, 0x00000000 },
+		{ 0x4c00, 0x0002, 0x00000000, 0x000003fc },
+		{ 0x4c00, 0x0001, 0x00000000, 0x000007fc },	/* 5705 */
+		{ 0x4c04, 0x0000, 0x000003fc, 0x00000000 },
+
+		/* Mailbox Registers */
+		{ 0x5804, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x586c, 0x0000, 0x00000000, 0x000001ff },
+		{ 0x5874, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x5884, 0x0000, 0x00000000, 0x000007ff },
+		{ 0x5904, 0x0000, 0x00000000, 0x000001ff },
+		{ 0x5984, 0x0002, 0x00000000, 0x000001ff },
+		{ 0x5a04, 0x0000, 0x00000000, 0xffffffff },
+		{ 0x5a0c, 0x0000, 0x00000000, 0xffffffff },
+
+		/* Flow Through Queues. */
+		{ 0x5c14, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5c24, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5c34, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5c44, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5c54, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5c64, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5c74, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5c84, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5c94, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5ca4, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5cb4, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5cc4, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5cd4, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5ce4, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5cf4, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5d04, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0x5d14, 0x0002, 0xffffffff, 0x00000000 },
+		{ 0xffff, 0x0000, 0x00000000, 0x00000000 },
+	};
+
+	if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId)) {
+		bcm5705 = 1;
+	}
+	else {
+		bcm5705 = 0;
+	}
+
+	ret = 1;
+	for (i = 0; reg_tbl[i].offset != 0xffff; i++) {
+		if (bcm5705 && (reg_tbl[i].flags & NOT_FOR_BCM5705))
+			continue;
+		if (!bcm5705 && (reg_tbl[i].flags & BCM5705_ONLY))
+			continue;
+		if ((pDevice->Flags & BCM5788_FLAG) &&
+			(reg_tbl[i].flags & NOT_FOR_BCM5788))
+			continue;
+		offset = (LM_UINT32) reg_tbl[i].offset;
+		read_mask = reg_tbl[i].read_mask;
+		write_mask = reg_tbl[i].write_mask;
+
+		/* Save the original register content */
+		save_val = LM_RegRd(pDevice, offset);
+
+		/* Determine the read-only value. */
+		read_val = save_val & read_mask;
+
+		/* Write zero to the register, then make sure the read-only bits
+		   are not changed and the read/write bits are all zeros. */
+		LM_RegWr(pDevice, offset, 0, FALSE);
+
+		val = LM_RegRd(pDevice, offset);
+
+		/* Test the read-only and read/write bits. */
+		if (((val & read_mask) != read_val) ||
+			(val & write_mask)) {
+
+	                ret = 0;
+			LM_RegWr(pDevice, offset, save_val, FALSE);
+			break;
+		}
+
+
+		/* Write ones to all the bits defined by RdMask and WrMask, then
+		   make sure the read-only bits are not changed and the
+		   read/write bits are all ones. */
+		LM_RegWr(pDevice, offset, read_mask | write_mask, FALSE);
+
+		val = LM_RegRd(pDevice, offset);
+
+		/* Test the read-only bits. */
+		if ((val & read_mask) != read_val) {
+	                ret = 0;
+			LM_RegWr(pDevice, offset, save_val, FALSE);
+			break;
+		}
+
+		/* Test the read/write bits. */
+		if ((val & write_mask) != write_mask) {
+	                ret = 0;
+			LM_RegWr(pDevice, offset, save_val, FALSE);
+			break;
+		}
+
+		LM_RegWr(pDevice, offset, save_val, FALSE);
+	}
+
+	return ret;
+}
+
+
+/* Returns 1 on success, 0 on failure */
+int
+b57_do_memory_test(LM_DEVICE_BLOCK *pDevice, LM_UINT32 start, LM_UINT32 size)
+{
+	const LM_UINT32 test_pattern[] = { 0x00000000, 0xffffffff, 0x55555555,
+		0xaaaaaaaa , 0xaa55aa55, 0x55aa55aa };
+	LM_UINT32 offset;
+	int i;
+
+	for (i = 0; i < sizeof(test_pattern)/sizeof(LM_UINT32); i++) {
+		for (offset = 0; offset < size; offset += 4) {
+
+			LM_MemWrInd(pDevice, start + offset, test_pattern[i]);
+
+			if (LM_MemRdInd(pDevice, start + offset) !=
+				test_pattern[i]) {
+				return 0;
+			}
+		}
+	}
+	return 1;
+}
+
+/* Returns 1 on success, 0 on failure */
+int
+b57_test_memory(UM_DEVICE_BLOCK *pUmDevice)
+{
+	LM_DEVICE_BLOCK *pDevice = &pUmDevice->lm_dev;
+	int ret = 0;
+	int i;
+	mem_entry_t *mem_tbl;
+
+	static mem_entry_t mem_tbl_570x[] = {
+		{ 0x00000000, 0x01000},
+		{ 0x00002000, 0x1c000},
+		{ 0xffffffff, 0x00000}
+	};
+	static mem_entry_t mem_tbl_5705[] = {
+		{ 0x00000100, 0x0000c},
+		{ 0x00000200, 0x00008},
+		{ 0x00000b50, 0x00400},
+		{ 0x00004000, 0x00800},
+		{ 0x00006000, 0x01000},
+		{ 0x00008000, 0x02000},
+		{ 0x00010000, 0x0e000},
+		{ 0xffffffff, 0x00000}
+	};
+
+	if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId)) {
+		mem_tbl = mem_tbl_5705;
+	}
+	else {
+		mem_tbl = mem_tbl_570x;
+	}
+	for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) {
+		if ((ret = b57_do_memory_test(pDevice, mem_tbl[i].offset,
+			mem_tbl[i].len)) == 0) {
+			return ret;
+		}
+	}
+	
+	return ret;
+}
+
+#define EEPROM_SIZE 0x100
+
+/* Returns 1 on success, 0 on failure */
+int
+b57_test_nvram(UM_DEVICE_BLOCK *pUmDevice)
+{
+	LM_DEVICE_BLOCK *pDevice = &pUmDevice->lm_dev;
+	LM_UINT32 buf[EEPROM_SIZE/4];
+	LM_UINT8 *pdata = (LM_UINT8 *) buf;
+	int i;
+	LM_UINT32 magic, csum;
+
+	for (i = 0; i < EEPROM_SIZE; i += 4) {
+		if (LM_NvramRead(pDevice, i, (LM_UINT32 *) (pdata + i)) !=
+			LM_STATUS_SUCCESS) {
+			break;
+		}
+	}
+	if (i < EEPROM_SIZE) {
+		return 0;
+	}
+
+        magic = MM_SWAP_BE32(buf[0]);
+	if (magic != 0x669955aa) {
+		return 0;
+	}
+
+	csum = ComputeCrc32(pdata, 16);
+	if(csum != MM_SWAP_LE32(buf[0x10/4])) {
+		return 0;
+	}
+
+	csum = ComputeCrc32(&pdata[0x74], 136);
+	if (csum != MM_SWAP_LE32(buf[0xfc/4])) {
+		return 0;
+	}
+
+	return 1;
+}
+
+/* Returns 1 on success, 0 on failure */
+int
+b57_test_link(UM_DEVICE_BLOCK *pUmDevice)
+{
+	LM_DEVICE_BLOCK *pDevice = &pUmDevice->lm_dev;
+	LM_UINT32 phy_reg;
+
+	if (pDevice->TbiFlags & ENABLE_TBI_FLAG) {
+		if (REG_RD(pDevice, MacCtrl.Status) &
+			(MAC_STATUS_PCS_SYNCED | MAC_STATUS_SIGNAL_DETECTED)) {
+			return 1;
+		}
+		return 0;
+	}
+	LM_ReadPhy(pDevice, PHY_STATUS_REG, &phy_reg);
+	LM_ReadPhy(pDevice, PHY_STATUS_REG, &phy_reg);
+	if (phy_reg & PHY_STATUS_LINK_PASS)
+		return 1;
+	return 0;
+}
+
+/* Returns 1 on success, 0 on failure */
+int
+b57_test_loopback(UM_DEVICE_BLOCK *pUmDevice)
+{
+	LM_DEVICE_BLOCK *pDevice = &pUmDevice->lm_dev;
+	struct sk_buff *skb, *rx_skb;
+	unsigned char *packet;
+	dma_addr_t map;
+	LM_UINT32 send_idx, rx_start_idx, rx_idx;
+	int num_pkts, pkt_size, i, ret;
+	LM_PACKET *pPacket;
+	T3_SND_BD *pSendBd;
+	T3_RCV_BD *pRcvBd;
+
+	ret = 0;
+	if (!pUmDevice->opened)
+		return ret;
+	LM_ResetAdapter(pDevice);
+	LM_EnableMacLoopBack(pDevice);
+	pkt_size = 1514;
+	skb = dev_alloc_skb(pkt_size);
+	packet = skb_put(skb, pkt_size);
+	memcpy(packet, pDevice->NodeAddress, 6);
+	memset(packet + 6, 0x0, 8);
+	for (i = 14; i < pkt_size; i++)
+		packet[i] = (unsigned char) (i & 0xff);
+	map = pci_map_single(pUmDevice->pdev, skb->data, pkt_size,
+		PCI_DMA_TODEVICE);
+
+	REG_WR(pDevice, HostCoalesce.Mode,
+		pDevice->CoalesceMode | HOST_COALESCE_ENABLE |
+			HOST_COALESCE_NOW);
+	MM_Wait(10);
+	rx_start_idx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
+
+	send_idx = 0;
+	num_pkts = 0;
+	pSendBd = &pDevice->pSendBdVirt[send_idx];
+	if (pDevice->Flags & NIC_SEND_BD_FLAG) {
+		T3_64BIT_HOST_ADDR HostAddr;
+
+		MM_SetT3Addr(&HostAddr, map);
+		MM_MEMWRITEL(&(pSendBd->HostAddr.High), HostAddr.High);
+		MM_MEMWRITEL(&(pSendBd->HostAddr.Low), HostAddr.Low);
+                MM_MEMWRITEL(&(pSendBd->u1.Len_Flags), 
+                	(pkt_size << 16) | SND_BD_FLAG_END);
+		send_idx++;
+		num_pkts++;
+	        MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low, send_idx);
+		if (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
+	        	MB_REG_WR(pDevice, Mailbox.SendNicProdIdx[0].Low,
+				send_idx);
+		}
+	        MB_REG_RD(pDevice, Mailbox.SendNicProdIdx[0].Low);
+	}
+	else {
+		MM_SetT3Addr(&pSendBd->HostAddr, map);
+                pSendBd->u1.Len_Flags = (pkt_size << 16) | SND_BD_FLAG_END;
+        	MM_WMB();
+		send_idx++;
+		num_pkts++;
+	        MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low, send_idx);
+		if (T3_CHIP_REV(pDevice->ChipRevId) == T3_CHIP_REV_5700_BX) {
+	        	MB_REG_WR(pDevice, Mailbox.SendHostProdIdx[0].Low,
+				send_idx);
+		}
+	        MB_REG_RD(pDevice, Mailbox.SendHostProdIdx[0].Low);
+	}
+	MM_Wait(100);
+	REG_WR(pDevice, HostCoalesce.Mode,
+		pDevice->CoalesceMode | HOST_COALESCE_ENABLE |
+			HOST_COALESCE_NOW);
+	MM_Wait(10);
+	dev_kfree_skb_irq(skb);
+	if (pDevice->pStatusBlkVirt->Idx[0].SendConIdx != send_idx) {
+		goto loopback_test_done;
+	}
+	rx_idx = pDevice->pStatusBlkVirt->Idx[0].RcvProdIdx;
+	if (rx_idx != rx_start_idx + num_pkts) {
+		goto loopback_test_done;
+	}
+	pRcvBd = &pDevice->pRcvRetBdVirt[rx_start_idx];
+	pPacket = (PLM_PACKET) (MM_UINT_PTR(pDevice->pPacketDescBase) +
+		MM_UINT_PTR(pRcvBd->Opaque));
+
+	if (pRcvBd->ErrorFlag &&
+		pRcvBd->ErrorFlag != RCV_BD_ERR_ODD_NIBBLED_RCVD_MII) {
+		goto loopback_test_done;
+	}
+	if ((pRcvBd->Len - 4) != pkt_size) {
+		goto loopback_test_done;
+	}
+	rx_skb = ((UM_PACKET *) pPacket)->skbuff;
+	for (i = 14; i < pkt_size; i++) {
+		if (*(skb->data + i) != (unsigned char) (i & 0xff))
+			goto loopback_test_done;
+	}
+	ret = 1;
+	
+loopback_test_done:
+	LM_DisableMacLoopBack(pDevice);
+	return ret;
+}
+#endif
diff -u --recursive --new-file linux-2.4.26/drivers/net/bcm/b57proc.c linux-2.4.26.patch/drivers/net/bcm/b57proc.c
--- linux-2.4.26/drivers/net/bcm/b57proc.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.26.patch/drivers/net/bcm/b57proc.c	2004-06-22 16:07:37.000000000 -0700
@@ -0,0 +1,473 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2003 Broadcom  */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/* /proc file system handling code.                                           */
+/*                                                                            */
+/******************************************************************************/
+
+#include "mm.h"
+#ifdef BCM_PROC_FS
+
+#define NICINFO_PROC_DIR "nicinfo"
+
+static struct proc_dir_entry *bcm5700_procfs_dir;
+
+extern char bcm5700_driver[], bcm5700_version[];
+
+extern uint64_t bcm5700_crc_count(PUM_DEVICE_BLOCK pUmDevice);
+extern uint64_t bcm5700_rx_err_count(PUM_DEVICE_BLOCK pUmDevice);
+
+static char *na_str = "n/a";
+static char *pause_str = "pause ";
+static char *asym_pause_str = "asym_pause ";
+static char *on_str = "on";
+static char *off_str = "off";
+static char *up_str = "up";
+static char *down_str = "down";
+
+static struct proc_dir_entry *
+proc_getdir(char *name, struct proc_dir_entry *proc_dir)
+{
+	struct proc_dir_entry *pde = proc_dir;
+
+	lock_kernel();
+	for (pde=pde->subdir; pde; pde = pde->next) {
+		if (pde->namelen && (strcmp(name, pde->name) == 0)) {
+			/* directory exists */
+			break;
+		}
+	}
+	if (pde == (struct proc_dir_entry *) 0)
+	{
+		/* create the directory */
+#if (LINUX_VERSION_CODE > 0x20300)
+		pde = proc_mkdir(name, proc_dir);
+#else
+		pde = create_proc_entry(name, S_IFDIR, proc_dir);
+#endif
+		if (pde == (struct proc_dir_entry *) 0) {
+			unlock_kernel();
+			return (pde);
+		}
+	}
+	unlock_kernel();
+	return (pde);
+}
+
+int
+bcm5700_proc_create(void)
+{
+	bcm5700_procfs_dir = proc_getdir(NICINFO_PROC_DIR, proc_net);
+
+	if (bcm5700_procfs_dir == (struct proc_dir_entry *) 0) {
+		printk(KERN_DEBUG "Could not create procfs nicinfo directory %s\n", NICINFO_PROC_DIR);
+		return -1;
+	}
+	return 0;
+}
+
+void
+b57_get_speed_adv(PUM_DEVICE_BLOCK pUmDevice, char *str)
+{
+	PLM_DEVICE_BLOCK pDevice = &pUmDevice->lm_dev;
+
+	if (pDevice->DisableAutoNeg == TRUE) {
+		strcpy(str, na_str);
+		return;
+	}
+	if (pDevice->TbiFlags & ENABLE_TBI_FLAG) {
+		strcpy(str, "1000full");
+		return;
+	}
+	str[0] = 0;
+	if (pDevice->advertising & PHY_AN_AD_10BASET_HALF) {
+		strcat(str, "10half ");
+	}
+	if (pDevice->advertising & PHY_AN_AD_10BASET_FULL) {
+		strcat(str, "10full ");
+	}
+	if (pDevice->advertising & PHY_AN_AD_100BASETX_HALF) {
+		strcat(str, "100half ");
+	}
+	if (pDevice->advertising & PHY_AN_AD_100BASETX_FULL) {
+		strcat(str, "100full ");
+	}
+	if (pDevice->advertising1000 & BCM540X_AN_AD_1000BASET_HALF) {
+		strcat(str, "1000half ");
+	}
+	if (pDevice->advertising1000 & BCM540X_AN_AD_1000BASET_FULL) {
+		strcat(str, "1000full ");
+	}
+}
+
+void
+b57_get_fc_adv(PUM_DEVICE_BLOCK pUmDevice, char *str)
+{
+	PLM_DEVICE_BLOCK pDevice = &pUmDevice->lm_dev;
+
+	if (pDevice->DisableAutoNeg == TRUE) {
+		strcpy(str, na_str);
+		return;
+	}
+	str[0] = 0;
+	if (pDevice->TbiFlags & ENABLE_TBI_FLAG) {
+		if(pDevice->DisableAutoNeg == FALSE ||
+			pDevice->RequestedLineSpeed == LM_LINE_SPEED_AUTO) {
+			if (pDevice->FlowControlCap &
+				LM_FLOW_CONTROL_RECEIVE_PAUSE) {
+
+				strcpy(str, pause_str);
+				if (!(pDevice->FlowControlCap &
+					LM_FLOW_CONTROL_TRANSMIT_PAUSE)) {
+
+					strcpy(str, asym_pause_str);
+				}
+			}
+			else if (pDevice->FlowControlCap &
+				LM_FLOW_CONTROL_TRANSMIT_PAUSE) {
+
+				strcpy(str, asym_pause_str);
+			}
+		}
+		return;
+	}
+	if (pDevice->advertising & PHY_AN_AD_PAUSE_CAPABLE) {
+		strcat(str, pause_str);
+	}
+	if (pDevice->advertising & PHY_AN_AD_ASYM_PAUSE) {
+		strcat(str, asym_pause_str);
+	}
+}
+
+int
+bcm5700_read_pfs(char *page, char **start, off_t off, int count,
+	int *eof, void *data)
+{
+	struct net_device *dev = (struct net_device *) data;
+	PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) dev->priv;
+	PLM_DEVICE_BLOCK pDevice = &pUmDevice->lm_dev;
+	PT3_STATS_BLOCK pStats = (PT3_STATS_BLOCK) pDevice->pStatsBlkVirt;
+	int len = 0;
+	unsigned long rx_mac_errors, rx_crc_errors, rx_align_errors;
+	unsigned long rx_runt_errors, rx_frag_errors, rx_long_errors;
+	unsigned long rx_overrun_errors, rx_jabber_errors;
+	char str[64];
+
+	if (pUmDevice->opened == 0)
+		pStats = 0;
+
+	len += sprintf(page+len, "Description\t\t\t%s\n", pUmDevice->name);
+	len += sprintf(page+len, "Driver_Name\t\t\t%s\n", bcm5700_driver);
+	len += sprintf(page+len, "Driver_Version\t\t\t%s\n", bcm5700_version);
+	len += sprintf(page+len, "Bootcode_Version\t\t%s\n", pDevice->BootCodeVer);
+	len += sprintf(page+len, "PCI_Vendor\t\t\t0x%04x\n", pDevice->PciVendorId);
+	len += sprintf(page+len, "PCI_Device_ID\t\t\t0x%04x\n",
+		pDevice->PciDeviceId);
+	len += sprintf(page+len, "PCI_Subsystem_Vendor\t\t0x%04x\n",
+		pDevice->SubsystemVendorId);
+	len += sprintf(page+len, "PCI_Subsystem_ID\t\t0x%04x\n",
+		pDevice->SubsystemId);
+	len += sprintf(page+len, "PCI_Revision_ID\t\t\t0x%02x\n",
+		pDevice->PciRevId);
+	len += sprintf(page+len, "PCI_Slot\t\t\t%d\n",
+		PCI_SLOT(pUmDevice->pdev->devfn));
+	if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) {
+		len += sprintf(page+len, "PCI_Function\t\t\t%d\n",
+			pDevice->FunctNum);
+	}
+	len += sprintf(page+len, "PCI_Bus\t\t\t\t%d\n",
+		pUmDevice->pdev->bus->number);
+
+	len += sprintf(page+len, "PCI_Bus_Speed\t\t\t%s\n",
+		pDevice->BusSpeedStr);
+
+	len += sprintf(page+len, "Memory\t\t\t\t0x%lx\n", pUmDevice->dev->base_addr);
+	len += sprintf(page+len, "IRQ\t\t\t\t%d\n", dev->irq);
+	len += sprintf(page+len, "System_Device_Name\t\t%s\n", dev->name);
+	len += sprintf(page+len, "Current_HWaddr\t\t\t%02x:%02x:%02x:%02x:%02x:%02x\n",
+		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+	len += sprintf(page+len,
+		"Permanent_HWaddr\t\t%02x:%02x:%02x:%02x:%02x:%02x\n",
+		pDevice->NodeAddress[0], pDevice->NodeAddress[1],
+		pDevice->NodeAddress[2], pDevice->NodeAddress[3],
+		pDevice->NodeAddress[4], pDevice->NodeAddress[5]);
+	len += sprintf(page+len, "Part_Number\t\t\t%s\n\n", pDevice->PartNo);
+
+	len += sprintf(page+len, "Link\t\t\t\t%s\n", 
+		(pUmDevice->opened == 0) ? "unknown" :
+    		((pDevice->LinkStatus == LM_STATUS_LINK_ACTIVE) ? up_str :
+		down_str));
+	len += sprintf(page+len, "Auto_Negotiate\t\t\t%s\n", 
+    		(pDevice->DisableAutoNeg == TRUE) ? off_str : on_str);
+	b57_get_speed_adv(pUmDevice, str);
+	len += sprintf(page+len, "Speed_Advertisement\t\t%s\n", str);
+	b57_get_fc_adv(pUmDevice, str);
+	len += sprintf(page+len, "Flow_Control_Advertisement\t%s\n", str);
+	len += sprintf(page+len, "Speed\t\t\t\t%s\n", 
+    		((pDevice->LinkStatus == LM_STATUS_LINK_DOWN) ||
+		(pUmDevice->opened == 0)) ? na_str :
+    		((pDevice->LineSpeed == LM_LINE_SPEED_1000MBPS) ? "1000" :
+    		((pDevice->LineSpeed == LM_LINE_SPEED_100MBPS) ? "100" :
+    		(pDevice->LineSpeed == LM_LINE_SPEED_10MBPS) ? "10" : na_str)));
+	len += sprintf(page+len, "Duplex\t\t\t\t%s\n", 
+    		((pDevice->LinkStatus == LM_STATUS_LINK_DOWN) ||
+		(pUmDevice->opened == 0)) ? na_str :
+		((pDevice->DuplexMode == LM_DUPLEX_MODE_FULL) ? "full" :
+			"half"));
+	len += sprintf(page+len, "Flow_Control\t\t\t%s\n", 
+    		((pDevice->LinkStatus == LM_STATUS_LINK_DOWN) ||
+		(pUmDevice->opened == 0)) ? na_str :
+		((pDevice->FlowControl == LM_FLOW_CONTROL_NONE) ? off_str :
+		(((pDevice->FlowControl & LM_FLOW_CONTROL_RX_TX_PAUSE) ==
+			LM_FLOW_CONTROL_RX_TX_PAUSE) ? "receive/transmit" :
+		(pDevice->FlowControl & LM_FLOW_CONTROL_RECEIVE_PAUSE) ?
+			"receive" : "transmit")));
+	len += sprintf(page+len, "State\t\t\t\t%s\n", 
+		(pUmDevice->suspended ? "suspended" :
+    		((dev->flags & IFF_UP) ? up_str : down_str)));
+	len += sprintf(page+len, "MTU_Size\t\t\t%d\n\n", dev->mtu);
+	len += sprintf(page+len, "Rx_Packets\t\t\t%lu\n", 
+			((pStats == 0) ? 0 :
+			MM_GETSTATS(pStats->ifHCInUcastPkts) +
+			MM_GETSTATS(pStats->ifHCInMulticastPkts) +
+			MM_GETSTATS(pStats->ifHCInBroadcastPkts)));
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+	if (dev->mtu > 1500) {
+		len += sprintf(page+len, "Rx_Jumbo_Packets\t\t%lu\n", 
+			((pStats == 0) ? 0 :
+			MM_GETSTATS(
+				pStats->etherStatsPkts1523Octetsto2047Octets) +
+			MM_GETSTATS(
+				pStats->etherStatsPkts2048Octetsto4095Octets) +
+			MM_GETSTATS(
+				pStats->etherStatsPkts4096Octetsto8191Octets) +
+			MM_GETSTATS(
+				pStats->etherStatsPkts8192Octetsto9022Octets)));
+	}
+#endif
+	len += sprintf(page+len, "Tx_Packets\t\t\t%lu\n",
+		((pStats == 0) ? 0 :
+		MM_GETSTATS(pStats->ifHCOutUcastPkts) +
+		MM_GETSTATS(pStats->ifHCOutMulticastPkts) +
+		MM_GETSTATS(pStats->ifHCOutBroadcastPkts)));
+#ifdef BCM_TSO
+	len += sprintf(page+len, "TSO_Large_Packets\t\t%lu\n",
+		pUmDevice->tso_pkt_count);
+#endif
+	len += sprintf(page+len, "Rx_Bytes\t\t\t%lu\n",
+		((pStats == 0) ? 0 :
+		MM_GETSTATS(pStats->ifHCInOctets)));
+	len += sprintf(page+len, "Tx_Bytes\t\t\t%lu\n",
+		((pStats == 0) ? 0 :
+		MM_GETSTATS(pStats->ifHCOutOctets)));
+	if (pStats == 0) {
+		rx_crc_errors = 0;
+		rx_align_errors = 0;
+		rx_runt_errors = 0;
+		rx_frag_errors = 0;
+		rx_long_errors = 0;
+		rx_overrun_errors = 0;
+		rx_jabber_errors = 0;
+	}
+	else {
+		rx_crc_errors = (unsigned long) bcm5700_crc_count(pUmDevice);
+		rx_align_errors = MM_GETSTATS(pStats->dot3StatsAlignmentErrors);
+		rx_runt_errors = MM_GETSTATS(pStats->etherStatsUndersizePkts);
+		rx_frag_errors = MM_GETSTATS(pStats->etherStatsFragments);
+		rx_long_errors = MM_GETSTATS(pStats->dot3StatsFramesTooLong);
+		rx_overrun_errors = MM_GETSTATS(pStats->nicNoMoreRxBDs);
+		rx_jabber_errors = MM_GETSTATS(pStats->etherStatsJabbers);
+	}
+	rx_mac_errors = (unsigned long) bcm5700_rx_err_count(pUmDevice);
+	len += sprintf(page+len, "Rx_Errors\t\t\t%lu\n",
+		((pStats == 0) ? 0 :
+		rx_mac_errors + rx_overrun_errors + pUmDevice->rx_misc_errors));
+	len += sprintf(page+len, "Tx_Errors\t\t\t%lu\n",
+		((pStats == 0) ? 0 :
+		MM_GETSTATS(pStats->ifOutErrors)));
+	len += sprintf(page+len, "\nTx_Carrier_Errors\t\t%lu\n",
+		((pStats == 0) ? 0 :
+		MM_GETSTATS(pStats->dot3StatsCarrierSenseErrors)));
+	len += sprintf(page+len, "Tx_Abort_Excess_Coll\t\t%lu\n",
+		((pStats == 0) ? 0 :
+    		MM_GETSTATS(pStats->dot3StatsExcessiveCollisions)));
+	len += sprintf(page+len, "Tx_Abort_Late_Coll\t\t%lu\n",
+		((pStats == 0) ? 0 :
+    		MM_GETSTATS(pStats->dot3StatsLateCollisions)));
+	len += sprintf(page+len, "Tx_Deferred_Ok\t\t\t%lu\n",
+		((pStats == 0) ? 0 :
+    		MM_GETSTATS(pStats->dot3StatsDeferredTransmissions)));
+	len += sprintf(page+len, "Tx_Single_Coll_Ok\t\t%lu\n",
+		((pStats == 0) ? 0 :
+    		MM_GETSTATS(pStats->dot3StatsSingleCollisionFrames)));
+	len += sprintf(page+len, "Tx_Multi_Coll_Ok\t\t%lu\n",
+		((pStats == 0) ? 0 :
+    		MM_GETSTATS(pStats->dot3StatsMultipleCollisionFrames)));
+	len += sprintf(page+len, "Tx_Total_Coll_Ok\t\t%lu\n",
+		((pStats == 0) ? 0 :
+		MM_GETSTATS(pStats->etherStatsCollisions)));
+	len += sprintf(page+len, "Tx_XON_Pause_Frames\t\t%lu\n",
+		((pStats == 0) ? 0 :
+		MM_GETSTATS(pStats->outXonSent)));
+	len += sprintf(page+len, "Tx_XOFF_Pause_Frames\t\t%lu\n",
+		((pStats == 0) ? 0 :
+		MM_GETSTATS(pStats->outXoffSent)));
+	len += sprintf(page+len, "\nRx_CRC_Errors\t\t\t%lu\n", rx_crc_errors);
+	len += sprintf(page+len, "Rx_Short_Fragment_Errors\t%lu\n",
+		rx_frag_errors);
+	len += sprintf(page+len, "Rx_Short_Length_Errors\t\t%lu\n",
+		rx_runt_errors);
+	len += sprintf(page+len, "Rx_Long_Length_Errors\t\t%lu\n",
+		rx_long_errors);
+	len += sprintf(page+len, "Rx_Align_Errors\t\t\t%lu\n",
+		rx_align_errors);
+	len += sprintf(page+len, "Rx_Overrun_Errors\t\t%lu\n",
+		rx_overrun_errors);
+	len += sprintf(page+len, "Rx_XON_Pause_Frames\t\t%lu\n",
+		((pStats == 0) ? 0 :
+		MM_GETSTATS(pStats->xonPauseFramesReceived)));
+	len += sprintf(page+len, "Rx_XOFF_Pause_Frames\t\t%lu\n",
+		((pStats == 0) ? 0 :
+		MM_GETSTATS(pStats->xoffPauseFramesReceived)));
+	len += sprintf(page+len, "\nTx_MAC_Errors\t\t\t%lu\n",
+		((pStats == 0) ? 0 :
+		MM_GETSTATS(pStats->dot3StatsInternalMacTransmitErrors)));
+	len += sprintf(page+len, "Rx_MAC_Errors\t\t\t%lu\n\n",
+		rx_mac_errors);
+
+	len += sprintf(page+len, "Tx_Checksum\t\t\t%s\n",
+		((pDevice->TaskToOffload & LM_TASK_OFFLOAD_TX_TCP_CHECKSUM) ?
+		on_str : off_str));
+	len += sprintf(page+len, "Rx_Checksum\t\t\t%s\n",
+		((pDevice->TaskToOffload & LM_TASK_OFFLOAD_RX_TCP_CHECKSUM) ?
+		on_str : off_str));
+	len += sprintf(page+len, "Scatter_Gather\t\t\t%s\n",
+#if (LINUX_VERSION_CODE >= 0x20400)
+		((dev->features & NETIF_F_SG) ? on_str : off_str));
+#else
+		off_str);
+#endif
+#ifdef BCM_TSO
+	len += sprintf(page+len, "TSO\t\t\t\t%s\n",
+		((dev->features & NETIF_F_TSO) ? on_str : off_str));
+#endif
+	len += sprintf(page+len, "VLAN\t\t\t\t%s\n\n",
+		((pDevice->RxMode & RX_MODE_KEEP_VLAN_TAG) ? off_str : on_str));
+
+#ifdef BCM_NIC_SEND_BD
+	len += sprintf(page+len, "NIC_Tx_BDs\t\t\t%s\n",
+		(pDevice->Flags & NIC_SEND_BD_FLAG) ? on_str : off_str);
+#endif
+	len += sprintf(page+len, "Tx_Desc_Count\t\t\t%u\n",
+		pDevice->TxPacketDescCnt);
+	len += sprintf(page+len, "Rx_Desc_Count\t\t\t%u\n",
+		pDevice->RxStdDescCnt);
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+	len += sprintf(page+len, "Rx_Jumbo_Desc_Count\t\t%u\n",
+		pDevice->RxJumboDescCnt);
+#endif
+#ifdef BCM_INT_COAL
+	len += sprintf(page+len, "Adaptive_Coalescing\t\t%s\n",
+		(pUmDevice->adaptive_coalesce ? on_str : off_str));
+	len += sprintf(page+len, "Rx_Coalescing_Ticks\t\t%u\n",
+		pUmDevice->rx_curr_coalesce_ticks);
+	len += sprintf(page+len, "Rx_Coalesced_Frames\t\t%u\n",
+		pUmDevice->rx_curr_coalesce_frames);
+	len += sprintf(page+len, "Tx_Coalescing_Ticks\t\t%u\n",
+		pDevice->TxCoalescingTicks);
+	len += sprintf(page+len, "Tx_Coalesced_Frames\t\t%u\n",
+		pUmDevice->tx_curr_coalesce_frames);
+	len += sprintf(page+len, "Stats_Coalescing_Ticks\t\t%u\n",
+		pDevice->StatsCoalescingTicks);
+#endif
+#ifdef BCM_WOL
+	len += sprintf(page+len, "Wake_On_LAN\t\t\t%s\n",
+        	((pDevice->WakeUpMode & LM_WAKE_UP_MODE_MAGIC_PACKET) ?
+		on_str : off_str));
+#endif
+#if TIGON3_DEBUG
+	len += sprintf(page+len, "\nDmaReadWriteCtrl\t\t%x\n",
+		pDevice->DmaReadWriteCtrl);
+	len += sprintf(page+len, "\nTx_Zero_Copy_Packets\t\t%u\n",
+		pUmDevice->tx_zc_count);
+	len += sprintf(page+len, "Tx_Chksum_Packets\t\t%u\n",
+		pUmDevice->tx_chksum_count);
+	len += sprintf(page+len, "Tx_Highmem_Fragments\t\t%u\n",
+		pUmDevice->tx_himem_count);
+	len += sprintf(page+len, "Rx_Good_Chksum_Packets\t\t%u\n",
+		pUmDevice->rx_good_chksum_count);
+	len += sprintf(page+len, "Rx_Bad_Chksum_Packets\t\t%u\n",
+		pUmDevice->rx_bad_chksum_count);
+	if (!(pDevice->TbiFlags & ENABLE_TBI_FLAG)) {
+		LM_UINT32 value32;
+		unsigned long flags;
+
+		BCM5700_PHY_LOCK(pUmDevice, flags);
+        	LM_ReadPhy(pDevice, 0, &value32);
+		len += sprintf(page+len, "\nPhy_Register_0x00\t\t0x%x\n", value32);
+        	LM_ReadPhy(pDevice, 1, &value32);
+		len += sprintf(page+len, "Phy_Register_0x01\t\t0x%x\n", value32);
+        	LM_ReadPhy(pDevice, 2, &value32);
+		len += sprintf(page+len, "Phy_Register_0x02\t\t0x%x\n", value32);
+        	LM_ReadPhy(pDevice, 3, &value32);
+		len += sprintf(page+len, "Phy_Register_0x03\t\t0x%x\n", value32);
+        	LM_ReadPhy(pDevice, 4, &value32);
+		len += sprintf(page+len, "Phy_Register_0x04\t\t0x%x\n", value32);
+        	LM_ReadPhy(pDevice, 5, &value32);
+		len += sprintf(page+len, "Phy_Register_0x05\t\t0x%x\n", value32);
+        	LM_ReadPhy(pDevice, 9, &value32);
+		len += sprintf(page+len, "Phy_Register_0x09\t\t0x%x\n", value32);
+        	LM_ReadPhy(pDevice, 0xa, &value32);
+		len += sprintf(page+len, "Phy_Register_0x0A\t\t0x%x\n", value32);
+        	LM_ReadPhy(pDevice, 0xf, &value32);
+		len += sprintf(page+len, "Phy_Register_0x0F\t\t0x%x\n", value32);
+        	LM_ReadPhy(pDevice, 0x10, &value32);
+		len += sprintf(page+len, "Phy_Register_0x10\t\t0x%x\n", value32);
+        	LM_ReadPhy(pDevice, 0x19, &value32);
+		len += sprintf(page+len, "Phy_Register_0x19\t\t0x%x\n", value32);
+        	LM_WritePhy(pDevice, 0x18, 0x0007);
+        	LM_ReadPhy(pDevice, 0x18, &value32);
+		len += sprintf(page+len, "Phy_Register_0x18_00\t\t0x%x\n", value32);
+		BCM5700_PHY_UNLOCK(pUmDevice, flags);
+	}
+#endif
+
+	*eof = 1;
+	return len;
+}
+
+int
+bcm5700_proc_create_dev(struct net_device *dev)
+{
+	PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) dev->priv;
+
+	if (!bcm5700_procfs_dir)
+		return -1;
+
+	sprintf(pUmDevice->pfs_name, "%s.info", dev->name);
+	pUmDevice->pfs_entry = create_proc_entry(pUmDevice->pfs_name,
+		S_IFREG, bcm5700_procfs_dir);
+	if (pUmDevice->pfs_entry == 0)
+		return -1;
+	pUmDevice->pfs_entry->read_proc = bcm5700_read_pfs;
+	pUmDevice->pfs_entry->data = dev;
+	return 0;
+}
+int
+bcm5700_proc_remove_dev(struct net_device *dev)
+{
+	PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK) dev->priv;
+
+	remove_proc_entry(pUmDevice->pfs_name, bcm5700_procfs_dir);
+	return 0;
+}
+
+#endif
diff -u --recursive --new-file linux-2.4.26/drivers/net/bcm/b57um.c linux-2.4.26.patch/drivers/net/bcm/b57um.c
--- linux-2.4.26/drivers/net/bcm/b57um.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.26.patch/drivers/net/bcm/b57um.c	2004-06-22 16:21:25.000000000 -0700
@@ -0,0 +1,4981 @@
+/******************************************************************************/
+/*                                                                            */
+/* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2004 Broadcom  */
+/* Corporation.                                                               */
+/* All rights reserved.                                                       */
+/*                                                                            */
+/* 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, located in the file LICENSE.                 */
+/*                                                                            */
+/******************************************************************************/
+
+
+char bcm5700_driver[] = "bcm5700";
+char bcm5700_version[] = "7.3.5";
+char bcm5700_date[] = "(06/23/04)";
+
+#define B57UM
+#include "mm.h"
+
+/* A few user-configurable values. */
+
+#define MAX_UNITS 16
+/* Used to pass the full-duplex flag, etc. */
+static int line_speed[MAX_UNITS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static int auto_speed[MAX_UNITS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+static int full_duplex[MAX_UNITS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+static int rx_flow_control[MAX_UNITS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+static int tx_flow_control[MAX_UNITS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+static int auto_flow_control[MAX_UNITS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+static int mtu[MAX_UNITS] = {1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500,1500};	/* Jumbo MTU for interfaces. */
+#endif
+static int tx_checksum[MAX_UNITS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+static int rx_checksum[MAX_UNITS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+static int scatter_gather[MAX_UNITS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+
+#define TX_DESC_CNT DEFAULT_TX_PACKET_DESC_COUNT
+static unsigned int tx_pkt_desc_cnt[MAX_UNITS] =
+	{TX_DESC_CNT,TX_DESC_CNT,TX_DESC_CNT,TX_DESC_CNT,TX_DESC_CNT,
+	TX_DESC_CNT,TX_DESC_CNT,TX_DESC_CNT,TX_DESC_CNT,TX_DESC_CNT,
+	TX_DESC_CNT,TX_DESC_CNT,TX_DESC_CNT,TX_DESC_CNT,TX_DESC_CNT,
+	TX_DESC_CNT};
+
+#define RX_DESC_CNT DEFAULT_STD_RCV_DESC_COUNT
+static unsigned int rx_std_desc_cnt[MAX_UNITS] =
+	{RX_DESC_CNT,RX_DESC_CNT,RX_DESC_CNT,RX_DESC_CNT,RX_DESC_CNT,
+	RX_DESC_CNT,RX_DESC_CNT,RX_DESC_CNT,RX_DESC_CNT,RX_DESC_CNT,
+	RX_DESC_CNT,RX_DESC_CNT,RX_DESC_CNT,RX_DESC_CNT,RX_DESC_CNT,
+	RX_DESC_CNT };
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+#define JBO_DESC_CNT DEFAULT_JUMBO_RCV_DESC_COUNT
+static unsigned int rx_jumbo_desc_cnt[MAX_UNITS] =
+	{JBO_DESC_CNT,JBO_DESC_CNT,JBO_DESC_CNT,JBO_DESC_CNT,JBO_DESC_CNT,
+	JBO_DESC_CNT,JBO_DESC_CNT,JBO_DESC_CNT,JBO_DESC_CNT,JBO_DESC_CNT,
+	JBO_DESC_CNT,JBO_DESC_CNT,JBO_DESC_CNT,JBO_DESC_CNT,JBO_DESC_CNT,
+	JBO_DESC_CNT };
+#endif
+
+#ifdef BCM_INT_COAL
+#ifdef BCM_NAPI_RXPOLL
+static unsigned int adaptive_coalesce[MAX_UNITS] =
+	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+#else
+static unsigned int adaptive_coalesce[MAX_UNITS] =
+	{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+#endif
+
+#define RX_COAL_TK DEFAULT_RX_COALESCING_TICKS
+static unsigned int rx_coalesce_ticks[MAX_UNITS] =
+	{RX_COAL_TK,RX_COAL_TK,RX_COAL_TK,RX_COAL_TK,RX_COAL_TK,
+	RX_COAL_TK, RX_COAL_TK,RX_COAL_TK,RX_COAL_TK,RX_COAL_TK,
+	RX_COAL_TK,RX_COAL_TK, RX_COAL_TK,RX_COAL_TK,RX_COAL_TK,
+	RX_COAL_TK};
+
+#define RX_COAL_FM DEFAULT_RX_MAX_COALESCED_FRAMES
+static unsigned int rx_max_coalesce_frames[MAX_UNITS] =
+	{RX_COAL_FM,RX_COAL_FM,RX_COAL_FM,RX_COAL_FM,RX_COAL_FM,
+	RX_COAL_FM,RX_COAL_FM,RX_COAL_FM,RX_COAL_FM,RX_COAL_FM,
+	RX_COAL_FM,RX_COAL_FM,RX_COAL_FM,RX_COAL_FM,RX_COAL_FM,
+	RX_COAL_FM};
+
+#define TX_COAL_TK DEFAULT_TX_COALESCING_TICKS
+static unsigned int tx_coalesce_ticks[MAX_UNITS] =
+	{TX_COAL_TK,TX_COAL_TK,TX_COAL_TK,TX_COAL_TK,TX_COAL_TK,
+	TX_COAL_TK, TX_COAL_TK,TX_COAL_TK,TX_COAL_TK,TX_COAL_TK,
+	TX_COAL_TK,TX_COAL_TK, TX_COAL_TK,TX_COAL_TK,TX_COAL_TK,
+	TX_COAL_TK};
+
+#define TX_COAL_FM DEFAULT_TX_MAX_COALESCED_FRAMES
+static unsigned int tx_max_coalesce_frames[MAX_UNITS] =
+	{TX_COAL_FM,TX_COAL_FM,TX_COAL_FM,TX_COAL_FM,TX_COAL_FM,
+	TX_COAL_FM,TX_COAL_FM,TX_COAL_FM,TX_COAL_FM,TX_COAL_FM,
+	TX_COAL_FM,TX_COAL_FM,TX_COAL_FM,TX_COAL_FM,TX_COAL_FM,
+	TX_COAL_FM};
+
+#define ST_COAL_TK DEFAULT_STATS_COALESCING_TICKS
+static unsigned int stats_coalesce_ticks[MAX_UNITS] =
+	{ST_COAL_TK,ST_COAL_TK,ST_COAL_TK,ST_COAL_TK,ST_COAL_TK,
+	ST_COAL_TK,ST_COAL_TK,ST_COAL_TK,ST_COAL_TK,ST_COAL_TK,
+	ST_COAL_TK,ST_COAL_TK,ST_COAL_TK,ST_COAL_TK,ST_COAL_TK,
+	ST_COAL_TK,};
+
+#endif
+#ifdef BCM_WOL
+static int enable_wol[MAX_UNITS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+#endif
+#ifdef BCM_TSO
+static int enable_tso[MAX_UNITS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+#endif
+#ifdef BCM_NIC_SEND_BD
+static int nic_tx_bd[MAX_UNITS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+#endif
+#ifdef BCM_ASF
+static int vlan_tag_mode[MAX_UNITS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+#endif
+#ifdef INCLUDE_5750_A0_FIX
+static int shasta_smp_fix[MAX_UNITS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+#endif
+static int delay_link[MAX_UNITS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+static int disable_d3hot[MAX_UNITS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+/* Operational parameters that usually are not changed. */
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  (2*HZ)
+
+#if (LINUX_VERSION_CODE < 0x02030d)
+#define pci_resource_start(dev, bar)	(dev->base_address[bar] & PCI_BASE_ADDRESS_MEM_MASK)
+#elif (LINUX_VERSION_CODE < 0x02032b)
+#define pci_resource_start(dev, bar)	(dev->resource[bar] & PCI_BASE_ADDRESS_MEM_MASK)
+#endif
+
+#if (LINUX_VERSION_CODE < 0x02032b)
+#define dev_kfree_skb_irq(skb)  dev_kfree_skb(skb)
+#define netif_wake_queue(dev)	clear_bit(0, &dev->tbusy); mark_bh(NET_BH)
+#define netif_stop_queue(dev)	set_bit(0, &dev->tbusy)
+
+static inline void netif_start_queue(struct net_device *dev)
+{
+	dev->tbusy = 0;
+	dev->interrupt = 0;
+	dev->start = 1;
+}
+
+#define netif_queue_stopped(dev)	dev->tbusy
+#define netif_running(dev)		dev->start
+
+static inline void tasklet_schedule(struct tasklet_struct *tasklet)
+{
+	queue_task(tasklet, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+}
+
+static inline void tasklet_init(struct tasklet_struct *tasklet,
+				void (*func)(unsigned long),
+				unsigned long data)
+{
+        tasklet->next = NULL;
+        tasklet->sync = 0;
+        tasklet->routine = (void (*)(void *))func;
+        tasklet->data = (void *)data;
+}
+
+#define tasklet_kill(tasklet)
+
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020300)
+struct pci_device_id {
+	unsigned int vendor, device;		/* Vendor and device ID or PCI_ANY_ID */
+	unsigned int subvendor, subdevice;	/* Subsystem ID's or PCI_ANY_ID */
+	unsigned int class, class_mask;		/* (class,subclass,prog-if) triplet */
+	unsigned long driver_data;		/* Data private to the driver */
+};
+
+#define PCI_ANY_ID		0
+
+#define pci_set_drvdata(pdev, dev)
+#define pci_get_drvdata(pdev) 0
+
+#define pci_enable_device(pdev) 0
+
+#define __devinit		__init
+#define __devinitdata		__initdata
+#define __devexit
+
+#define SET_MODULE_OWNER(dev)
+#define MODULE_DEVICE_TABLE(pci, pci_tbl)
+
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020411)
+#ifndef __devexit_p
+#define __devexit_p(x)	x
+#endif
+#endif
+
+#ifndef MODULE_LICENSE
+#define MODULE_LICENSE(license)
+#endif
+
+#ifndef IRQ_RETVAL
+typedef void irqreturn_t;
+#define IRQ_RETVAL(x)
+#endif
+
+#if (LINUX_VERSION_CODE < 0x02032a)
+static inline void *pci_alloc_consistent(struct pci_dev *pdev, size_t size,
+					 dma_addr_t *dma_handle)
+{
+	void *virt_ptr;
+
+	/* Maximum in slab.c */
+	if (size > 131072)
+		return 0;
+
+	virt_ptr = kmalloc(size, GFP_KERNEL);
+	*dma_handle = virt_to_bus(virt_ptr);
+	return virt_ptr;
+}
+#define pci_free_consistent(dev, size, ptr, dma_ptr)	kfree(ptr)
+
+#endif /*#if (LINUX_VERSION_CODE < 0x02032a) */
+
+
+#if (LINUX_VERSION_CODE < 0x02040d)
+
+#if (LINUX_VERSION_CODE >= 0x020409) && defined(RED_HAT_LINUX_KERNEL)
+
+#define BCM_32BIT_DMA_MASK ((u64) 0x00000000ffffffffULL)
+#define BCM_64BIT_DMA_MASK ((u64) 0xffffffffffffffffULL)
+
+#else
+/* pci_set_dma_mask is using dma_addr_t */
+
+#define BCM_32BIT_DMA_MASK ((dma_addr_t) 0xffffffff)
+#define BCM_64BIT_DMA_MASK ((dma_addr_t) 0xffffffff)
+
+#endif
+
+#else /* (LINUX_VERSION_CODE < 0x02040d) */
+
+#define BCM_32BIT_DMA_MASK ((u64) 0x00000000ffffffffULL)
+#define BCM_64BIT_DMA_MASK ((u64) 0xffffffffffffffffULL)
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020329)
+#define pci_set_dma_mask(pdev, mask) (0)
+#else
+#if (LINUX_VERSION_CODE < 0x020403)
+int
+pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask)
+{
+    if(! pci_dma_supported(dev, mask))
+        return -EIO;
+
+    dev->dma_mask = mask;
+
+    return 0;
+}
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020547)
+#define pci_set_consistent_dma_mask(pdev, mask) (0)
+#endif
+
+#if (LINUX_VERSION_CODE < 0x020402)
+#define pci_request_regions(pdev, name) (0)
+#define pci_release_regions(pdev)
+#endif
+
+#if ! defined(spin_is_locked)
+#define spin_is_locked(lock)    (test_bit(0,(lock)))
+#endif
+
+#define BCM5700_LOCK(pUmDevice, flags)					\
+	if ((pUmDevice)->do_global_lock) {				\
+		spin_lock_irqsave(&(pUmDevice)->global_lock, flags);	\
+	}
+
+#define BCM5700_UNLOCK(pUmDevice, flags)				\
+	if ((pUmDevice)->do_global_lock) {				\
+		spin_unlock_irqrestore(&(pUmDevice)->global_lock, flags);\
+	}
+
+inline void
+bcm5700_intr_lock(PUM_DEVICE_BLOCK pUmDevice)
+{
+	if (pUmDevice->do_global_lock) {
+		spin_lock(&pUmDevice->global_lock);
+	}
+}
+
+inline void
+bcm5700_intr_unlock(PUM_DEVICE_BLOCK pUmDevice)
+{
+	if (pUmDevice->do_global_lock) {
+		spin_unlock(&pUmDevice->global_lock);
+	}
+}
+
+void
+bcm5700_intr_off(PUM_DEVICE_BLOCK pUmDevice)
+{
+	atomic_inc(&pUmDevice->intr_sem);
+	LM_DisableInterrupt(&pUmDevice->lm_dev);
+#if (LINUX_VERSION_CODE >= 0x2051c)
+	synchronize_irq(pUmDevice->dev->irq);
+#else
+	synchronize_irq();
+#endif
+	LM_DisableInterrupt(&pUmDevice->lm_dev);
+}
+
+void
+bcm5700_intr_on(PUM_DEVICE_BLOCK pUmDevice)
+{
+	if (atomic_dec_and_test(&pUmDevice->intr_sem)) {
+		LM_EnableInterrupt(&pUmDevice->lm_dev);
+	}
+}
+
+/*
+ * Broadcom NIC Extension support
+ * -ffan
+ */
+#ifdef NICE_SUPPORT
+#include "nicext.h"
+
+typedef struct {
+	ushort  tag;
+	ushort  signature;
+} vlan_tag_t;
+
+#endif /* NICE_SUPPORT */
+
+int MM_Packet_Desc_Size = sizeof(UM_PACKET);
+
+#if defined(MODULE)
+MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>");
+MODULE_DESCRIPTION("BCM5700 Driver");
+MODULE_LICENSE("GPL");
+MODULE_PARM(debug, "i");
+MODULE_PARM(line_speed, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(auto_speed, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(rx_flow_control, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(tx_flow_control, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(auto_flow_control, "1-" __MODULE_STRING(MAX_UNITS) "i");
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+MODULE_PARM(mtu, "1-" __MODULE_STRING(MAX_UNITS) "i");
+#endif
+MODULE_PARM(tx_checksum, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(rx_checksum, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(scatter_gather, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(tx_pkt_desc_cnt, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(rx_std_desc_cnt, "1-" __MODULE_STRING(MAX_UNITS) "i");
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+MODULE_PARM(rx_jumbo_desc_cnt, "1-" __MODULE_STRING(MAX_UNITS) "i");
+#endif
+#ifdef BCM_INT_COAL
+MODULE_PARM(adaptive_coalesce, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(rx_coalesce_ticks, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(rx_max_coalesce_frames, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(tx_coalesce_ticks, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(tx_max_coalesce_frames, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(stats_coalesce_ticks, "1-" __MODULE_STRING(MAX_UNITS) "i");
+#endif
+#ifdef BCM_WOL
+MODULE_PARM(enable_wol, "1-" __MODULE_STRING(MAX_UNITS) "i");
+#endif
+#ifdef BCM_TSO
+MODULE_PARM(enable_tso, "1-" __MODULE_STRING(MAX_UNITS) "i");
+#endif
+#ifdef BCM_NIC_SEND_BD
+MODULE_PARM(nic_tx_bd, "1-" __MODULE_STRING(MAX_UNITS) "i");
+#endif
+#ifdef BCM_ASF
+MODULE_PARM(vlan_tag_mode, "1-" __MODULE_STRING(MAX_UNITS) "i");
+#endif
+#ifdef INCLUDE_5750_A0_FIX
+MODULE_PARM(shasta_smp_fix, "1-" __MODULE_STRING(MAX_UNITS) "i");
+#endif
+MODULE_PARM(delay_link, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(disable_d3hot, "1-" __MODULE_STRING(MAX_UNITS) "i");
+#endif
+
+#define RUN_AT(x) (jiffies + (x))
+
+char kernel_version[] = UTS_RELEASE;
+
+#define PCI_SUPPORT_VER2
+
+#if ! defined(CAP_NET_ADMIN)
+#define capable(CAP_XXX) (suser())
+#endif
+
+#define tigon3_debug debug
+#if TIGON3_DEBUG
+static int tigon3_debug = TIGON3_DEBUG;
+#else
+static int tigon3_debug = 0;
+#endif
+
+
+STATIC int bcm5700_open(struct net_device *dev);
+STATIC void bcm5700_timer(unsigned long data);
+STATIC void bcm5700_reset(struct net_device *dev);
+STATIC int bcm5700_start_xmit(struct sk_buff *skb, struct net_device *dev);
+STATIC irqreturn_t bcm5700_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+#ifdef BCM_TASKLET
+STATIC void bcm5700_tasklet(unsigned long data);
+#endif
+STATIC int bcm5700_close(struct net_device *dev);
+STATIC struct net_device_stats *bcm5700_get_stats(struct net_device *dev);
+STATIC int bcm5700_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+STATIC void bcm5700_set_rx_mode(struct net_device *dev);
+STATIC int bcm5700_set_mac_addr(struct net_device *dev, void *p);
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+STATIC int bcm5700_change_mtu(struct net_device *dev, int new_mtu);
+#endif
+#ifdef BCM_NAPI_RXPOLL
+STATIC int bcm5700_poll(struct net_device *dev, int *budget);
+#endif
+STATIC int replenish_rx_buffers(PUM_DEVICE_BLOCK pUmDevice, int max);
+STATIC int bcm5700_freemem(struct net_device *dev);
+#ifdef NICE_SUPPORT
+STATIC int bcm5700_freemem2(UM_DEVICE_BLOCK *pUmDevice, int index);
+#endif
+#ifdef BCM_INT_COAL
+#ifndef BCM_NAPI_RXPOLL
+STATIC int bcm5700_adapt_coalesce(PUM_DEVICE_BLOCK pUmDevice);
+#endif
+#endif
+STATIC void bcm5700_set_vlan_mode(UM_DEVICE_BLOCK *pUmDevice);
+STATIC int bcm5700_init_counters(PUM_DEVICE_BLOCK pUmDevice);
+#ifdef BCM_VLAN
+STATIC void bcm5700_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp);
+STATIC void bcm5700_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid);
+#endif
+void bcm5700_shutdown(UM_DEVICE_BLOCK *pUmDevice);
+void bcm5700_free_remaining_rx_bufs(UM_DEVICE_BLOCK *pUmDevice);
+void bcm5700_validate_param_range(UM_DEVICE_BLOCK *pUmDevice, int *param,
+	char *param_name, int min, int max, int deflt);
+
+#ifdef HAVE_POLL_CONTROLLER
+STATIC void poll_bcm5700(struct net_device *dev);
+#endif
+
+/* A list of all installed bcm5700 devices. */
+static struct net_device *root_tigon3_dev = NULL;
+
+#if defined(CONFIG_SPARC64) || defined(CONFIG_X86_64) ||defined(CONFIG_PPC64)
+
+#ifdef NICE_SUPPORT
+#if (LINUX_VERSION_CODE < 0x20500)
+extern int register_ioctl32_conversion(unsigned int cmd,
+	int (*handler)(unsigned int, unsigned int, unsigned long,
+	struct file *));
+int unregister_ioctl32_conversion(unsigned int cmd);
+#else
+#include <linux/ioctl32.h>
+#endif
+
+#define BCM_IOCTL32 1
+
+atomic_t bcm5700_load_count = ATOMIC_INIT(0);
+
+static int
+bcm5700_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg,
+	struct file *filep)
+{
+	struct ifreq rq;
+	struct net_device *tmp_dev = root_tigon3_dev;
+	int ret;
+	struct nice_req* nrq;
+	struct ifreq_nice32 {
+		char ifnr_name[16];
+		__u32 cmd;
+		__u32 nrq1;
+		__u32 nrq2;
+		__u32 nrq3;
+	} nrq32;
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	if (copy_from_user(&nrq32, (char *) arg, 32))
+		return -EFAULT;
+
+	memcpy(rq.ifr_name, nrq32.ifnr_name, 16);
+
+	nrq = (struct nice_req*) &rq.ifr_ifru;
+	nrq->cmd = nrq32.cmd;
+	if (nrq->cmd == NICE_CMD_GET_STATS_BLOCK) {
+		nrq->nrq_stats_useraddr = (void *) ((__u64) nrq32.nrq1);
+		nrq->nrq_stats_size = nrq32.nrq2;
+	}
+	else {
+		memcpy(&nrq->nrq_speed, &nrq32.nrq1, 12);
+	}
+	while (tmp_dev) {
+		if (strcmp(rq.ifr_name, tmp_dev->name) == 0) {
+			ret = bcm5700_ioctl(tmp_dev, &rq, cmd);
+			if (ret == 0) {
+				if (nrq->cmd == NICE_CMD_GET_STATS_BLOCK)
+					return ret;
+
+				memcpy(&nrq32.nrq1, &nrq->nrq_speed, 12);
+				if (copy_to_user((char *) arg, &nrq32, 32))
+					return -EFAULT;
+			}
+			return ret;
+		}
+		tmp_dev = ((UM_DEVICE_BLOCK *)(tmp_dev->priv))->next_module;
+	}
+	return -ENODEV;
+}
+#endif /* NICE_SUPPORT */
+#endif
+
+typedef enum {
+	BCM5700A6 = 0,
+	BCM5700T6,
+	BCM5700A9,
+	BCM5700T9,
+	BCM5700,
+	BCM5701A5,
+	BCM5701T1,
+	BCM5701T8,
+	BCM5701A7,
+	BCM5701A10,
+	BCM5701A12,
+	BCM5701,
+	BCM5702,
+	BCM5703,
+	BCM5703A31,
+	BCM5703ARBUCKLE,
+	TC996T,
+	TC996ST,
+	TC996SSX,
+	TC996SX,
+	TC996BT,
+	TC997T,
+	TC997SX,
+	TC1000T,
+	TC1000BT,
+	TC940BR01,
+	TC942BR01,
+	TC998T,
+	TC998SX,
+	TC999T,
+	NC6770,
+	NC1020,
+	NC150T,
+	NC7760,
+	NC7761,
+	NC7770,
+	NC7771,
+	NC7780,
+	NC7781,
+	NC7772,
+	NC7782,
+	NC7783,
+	NC320T,
+	BCM5704CIOBE,
+	BCM5704,
+	BCM5704S,
+	BCM5705,
+	BCM5705M,
+	BCM5705F,
+	BCM5901,
+	BCM5782,
+	BCM5788,
+	BCM5789,
+	BCM5750,
+	BCM5750M,
+	BCM5720,
+	BCM5751,
+	BCM5751M,
+	BCM5751F,
+	BCM5721,
+} board_t;
+
+
+/* indexed by board_t, above */
+static struct {
+	char *name;
+} board_info[] __devinitdata = {
+	{ "Broadcom BCM5700 1000Base-T" },
+	{ "Broadcom BCM5700 1000Base-SX" },
+	{ "Broadcom BCM5700 1000Base-SX" },
+	{ "Broadcom BCM5700 1000Base-T" },
+	{ "Broadcom BCM5700" },
+	{ "Broadcom BCM5701 1000Base-T" },
+	{ "Broadcom BCM5701 1000Base-T" },
+	{ "Broadcom BCM5701 1000Base-T" },
+	{ "Broadcom BCM5701 1000Base-SX" },
+	{ "Broadcom BCM5701 1000Base-T" },
+	{ "Broadcom BCM5701 1000Base-T" },
+	{ "Broadcom BCM5701" },
+	{ "Broadcom BCM5702 1000Base-T" },
+	{ "Broadcom BCM5703 1000Base-T" },
+	{ "Broadcom BCM5703 1000Base-SX" },
+	{ "Broadcom B5703 1000Base-SX" },
+	{ "3Com 3C996 10/100/1000 Server NIC" },
+	{ "3Com 3C996 10/100/1000 Server NIC" },
+	{ "3Com 3C996 Gigabit Fiber-SX Server NIC" },
+	{ "3Com 3C996 Gigabit Fiber-SX Server NIC" },
+	{ "3Com 3C996B Gigabit Server NIC" },
+	{ "3Com 3C997 Gigabit Server NIC" },
+	{ "3Com 3C997 Gigabit Fiber-SX Server NIC" },
+	{ "3Com 3C1000 Gigabit NIC" },
+	{ "3Com 3C1000B-T 10/100/1000 PCI" },
+	{ "3Com 3C940 Gigabit LOM (21X21)" },
+	{ "3Com 3C942 Gigabit LOM (31X31)" },
+	{ "3Com 3C998-T Dual Port 10/100/1000 PCI-X Server NIC" },
+	{ "3Com 3C998-SX Dual Port 1000-SX PCI-X Server NIC" },
+	{ "3Com 3C999-T Quad Port 10/100/1000 PCI-X Server NIC" },
+	{ "HP NC6770 Gigabit Server Adapter" },
+	{ "NC1020 HP ProLiant Gigabit Server Adapter 32 PCI" },
+	{ "HP ProLiant NC 150T PCI 4-port Gigabit Combo Switch Adapter" },
+	{ "HP NC7760 Gigabit Server Adapter" },
+	{ "HP NC7761 Gigabit Server Adapter" },
+	{ "HP NC7770 Gigabit Server Adapter" },
+	{ "HP NC7771 Gigabit Server Adapter" },
+	{ "HP NC7780 Gigabit Server Adapter" },
+	{ "HP NC7781 Gigabit Server Adapter" },
+	{ "HP NC7772 Gigabit Server Adapter" },
+	{ "HP NC7782 Gigabit Server Adapter" },
+	{ "HP NC7783 Gigabit Server Adapter" },
+	{ "HP ProLiant NC 320T PCI Express Gigabit Server Adapter" },
+	{ "Broadcom BCM5704 CIOB-E 1000Base-T" },
+	{ "Broadcom BCM5704 1000Base-T" },
+	{ "Broadcom BCM5704 1000Base-SX" },
+	{ "Broadcom BCM5705 1000Base-T" },
+	{ "Broadcom BCM5705M 1000Base-T" },
+	{ "Broadcom 570x 10/100 Integrated Controller" },
+	{ "Broadcom BCM5901 100Base-TX" },
+	{ "Broadcom NetXtreme Gigabit Ethernet for hp" },
+	{ "Broadcom BCM5788 NetLink 1000Base-T" },
+	{ "Broadcom BCM5789 NetLink 1000Base-T PCI Express" },
+	{ "Broadcom BCM5750 1000Base-T PCI" },
+	{ "Broadcom BCM5750M 1000Base-T PCI" },
+	{ "Broadcom BCM5720 1000Base-T PCI" },
+	{ "Broadcom BCM5751 1000Base-T PCI Express" },
+	{ "Broadcom BCM5751M 1000Base-T PCI Express" },
+	{ "Broadcom BCM5751F 100Base-TX PCI Express" },
+	{ "Broadcom BCM5721 1000Base-T PCI Express" },
+	{ 0 },
+	};
+
+static struct pci_device_id bcm5700_pci_tbl[] __devinitdata = {
+	{0x14e4, 0x1644, 0x14e4, 0x1644, 0, 0, BCM5700A6 },
+	{0x14e4, 0x1644, 0x14e4, 0x2, 0, 0, BCM5700T6 },
+	{0x14e4, 0x1644, 0x14e4, 0x3, 0, 0, BCM5700A9 },
+	{0x14e4, 0x1644, 0x14e4, 0x4, 0, 0, BCM5700T9 },
+	{0x14e4, 0x1644, 0x1028, 0xd1, 0, 0, BCM5700 },
+	{0x14e4, 0x1644, 0x1028, 0x0106, 0, 0, BCM5700 },
+	{0x14e4, 0x1644, 0x1028, 0x0109, 0, 0, BCM5700 },
+	{0x14e4, 0x1644, 0x1028, 0x010a, 0, 0, BCM5700 },
+	{0x14e4, 0x1644, 0x10b7, 0x1000, 0, 0, TC996T },
+	{0x14e4, 0x1644, 0x10b7, 0x1001, 0, 0, TC996ST },
+	{0x14e4, 0x1644, 0x10b7, 0x1002, 0, 0, TC996SSX },
+	{0x14e4, 0x1644, 0x10b7, 0x1003, 0, 0, TC997T },
+	{0x14e4, 0x1644, 0x10b7, 0x1005, 0, 0, TC997SX },
+	{0x14e4, 0x1644, 0x10b7, 0x1008, 0, 0, TC942BR01 },
+	{0x14e4, 0x1644, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5700 },
+	{0x14e4, 0x1645, 0x14e4, 1, 0, 0, BCM5701A5 },
+	{0x14e4, 0x1645, 0x14e4, 5, 0, 0, BCM5701T1 },
+	{0x14e4, 0x1645, 0x14e4, 6, 0, 0, BCM5701T8 },
+	{0x14e4, 0x1645, 0x14e4, 7, 0, 0, BCM5701A7 },
+	{0x14e4, 0x1645, 0x14e4, 8, 0, 0, BCM5701A10 },
+	{0x14e4, 0x1645, 0x14e4, 0x8008, 0, 0, BCM5701A12 },
+	{0x14e4, 0x1645, 0x0e11, 0xc1, 0, 0, NC6770 },
+	{0x14e4, 0x1645, 0x0e11, 0x7c, 0, 0, NC7770 },
+	{0x14e4, 0x1645, 0x0e11, 0x85, 0, 0, NC7780 },
+	{0x14e4, 0x1645, 0x1028, 0x0121, 0, 0, BCM5701 },
+	{0x14e4, 0x1645, 0x10b7, 0x1004, 0, 0, TC996SX },
+	{0x14e4, 0x1645, 0x10b7, 0x1006, 0, 0, TC996BT },
+	{0x14e4, 0x1645, 0x10b7, 0x1007, 0, 0, TC1000T },
+	{0x14e4, 0x1645, 0x10b7, 0x1008, 0, 0, TC940BR01 },
+	{0x14e4, 0x1645, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5701 },
+	{0x14e4, 0x1646, 0x14e4, 0x8009, 0, 0, BCM5702 },
+	{0x14e4, 0x1646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5702 },
+	{0x14e4, 0x16a6, 0x14e4, 0x8009, 0, 0, BCM5702 },
+	{0x14e4, 0x16a6, 0x14e4, 0x000c, 0, 0, BCM5702 },
+	{0x14e4, 0x16a6, 0x0e11, 0xbb, 0, 0, NC7760 },
+	{0x14e4, 0x16a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5702 },
+	{0x14e4, 0x16c6, 0x10b7, 0x1100, 0, 0, TC1000BT },
+	{0x14e4, 0x16c6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5702 },
+	{0x14e4, 0x1647, 0x14e4, 0x0009, 0, 0, BCM5703 },
+	{0x14e4, 0x1647, 0x14e4, 0x000a, 0, 0, BCM5703A31 },
+	{0x14e4, 0x1647, 0x14e4, 0x000b, 0, 0, BCM5703 },
+	{0x14e4, 0x1647, 0x14e4, 0x800a, 0, 0, BCM5703 },
+	{0x14e4, 0x1647, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5703 },
+	{0x14e4, 0x16a7, 0x14e4, 0x0009, 0, 0, BCM5703 },
+	{0x14e4, 0x16a7, 0x14e4, 0x000a, 0, 0, BCM5703A31 },
+	{0x14e4, 0x16a7, 0x14e4, 0x000b, 0, 0, BCM5703 },
+	{0x14e4, 0x16a7, 0x14e4, 0x800a, 0, 0, BCM5703 },
+	{0x14e4, 0x16a7, 0x0e11, 0xca, 0, 0, NC7771 },
+	{0x14e4, 0x16a7, 0x0e11, 0xcb, 0, 0, NC7781 },
+	{0x14e4, 0x16a7, 0x1014, 0x0281, 0, 0, BCM5703ARBUCKLE },
+	{0x14e4, 0x16a7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5703 },
+	{0x14e4, 0x16c7, 0x14e4, 0x000a, 0, 0, BCM5703A31 },
+	{0x14e4, 0x16c7, 0x0e11, 0xca, 0, 0, NC7771 },
+	{0x14e4, 0x16c7, 0x0e11, 0xcb, 0, 0, NC7781 },
+	{0x14e4, 0x16c7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5703 },
+	{0x14e4, 0x1648, 0x0e11, 0xcf, 0, 0, NC7772 },
+	{0x14e4, 0x1648, 0x0e11, 0xd0, 0, 0, NC7782 },
+	{0x14e4, 0x1648, 0x0e11, 0xd1, 0, 0, NC7783 },
+	{0x14e4, 0x1648, 0x10b7, 0x2000, 0, 0, TC998T },
+	{0x14e4, 0x1648, 0x10b7, 0x3000, 0, 0, TC999T },
+	{0x14e4, 0x1648, 0x1166, 0x1648, 0, 0, BCM5704CIOBE },
+	{0x14e4, 0x1648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5704 },
+	{0x14e4, 0x1649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5704S },
+	{0x14e4, 0x16a8, 0x14e4, 0x16a8, 0, 0, BCM5704S },
+	{0x14e4, 0x16a8, 0x10b7, 0x2001, 0, 0, TC998SX },
+	{0x14e4, 0x16a8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5704S },
+	{0x14e4, 0x1653, 0x0e11, 0x00e3, 0, 0, NC7761 },
+	{0x14e4, 0x1653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5705 },
+	{0x14e4, 0x1654, 0x0e11, 0x00e3, 0, 0, NC7761 },
+	{0x14e4, 0x1654, 0x103c, 0x3100, 0, 0, NC1020 },
+	{0x14e4, 0x1654, 0x103c, 0x3226, 0, 0, NC150T },
+	{0x14e4, 0x1654, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5705 },
+	{0x14e4, 0x165d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5705M },
+	{0x14e4, 0x165e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5705M },
+	{0x14e4, 0x166e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5705F },
+	{0x14e4, 0x1696, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5782 },
+	{0x14e4, 0x169c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5788 },
+	{0x14e4, 0x169d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5789 },
+	{0x14e4, 0x170d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5901 },
+	{0x14e4, 0x170e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5901 },
+	{0x14e4, 0x1676, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5750 },
+	{0x14e4, 0x167c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5750M },
+	{0x14e4, 0x1677, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5751 },
+	{0x14e4, 0x167d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5751M },
+	{0x14e4, 0x167e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5751F },
+	{0x14e4, 0x1658, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5720 },
+	{0x14e4, 0x1659, 0x103c, 0x7031, 0, 0, NC320T },
+	{0x14e4, 0x1659, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5721 },
+	{0,}
+};
+
+MODULE_DEVICE_TABLE(pci, bcm5700_pci_tbl);
+
+#ifdef BCM_PROC_FS
+extern int bcm5700_proc_create(void);
+extern int bcm5700_proc_create_dev(struct net_device *dev);
+extern int bcm5700_proc_remove_dev(struct net_device *dev);
+#endif
+
+static int __devinit bcm5700_init_board(struct pci_dev *pdev,
+					struct net_device **dev_out,
+					int board_idx)
+{
+	struct net_device *dev;
+	PUM_DEVICE_BLOCK pUmDevice;
+	PLM_DEVICE_BLOCK pDevice;
+	int rc;
+
+	*dev_out = NULL;
+
+	/* dev zeroed in init_etherdev */
+#if (LINUX_VERSION_CODE >= 0x20600)
+	dev = alloc_etherdev(sizeof(*pUmDevice));
+#else
+	dev = init_etherdev(NULL, sizeof(*pUmDevice));
+#endif
+	if (dev == NULL) {
+		printk (KERN_ERR "%s: unable to alloc new ethernet\n",
+			bcm5700_driver);
+		return -ENOMEM;
+	}
+	SET_MODULE_OWNER(dev);
+#if (LINUX_VERSION_CODE >= 0x20600)
+	SET_NETDEV_DEV(dev, &pdev->dev);
+#endif
+	pUmDevice = (PUM_DEVICE_BLOCK) dev->priv;
+
+	/* enable device (incl. PCI PM wakeup), and bus-mastering */
+	rc = pci_enable_device (pdev);
+	if (rc)
+		goto err_out;
+
+	rc = pci_request_regions(pdev, bcm5700_driver);
+	if (rc)
+		goto err_out;
+
+	pci_set_master(pdev);
+
+	if (pci_set_dma_mask(pdev, BCM_64BIT_DMA_MASK) == 0) {
+		pUmDevice->using_dac = 1;
+		if (pci_set_consistent_dma_mask(pdev, BCM_64BIT_DMA_MASK) != 0)
+		{
+			printk(KERN_ERR "pci_set_consistent_dma_mask failed\n");
+			pci_release_regions(pdev);
+			goto err_out;
+		}
+	}
+	else if (pci_set_dma_mask(pdev, BCM_32BIT_DMA_MASK) == 0) {
+		pUmDevice->using_dac = 0;
+	}
+	else {
+		printk(KERN_ERR "System does not support DMA\n");
+		pci_release_regions(pdev);
+		goto err_out;
+	}
+
+	pUmDevice->dev = dev;
+	pUmDevice->pdev = pdev;
+	pUmDevice->mem_list_num = 0;
+	pUmDevice->next_module = root_tigon3_dev;
+	pUmDevice->index = board_idx;
+	root_tigon3_dev = dev;
+
+	spin_lock_init(&pUmDevice->global_lock);
+
+	spin_lock_init(&pUmDevice->undi_lock);
+
+	spin_lock_init(&pUmDevice->phy_lock);
+
+	pDevice = (PLM_DEVICE_BLOCK) pUmDevice;
+	pDevice->Flags = 0;
+	pDevice->FunctNum = PCI_FUNC(pUmDevice->pdev->devfn);
+
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+	bcm5700_validate_param_range(pUmDevice, &mtu[board_idx], "mtu", 1500, 9000, 1500);
+	dev->mtu = mtu[board_idx];
+#endif
+
+	if (pci_find_device(0x8086, 0x2418, NULL) ||
+		pci_find_device(0x8086, 0x2428, NULL) ||
+		pci_find_device(0x8086, 0x244e, NULL) ||
+		pci_find_device(0x8086, 0x2448, NULL)) {
+
+		/* Found ICH, ICH0, or ICH2 */
+		pDevice->Flags |= UNDI_FIX_FLAG;
+	}
+
+	if (LM_GetAdapterInfo(pDevice) != LM_STATUS_SUCCESS) {
+		printk(KERN_ERR "Get Adapter info failed\n");
+		rc = -ENODEV;
+		goto err_out_unmap;
+	}
+
+	if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId)) {
+		if (dev->mtu > 1500) {
+			dev->mtu = 1500;
+			printk(KERN_WARNING "%s-%d: Jumbo mtu sizes not supported, using mtu=1500\n", bcm5700_driver, pUmDevice->index);
+		}
+	}
+
+	if (pci_find_device(0x1022, 0x700c, NULL)) {
+		/* AMD762 writes I/O out of order */
+		/* Setting bit 1 in 762's register 0x4C still doesn't work */
+		/* in all cases */
+		pDevice->Flags |= FLUSH_POSTED_WRITE_FLAG;
+		pDevice->Flags &= ~NIC_SEND_BD_FLAG;
+	}
+	pUmDevice->do_global_lock = 0;
+	if (T3_ASIC_REV(pUmDevice->lm_dev.ChipRevId) == T3_ASIC_REV_5700) {
+		/* The 5700 chip works best without interleaved register */
+		/* accesses on certain machines. */
+		pUmDevice->do_global_lock = 1;
+	}
+#ifdef INCLUDE_5750_A0_FIX
+	if ((pDevice->Flags & PCI_EXPRESS_FLAG) &&
+		(pDevice->ChipRevId == T3_CHIP_ID_5750_A0))
+	{
+		if (shasta_smp_fix[pUmDevice->index]) {
+			pUmDevice->do_global_lock = 1;
+			pDevice->Flags |= (FLUSH_POSTED_WRITE_FLAG |
+					REG_RD_BACK_FLAG);
+		}
+		else {
+			pDevice->Flags &= ~REG_RD_BACK_FLAG;
+		}
+	}
+#endif
+	if ((T3_ASIC_REV(pUmDevice->lm_dev.ChipRevId) == T3_ASIC_REV_5701) &&
+		((pDevice->PciState & T3_PCI_STATE_NOT_PCI_X_BUS) == 0)) {
+
+		pUmDevice->rx_buf_align = 0;
+	}
+	else {
+		pUmDevice->rx_buf_align = 2;
+	}
+/*	dev->base_addr = pci_resource_start(pdev, 0);*/
+	dev->mem_start = pci_resource_start(pdev, 0);
+	dev->mem_end = dev->mem_start + sizeof(T3_STD_MEM_MAP); 
+	dev->irq = pdev->irq;
+
+	*dev_out = dev;
+	return 0;
+
+err_out_unmap:
+	pci_release_regions(pdev);
+	bcm5700_freemem(dev);
+
+err_out:
+#if (LINUX_VERSION_CODE < 0x020600)
+	unregister_netdev(dev);
+	kfree(dev);
+#else
+	free_netdev(dev);
+#endif
+	return rc;
+}
+
+static int __devinit
+bcm5700_print_ver(void)
+{
+	printk(KERN_INFO "Broadcom Gigabit Ethernet Driver %s ",
+		bcm5700_driver);
+#ifdef NICE_SUPPORT
+	printk("with Broadcom NIC Extension (NICE) ");
+#endif
+	printk("ver. %s %s\n", bcm5700_version, bcm5700_date);
+	return 0;
+}
+
+static int __devinit
+bcm5700_init_one(struct pci_dev *pdev,
+				       const struct pci_device_id *ent)
+{
+	struct net_device *dev = NULL;
+	PUM_DEVICE_BLOCK pUmDevice;
+	PLM_DEVICE_BLOCK pDevice;
+	int i;
+	static int board_idx = -1;
+	static int printed_version = 0;
+	struct pci_dev *amd_dev;
+
+	board_idx++;
+
+	if (!printed_version) {
+		bcm5700_print_ver();
+#ifdef BCM_PROC_FS
+		bcm5700_proc_create();
+#endif
+		printed_version = 1;
+	}
+
+	i = bcm5700_init_board(pdev, &dev, board_idx);
+	if (i < 0) {
+		return i;
+	}
+
+	if (dev == NULL)
+		return -ENOMEM;
+
+#ifdef BCM_IOCTL32
+	if (atomic_read(&bcm5700_load_count) == 0) {
+		register_ioctl32_conversion(SIOCNICE, bcm5700_ioctl32);
+	}
+	atomic_inc(&bcm5700_load_count);
+#endif
+	dev->open = bcm5700_open;
+	dev->hard_start_xmit = bcm5700_start_xmit;
+	dev->stop = bcm5700_close;
+	dev->get_stats = bcm5700_get_stats;
+	dev->set_multicast_list = bcm5700_set_rx_mode;
+	dev->do_ioctl = bcm5700_ioctl;
+	dev->set_mac_address = &bcm5700_set_mac_addr;
+#if T3_JUMBO_RCV_RCB_ENTRY_COUNT
+	dev->change_mtu = &bcm5700_change_mtu;
+#endif
+#if (LINUX_VERSION_CODE >= 0x20400)
+	dev->tx_timeout = bcm5700_reset;
+	dev->watchdog_timeo = TX_TIMEOUT;
+#endif
+#ifdef BCM_VLAN
+	dev->vlan_rx_register = &bcm5700_vlan_rx_register;
+	dev->vlan_rx_kill_vid = &bcm5700_vlan_rx_kill_vid;
+#endif
+#ifdef BCM_NAPI_RXPOLL
+	dev->poll = bcm5700_poll;
+	dev->weight = 64;
+#endif
+
+	pUmDevice = (PUM_DEVICE_BLOCK) dev->priv;
+	pDevice = (PLM_DEVICE_BLOCK) pUmDevice;
+
+	dev->base_addr = pci_resource_start(pdev, 0);
+	dev->irq = pdev->irq;
+#ifdef HAVE_POLL_CONTROLLER
+	dev->poll_controller = poll_bcm5700;
+#endif
+
+#if (LINUX_VERSION_CODE >= 0x20600)
+	if ((i = register_netdev(dev))) {
+		printk(KERN_ERR "%s: Cannot register net device\n",
+			bcm5700_driver);
+		if (pUmDevice->lm_dev.pMappedMemBase)
+			iounmap(pUmDevice->lm_dev.pMappedMemBase);
+		pci_release_regions(pdev);
+		bcm5700_freemem(dev);
+		free_netdev(dev);
+		return i;
+	}
+#endif
+
+	pci_set_drvdata(pdev, dev);
+
+	memcpy(dev->dev_addr, pDevice->NodeAddress, 6);
+	pUmDevice->name = board_info[ent->driver_data].name,
+	printk(KERN_INFO "%s: %s found at mem %lx, IRQ %d, ",
+		dev->name, pUmDevice->name, dev->base_addr,
+		dev->irq);
+	printk("node addr ");
+	for (i = 0; i < 6; i++) {
+		printk("%2.2x", dev->dev_addr[i]);
+	}
+	printk("\n");
+
+	printk(KERN_INFO "%s: ", dev->name);
+	if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5400_PHY_ID)
+		printk("Broadcom BCM5400 Copper ");
+	else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5401_PHY_ID)
+		printk("Broadcom BCM5401 Copper ");
+	else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5411_PHY_ID)
+		printk("Broadcom BCM5411 Copper ");
+	else if (((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5701_PHY_ID) &&
+		!(pDevice->TbiFlags & ENABLE_TBI_FLAG)) {
+		printk("Broadcom BCM5701 Integrated Copper ");
+	}
+	else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5703_PHY_ID) {
+		printk("Broadcom BCM5703 Integrated ");
+		if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
+			printk("SerDes ");
+		else
+			printk("Copper ");
+	}
+	else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5704_PHY_ID) {
+		printk("Broadcom BCM5704 Integrated ");
+		if (pDevice->TbiFlags & ENABLE_TBI_FLAG)
+			printk("SerDes ");
+		else
+			printk("Copper ");
+	}
+	else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5705_PHY_ID)
+		printk("Broadcom BCM5705 Integrated Copper ");
+	else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM5750_PHY_ID)
+		printk("Broadcom BCM5750 Integrated Copper ");
+	else if ((pDevice->PhyId & PHY_ID_MASK) == PHY_BCM8002_PHY_ID)
+		printk("Broadcom BCM8002 SerDes ");
+	else if (pDevice->TbiFlags & ENABLE_TBI_FLAG) {
+		if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) {
+			printk("Broadcom BCM5703 Integrated SerDes ");
+		}
+		else if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) {
+			printk("Broadcom BCM5704 Integrated SerDes ");
+		}
+		else {
+			printk("Agilent HDMP-1636 SerDes ");
+		}
+	}
+	else {
+		printk("Unknown ");
+	}
+	printk("transceiver found\n");
+
+	printk(KERN_INFO "%s: ", dev->name);
+#if (LINUX_VERSION_CODE >= 0x20400)
+	if (scatter_gather[board_idx]) {
+		dev->features |= NETIF_F_SG;
+		if (pUmDevice->using_dac && !(pDevice->Flags & BCM5788_FLAG))
+			dev->features |= NETIF_F_HIGHDMA;
+	}
+	if ((pDevice->TaskOffloadCap & LM_TASK_OFFLOAD_TX_TCP_CHECKSUM) &&
+		tx_checksum[board_idx]) {
+		dev->features |= NETIF_F_IP_CSUM;
+	}
+#ifdef BCM_VLAN
+	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+#endif
+#ifdef BCM_TSO
+	if ((pDevice->TaskToOffload & LM_TASK_OFFLOAD_TCP_SEGMENTATION) &&
+		enable_tso[board_idx]) {
+		dev->features |= NETIF_F_TSO;
+	}
+#endif
+
+	printk("Scatter-gather %s, 64-bit DMA %s, Tx Checksum %s, ",
+		(char *) ((dev->features & NETIF_F_SG) ? "ON" : "OFF"),
+		(char *) ((dev->features & NETIF_F_HIGHDMA) ? "ON" : "OFF"),
+		(char *) ((dev->features & NETIF_F_IP_CSUM) ? "ON" : "OFF"));
+#endif
+	if ((pDevice->ChipRevId != T3_CHIP_ID_5700_B0) &&
+		rx_checksum[board_idx])
+		printk("Rx Checksum ON");
+	else
+		printk("Rx Checksum OFF");
+#ifdef BCM_VLAN
+	printk(", 802.1Q VLAN ON");
+#endif
+#ifdef BCM_TSO
+	if (dev->features & NETIF_F_TSO) {
+		printk(", TSO ON");
+	}
+	else
+#endif
+#ifdef BCM_NAPI_RXPOLL
+	printk(", NAPI ON");
+#endif
+	printk("\n");
+
+#ifdef BCM_PROC_FS
+	bcm5700_proc_create_dev(dev);
+#endif
+#ifdef BCM_TASKLET
+	tasklet_init(&pUmDevice->tasklet, bcm5700_tasklet,
+		(unsigned long) pUmDevice);
+#endif
+	if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5704) {
+		if ((REG_RD(pDevice, PciCfg.DualMacCtrl) &
+			T3_DUAL_MAC_CH_CTRL_MASK) == 3) {
+
+			printk(KERN_WARNING "%s: Device is configured for Hardware Based Teaming which is not supported with this operating system. Please consult the user diagnostic guide to disable Turbo Teaming.\n", dev->name);
+		}
+	}
+
+	if ((amd_dev = pci_find_device(0x1022, 0x700c, NULL))) {
+		u32 val;
+
+		/* Found AMD 762 North bridge */
+		pci_read_config_dword(amd_dev, 0x4c, &val);
+		if ((val & 0x02) == 0) {
+			pci_write_config_dword(amd_dev, 0x4c, val | 0x02);
+			printk(KERN_INFO "%s: Setting AMD762 Northbridge to enable PCI ordering compliance\n", bcm5700_driver);
+		}
+	}
+	return 0;
+
+}
+
+
+static void __devexit
+bcm5700_remove_one (struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata (pdev);
+	PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK)dev->priv;
+
+#ifdef BCM_PROC_FS
+	bcm5700_proc_remove_dev(dev); 
+#endif
+#ifdef BCM_IOCTL32
+	atomic_dec(&bcm5700_load_count);
+	if (atomic_read(&bcm5700_load_count) == 0)
+		unregister_ioctl32_conversion(SIOCNICE);
+#endif
+	unregister_netdev(dev);
+
+	if (pUmDevice->lm_dev.pMappedMemBase)
+		iounmap(pUmDevice->lm_dev.pMappedMemBase);
+
+	pci_release_regions(pdev);
+
+#if (LINUX_VERSION_CODE < 0x020600)
+	kfree(dev);
+#else
+	free_netdev(dev);
+#endif
+
+	pci_set_drvdata(pdev, NULL);
+
+/*	pci_power_off(pdev, -1);*/
+
+}
+
+
+
+STATIC int
+bcm5700_open(struct net_device *dev)
+{
+	PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK)dev->priv;
+	PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK) pUmDevice;
+
+	if (pUmDevice->suspended)
+		return -EAGAIN;
+
+	/* delay for 6 seconds */
+	pUmDevice->delayed_link_ind = (6 * HZ) / pUmDevice->timer_interval;
+
+#ifdef BCM_INT_COAL
+#ifndef BCM_NAPI_RXPOLL
+	pUmDevice->adaptive_expiry = HZ / pUmDevice->timer_interval;
+#endif
+#endif
+
+#if INCLUDE_TBI_SUPPORT
+	if ((pDevice->TbiFlags & ENABLE_TBI_FLAG) &&
+		(pDevice->TbiFlags & TBI_POLLING_FLAGS)) {
+		pUmDevice->poll_tbi_interval = HZ / pUmDevice->timer_interval;
+		if (T3_ASIC_REV(pDevice->ChipRevId) == T3_ASIC_REV_5703) {
+			pUmDevice->poll_tbi_interval /= 4;
+		}
+		pUmDevice->poll_tbi_expiry = pUmDevice->poll_tbi_interval;
+	}
+#endif
+
+	pUmDevice->asf_heartbeat = (120 * HZ) / pUmDevice->timer_interval;
+
+	pUmDevice->stats_interval = HZ / pUmDevice->timer_interval;
+
+	/* Sometimes we get spurious ints. after reset when link is down. */
+	/* This field tells the isr to service the int. even if there is */
+	/* no status block update. */
+	if (pDevice->LedCtrl != LED_CTRL_PHY_MODE_2) {
+		pUmDevice->adapter_just_inited = (3 * HZ) /
+			pUmDevice->timer_interval;
+	}
+	else {
+		pUmDevice->adapter_just_inited = 0;
+	}
+
+	if (request_irq(dev->irq, &bcm5700_interrupt, SA_SHIRQ, dev->name, dev)) {
+		return -EAGAIN;
+	}
+
+	pUmDevice->opened = 1;
+	if (LM_InitializeAdapter(pDevice) != LM_STATUS_SUCCESS) {
+		pUmDevice->opened = 0;
+		free_irq(dev->irq, dev);
+		bcm5700_freemem(dev);
+		return -EAGAIN;
+	}
+
+	bcm5700_set_vlan_mode(pUmDevice);
+	bcm5700_init_counters(pUmDevice);
+
+	if (pDevice->Flags & UNDI_FIX_FLAG) {
+		printk(KERN_INFO "%s: Using indirect register access\n", dev->name);
+	}
+
+	if (memcmp(dev->dev_addr, pDevice->NodeAddress, 6)) {
+		LM_SetMacAddress(pDevice, dev->dev_addr);
+	}
+
+	if (tigon3_debug > 1)
+		printk(KERN_DEBUG "%s: tigon3_open() irq %d.\n", dev->name, dev->irq);
+
+	QQ_InitQueue(&pUmDevice->rx_out_of_buf_q.Container,
+        MAX_RX_PACKET_DESC_COUNT);
+	netif_start_queue(dev);
+
+#if (LINUX_VERSION_CODE < 0x020300)
+	MOD_INC_USE_COUNT;
+#endif
+
+	init_timer(&pUmDevice->timer);
+	pUmDevice->timer.expires = RUN_AT(pUmDevice->timer_interval);
+	pUmDevice->timer.data = (unsigned long)dev;
+	pUmDevice->timer.function = &bcm5700_timer;
+	add_timer(&pUmDevice->timer);
+
+	atomic_set(&pUmDevice->intr_sem, 0);
+	LM_EnableInterrupt(pDevice);
+
+	return 0;
+}
+
+
+STATIC void
+bcm5700_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	PUM_DEVICE_BLOCK pUmDevice = (PUM_DEVICE_BLOCK)dev->priv;
+	PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK) pUmDevice;
+	unsigned long flags = 0;
+	LM_UINT32 value32;
+
+	if (!pUmDevice->opened)
+		return;
+
+	if (atomic_read(&pUmDevice->intr_sem) || pUmDevice->suspended) {
+		pUmDevice->timer.expires = RUN_AT(pUmDevice->timer_interval);
+		add_timer(&pUmDevice->timer);
+		return;
+	}
+
+	if (T3_ASIC_5705_OR_5750(pDevice->ChipRevId) &&
+		(pDevice->LinkStatus == LM_STATUS_LINK_ACTIVE) &&
+		(--pUmDevice->stats_interval <= 0)) {
+
+		BCM5700_LOCK(pUmDevice, flags);
+		LM_GetStats(pDevice);
+		BCM5700_UNLOCK(pUmDevice, flags);
+		pUmDevice->stats_interval = HZ / pUmDevice->timer_interval;
+	}
+
+#if INCLUDE_TBI_SUPPORT
+	if ((pDevice->TbiFlags & TBI_POLLING_FLAGS) &&
+		(--pUmDevice->poll_tbi_expiry <= 0)) {
+
+		BCM5700_PHY_LOCK(pUmDevice, flags);
+		value32 = REG_RD(pDevice, MacCtrl.Status);
+		if (((pDevice->LinkStatus == LM_STATUS_LINK_ACTIVE) &&
+			((value32 & (MAC_STATUS_LINK_STATE_CHANGED |
+				MAC_STATUS_CFG_CHANGED)) ||
+			!(value32 & MAC_STATUS_PCS_SYNCED)))
+			||
+			((pDevice->LinkStatus != LM_STATUS_LINK_ACTIVE) &&
+			(value32 & (MAC_STATUS_PCS_SYNCED |
+				MAC_STATUS_SIGNAL_DETECTED))))
+		{
+			LM_SetupPhy(pDevice);
+		}
+		BCM5700_PHY_UNLOCK(pUmDevice, flags);
+		pUmDevice->poll_tbi_expiry = pUmDevice->poll_tbi_interval;
+		
+        }
+#endif
+
+	if (pUmDevice->delayed_link_ind > 0) {
+		if (pUmDevice->delayed_link_ind == 1)
+			MM_IndicateStatus(pDevice, pDevice->LinkStatus);
+		else
+			pUmDevice->delayed_link_ind--;
+	}
+	if (pUmDevice->adapter_just_inited > 0) {
+		pUmDevice->adapter_just_inited--;
+	}
+
+	if (pUmDevice->crc_counter_expiry > 0)
+		pUmDevice->crc_counter_expiry--;
+
+	if (!pUmDevice->interrupt) {
+		if (!(pDevice->Flags & USE_TAGGED_STATUS_FLAG)) {
+			BCM5700_LOCK(pUmDevice, flags);
+			if (pDevice->pStatusBlkVirt->Status & STATUS_BLOCK_UPDATED) {
+				/* This will generate an interrupt */
+				REG_WR(pDevice, Grc.LocalCtrl,
+					pDevice->GrcLocalCtrl |
+					GRC_MISC_LOCAL_CTRL_SET_INT);
+			}
+			else {
+				REG_WR(pDevice, HostCoalesce.Mode,
+					pDevice->CoalesceMode |
+					HOST_COALESCE_ENABLE |
+					HOST_COALESCE_NOW);
+			}
+			if (!(REG_RD(pDevice, DmaWrite.Mode) &
+				DMA_WRITE_MODE_ENABLE)) {
+				BCM5700_UNLOCK(pUmDevice, flags);
+				bcm5700_reset(dev);
+			}
+			else {
+				BCM5700_UNLOCK(pUmDevice, flags);
+			}
+			if (pUmDevice->tx_queued) {
+				pUmDevice->tx_queued = 0;
+				netif_wake_queue(dev);
+			}
+		}
+#if (LINUX_VERSION_CODE < 0x02032b)
+		if ((QQ_GetEntryCnt(&pDevice->TxPacketFreeQ.Container) !=
+			pDevice->TxPacketDescCnt) &&
+			((jiffies - dev->trans_start) > TX_TIMEOUT)) {
+
+			printk(KERN_WARNING "%s: Tx hung\n", dev->name);
+			bcm5700_reset(dev);
+		}
+#endif
+	}
+#ifdef BCM_INT_COAL
+#ifndef BCM_NAPI_RXPOLL
+	if (pUmDevice->adaptive_coalesce) {
+		pUmDevice->adaptive_expiry--;
+		if (pUmDevice->adaptive_expiry == 0) {	
+			pUmDevice->adaptive_expiry = HZ /
+				pUmDevice->timer_interval;
+			bcm5700_adapt_coalesce(pUmDevice);
+		}
+	}
+#endif
+#endif
+	if (QQ_GetEntryCnt(&pUmDevice->rx_out_of_buf_q.Container) >
+		(unsigned int) pUmDevice->rx_buf_repl_panic_thresh) {
+		/* Generate interrupt and let isr allocate buffers */
+		REG_WR(pDevice, HostCoalesce.Mode, pDevice->CoalesceMode |
+			HOST_COALESCE_ENABLE | HOST_COALESCE_NOW);
+	}
+
+#ifdef BCM_ASF
+	if (pDevice->AsfFlags & ASF_ENABLED) {
+		pUmDevice->asf_heartbeat--;
+		if (pUmDevice->asf_heartbeat == 0) {
+			MEM_WR_OFFSET(pDevice, T3_CMD_MAILBOX,
+				T3_CMD_NICDRV_ALIVE);
+			MEM_WR_OFFSET(pDevice, T3_CMD_LENGTH_MAILBOX, 4);
+			MEM_WR_OFFSET(pDevice, T3_CMD_DATA_MAILBOX, 3);
+			value32 = REG_RD(pDevice, Grc.RxCpuEvent);
+			REG_WR(pDevice, Grc.RxCpuEvent, value32 | BIT_14);
+			pUmDevice->asf_heartbeat = (120 * HZ) /
+				pUmDevice->timer_interval;
+		}
+	}
+#endif
+
+	pUmDevice->timer.expires = RUN_AT(pUmDevice->timer_interval);
+	add_timer(&pUmDevice->timer);
+}
+
+STATIC int
+bcm5700_init_counters(PUM_DEVICE_BLOCK pUmDevice)
+{
+#ifdef BCM_INT_COAL
+#ifndef BCM_NAPI_RXPOLL
+	LM_DEVICE_BLOCK *pDevice = &pUmDevice->lm_dev;
+
+	pUmDevice->rx_curr_coalesce_frames = pDevice->RxMaxCoalescedFrames;
+	pUmDevice->rx_curr_coalesce_ticks = pDevice->RxCoalescingTicks;
+	pUmDevice->tx_curr_coalesce_frames = pDevice->TxMaxCoalescedFrames;
+	pUmDevice->rx_last_cnt = 0;
+	pUmDevice->tx_last_cnt = 0;
+#endif
+#endif
+	pUmDevice->phy_crc_count = 0;
+#if TIGON3_DEBUG
+	pUmDevice->tx_zc_count = 0;
+	pUmDevice->tx_chksum_count = 0;
+	pUmDevice->tx_himem_count = 0;
+	pUmDevice->rx_good_chksum_count = 0;
+	pUmDevice->rx_bad_chksum_count = 0;
+#endif
+#ifdef BCM_TSO
+	pUmDevice->tso_pkt_count = 0;
+#endif
+	return 0;
+}
+
+#ifdef BCM_INT_COAL
+#ifndef BCM_NAPI_RXPOLL
+STATIC int
+bcm5700_do_adapt_coalesce(PUM_DEVICE_BLOCK pUmDevice,
+	int rx_frames, int rx_ticks, int tx_frames, int rx_frames_intr)
+{
+	unsigned long flags = 0;
+	LM_DEVICE_BLOCK *pDevice = &pUmDevice->lm_dev;
+
+	if (pUmDevice->do_global_lock) {
+		if (spin_is_locked(&pUmDevice->global_lock))
+			return 0;
+		spin_lock_irqsave(&pUmDevice->global_lock, flags);
+	}
+	pUmDevice->rx_curr_coalesce_frames = rx_frames;
+	pUmDevice->rx_curr_coalesce_ticks = rx_ticks;
+	pUmDevice->tx_curr_coalesce_frames = tx_frames;
+	pUmDevice->rx_curr_coalesce_frames_intr = rx_frames_intr;
+	REG_W