add updates for atheros SOC support from Mike A., thx
[openwrt/svn-archive/archive.git] / openwrt / target / linux / linux-2.4 / patches / ar531x / 001-ar531x-ethernet.patch
diff --git a/openwrt/target/linux/linux-2.4/patches/ar531x/001-ar531x-ethernet.patch b/openwrt/target/linux/linux-2.4/patches/ar531x/001-ar531x-ethernet.patch
deleted file mode 100644 (file)
index 15dd777..0000000
+++ /dev/null
@@ -1,4890 +0,0 @@
-diff -urN linux-2.4.32.new/arch/mips/ar531x/ae531xlnx.c linux-2.4.32.new-eth/arch/mips/ar531x/ae531xlnx.c\r
---- linux-2.4.32.new/arch/mips/ar531x/ae531xlnx.c      1970-01-01 01:00:00.000000000 +0100\r
-+++ linux-2.4.32.new-eth/arch/mips/ar531x/ae531xlnx.c  2005-12-25 11:54:20.756273952 +0000\r
-@@ -0,0 +1,1534 @@\r
-+/*\r
-+ * This file is subject to the terms and conditions of the GNU General Public\r
-+ * License.  See the file "COPYING" in the main directory of this archive\r
-+ * for more details.\r
-+ *\r
-+ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
-+ */\r
-+\r
-+/*\r
-+ * Ethernet driver for Atheros' ae531x ethernet MAC.\r
-+ * This is a fairly generic driver, but it's intended\r
-+ * for use in typical Atheros products.\r
-+ */\r
-+\r
-+#include <linux/config.h>\r
-+#include <linux/types.h>\r
-+#include <linux/delay.h>\r
-+#include <linux/netdevice.h>\r
-+#include <linux/etherdevice.h>\r
-+#include <linux/init.h>\r
-+#include <linux/skbuff.h>\r
-+#include <asm/io.h>\r
-+\r
-+#include "ar531xlnx.h"\r
-+#include "ae531xreg.h"\r
-+#include "ae531xmac.h"\r
-+\r
-+/*\r
-+ * A word about CONFIG_VENETDEV: It's intended to support two\r
-+ * "virtualized ethernet devices" that share a single underlying MAC.\r
-+ * To upper layers, it appears that the hardware supports two MACs,\r
-+ * with enet0 used for LAN ports and enet1 used for a WAN port. This\r
-+ * is useful, for instance, when building a 5-port router on hardware\r
-+ * that uses only one of the AR5312's ethernet MACs.\r
-+ *\r
-+ * Virtualization is accomplished through trickery at the ethernet\r
-+ * PHY layer.  We use PHY hardware to determine which port a packet\r
-+ * was received on, and in order to direct a packet to a particular\r
-+ * port or set of ports.\r
-+ *\r
-+ * The code is mostly written to be generalized to more than two\r
-+ * virtual devices; but it's intended for one multi-port LAN enet\r
-+ * device and one single-port WAN enet device.\r
-+ */\r
-+\r
-+#define AE531X_LAN_PORT 0\r
-+#ifdef CONFIG_VENETDEV\r
-+#define AE531X_DEV_PER_MAC 2\r
-+#define AE531X_WAN_PORT 1\r
-+#else\r
-+#define AE531X_DEV_PER_MAC 1\r
-+#endif\r
-+\r
-+\r
-+/*\r
-+ * ae531x_MAC_state contains driver-specific linux-specific per-MAC information.\r
-+ * The OSinfo member of ae531x_MAC_t points to one of these.\r
-+ */\r
-+typedef struct ae531x_MAC_state {\r
-+    int                         irq;\r
-+    struct tq_struct            restart_task;\r
-+    struct net_device_stats     stats;\r
-+    struct ae531x_dev_sw_state  *dev_sw_state[AE531X_DEV_PER_MAC];\r
-+    int                         primary_dev;\r
-+    ae531x_MAC_t                MACInfo; /* hardware state */\r
-+} ae531x_MAC_state_t;\r
-+\r
-+/*\r
-+ * ae531x_dev_sw_state contains driver-specific linux-specific per-device\r
-+ * information.  The net_device priv member points to one of these, and\r
-+ * this structure contains a pointer to the associated MAC information.\r
-+ * In the case of CONFIG_VENETDEV, each virtual device has its own\r
-+ * ae531x_dev_sw_state, and virtual devices that share a physical MAC\r
-+ * point to the same ae531x_MAC_state.\r
-+ */\r
-+typedef struct ae531x_dev_sw_state {\r
-+    int                     enetUnit;        /* system unit number "eth%d" */\r
-+    int                     unit_on_MAC;     /* MAC-relative unit number */\r
-+    struct net_device       *dev;\r
-+    ae531x_MAC_state_t      *MAC_state;      /* underlying MAC hw/sw state */\r
-+#ifdef CONFIG_VENETDEV\r
-+    BOOL                    isLAN;           /* 0-->WAN; 1-->LAN */\r
-+#endif\r
-+} ae531x_dev_sw_state_t;\r
-+\r
-+/*\r
-+ * Driver-independent linux-specific per-ethernet device software information.\r
-+ * Regarding CONFIG_VENETDEV: If a system has 2 physical MACs, and each\r
-+ * physical MAC has 2 virtual ethernet devices (one for LAN and one for WAN),\r
-+ * then there are a total of 4 ethernet devices.\r
-+ */\r
-+static struct net_device *ae531x_MAC_dev[AR531X_NUM_ENET_MAC * AE531X_DEV_PER_MAC];\r
-+\r
-+/* Driver-dependent per-MAC information */\r
-+static ae531x_MAC_state_t per_MAC_info[AR531X_NUM_ENET_MAC];\r
-+\r
-+/*\r
-+ * Receive buffers need enough room to hold the following:\r
-+ * 1) a max MTU-sized packet.  \r
-+ * 2) space for an ethernet header\r
-+ * 3) room at the beginning of the receive buffer in order\r
-+ *    to facilitate cooperating drivers that need to PREpend\r
-+ *    data.\r
-+ * 4) Depending on configuration, we may need some additional\r
-+ *    room at the END of the rx buffer for phy-supplied\r
-+ *    trailers (if any). (c.f. CONFIG_VENETDEV)\r
-+ *\r
-+ * The DMA engine insists on 32-bit aligned RX buffers.\r
-+ * TBDXXX: With current code, the IP stack ends up looking\r
-+ * at misaligned headers with word operations.  The misaligned\r
-+ * reads are software-emulated via handle_adel_int.  We'd\r
-+ * rather align the buffers on a 16-bit boundary, but the\r
-+ * DMA engine doesn't permit it???\r
-+ */\r
-+\r
-+#ifdef CONFIG_VLAN_8021Q\r
-+#define ETH_MAX_MTU 1522\r
-+#define HLEN 18\r
-+#else\r
-+#define ETH_MAX_MTU 1518\r
-+#define HLEN ETH_HLEN\r
-+#endif\r
-+\r
-+#define AE531X_RX_BUF_SIZE \\r
-+    (((2 + RXBUFF_RESERVE + HLEN + ETH_MAX_MTU + PHY_TRAILER_SIZE) + 3) & ~3)\r
-+\r
-+/* Forward references to local functions */\r
-+static void ae531x_TxReap(ae531x_MAC_state_t *MAC_state);\r
-+static int ae531x_phy_poll(void *data);\r
-+static int ae531x_MAC_stop(struct net_device *dev);\r
-+static int ae531x_MAC_open(struct net_device *dev);\r
-+\r
-+/* Global to track number of MACs */\r
-+\r
-+int ar531x_num_enet_macs;\r
-+\r
-+#undef DEBUG_VENETDEV\r
-+#define AR531X_NAPI\r
-+\r
-+#if defined(CONFIG_VENETDEV) && defined(DEBUG_VENETDEV)\r
-+static int cloned_counter;\r
-+static int expand_counter;\r
-+static int both_counter;\r
-+#endif\r
-+\r
-+#ifdef AR531X_NAPI\r
-+/*******************************************************************************\r
-+* ae531x_MAC_poll checks for received packets, and sends data\r
-+* up the stack.\r
-+*/\r
-+int\r
-+ae531x_MAC_poll(struct net_device *dev, int *budget)\r
-+{\r
-+    struct sk_buff *skb;\r
-+    struct sk_buff *newskb;\r
-+    char *rxBufp;\r
-+    int unused_length;\r
-+    VIRT_ADDR   rxDesc;\r
-+    int length;\r
-+    ae531x_dev_sw_state_t *dev_sw_state;\r
-+    ae531x_MAC_state_t *MAC_state;\r
-+    ae531x_MAC_t *MACInfo;\r
-+    u32 cmdsts;\r
-+    int rx_limit;\r
-+    int rx_received;\r
-+    int rxDescCount;\r
-+    struct net_device *rxdev;\r
-+    int early_stop;\r
-+    int retval;\r
-+#ifdef CONFIG_VENETDEV\r
-+    int i;\r
-+#endif\r
-+\r
-+    ARRIVE();\r
-+\r
-+    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
-+    MAC_state = dev_sw_state->MAC_state;\r
-+    MACInfo = &MAC_state->MACInfo;\r
-+    rx_limit = MAC_state->dev_sw_state[MAC_state->primary_dev]->dev->quota;\r
-+    rx_received = 0;\r
-+\r
-+#ifdef CONFIG_VENETDEV\r
-+    /*\r
-+     * Non-primary devs don't explicitly get polled by the upper layers;\r
-+     * rather, they rely on primary_dev polling to feed packets.  But in\r
-+     * order to keep netif_receive_skb happy, we need to temporarily put the\r
-+     * net_devices into "polling mode".  We pull them back out before\r
-+     * leaving this function.\r
-+     */\r
-+    for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
-+        if ((MAC_state->dev_sw_state[i]->dev) &&\r
-+            (MAC_state->dev_sw_state[i]->unit_on_MAC != MAC_state->primary_dev)) {\r
-+                netif_rx_schedule(MAC_state->dev_sw_state[i]->dev);\r
-+        }\r
-+    }\r
-+#endif\r
-+    rxDescCount = 0;\r
-+\r
-+    early_stop = 0;\r
-+    do {\r
-+        for(;;) {\r
-+            // ae531x_AckIntr(MACInfo, (DmaIntRxCompleted | DmaIntRxNoBuffer));\r
-+\r
-+            rxDesc = MACInfo->rxQueue.curDescAddr;\r
-+            cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(rxDesc));\r
-+\r
-+            AE531X_PRINT(AE531X_DEBUG_RX,\r
-+                  ("examine rxDesc %p with cmdsts=0x%x\n",\r
-+                   (void *)rxDesc, cmdsts));\r
-+    \r
-+            if (cmdsts & DescOwnByDma) {\r
-+                /* There's nothing left to process in the RX ring */\r
-+                goto rx_all_done;\r
-+            }\r
-+\r
-+            rxDescCount++;\r
-+\r
-+            AE531X_CONSUME_DESC((&MACInfo->rxQueue));\r
-+    \r
-+            // A_DATA_CACHE_INVAL(rxDesc, AE531X_DESC_SIZE);\r
-+\r
-+            /*  Process a packet */\r
-+            length = AE531X_DESC_STATUS_RX_SIZE(cmdsts) - ETH_CRC_LEN;\r
-+            if ( (cmdsts & (DescRxFirst |DescRxLast | DescRxErrors)) ==\r
-+                           (DescRxFirst | DescRxLast) ) {\r
-+                /* Descriptor status indicates "NO errors" */\r
-+                skb = AE531X_DESC_SWPTR_GET(rxDesc);\r
-+    \r
-+                /*\r
-+                 * Allocate a replacement skb.\r
-+                 * We want to get another buffer ready for Rx ASAP.\r
-+                 */\r
-+                newskb = (struct sk_buff *)ae531x_rxbuf_alloc(MACInfo, &rxBufp, &unused_length);\r
-+                if(newskb == NULL ) {\r
-+                    /*\r
-+                     * Give this descriptor back to the DMA engine,\r
-+                     * and drop the received packet.\r
-+                     */\r
-+                    MAC_state->stats.rx_dropped++;\r
-+                    AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                              ("Can't allocate new skb\n"));\r
-+                } else {\r
-+                    AE531X_DESC_BUFPTR_SET(rxDesc, rxBufp);\r
-+                    AE531X_DESC_SWPTR_SET(rxDesc, newskb);\r
-+                }\r
-+\r
-+                AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma);\r
-+              A_DATA_CACHE_FLUSH_INVAL(rxDesc, AE531X_DESC_SIZE);\r
-+                // rxDesc = NULL; /* sanity -- cannot use rxDesc now */\r
-+                sysWbFlush();\r
-+    \r
-+                if (newskb == NULL) {\r
-+                    retval = 1;\r
-+                    goto rx_no_skbs;\r
-+                } else {\r
-+                    /* Sync data cache w.r.t. DMA */\r
-+                    // A_DATA_CACHE_INVAL(skb->data, length);\r
-+        \r
-+#ifdef CONFIG_VENETDEV\r
-+                    /* Determine which associated device owns this rx buffer */\r
-+                    {\r
-+                        int fromLAN;\r
-+\r
-+                        fromLAN = phyDetermineSource(skb->data, length);\r
-+\r
-+                      if (fromLAN == -1) {\r
-+                          /*\r
-+                           * Could not determine source, so drop the packet\r
-+                           */\r
-+                          dev_kfree_skb(skb);\r
-+                          continue;\r
-+                      }\r
-+\r
-+                        length -= PHY_TRAILER_SIZE;\r
-+                        if (fromLAN) {\r
-+                            dev_sw_state = MAC_state->dev_sw_state[AE531X_LAN_PORT];\r
-+                        } else {\r
-+                            dev_sw_state = MAC_state->dev_sw_state[AE531X_WAN_PORT];\r
-+                        }\r
-+                    }\r
-+#endif\r
-+                    rxdev = dev_sw_state->dev;\r
-+\r
-+                    if (rxdev == NULL) {\r
-+                        /*\r
-+                         * We received a packet for a virtual enet device\r
-+                         * that is no longer up.  Ignore it.\r
-+                         */\r
-+                        dev_kfree_skb(skb);\r
-+                        continue;\r
-+                    }\r
-+\r
-+                    /* Advance data pointer to show that there's data here */\r
-+                    skb_put(skb, length);\r
-+                    skb->protocol = eth_type_trans(skb, rxdev);\r
-+                    skb->dev = rxdev;\r
-+                    rxdev->last_rx = jiffies;\r
-+                    rxdev->quota--;\r
-+\r
-+                    if (rx_limit-- < 0) {\r
-+                        early_stop=1;\r
-+                        /* We've done enough for now -- more later */\r
-+                        AE531X_PRINT(AE531X_DEBUG_RX_STOP,\r
-+                            ("Enet%d RX early stop.  Quota=%d rxDescCount=%d budget=%d\n",\r
-+                             MACInfo->unit, dev->quota, rxDescCount, *budget));\r
-+                    }\r
-+                    rx_received++;\r
-+        \r
-+                    /* Send the data up the stack */\r
-+                    AE531X_PRINT(AE531X_DEBUG_RX,\r
-+                              ("Send data up stack: skb=%p data=%p length=%d\n",\r
-+                               (void *)skb, (void *)skb->data, length));\r
-+\r
-+                    netif_receive_skb(skb);\r
-+\r
-+                    MAC_state->stats.rx_packets++;\r
-+                    MAC_state->stats.rx_bytes += length;\r
-+                }\r
-+            } else {\r
-+                /* Descriptor status indicates ERRORS */\r
-+                MAC_state->stats.rx_errors++;\r
-+    \r
-+                if (cmdsts & (DescRxRunt | DescRxLateColl)) {\r
-+                  AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                                 ("Runt | RX Late Collision Error\n"));\r
-+                    MAC_state->stats.collisions++;\r
-+                }\r
-+    \r
-+                if (cmdsts & DescRxLengthError) {\r
-+                  AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                                 ("RX Length Error\n"));\r
-+                    MAC_state->stats.rx_length_errors++;\r
-+                }\r
-+    \r
-+                if (cmdsts & DescRxCrc) {\r
-+                  AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                                 ("RX CRC Error\n"));\r
-+                    MAC_state->stats.rx_crc_errors++;\r
-+                }\r
-+    \r
-+                if (cmdsts & DescRxDribbling) {\r
-+                  AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                                 ("Dribbling Error\n"));\r
-+                    MAC_state->stats.rx_frame_errors++;\r
-+                }\r
-+    \r
-+                AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                          ("Bad receive.  rxDesc=%p  cmdsts=0x%8.8x\n",\r
-+                           (void *)rxDesc, cmdsts));\r
-+\r
-+              /* Give this one back */\r
-+                AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma);\r
-+              A_DATA_CACHE_FLUSH_INVAL(rxDesc, AE531X_DESC_SIZE);\r
-+                sysWbFlush();\r
-+            }\r
-+        }\r
-+    } while ((!early_stop) &&\r
-+             ae531x_ReadDmaReg(MACInfo, DmaStatus) & DmaIntRxCompleted);\r
-+\r
-+rx_all_done:\r
-+    AE531X_PRINT(AE531X_DEBUG_RX, \r
-+             ("rx done (%d)\n", rxDescCount));\r
-+    *budget -= rxDescCount;\r
-+\r
-+    if (!early_stop) {\r
-+        netif_rx_complete(dev);\r
-+\r
-+        ae531x_SetDmaReg(MACInfo, DmaIntrEnb,\r
-+                     DmaIeRxCompleted | DmaIeRxNoBuffer);\r
-+        ae531x_WriteDmaReg(MACInfo, DmaRxPollDemand, 0);\r
-+    }\r
-+    \r
-+    retval = early_stop;\r
-+\r
-+rx_no_skbs:\r
-+\r
-+#ifdef CONFIG_VENETDEV\r
-+    for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
-+        if ((MAC_state->dev_sw_state[i]->dev) &&\r
-+            (MAC_state->dev_sw_state[i]->unit_on_MAC !=\r
-+                                      MAC_state->primary_dev)) {\r
-+                netif_rx_complete(MAC_state->dev_sw_state[i]->dev);\r
-+        }\r
-+    }\r
-+#endif\r
-+\r
-+    LEAVE();\r
-+    return retval;\r
-+}\r
-+#endif\r
-+\r
-+#ifndef AR531X_NAPI\r
-+/*******************************************************************************\r
-+* ae531x_MAC_recv checks for received packets, and sends data\r
-+* up the stack.\r
-+*/\r
-+static void\r
-+ae531x_MAC_recv(struct net_device *dev)\r
-+{\r
-+    struct sk_buff *skb;\r
-+    struct sk_buff *newskb;\r
-+    char *rxBufp;\r
-+    int unused_length;\r
-+    VIRT_ADDR   rxDesc;\r
-+    int length;\r
-+    ae531x_dev_sw_state_t *dev_sw_state;\r
-+    ae531x_MAC_state_t *MAC_state;\r
-+    ae531x_MAC_t *MACInfo;\r
-+    u32 cmdsts;\r
-+    int rx_limit;\r
-+    int rx_received;\r
-+    struct net_device *rxdev;\r
-+    int retval;\r
-+\r
-+    ARRIVE();\r
-+\r
-+    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
-+    MAC_state = dev_sw_state->MAC_state;\r
-+    MACInfo = &MAC_state->MACInfo;\r
-+    rx_limit = MAC_state->dev_sw_state[MAC_state->primary_dev]->dev->quota;\r
-+    rx_received = 0;\r
-+\r
-+    for(;;) {\r
-+      rxDesc = MACInfo->rxQueue.curDescAddr;\r
-+      cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(rxDesc));\r
-+\r
-+      AE531X_PRINT(AE531X_DEBUG_RX,\r
-+            ("examine rxDesc %p with cmdsts=0x%x\n",\r
-+             (void *)rxDesc, cmdsts));\r
-+\r
-+      if (cmdsts & DescOwnByDma) {\r
-+          /* There's nothing left to process in the RX ring */\r
-+          break;\r
-+      }\r
-+\r
-+      AE531X_CONSUME_DESC((&MACInfo->rxQueue));\r
-+\r
-+      // A_DATA_CACHE_INVAL(rxDesc, AE531X_DESC_SIZE);\r
-+\r
-+      /*  Process a packet */\r
-+      length = AE531X_DESC_STATUS_RX_SIZE(cmdsts) - ETH_CRC_LEN;\r
-+      if ( (cmdsts & (DescRxFirst |DescRxLast | DescRxErrors)) ==\r
-+                     (DescRxFirst | DescRxLast) ) {\r
-+          /* Descriptor status indicates "NO errors" */\r
-+          skb = AE531X_DESC_SWPTR_GET(rxDesc);\r
-+\r
-+          /*\r
-+           * Allocate a replacement skb.\r
-+           * We want to get another buffer ready for Rx ASAP.\r
-+           */\r
-+          newskb = (struct sk_buff *)ae531x_rxbuf_alloc(MACInfo,\r
-+                                                        &rxBufp,\r
-+                                                        &unused_length);\r
-+          if(newskb == NULL ) {\r
-+              /*\r
-+               * Give this descriptor back to the DMA engine,\r
-+               * and drop the received packet.\r
-+               */\r
-+              MAC_state->stats.rx_dropped++;\r
-+              AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                        ("Can't allocate new skb\n"));\r
-+          } else {\r
-+              AE531X_DESC_BUFPTR_SET(rxDesc, rxBufp);\r
-+              AE531X_DESC_SWPTR_SET(rxDesc, newskb);\r
-+          }\r
-+\r
-+          AE531X_DESC_STATUS_SET(rxDesc, DescOwnByDma);\r
-+          A_DATA_CACHE_FLUSH_INVAL(rxDesc, AE531X_DESC_SIZE);\r
-+          sysWbFlush();\r
-+\r
-+          if (newskb == NULL) {\r
-+              break;\r
-+          } else {\r
-+#ifdef CONFIG_VENETDEV\r
-+              /* Determine which associated device owns this rx buffer */\r
-+              {\r
-+                  int fromLAN;\r
-+\r
-+                  fromLAN = phyDetermineSource(skb->data, length);\r
-+\r
-+                  if (fromLAN == -1) {\r
-+                      /*\r
-+                       * Could not determine source, so drop the packet\r
-+                       */\r
-+                      dev_kfree_skb(skb);\r
-+                      continue;\r
-+                  }\r
-+\r
-+                  length -= PHY_TRAILER_SIZE;\r
-+                  if (fromLAN) {\r
-+                      dev_sw_state =\r
-+                          MAC_state->dev_sw_state[AE531X_LAN_PORT];\r
-+                  } else {\r
-+                      dev_sw_state =\r
-+                          MAC_state->dev_sw_state[AE531X_WAN_PORT];\r
-+                  }\r
-+              }\r
-+#endif\r
-+              rxdev = dev_sw_state->dev;\r
-+\r
-+              if (rxdev == NULL) {\r
-+                  /*\r
-+                   * We received a packet for a virtual enet device\r
-+                   * that is no longer up.  Ignore it.\r
-+                   */\r
-+                  dev_kfree_skb(skb);\r
-+                  continue;\r
-+              }\r
-+\r
-+              /* Advance data pointer to show that there's data here */\r
-+              skb_put(skb, length);\r
-+              skb->protocol = eth_type_trans(skb, rxdev);\r
-+              skb->dev = rxdev;\r
-+              rxdev->last_rx = jiffies;\r
-+              rxdev->quota--;\r
-+\r
-+              rx_received++;\r
-+    \r
-+              /* Send the data up the stack */\r
-+              AE531X_PRINT(AE531X_DEBUG_RX,\r
-+                        ("Send data up stack: skb=%p data=%p length=%d\n",\r
-+                         (void *)skb, (void *)skb->data, length));\r
-+\r
-+              netif_rx(skb);\r
-+\r
-+              MAC_state->stats.rx_packets++;\r
-+              MAC_state->stats.rx_bytes += length;\r
-+          }\r
-+      } else {\r
-+          /* Descriptor status indicates ERRORS */\r
-+          MAC_state->stats.rx_errors++;\r
-+\r
-+          if (cmdsts & (DescRxRunt | DescRxLateColl)) {\r
-+              MAC_state->stats.collisions++;\r
-+          }\r
-+\r
-+          if (cmdsts & DescRxLengthError) {\r
-+              MAC_state->stats.rx_length_errors++;\r
-+          }\r
-+\r
-+          if (cmdsts & DescRxCrc) {\r
-+              MAC_state->stats.rx_crc_errors++;\r
-+          }\r
-+\r
-+          if (cmdsts & DescRxDribbling) {\r
-+              MAC_state->stats.rx_frame_errors++;\r
-+          }\r
-+\r
-+          AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                    ("Bad receive.  rxDesc=%p  cmdsts=0x%8.8x\n",\r
-+                     (void *)rxDesc, cmdsts));\r
-+      }\r
-+    }\r
-+\r
-+    LEAVE();\r
-+    return;\r
-+}\r
-+#endif\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_restart stops all ethernet devices associated with a physical MAC,\r
-+* then shuts down the MAC.  Then it re-opens all devices that were in use.\r
-+* TBDXXX: needs testing!\r
-+*/\r
-+static void\r
-+ae531x_restart(void *data)\r
-+{\r
-+    ae531x_MAC_t *MACInfo = (ae531x_MAC_t *)data;\r
-+    ae531x_MAC_state_t *MAC_state = (ae531x_MAC_state_t *)MACInfo->OSinfo;\r
-+    struct net_device *saved_dev[AE531X_DEV_PER_MAC];\r
-+    int i;\r
-+\r
-+    for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
-+        if ((saved_dev[i] = MAC_state->dev_sw_state[i]->dev) != NULL) {\r
-+            ae531x_MAC_stop(saved_dev[i]);\r
-+        }\r
-+    }\r
-+\r
-+    for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
-+        if (saved_dev[i])\r
-+            ae531x_MAC_open(saved_dev[i]);\r
-+    }\r
-+}\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_MAC_intr handle interrupts from an ethernet MAC.\r
-+* It checks MAC status registers, and dispatches as appropriate.\r
-+*/\r
-+void\r
-+ae531x_MAC_intr(int cpl, void *dev_id, struct pt_regs *regs)\r
-+{\r
-+        ae531x_MAC_state_t *MAC_state;\r
-+        ae531x_MAC_t *MACInfo;\r
-+        u32 regIsr;\r
-+        u32 regImr;\r
-+        u32 pendIntrs;\r
-+      struct net_device * primary_dev;\r
-+\r
-+        ARRIVE();\r
-+\r
-+        MACInfo = (ae531x_MAC_t *)dev_id;\r
-+        MAC_state = (ae531x_MAC_state_t *)MACInfo->OSinfo;\r
-+      primary_dev = MAC_state->dev_sw_state[MAC_state->primary_dev]->dev;\r
-+\r
-+        for(;;) {\r
-+                /* Clear any unhandled intr causes. */\r
-+                ae531x_WriteDmaReg(MACInfo, DmaStatus, UnhandledIntrMask);\r
-+\r
-+                regIsr = ae531x_ReadDmaReg(MACInfo, DmaStatus);\r
-+\r
-+                regImr = ae531x_ReadDmaReg(MACInfo, DmaIntrEnb);\r
-+                pendIntrs = regIsr & regImr;\r
-+\r
-+                AE531X_PRINT(AE531X_DEBUG_INT,\r
-+                          ("ethmac%d: intIsr=0x%8.8x intImr=0x%8.8x\n",\r
-+                           MACInfo->unit, regIsr, regImr));\r
-+\r
-+                if ((pendIntrs & DmaAllIntCauseMask) == 0)\r
-+                    break;\r
-+\r
-+                if ((pendIntrs & DmaIntRxCompleted) ||\r
-+                    (pendIntrs & DmaIntRxNoBuffer)) {\r
-+#ifdef AR531X_NAPI\r
-+                    if (netif_rx_schedule_prep(primary_dev)) {\r
-+                        ae531x_ClearDmaReg(MACInfo,\r
-+                                           DmaIntrEnb,\r
-+                                           DmaIeRxCompleted | DmaIeRxNoBuffer);\r
-+                        ae531x_AckIntr(MACInfo,\r
-+                                       DmaIntRxCompleted | DmaIntRxNoBuffer);\r
-+                        (void)ae531x_ReadDmaReg(MACInfo, DmaIntrEnb);\r
-+                        __netif_rx_schedule(primary_dev);\r
-+                    } else {\r
-+                        AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                                 ("%s: Interrupt (0x%8.8x/0x%8.8x) while in poll.  regs@%p, pc=%p, ra=%p\n",\r
-+                               __FILE__,\r
-+                               regIsr,\r
-+                               ae531x_ReadDmaReg(MACInfo, DmaIntrEnb),\r
-+                               (void *)regs,\r
-+                               (void *)regs->cp0_epc,\r
-+                               (void *)regs->regs[31]));\r
-+                        ae531x_ClearDmaReg(MACInfo,\r
-+                                           DmaIntrEnb,\r
-+                                           DmaIeRxCompleted | DmaIeRxNoBuffer);\r
-+                        ae531x_AckIntr(MACInfo,\r
-+                                       DmaIntRxCompleted | DmaIntRxNoBuffer);\r
-+                    }\r
-+#else\r
-+                  ae531x_MAC_recv(primary_dev);\r
-+                  ae531x_AckIntr(MACInfo,\r
-+                                   DmaIntRxCompleted | DmaIntRxNoBuffer);\r
-+#endif\r
-+                }\r
-+\r
-+                if (pendIntrs &\r
-+                    (DmaIntTxStopped | DmaIntTxJabber | DmaIntTxUnderflow)) {\r
-+                    AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                              ("ethmac%d: TX Error Intr (0x%x)\n",\r
-+                               MACInfo->unit, pendIntrs));\r
-+                    ae531x_AckIntr(MACInfo,\r
-+                        (DmaIntTxStopped | DmaIntTxJabber | DmaIntTxUnderflow));\r
-+                }\r
-+\r
-+                if (pendIntrs & DmaIntBusError) {\r
-+                    AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                              ("ethmac%d: DMA Bus Error Intr (0x%x)\n",\r
-+                               MACInfo->unit, pendIntrs));\r
-+                    ae531x_AckIntr(MACInfo, DmaIntBusError);\r
-+                    /* Reset the chip, if it's not already being done */\r
-+                    if (ae531x_IsInResetMode(MACInfo)) {\r
-+                        goto intr_done;\r
-+                    }\r
-+                    ae531x_BeginResetMode(MACInfo);\r
-+                    schedule_task(&MAC_state->restart_task);\r
-+                }\r
-+\r
-+                if (pendIntrs & DmaIntRxStopped) {\r
-+                    AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                              ("ethmac%d: RX Stopped Intr (0x%x)\n",\r
-+                               MACInfo->unit, pendIntrs));\r
-+                    ae531x_AckIntr(MACInfo, DmaIntRxStopped);\r
-+                }\r
-+      }\r
-+\r
-+      ae531x_DmaIntEnable(MACInfo);\r
-+\r
-+intr_done:\r
-+      LEAVE();\r
-+}\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_MAC_get_stats returns statistics for a specified device\r
-+*/\r
-+static struct net_device_stats*\r
-+ae531x_MAC_get_stats(struct net_device *dev)\r
-+{\r
-+        ae531x_dev_sw_state_t *dev_sw_state;\r
-+        ae531x_MAC_state_t *MAC_state;\r
-+\r
-+        ARRIVE();\r
-+        dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
-+        MAC_state = dev_sw_state->MAC_state;\r
-+\r
-+        LEAVE();\r
-+        return &MAC_state->stats;\r
-+}\r
-+\r
-+#define AE531X_PHY_POLL_SECONDS 2\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_phy_poll periodically checks for changes in phy status\r
-+* (e.g. dropped link).\r
-+*/\r
-+static int\r
-+ae531x_phy_poll(void *data)\r
-+{\r
-+    ae531x_dev_sw_state_t *dev_sw_state = (ae531x_dev_sw_state_t *)data;\r
-+    ae531x_MAC_t *MACInfo = &dev_sw_state->MAC_state->MACInfo;\r
-+    int unit = dev_sw_state->enetUnit;\r
-+\r
-+#if defined(CONFIG_VENETDEV) && defined(DEBUG_VENETDEV)\r
-+    int       previous_cloned = 0;\r
-+    int       previous_expand = 0;\r
-+    int       previous_both = 0;\r
-+#endif\r
-+\r
-+    daemonize();\r
-+    reparent_to_init();\r
-+    spin_lock_irq(&current->sigmask_lock);\r
-+    sigemptyset(&current->blocked);\r
-+    recalc_sigpending(current);\r
-+    spin_unlock_irq(&current->sigmask_lock);\r
-+\r
-+    snprintf(current->comm, sizeof(current->comm), "%s",\r
-+           dev_sw_state->dev->name);\r
-+\r
-+    for(;;) {\r
-+        if (MACInfo->port_is_up) {\r
-+            phyCheckStatusChange(unit);\r
-+        }\r
-+\r
-+#if defined(CONFIG_VENETDEV) && defined(DEBUG_VENETDEV)\r
-+      if (cloned_counter != previous_cloned) {\r
-+              printk("Cloned Counter: %d (delta %d)\n",\r
-+                      cloned_counter, cloned_counter - previous_cloned);\r
-+              previous_cloned = cloned_counter;\r
-+      }\r
-+      if (expand_counter != previous_expand) {\r
-+              printk("Expand Counter: %d (delta %d)\n",\r
-+                      expand_counter, expand_counter - previous_expand);\r
-+              previous_expand = expand_counter;\r
-+      }\r
-+      if (both_counter != previous_both) {\r
-+              printk("Expand & Cloned Counter: %d (delta %d)\n",\r
-+                      both_counter, both_counter - previous_both);\r
-+              previous_both = both_counter;\r
-+      }\r
-+#endif\r
-+\r
-+        set_current_state(TASK_UNINTERRUPTIBLE);\r
-+        schedule_timeout(AE531X_PHY_POLL_SECONDS * HZ);\r
-+    }\r
-+\r
-+    return 0;\r
-+}\r
-+\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_MAC_set_rx_mode is used to set the RX mode options, such as\r
-+* promiscuous or multicast.\r
-+*/\r
-+static void\r
-+ae531x_MAC_set_rx_mode(struct net_device *dev)\r
-+{\r
-+    ae531x_dev_sw_state_t *dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
-+    ae531x_MAC_state_t *MAC_state=dev_sw_state->MAC_state;\r
-+    ae531x_MAC_t *MACInfo = &MAC_state->MACInfo;\r
-+\r
-+    if (dev->flags & IFF_PROMISC) {\r
-+      ae531x_SetMacReg(MACInfo, MacControl, MacPromiscuousModeOn);\r
-+    } else {\r
-+      ae531x_ClearMacReg(MACInfo, MacControl, MacPromiscuousModeOn);\r
-+    }\r
-+\r
-+    if (dev->flags & IFF_MULTICAST) {\r
-+      ae531x_SetMacReg(MACInfo, MacControl, MacMulticastFilterOff);\r
-+    } else {\r
-+      ae531x_ClearMacReg(MACInfo, MacControl, MacMulticastFilterOff);\r
-+    }\r
-+}\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_MAC_open is the standard Linux open function.  It puts\r
-+* hardware into a known good state, allocates queues, starts\r
-+* the phy polling task, and arranges for interrupts to be handled.\r
-+*/\r
-+static int\r
-+ae531x_MAC_open(struct net_device *dev)\r
-+{\r
-+    ae531x_dev_sw_state_t *dev_sw_state;\r
-+    ae531x_MAC_state_t *MAC_state;\r
-+    ae531x_MAC_t *MACInfo;\r
-+    int rv;\r
-+    struct tq_struct *restart_task;\r
-+    pid_t phy_poll_pid;\r
-+\r
-+    ARRIVE();\r
-+\r
-+    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
-+    dev_sw_state->dev = dev;\r
-+    MAC_state = dev_sw_state->MAC_state;\r
-+    MACInfo = &MAC_state->MACInfo;\r
-+\r
-+    restart_task = &MAC_state->restart_task;\r
-+    restart_task->routine = ae531x_restart;\r
-+    restart_task->data = (void *)MACInfo;\r
-+\r
-+    AE531X_PRINT(AE531X_DEBUG_RESET,\r
-+              ("ae531x_MAC_open eth%d ethmac%d macBase=0x%x dmaBase=0x%x irq=0x%x\n",\r
-+               dev_sw_state->enetUnit,\r
-+               MACInfo->unit,\r
-+               MACInfo->macBase,\r
-+               MACInfo->dmaBase,\r
-+               MAC_state->irq));\r
-+\r
-+    if (!MACInfo->port_is_up) {\r
-+        /* Bring MAC and PHY out of reset */\r
-+        ae531x_reset(MACInfo);\r
-+    \r
-+        /* Attach interrupt handler */\r
-+        rv = request_irq(MAC_state->irq, ae531x_MAC_intr, SA_INTERRUPT,\r
-+                    "ae531x_MAC_intr", (void *)MACInfo);\r
-+        if (rv < 0) {\r
-+            AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                         ("request_irq(0x%x) failed (%d)\n",\r
-+                          MAC_state->irq, rv));\r
-+            goto open_failure;\r
-+        }\r
-+\r
-+        /* Initialize PHY */\r
-+        phySetup(MACInfo->unit, MACInfo->phyBase);\r
-+\r
-+        /* Start thread to poll for phy link status changes */\r
-+        phy_poll_pid = kernel_thread(ae531x_phy_poll,\r
-+                                   dev_sw_state,\r
-+                                   CLONE_FS | CLONE_FILES);\r
-+        if (phy_poll_pid < 0) {\r
-+            AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                     ("ethmac%d unable to start Phy Poll thread\n",\r
-+                     MACInfo->unit));\r
-+        }\r
-+\r
-+        /* Allocate RX/TX Queues */\r
-+        if (ae531x_AllocateQueues(MACInfo) < 0) {\r
-+            AE531X_PRINT(AE531X_DEBUG_RESET, ("Queue allocation failed"));\r
-+            free_irq(MAC_state->irq, (void *)MACInfo);\r
-+            goto open_failure;\r
-+        }\r
-+    \r
-+        /* Initialize DMA and descriptors */\r
-+        ae531x_DmaReset(MACInfo);\r
-+\r
-+        /* Initialize MAC */\r
-+        ae531x_MACReset(MACInfo);\r
-+\r
-+      /* Set RX mode */\r
-+      ae531x_MAC_set_rx_mode(dev);\r
-+\r
-+        /* Enable Receive/Transmit */\r
-+        ae531x_EnableComm(MACInfo);\r
-+    \r
-+        MAC_state->primary_dev = dev_sw_state->unit_on_MAC;\r
-+        MACInfo->port_is_up = TRUE;\r
-+    }\r
-+\r
-+    dev->trans_start = jiffies;\r
-+\r
-+    LEAVE();\r
-+    return 0;\r
-+\r
-+open_failure:\r
-+    LEAVE();\r
-+    return -1;\r
-+}\r
-+\r
-+/*\r
-+ * Shut down MAC hardware.\r
-+ */\r
-+static void\r
-+ae531x_MAC_shutdown(ae531x_MAC_state_t *MAC_state)\r
-+{\r
-+    ae531x_MAC_t *MACInfo;\r
-+\r
-+    MACInfo = &MAC_state->MACInfo;\r
-+    MACInfo->port_is_up = FALSE;\r
-+\r
-+    /* Disable Receive/Transmit */\r
-+    ae531x_DisableComm(MACInfo);\r
-+\r
-+    /* Disable Interrupts */\r
-+    ae531x_DmaIntDisable(MACInfo);\r
-+    sysWbFlush();\r
-+    free_irq(MAC_state->irq, (void *)MACInfo);\r
-+\r
-+    /* Free Transmit & Receive skb's/descriptors */\r
-+    ae531x_TxReap(MAC_state); /* one last time */\r
-+    ae531x_FreeQueues(MACInfo);\r
-+}\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_MAC_stop is the standard Linux stop function.  It undoes\r
-+* everything set up by ae531x_MAC_open.\r
-+*/\r
-+static int\r
-+ae531x_MAC_stop(struct net_device *dev)\r
-+{\r
-+    ae531x_dev_sw_state_t *dev_sw_state;\r
-+    ae531x_MAC_state_t *MAC_state;\r
-+    ae531x_MAC_t *MACInfo;\r
-+    int i;\r
-+\r
-+    ARRIVE();\r
-+\r
-+    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
-+    MAC_state = dev_sw_state->MAC_state;\r
-+    MACInfo = &MAC_state->MACInfo;\r
-+\r
-+    for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
-+        if ((MAC_state->dev_sw_state[i]->dev) &&\r
-+            (MAC_state->dev_sw_state[i]->dev != dev_sw_state->dev)) {\r
-+            break;\r
-+        }\r
-+    }\r
-+\r
-+    if (i < AE531X_DEV_PER_MAC) {\r
-+        /* Physical MAC is still in use */\r
-+        if (MAC_state->primary_dev == dev_sw_state->unit_on_MAC) {\r
-+            /*\r
-+             * If the primary_dev is being stopped\r
-+             * then we need to assign a new one.\r
-+             */\r
-+            MAC_state->primary_dev = i;\r
-+        }\r
-+    } else {\r
-+        /* Physical MAC is no longer in use */\r
-+        ae531x_MAC_shutdown(MAC_state);\r
-+    }\r
-+\r
-+    dev_sw_state->dev = NULL;\r
-+\r
-+    LEAVE();\r
-+    return 0;\r
-+}\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_rxbuf_alloc - Allocate an skb to be associated with an RX descriptor.\r
-+*\r
-+* RETURNS: A pointer to the skb.  Also returns a pointer to the underlying\r
-+* buffer and the size of that buffer. \r
-+*/\r
-+void *\r
-+ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBuffp, int *rxBuffSizep)\r
-+{\r
-+    struct sk_buff *skb;\r
-+    char *rxBuff;\r
-+    int rxBuffSize;\r
-+\r
-+    skb = dev_alloc_skb(AE531X_RX_BUF_SIZE);\r
-+    if (skb) {\r
-+      /* Add 2 to align the IP header on a DWORD boundary */\r
-+        skb_reserve(skb, RXBUFF_RESERVE + 2);\r
-+\r
-+        rxBuffSize = skb_tailroom(skb);\r
-+        rxBuff = skb->tail;\r
-+\r
-+        *rxBuffp = rxBuff;\r
-+        *rxBuffSizep = rxBuffSize;\r
-+\r
-+      A_DATA_CACHE_INVAL(rxBuff, rxBuffSize);\r
-+    }\r
-+\r
-+    return skb;\r
-+}\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_swptr_free - Free the skb, if any, associated with a descriptor.\r
-+*/\r
-+void\r
-+ae531x_swptr_free(VIRT_ADDR desc)\r
-+{\r
-+    struct sk_buff *skb;\r
-+\r
-+    skb = (struct sk_buff *)AE531X_DESC_SWPTR_GET(desc);\r
-+    if (skb) {\r
-+        AE531X_DESC_SWPTR_SET(desc, NULL);\r
-+        kfree_skb(skb);\r
-+    }\r
-+}\r
-+\r
-+/*******************************************************************************\r
-+*\r
-+* ae531x_TxReap - the driver Tx completion routine.\r
-+*\r
-+* This routine reaps sk_buffs which have already been transmitted.\r
-+*\r
-+*/\r
-+static void\r
-+ae531x_TxReap(ae531x_MAC_state_t *MAC_state)\r
-+{\r
-+    AE531X_QUEUE      *txq;\r
-+    VIRT_ADDR         txDesc;\r
-+    UINT32            cmdsts;\r
-+    struct            sk_buff *skb;\r
-+    int               reaped;\r
-+    ae531x_MAC_t      *MACInfo;\r
-+    static int        aeUselessReap = 0;\r
-+\r
-+    ARRIVE();\r
-+\r
-+    MACInfo = &MAC_state->MACInfo;\r
-+    txq = &MACInfo->txQueue;\r
-+    reaped = 0;\r
-+\r
-+    while (1) {\r
-+        txDesc = AE531X_QUEUE_ELE_NEXT_GET(txq, txq->reapDescAddr);\r
-+        if (txDesc == txq->curDescAddr) {\r
-+            break;\r
-+        }\r
-+\r
-+        cmdsts = AE531X_DESC_STATUS_GET(KSEG1ADDR(txDesc));\r
-+        if (cmdsts & DescOwnByDma) {\r
-+            break;\r
-+        }\r
-+\r
-+        /* Release sk_buff associated with completed transmit */\r
-+        skb = (struct sk_buff *)AE531X_DESC_SWPTR_GET(txDesc);\r
-+\r
-+        if (skb) {\r
-+            kfree_skb(skb);\r
-+            AE531X_DESC_SWPTR_SET(txDesc, NULL);\r
-+        }\r
-+\r
-+        /* Update statistics according to completed transmit desc */\r
-+        if (cmdsts & DescTxErrors) {\r
-+            AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                    ("enetmac%d Tx prior error: 0x%8.8x <0x%8.8x> 0x%8.8x\n",\r
-+                    MACInfo->unit,\r
-+                    cmdsts,\r
-+                    DescTxErrors,\r
-+                    (int)txDesc));\r
-+            MAC_state->stats.tx_errors++;\r
-+            if (cmdsts & (DescTxLateCollision | DescTxExcCollisions)) {\r
-+                MAC_state->stats.tx_aborted_errors++;\r
-+            }\r
-+            if (cmdsts & (DescTxLostCarrier | DescTxNoCarrier)) {\r
-+                MAC_state->stats.tx_carrier_errors++;\r
-+            }\r
-+        } else {\r
-+            MAC_state->stats.tx_bytes += AE531X_DESC_STATUS_RX_SIZE(cmdsts);\r
-+            MAC_state->stats.tx_packets++;\r
-+        }\r
-+\r
-+        MAC_state->stats.collisions +=\r
-+            ((cmdsts & DescTxCollMask) >> DescTxCollShift);\r
-+\r
-+        txq->reapDescAddr = txDesc;\r
-+        reaped++;\r
-+    }\r
-+\r
-+    if (reaped > 0) {\r
-+        int i;\r
-+\r
-+        AE531X_PRINT(AE531X_DEBUG_TX_REAP,\r
-+             ("reaped %d\n", reaped));\r
-+\r
-+        /*\r
-+         * Re-start transmit queues for all ethernet devices\r
-+         * associated with this MAC.\r
-+         */\r
-+        for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
-+            if (MAC_state->dev_sw_state[i]->dev)\r
-+                netif_start_queue(MAC_state->dev_sw_state[i]->dev);\r
-+        }\r
-+    } else {\r
-+        aeUselessReap++;\r
-+    }\r
-+\r
-+    LEAVE();\r
-+}\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_MAC_start_xmit sends a packet.\r
-+*/\r
-+static int\r
-+ae531x_MAC_start_xmit(struct sk_buff *skb, struct net_device *dev)\r
-+{\r
-+    ae531x_dev_sw_state_t *dev_sw_state;\r
-+    ae531x_MAC_state_t *MAC_state;\r
-+    ae531x_MAC_t *MACInfo;\r
-+    u32 buf;\r
-+    u32 ctrlen;\r
-+    u32 length;\r
-+    int mtu;\r
-+    int max_buf_size;\r
-+    VIRT_ADDR txDesc;\r
-+\r
-+    ARRIVE();\r
-+\r
-+    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
-+    MAC_state = dev_sw_state->MAC_state;\r
-+    MACInfo = &MAC_state->MACInfo;\r
-+\r
-+    length = skb->len;\r
-+\r
-+    /* Check if this port is up, else toss packet */\r
-+    if (!MACInfo->port_is_up) {\r
-+        buf = virt_to_bus(skb->data);\r
-+        AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                  ("eth%d Tx Down, dropping buf=0x%8.8x, length=0x%8.8x, skb=%p\n",\r
-+                   dev_sw_state->enetUnit, buf, length, (void *)skb));\r
-+\r
-+        MAC_state->stats.tx_dropped++;\r
-+        MAC_state->stats.tx_carrier_errors++;\r
-+        goto dropFrame;\r
-+    }\r
-+\r
-+    if (ae531x_IsInResetMode(MACInfo)) {\r
-+        AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                  ("eth%d Tx: In Chip reset - drop frame\n",\r
-+                   dev_sw_state->enetUnit));\r
-+\r
-+        MAC_state->stats.tx_dropped++;\r
-+        MAC_state->stats.tx_aborted_errors++;\r
-+        goto dropFrame;\r
-+    }\r
-+\r
-+    /* Check if we can transport this packet */\r
-+    length = max((u32)60, length);  /* total length */\r
-+    mtu = dev->mtu;\r
-+    max_buf_size = mtu + HLEN;\r
-+    if (length > max_buf_size) {\r
-+        AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                  ("eth%d Tx: length %d too long.  mtu=%d, trailer=%d\n",\r
-+                   dev_sw_state->enetUnit, length, mtu, PHY_TRAILER_SIZE));\r
-+\r
-+        MAC_state->stats.tx_errors++;\r
-+        MAC_state->stats.tx_aborted_errors++;\r
-+\r
-+        goto dropFrame;\r
-+    }\r
-+\r
-+    /* Reap any old, completed Tx descriptors */\r
-+    ae531x_TxReap(MAC_state);\r
-+\r
-+    txDesc = MACInfo->txQueue.curDescAddr;\r
-+    if (txDesc == MACInfo->txQueue.reapDescAddr) {\r
-+        int i;\r
-+\r
-+        AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                  ("eth%d Tx: cannot get txDesc\n",\r
-+                   dev_sw_state->enetUnit));\r
-+\r
-+        MAC_state->stats.tx_dropped++;\r
-+        MAC_state->stats.tx_fifo_errors++;\r
-+\r
-+        /*\r
-+         * Stop transmit queues for any ethernet devices\r
-+         * associated with this MAC.\r
-+         */\r
-+        for (i=0; i<AE531X_DEV_PER_MAC; i++) {\r
-+            if (MAC_state->dev_sw_state[i]->dev)\r
-+                netif_stop_queue(MAC_state->dev_sw_state[i]->dev);\r
-+        }\r
-+        goto dropFrame;\r
-+    }\r
-+\r
-+#ifdef CONFIG_VENETDEV\r
-+    {\r
-+        struct sk_buff *newskb;\r
-+\r
-+      if (skb_cloned(skb) || (skb_tailroom(skb) < PHY_TRAILER_SIZE)) {\r
-+#ifdef DEBUG_VENETDEV\r
-+              if (skb_cloned(skb)) {\r
-+                      cloned_counter++;\r
-+                      if (skb_tailroom(skb) < PHY_TRAILER_SIZE) {\r
-+                              both_counter++;\r
-+                      }\r
-+              } else {\r
-+                      expand_counter++;\r
-+              }\r
-+#endif\r
-+              newskb = skb_copy_expand(skb, 0, PHY_TRAILER_SIZE, GFP_ATOMIC);\r
-+              if (newskb == NULL) {\r
-+                  goto dropFrame;\r
-+              }\r
-+\r
-+              dev_kfree_skb(skb);\r
-+              skb = newskb;\r
-+      }\r
-+\r
-+        phySetDestinationPort(skb->data, length, dev_sw_state->isLAN);\r
-+        skb_put(skb, PHY_TRAILER_SIZE);\r
-+        length += PHY_TRAILER_SIZE;\r
-+    }\r
-+#endif\r
-+\r
-+    /* We won't fail now; so consume this descriptor */\r
-+    AE531X_CONSUME_DESC((&MACInfo->txQueue));\r
-+\r
-+    /* Update the descriptor */\r
-+    buf = virt_to_bus(skb->data);\r
-+    A_DATA_CACHE_FLUSH(skb->data, skb->len);\r
-+    AE531X_DESC_BUFPTR_SET(txDesc, buf);\r
-+    AE531X_DESC_SWPTR_SET(txDesc, skb);\r
-+    ctrlen = AE531X_DESC_CTRLEN_GET(txDesc);\r
-+    ctrlen = (ctrlen & (DescEndOfRing)) |\r
-+                            DescTxFirst |\r
-+                             DescTxLast |\r
-+                        DescTxIntEnable;\r
-+\r
-+    ctrlen |= ((length << DescSize1Shift) & DescSize1Mask);\r
-+\r
-+    AE531X_DESC_CTRLEN_SET(txDesc, ctrlen);\r
-+    AE531X_DESC_STATUS_SET(txDesc, DescOwnByDma);\r
-+\r
-+    AE531X_PRINT(AE531X_DEBUG_TX,\r
-+              ("eth%d Tx: Desc=0x%8.8x, L=0x%8.8x, D=0x%8.8x, d=0x%8.8x, length=0x%8.8x\n",\r
-+               dev_sw_state->enetUnit,\r
-+               (UINT32)txDesc,\r
-+               AE531X_DESC_CTRLEN_GET(txDesc),\r
-+               buf,\r
-+               AE531X_DESC_LNKBUF_GET(txDesc),\r
-+               length));\r
-+\r
-+    /* Must not use txDesc after this point */\r
-+    A_DATA_CACHE_FLUSH_INVAL(txDesc, AE531X_DESC_SIZE);\r
-+\r
-+    /* Alert DMA engine to resume Tx */\r
-+    ae531x_WriteDmaReg(MACInfo, DmaTxPollDemand, 0);\r
-+    sysWbFlush();\r
-+\r
-+    MAC_state->stats.tx_packets++;\r
-+    MAC_state->stats.tx_bytes += length;\r
-+\r
-+    /* Tell upper layers to keep it coming */\r
-+    dev->trans_start = jiffies;\r
-+\r
-+    LEAVE();\r
-+    return 0;\r
-+\r
-+dropFrame:\r
-+    dev_kfree_skb(skb);\r
-+\r
-+    LEAVE();\r
-+    return 0;\r
-+}\r
-+\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_MAC_tx_timeout handles transmit timeouts\r
-+*/\r
-+static void\r
-+ae531x_MAC_tx_timeout(struct net_device *dev)\r
-+{\r
-+    ae531x_dev_sw_state_t *dev_sw_state;\r
-+    ae531x_MAC_state_t *MAC_state;\r
-+    ae531x_MAC_t *MACInfo;\r
-+\r
-+    ARRIVE();\r
-+\r
-+    dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
-+    MAC_state = dev_sw_state->MAC_state;\r
-+    MACInfo = &MAC_state->MACInfo;\r
-+\r
-+    AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+             ("enet%d: Tx timeout\n", dev_sw_state->enetUnit));\r
-+\r
-+    ae531x_restart(MACInfo);\r
-+\r
-+    LEAVE();\r
-+}\r
-+\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_MAC_do_ioctl is a placeholder for future ioctls.\r
-+*/\r
-+static int\r
-+ae531x_MAC_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)\r
-+{\r
-+        int rv;\r
-+        ae531x_MAC_t *MACInfo;\r
-+        struct ioctl_data {\r
-+                u32 unit;\r
-+                u32 addr;\r
-+                u32 data;\r
-+        } *req;\r
-+        ae531x_dev_sw_state_t *dev_sw_state;\r
-+        ae531x_MAC_state_t *MAC_state;\r
-+\r
-+        ARRIVE();\r
-+\r
-+        dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
-+        MAC_state = dev_sw_state->MAC_state;\r
-+        MACInfo = &MAC_state->MACInfo;\r
-+\r
-+        req = (struct ioctl_data *)ifr->ifr_data;\r
-+\r
-+        switch( cmd ) {\r
-+        default:\r
-+            AE531X_PRINT(AE531X_DEBUG_ERROR,\r
-+                     ("Unsupported ioctl: 0x%x\n", cmd));\r
-+            rv = -EOPNOTSUPP;\r
-+        }\r
-+\r
-+        LEAVE();\r
-+        return rv;\r
-+}\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_MAC_set_mac_address sets a new hardware address for the device\r
-+*/\r
-+static int\r
-+ae531x_MAC_set_mac_address(struct net_device *dev, void *addr)\r
-+{\r
-+      struct sockaddr *saddr = (struct sockaddr *)addr;\r
-+\r
-+      /* update dev struct */\r
-+      memcpy(dev->dev_addr, &saddr->sa_data[0], dev->addr_len);\r
-+\r
-+      return 0;\r
-+}\r
-+\r
-+/******************************************************************************\r
-+* macAddrGet - Given a MACInfo pointer, return a pointer to an\r
-+* array of chars that holds the corresponding MAC address.\r
-+*/\r
-+char *macAddrGet(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    // return enet_mac_address_get(MACInfo->unit);\r
-+    return ae531x_MAC_dev[MACInfo->unit]->dev_addr;\r
-+}\r
-+\r
-+static void\r
-+ae531x_MAC_setup_fntable(struct net_device *dev)\r
-+{\r
-+    /* Set a default (should be overridden by software) */\r
-+    u8 default_MAC_address[] = { 0x00, 0x03, 0x7f, 0xe0, 0x02, 0xbF };\r
-+\r
-+    ARRIVE();\r
-+\r
-+    dev->get_stats            = ae531x_MAC_get_stats;\r
-+    dev->open                 = ae531x_MAC_open;\r
-+    dev->stop                 = ae531x_MAC_stop;\r
-+    dev->hard_start_xmit      = ae531x_MAC_start_xmit;\r
-+    dev->do_ioctl             = ae531x_MAC_do_ioctl;\r
-+#ifdef AR531X_NAPI\r
-+    dev->poll                 = ae531x_MAC_poll;\r
-+    dev->weight                       = 16;\r
-+#endif\r
-+    dev->tx_timeout           = ae531x_MAC_tx_timeout;\r
-+    dev->features             = NETIF_F_HW_CSUM |\\r
-+                                 NETIF_F_HIGHDMA;\r
-+    dev->set_mac_address      = ae531x_MAC_set_mac_address;\r
-+    dev->set_multicast_list   = ae531x_MAC_set_rx_mode;\r
-+\r
-+    /* Copy default MAC address into device descriptor */\r
-+    memcpy(dev->dev_addr, default_MAC_address, dev->addr_len );\r
-+\r
-+    LEAVE();\r
-+}\r
-+\r
-+/*\r
-+ * ae531x_twisted_enet() returns 1 for chips where there is only one usable\r
-+ * MAC, and that MAC is 1.\r
-+ */\r
-+static BOOL\r
-+ae531x_twisted_enet(void)\r
-+{\r
-+    int wisoc_revision;\r
-+    int flash_bus_width;\r
-+\r
-+    wisoc_revision = (sysRegRead(AR531X_REV) & AR531X_REV_MAJ) >>\r
-+                                                             AR531X_REV_MAJ_S;\r
-+    if (wisoc_revision == AR531X_REV_MAJ_AR2313)\r
-+        return TRUE;\r
-+\r
-+    flash_bus_width = sysRegRead(AR531X_FLASHCTL0) & FLASHCTL_MWx16;\r
-+\r
-+    if (flash_bus_width == 0) {\r
-+      printk("Found AR2312-01\n");\r
-+      return TRUE;            /* AR2312-01 has 8 bit flash bus */\r
-+    } else {\r
-+      printk("Found AR2312-00\n");\r
-+      return FALSE;\r
-+    }\r
-+}\r
-+\r
-+int\r
-+ae531x_MAC_setup(void)\r
-+{\r
-+    int i;\r
-+    int next_dev;\r
-+    int rev;\r
-+    struct net_device *dev;\r
-+    ae531x_dev_sw_state_t *dev_sw_state;\r
-+    ae531x_MAC_state_t *MAC_state;\r
-+    ae531x_MAC_t *MACInfo;\r
-+\r
-+    ARRIVE();\r
-+\r
-+#if 0\r
-+    /*\r
-+     * This does not work since the AR2312 and AR5312 both have the same\r
-+     * revision information in the CPU :-(\r
-+     */\r
-+    rev = (sysRegRead(AR531X_REV) & AR531X_REV_CHIP);\r
-+\r
-+    if ((rev & AR531X_REV_MIN) == AR5312_REV_MIN_SINGLE_ENET) {\r
-+      ar531x_num_enet_macs = 1;\r
-+    } else {\r
-+      ar531x_num_enet_macs = 2;\r
-+    }\r
-+#else\r
-+    /*\r
-+     * Need to select the number of ethernet MACs based on the config\r
-+     * information (sadly)\r
-+     */\r
-+#ifdef CONFIG_AR5312\r
-+    ar531x_num_enet_macs = 2;\r
-+#else\r
-+    ar531x_num_enet_macs = 1;\r
-+#endif\r
-+#endif\r
-+\r
-+    next_dev = 0;\r
-+    for (i=0; i<ar531x_num_enet_macs; i++) {\r
-+\r
-+        dev = ae531x_MAC_dev[next_dev] =\r
-+            init_etherdev(NULL, sizeof(ae531x_dev_sw_state_t));\r
-+\r
-+        if (dev == NULL) {\r
-+            LEAVE();\r
-+            return -1;\r
-+        }\r
-+\r
-+        ae531x_MAC_setup_fntable(dev);\r
-+\r
-+        dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
-+        dev_sw_state->enetUnit = next_dev;\r
-+        dev_sw_state->unit_on_MAC = 0;\r
-+        MAC_state = &per_MAC_info[i];\r
-+        dev_sw_state->MAC_state = MAC_state;\r
-+        MAC_state->dev_sw_state[AE531X_LAN_PORT] = dev_sw_state;\r
-+        MAC_state->primary_dev = -1;\r
-+\r
-+        next_dev++;\r
-+\r
-+#ifdef CONFIG_VENETDEV\r
-+        {\r
-+            ae531x_dev_sw_state_t *lan_dev_sw_state;\r
-+\r
-+            lan_dev_sw_state = dev_sw_state;\r
-+    \r
-+            dev = ae531x_MAC_dev[next_dev] =\r
-+                init_etherdev(NULL, sizeof(ae531x_dev_sw_state_t));\r
-+\r
-+            if (dev == NULL) {\r
-+                LEAVE();\r
-+                return -1;\r
-+            }\r
-+    \r
-+            ae531x_MAC_setup_fntable(dev);\r
-+    \r
-+            dev_sw_state = (ae531x_dev_sw_state_t *)dev->priv;\r
-+            dev_sw_state->enetUnit = next_dev;\r
-+            dev_sw_state->unit_on_MAC = 1;\r
-+            dev_sw_state->MAC_state = MAC_state;\r
-+            MAC_state->dev_sw_state[AE531X_WAN_PORT] = dev_sw_state;\r
-+            lan_dev_sw_state->isLAN = TRUE; /* enet0 is LAN */\r
-+            dev_sw_state->isLAN = FALSE ;     /* enet1 is WAN */\r
-+\r
-+            next_dev++;\r
-+        }\r
-+#endif\r
-+\r
-+        /* Initialize per-MAC information */\r
-+        MACInfo = &MAC_state->MACInfo;\r
-+        MACInfo->unit = i;\r
-+\r
-+      if (ar531x_num_enet_macs == 1) {\r
-+          if (ae531x_twisted_enet()) {\r
-+                MACInfo->macBase =\r
-+                      (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_MAC_OFFSET);\r
-+                MACInfo->dmaBase =\r
-+                      (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_DMA_OFFSET);\r
-+                MACInfo->phyBase =\r
-+                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET);\r
-+                MAC_state->irq = AR531X_IRQ_ENET1_INTRS;\r
-+          } else {\r
-+                MACInfo->macBase =\r
-+                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_MAC_OFFSET);\r
-+                MACInfo->dmaBase =\r
-+                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_DMA_OFFSET);\r
-+                MACInfo->phyBase =\r
-+                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET);\r
-+                MAC_state->irq = AR531X_IRQ_ENET0_INTRS;\r
-+          }\r
-+      } else {\r
-+            if (MACInfo->unit == 0) {\r
-+                MACInfo->macBase =\r
-+                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_MAC_OFFSET);\r
-+                MACInfo->dmaBase =\r
-+                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_DMA_OFFSET);\r
-+                MACInfo->phyBase =\r
-+                      (u32)(PHYS_TO_K1(AR531X_ENET0)+AE531X_PHY_OFFSET);\r
-+                MAC_state->irq = AR531X_IRQ_ENET0_INTRS;\r
-+            } else {\r
-+                MACInfo->macBase =\r
-+                      (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_MAC_OFFSET);\r
-+                MACInfo->dmaBase =\r
-+                      (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_DMA_OFFSET);\r
-+                MACInfo->phyBase =\r
-+                      (u32)(PHYS_TO_K1(AR531X_ENET1)+AE531X_PHY_OFFSET);\r
-+                MAC_state->irq = AR531X_IRQ_ENET1_INTRS;\r
-+            }\r
-+      }\r
-+        MACInfo->OSinfo = (void *)MAC_state;\r
-+    }\r
-+\r
-+    LEAVE();\r
-+    return 0;\r
-+}\r
-+\r
-+module_init(ae531x_MAC_setup);\r
-+\r
-diff -urN linux-2.4.32.new/arch/mips/ar531x/ae531xmac.c linux-2.4.32.new-eth/arch/mips/ar531x/ae531xmac.c\r
---- linux-2.4.32.new/arch/mips/ar531x/ae531xmac.c      1970-01-01 01:00:00.000000000 +0100\r
-+++ linux-2.4.32.new-eth/arch/mips/ar531x/ae531xmac.c  2005-12-25 11:54:20.771271672 +0000\r
-@@ -0,0 +1,942 @@\r
-+/*\r
-+ * This file is subject to the terms and conditions of the GNU General Public\r
-+ * License.  See the file "COPYING" in the main directory of this archive\r
-+ * for more details.\r
-+ *\r
-+ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
-+ */\r
-+\r
-+\r
-+/*\r
-+ * Ethernet driver for Atheros' ae531x ethernet MAC.\r
-+ */\r
-+\r
-+#if linux\r
-+#include <linux/config.h>\r
-+#include <linux/types.h>\r
-+#include <linux/delay.h>\r
-+#include <linux/netdevice.h>\r
-+#include <linux/etherdevice.h>\r
-+#include <linux/init.h>\r
-+#include <asm/io.h>\r
-+\r
-+#include "ar531xlnx.h"\r
-+#endif /* linux */\r
-+\r
-+#include "ae531xreg.h"\r
-+#include "ae531xmac.h"\r
-+\r
-+int ae531x_MAC_debug = AE531X_DEBUG_ERROR;\r
-+\r
-+/*\r
-+ * These externs are for functions that this layer relies on\r
-+ * that have OS-dependent implementations.\r
-+ */\r
-+extern UINT8 *macAddrGet(ae531x_MAC_t *MACInfo);\r
-+\r
-+/* Forward references to local functions */\r
-+static void ae531x_QueueDestroy(AE531X_QUEUE *q);\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_ReadMacReg - read AE MAC register\r
-+*\r
-+* RETURNS: register value\r
-+*/\r
-+UINT32\r
-+ae531x_ReadMacReg(ae531x_MAC_t *MACInfo, UINT32 reg)\r
-+{\r
-+    UINT32 addr = MACInfo->macBase+reg;\r
-+    UINT32 data;\r
-+\r
-+    data = RegRead(addr);\r
-+    return data;\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_WriteMacReg - write AE MAC register\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_WriteMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data)\r
-+{\r
-+    UINT32 addr = MACInfo->macBase+reg;\r
-+\r
-+    RegWrite(data, addr);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_SetMacReg - set bits in AE MAC register\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_SetMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val)\r
-+{\r
-+    UINT32 addr = MACInfo->macBase+reg;\r
-+    UINT32 data = RegRead(addr);\r
-+\r
-+    data |= val;\r
-+    RegWrite(data, addr);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_ClearMacReg - clear bits in AE MAC register\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_ClearMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val)\r
-+{\r
-+    UINT32 addr = MACInfo->macBase+reg;\r
-+    UINT32 data = RegRead(addr);\r
-+\r
-+    data &= ~val;\r
-+    RegWrite(data, addr);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_ReadDmaReg - read AE DMA register\r
-+*\r
-+* RETURNS: register value\r
-+*/\r
-+UINT32\r
-+ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg)\r
-+{\r
-+    UINT32 addr = MACInfo->dmaBase+reg;\r
-+    UINT32 data = RegRead(addr);\r
-+\r
-+    return data;\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_WriteDmaReg - write AE DMA register\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data)\r
-+{\r
-+    UINT32 addr = MACInfo->dmaBase+reg;\r
-+\r
-+    RegWrite(data, addr);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+ *\r
-+ * ae531x_AckIntr - clear interrupt bits in the status register.\r
-+ * Note: Interrupt bits are *cleared* by writing a 1.\r
-+ */\r
-+void\r
-+ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 data)\r
-+{\r
-+      ae531x_WriteDmaReg(MACInfo, DmaStatus, data);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_SetDmaReg - set bits in an AE DMA register\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val)\r
-+{\r
-+    UINT32 addr = MACInfo->dmaBase+reg;\r
-+    UINT32 data = RegRead(addr);\r
-+\r
-+    data |= val;\r
-+    RegWrite(data, addr);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_ClearDmaReg - clear bits in an AE DMA register\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val)\r
-+{\r
-+    UINT32 addr = MACInfo->dmaBase+reg;\r
-+    UINT32 data = RegRead(addr);\r
-+\r
-+    data &= ~val;\r
-+    RegWrite(data, addr);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_ReadMiiReg - read PHY registers via AE MAC Mii addr/data registers\r
-+*\r
-+* RETURNS: register value\r
-+*/\r
-+UINT32\r
-+ae531x_ReadMiiReg(UINT32 phyBase, UINT32 reg)\r
-+{\r
-+    UINT32 data;\r
-+    UINT32 addr = phyBase+reg;\r
-+\r
-+    data = RegRead(addr);\r
-+    return data;\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_WriteMiiReg - write PHY registers via AE MAC Mii addr/data registers\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_WriteMiiReg(UINT32 phyBase, UINT32 reg, UINT32 data)\r
-+{\r
-+    UINT32 addr = phyBase+reg;\r
-+\r
-+    RegWrite(data, addr);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_MiiRead - read AE Mii register\r
-+*\r
-+* RETURNS: register value\r
-+*/\r
-+UINT16\r
-+ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg)\r
-+{\r
-+    UINT32 addr;\r
-+    UINT16 data;\r
-+\r
-+    addr = ((phyAddr << MiiDevShift) & MiiDevMask) | ((reg << MiiRegShift) & MiiRegMask);\r
-+\r
-+    ae531x_WriteMiiReg(phyBase, MacMiiAddr, addr );\r
-+    do {\r
-+        /* nop */\r
-+    } while ((ae531x_ReadMiiReg(phyBase, MacMiiAddr ) & MiiBusy) == MiiBusy);\r
-+\r
-+    data = ae531x_ReadMiiReg(phyBase, MacMiiData) & 0xFFFF;\r
-+\r
-+    return data;\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_MiiWrite - write AE Mii register\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, UINT16 data)\r
-+{\r
-+    UINT32 addr;\r
-+\r
-+    ae531x_WriteMiiReg(phyBase, MacMiiData, data );\r
-+\r
-+    addr = ((phyAddr << MiiDevShift) & MiiDevMask) |\r
-+        ((reg << MiiRegShift) & MiiRegMask) | MiiWrite;\r
-+    ae531x_WriteMiiReg(phyBase, MacMiiAddr, addr );\r
-+\r
-+    do {\r
-+        /* nop */\r
-+    } while ((ae531x_ReadMiiReg(phyBase, MacMiiAddr ) & MiiBusy) == MiiBusy);\r
-+}\r
-+\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_BeginResetMode - enter a special "reset mode" in which\r
-+*    -no interrupts are expected from the device\r
-+*    -the device will not transmit nor receive\r
-+*    -attempts to send or receive will return with an error and\r
-+*    -the device will be reset at the next convenient opportunity.\r
-+*/\r
-+void\r
-+ae531x_BeginResetMode(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    /* Set the reset flag */\r
-+    MACInfo->aeProcessRst = 1;\r
-+}\r
-+\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_EndResetMode - exit the special "reset mode" entered\r
-+* earlier via a call to ae531x_BeginResetMode.\r
-+*/\r
-+void\r
-+ae531x_EndResetMode(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    MACInfo->aeProcessRst = 0;\r
-+}\r
-+\r
-+\r
-+/*******************************************************************************\r
-+* ae531x_IsInResetMode - determine whether or not the device is\r
-+* currently in "reset mode" (i.e. that a device reset is pending)\r
-+*/\r
-+BOOL\r
-+ae531x_IsInResetMode(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    return MACInfo->aeProcessRst;\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_DmaRxStart - Start Rx\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+static void\r
-+ae531x_DmaRxStart(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    ae531x_SetDmaReg(MACInfo, DmaControl, DmaRxStart);\r
-+    sysWbFlush();\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_DmaRxStop - Stop Rx\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_DmaRxStop(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    ae531x_ClearDmaReg(MACInfo, DmaControl, DmaRxStart);\r
-+    sysWbFlush();\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_DmaTxStart - Start Tx\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_DmaTxStart(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    ae531x_SetDmaReg(MACInfo, DmaControl, DmaTxStart);\r
-+    sysWbFlush();\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_DmaTxStop - Stop Tx\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_DmaTxStop(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    ae531x_ClearDmaReg(MACInfo, DmaControl, DmaTxStart);\r
-+    sysWbFlush();\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_DmaIntEnable - Enable DMA interrupts\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntEnable);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_DmaIntDisable - Disable DMA interrupts\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_DmaIntClear - Clear DMA interrupts\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+static void\r
-+ae531x_DmaIntClear(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    /* clear all interrupt requests */\r
-+    ae531x_WriteDmaReg(MACInfo, DmaStatus,\r
-+                      ae531x_ReadDmaReg(MACInfo, DmaStatus));  \r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+* Initialize generic queue data\r
-+*/\r
-+void\r
-+ae531x_QueueInit(AE531X_QUEUE *q, char *pMem, int count)\r
-+{\r
-+    ARRIVE();\r
-+    q->firstDescAddr = pMem;\r
-+    q->lastDescAddr = (VIRT_ADDR)((UINT32)q->firstDescAddr +\r
-+                                  (count - 1) * AE531X_QUEUE_ELE_SIZE);\r
-+    q->curDescAddr = q->firstDescAddr;\r
-+    q->count = count;\r
-+    LEAVE();\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+* ae531x_TxQueueCreate - create a circular queue of descriptors for Transmit\r
-+*/\r
-+static int\r
-+ae531x_TxQueueCreate(ae531x_MAC_t *MACInfo,\r
-+                  AE531X_QUEUE *q,\r
-+                  char *pMem,\r
-+                  int count)\r
-+{\r
-+    int         i;\r
-+    VIRT_ADDR   descAddr;\r
-+\r
-+    ARRIVE();\r
-+\r
-+    ae531x_QueueInit(q, pMem, count);\r
-+    q->reapDescAddr = q->lastDescAddr;\r
-+\r
-+    /* Initialize Tx buffer descriptors.  */\r
-+    for (i=0, descAddr=q->firstDescAddr;\r
-+         i<count;\r
-+         i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE))\r
-+    {\r
-+        /* Update the size, BUFPTR, and SWPTR fields */\r
-+\r
-+        AE531X_DESC_STATUS_SET(descAddr, 0);\r
-+        AE531X_DESC_CTRLEN_SET(descAddr, 0);\r
-+\r
-+        AE531X_DESC_BUFPTR_SET(descAddr, (UINT32)0);\r
-+        AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0);\r
-+        AE531X_DESC_SWPTR_SET(descAddr, (void *)0);\r
-+    } /* for each desc */\r
-+\r
-+    /* Make the queue circular */\r
-+    AE531X_DESC_CTRLEN_SET(q->lastDescAddr,\r
-+                       DescEndOfRing|AE531X_DESC_CTRLEN_GET(q->lastDescAddr));\r
-+\r
-+    AE531X_PRINT(AE531X_DEBUG_RESET,\r
-+            ("ethmac%d Txbuf begin = %x, end = %x\n",\r
-+            MACInfo->unit,\r
-+            (UINT32)q->firstDescAddr,\r
-+            (UINT32)q->lastDescAddr));\r
-+\r
-+    LEAVE();\r
-+    return 0;\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+* ae531x_RxQueueCreate - create a circular queue of Rx descriptors\r
-+*/\r
-+int\r
-+ae531x_RxQueueCreate(ae531x_MAC_t *MACInfo,\r
-+                  AE531X_QUEUE *q,\r
-+                  char *pMem,\r
-+                  int count)\r
-+{\r
-+    int               i;\r
-+    VIRT_ADDR         descAddr;\r
-+\r
-+    ARRIVE();\r
-+\r
-+    ae531x_QueueInit(q, pMem, count);\r
-+    q->reapDescAddr = NULL;\r
-+\r
-+\r
-+    /* Initialize Rx buffer descriptors */\r
-+    for (i=0, descAddr=q->firstDescAddr;\r
-+         i<count;\r
-+         i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE))\r
-+    {\r
-+        void *swptr;\r
-+        char *rxBuffer;\r
-+        int  rxBufferSize;\r
-+\r
-+        swptr = ae531x_rxbuf_alloc(MACInfo, &rxBuffer, &rxBufferSize);\r
-+        if (swptr == NULL) {\r
-+                AE531X_PRINT(AE531X_DEBUG_RESET,\r
-+                          ("ethmac%d RX queue: ae531x_rxbuf_alloc failed\n",\r
-+                           MACInfo->unit));\r
-+                ae531x_QueueDestroy(q);\r
-+                return -1;\r
-+        }\r
-+        AE531X_DESC_SWPTR_SET(descAddr, swptr);\r
-+\r
-+        AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma);\r
-+        AE531X_DESC_CTRLEN_SET(descAddr, rxBufferSize);\r
-+        AE531X_DESC_BUFPTR_SET(descAddr, virt_to_bus(rxBuffer));\r
-+        AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0);\r
-+    } /* for each desc */\r
-+\r
-+    /* Make the queue circular */\r
-+    AE531X_DESC_CTRLEN_SET(q->lastDescAddr,\r
-+                       DescEndOfRing|AE531X_DESC_CTRLEN_GET(q->lastDescAddr));\r
-+\r
-+    AE531X_PRINT(AE531X_DEBUG_RESET,\r
-+              ("ethmac%d Rxbuf begin = %x, end = %x\n",\r
-+              MACInfo->unit,\r
-+              (UINT32)q->firstDescAddr,\r
-+              (UINT32)q->lastDescAddr));\r
-+\r
-+    LEAVE();\r
-+    return 0;\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+* ae531x_QueueDestroy -- Free all buffers and descriptors associated \r
-+* with a queue.\r
-+*/\r
-+static void\r
-+ae531x_QueueDestroy(AE531X_QUEUE *q)\r
-+{\r
-+    int i;\r
-+    int count;\r
-+    VIRT_ADDR    descAddr;\r
-+\r
-+    ARRIVE();\r
-+\r
-+    count = q->count;\r
-+\r
-+    for (i=0, descAddr=q->firstDescAddr;\r
-+         i<count;\r
-+         i++, descAddr=(VIRT_ADDR)((UINT32)descAddr + AE531X_QUEUE_ELE_SIZE)) {\r
-+\r
-+        AE531X_DESC_STATUS_SET(descAddr, 0);\r
-+        AE531X_DESC_CTRLEN_SET(descAddr, 0);\r
-+        AE531X_DESC_BUFPTR_SET(descAddr, (UINT32)0);\r
-+        AE531X_DESC_LNKBUF_SET(descAddr, (UINT32)0);\r
-+\r
-+        ae531x_swptr_free(descAddr); /* Free OS-specific software pointer */\r
-+    }\r
-+\r
-+    LEAVE();\r
-+}\r
-+\r
-+static void\r
-+ae531x_TxQueueDestroy(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    ae531x_QueueDestroy(&MACInfo->txQueue);\r
-+}\r
-+\r
-+static void\r
-+ae531x_RxQueueDestroy(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    ae531x_QueueDestroy(&MACInfo->rxQueue);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+* ae531x_AllocateQueues - Allocate receive and transmit queues\r
-+*/\r
-+int\r
-+ae531x_AllocateQueues(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    size_t QMemSize;\r
-+    char *pTxBuf = NULL;\r
-+    char *pRxBuf = NULL;\r
-+\r
-+    ARRIVE();\r
-+\r
-+    MACInfo->txDescCount = AE531X_TX_DESC_COUNT_DEFAULT;\r
-+    QMemSize = AE531X_QUEUE_ELE_SIZE * MACInfo->txDescCount;\r
-+    pTxBuf = MALLOC(QMemSize);\r
-+    if (pTxBuf == NULL) {\r
-+        AE531X_PRINT(AE531X_DEBUG_RESET,\r
-+                  ("ethmac%d Failed to allocate TX queue\n", MACInfo->unit));\r
-+        goto AllocQFail;\r
-+    }\r
-+\r
-+    if (ae531x_TxQueueCreate(MACInfo, &MACInfo->txQueue, pTxBuf,\r
-+                          MACInfo->txDescCount) < 0)\r
-+    {\r
-+        AE531X_PRINT(AE531X_DEBUG_RESET,\r
-+                ("ethmac%d Failed to create TX queue\n", MACInfo->unit));\r
-+        goto AllocQFail;\r
-+    }\r
-+\r
-+    MACInfo->rxDescCount = AE531X_RX_DESC_COUNT_DEFAULT;\r
-+    QMemSize = AE531X_QUEUE_ELE_SIZE * MACInfo->rxDescCount;\r
-+    pRxBuf = MALLOC(QMemSize);\r
-+    if (pRxBuf == NULL) {\r
-+        AE531X_PRINT(AE531X_DEBUG_RESET,\r
-+                  ("ethmac%d Failed to allocate RX queue\n", MACInfo->unit));\r
-+        goto AllocQFail;\r
-+    }\r
-+\r
-+    if (ae531x_RxQueueCreate(MACInfo, &MACInfo->rxQueue, pRxBuf,\r
-+                          MACInfo->rxDescCount) < 0)\r
-+    {\r
-+        AE531X_PRINT(AE531X_DEBUG_RESET,\r
-+                ("ethmac%d Failed to create RX queue\n", MACInfo->unit));\r
-+        goto AllocQFail;\r
-+    }\r
-+\r
-+    AE531X_PRINT(AE531X_DEBUG_RESET,\r
-+            ("ethmac%d Memory setup complete.\n", MACInfo->unit));\r
-+\r
-+    LEAVE();\r
-+    return 0;\r
-+\r
-+AllocQFail:\r
-+    MACInfo->txDescCount = 0; /* sanity */\r
-+    MACInfo->rxDescCount = 0; /* sanity */\r
-+\r
-+    if (pTxBuf) {\r
-+        FREE(pTxBuf);\r
-+    }\r
-+    if (pRxBuf) {\r
-+        FREE(pRxBuf);\r
-+    }\r
-+    \r
-+    LEAVE();\r
-+    return -1;\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_FreeQueues - Free Transmit & Receive queues\r
-+*/\r
-+void\r
-+ae531x_FreeQueues(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    ae531x_TxQueueDestroy(MACInfo);\r
-+    FREE(MACInfo->txQueue.firstDescAddr);\r
-+\r
-+    ae531x_RxQueueDestroy(MACInfo);\r
-+    FREE(MACInfo->rxQueue.firstDescAddr);\r
-+}\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_DmaReset - Reset DMA and TLI controllers\r
-+*\r
-+* RETURNS: N/A\r
-+*/\r
-+void\r
-+ae531x_DmaReset(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    int        i;\r
-+    UINT32     descAddr;\r
-+\r
-+    ARRIVE();\r
-+\r
-+    /* Disable device interrupts prior to any errors during stop */\r
-+    intDisable(MACInfo->ilevel);\r
-+\r
-+    /* Disable MAC rx and tx */\r
-+    ae531x_ClearMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable));\r
-+\r
-+    /* Reset dma controller */\r
-+    ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaResetOn);\r
-+\r
-+    /* Delay 2 usec */\r
-+    sysUDelay(2);\r
-+\r
-+    /* Flush the rx queue */\r
-+    descAddr = (UINT32)MACInfo->rxQueue.firstDescAddr;\r
-+    MACInfo->rxQueue.curDescAddr = MACInfo->rxQueue.firstDescAddr;\r
-+    for (i=0;\r
-+         i<(MACInfo->rxDescCount);\r
-+         i++, descAddr += AE531X_QUEUE_ELE_SIZE) {\r
-+            AE531X_DESC_STATUS_SET(descAddr, DescOwnByDma);\r
-+    }\r
-+\r
-+    /* Flush the tx queue */\r
-+    descAddr = (UINT32)MACInfo->txQueue.firstDescAddr;\r
-+    MACInfo->txQueue.curDescAddr = MACInfo->txQueue.firstDescAddr;\r
-+    MACInfo->txQueue.reapDescAddr = MACInfo->txQueue.lastDescAddr;\r
-+    for (i=0;\r
-+         i<(MACInfo->txDescCount);\r
-+         i++, descAddr += AE531X_QUEUE_ELE_SIZE) {\r
-+            AE531X_DESC_STATUS_SET (descAddr, 0);\r
-+    }\r
-+\r
-+    /* Set init register values  */\r
-+    ae531x_WriteDmaReg(MACInfo, DmaBusMode, DmaBusModeInit);\r
-+\r
-+    /* Install the first Tx and Rx queues on the device */\r
-+    ae531x_WriteDmaReg(MACInfo, DmaRxBaseAddr,\r
-+                      (UINT32)MACInfo->rxQueue.firstDescAddr);\r
-+    ae531x_WriteDmaReg(MACInfo, DmaTxBaseAddr,\r
-+                      (UINT32)MACInfo->txQueue.firstDescAddr);\r
-+\r
-+    ae531x_WriteDmaReg(MACInfo, DmaControl, DmaStoreAndForward);\r
-+\r
-+    ae531x_WriteDmaReg(MACInfo, DmaIntrEnb, DmaIntDisable);\r
-+\r
-+    AE531X_PRINT(AE531X_DEBUG_RESET,\r
-+              ("ethmac%d: DMA RESET!\n", MACInfo->unit));\r
-+\r
-+    /* Turn on device interrupts -- enable most errors */\r
-+    ae531x_DmaIntClear(MACInfo);    /* clear interrupt requests  */\r
-+    ae531x_DmaIntEnable(MACInfo);   /* enable interrupts */\r
-+    /* Enable receive interrupts separately (they are not part\r
-+     * of the main group since they are enabled & disabled by\r
-+     * the polling routine.\r
-+     */\r
-+    ae531x_SetDmaReg(MACInfo, DmaIntrEnb,\r
-+              (DmaIntRxNoBuffer | DmaIntRxCompleted));\r
-+\r
-+    ae531x_EndResetMode(MACInfo);\r
-+\r
-+    intEnable(MACInfo->ilevel);\r
-+\r
-+    LEAVE();\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae531x_MACAddressSet - Set the ethernet address\r
-+*\r
-+* Sets the ethernet address according to settings in flash.\r
-+*\r
-+* RETURNS: void\r
-+*/\r
-+static void\r
-+ae531x_MACAddressSet(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    unsigned int    data;\r
-+    UINT8 *macAddr;\r
-+\r
-+    ARRIVE();\r
-+        \r
-+    macAddr = macAddrGet(MACInfo);\r
-+\r
-+    /* set our MAC address  */\r
-+    data = (macAddr[5]<<8) | macAddr[4];\r
-+    ae531x_WriteMacReg(MACInfo, MacAddrHigh, data );\r
-+\r
-+    data = (macAddr[3]<<24) | (macAddr[2]<<16) | (macAddr[1]<<8) | macAddr[0];\r
-+    ae531x_WriteMacReg(MACInfo, MacAddrLow, data );\r
-+\r
-+    AE531X_PRINT(AE531X_DEBUG_RESET,\r
-+              ("ethmac%d Verify MAC address %8.8X %8.8X \n",\r
-+               MACInfo->unit,\r
-+               ae531x_ReadMacReg(MACInfo, MacAddrLow),\r
-+               ae531x_ReadMacReg(MACInfo, MacAddrHigh)));\r
-+\r
-+    AE531X_PRINT(AE531X_DEBUG_RESET,\r
-+              ("  sb = %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",\r
-+               0xff&macAddr[0],\r
-+               0xff&macAddr[1],\r
-+               0xff&macAddr[2],\r
-+               0xff&macAddr[3],\r
-+               0xff&macAddr[4],\r
-+               0xff&macAddr[5]));\r
-+    LEAVE();\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* ae_SetMACFromPhy - read Phy settings and update Mac\r
-+*                    with current duplex and speed.\r
-+*\r
-+* RETURNS:\r
-+*/\r
-+static void\r
-+ae531x_SetMACFromPhy(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    UINT32  macCtl;\r
-+    BOOL    fullDuplex;\r
-+\r
-+    ARRIVE();\r
-+\r
-+    /* Get duplex mode from Phy */\r
-+    fullDuplex = phyIsFullDuplex(MACInfo->unit);\r
-+\r
-+    /* Flag is set for full duplex mode, else cleared */\r
-+    macCtl = ae531x_ReadMacReg(MACInfo, MacControl);\r
-+\r
-+    if (fullDuplex) {\r
-+        /* set values of control registers */\r
-+        macCtl &= ~MacDisableRxOwn;\r
-+        macCtl |= MacFullDuplex;\r
-+        ae531x_WriteMacReg(MACInfo, MacControl, macCtl);\r
-+        ae531x_WriteMacReg(MACInfo, MacFlowControl, MacFlowControlInitFdx);\r
-+#if 0\r
-+      printk ("[Full Duplex] CTRL=%#x FLOW=%#x\n", macCtl,\r
-+              MacFlowControlInitFdx);\r
-+#endif\r
-+    } else {\r
-+        /* set values of control registers */\r
-+        ae531x_WriteMacReg(MACInfo, MacFlowControl, MacFlowControlInitHdx);\r
-+        macCtl |= MacDisableRxOwn;\r
-+        macCtl &= ~MacFullDuplex;\r
-+        ae531x_WriteMacReg(MACInfo, MacControl, macCtl);\r
-+#if 0\r
-+      printk ("[Half Duplex] CTRL=%#x FLOW=%#x\n", macCtl,\r
-+              MacFlowControlInitHdx);\r
-+#endif\r
-+    }\r
-+\r
-+    LEAVE();\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+* ae531x_MACReset -- sets MAC address and duplex.\r
-+*/\r
-+void\r
-+ae531x_MACReset(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    ae531x_MACAddressSet(MACInfo);\r
-+\r
-+    ae531x_SetMACFromPhy(MACInfo);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+* ae531x_EnableComm -- enable Transmit and Receive\r
-+*/\r
-+void\r
-+ae531x_EnableComm(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    ae531x_SetMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable));\r
-+    ae531x_DmaRxStart(MACInfo);     /* start receiver  */\r
-+    ae531x_DmaTxStart(MACInfo);     /* start transmitter */\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+* ae531x_DisableComm -- disable Transmit and Receive\r
-+*/\r
-+void\r
-+ae531x_DisableComm(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    ae531x_ClearMacReg(MACInfo, MacControl, (MacRxEnable | MacTxEnable));\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+* ae531x_reset -- Cold reset ethernet interface\r
-+*/\r
-+void\r
-+ae531x_reset(ae531x_MAC_t *MACInfo)\r
-+{\r
-+    UINT32 mask = 0;\r
-+    UINT32 regtmp;\r
-+   \r
-+    if (ar531x_num_enet_macs == 2) {\r
-+        if (MACInfo->unit == 0) {\r
-+            mask = AR531X_RESET_ENET0 | AR531X_RESET_EPHY0;\r
-+        } else {\r
-+            mask = AR531X_RESET_ENET1 | AR531X_RESET_EPHY1;\r
-+        }\r
-+    } else {\r
-+            mask = AR531X_RESET_ENET0 | AR531X_RESET_EPHY0 |\r
-+                   AR531X_RESET_ENET1 | AR531X_RESET_EPHY1;\r
-+    }\r
-+\r
-+    /* Put into reset */\r
-+    regtmp = sysRegRead(AR531X_RESET);\r
-+    sysRegWrite(AR531X_RESET, regtmp | mask);\r
-+    sysMsDelay(15);\r
-+\r
-+    /* Pull out of reset */\r
-+    regtmp = sysRegRead(AR531X_RESET);\r
-+    sysRegWrite(AR531X_RESET, regtmp & ~mask);\r
-+    sysUDelay(25);\r
-+\r
-+    /* Enable */\r
-+    if (ar531x_num_enet_macs == 2) {\r
-+        if (MACInfo->unit == 0) {\r
-+            mask = AR531X_ENABLE_ENET0;\r
-+        } else {\r
-+            mask = AR531X_ENABLE_ENET1;\r
-+        }\r
-+    } else {\r
-+            mask = AR531X_ENABLE_ENET0 | AR531X_ENABLE_ENET1;\r
-+    }\r
-+    regtmp = sysRegRead(AR531X_ENABLE);\r
-+    sysRegWrite(AR531X_ENABLE, regtmp | mask);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+* ae531x_unitLinkLost -- Called from PHY layer to notify the MAC layer\r
-+* that there are no longer any live links associated with a MAC.\r
-+*/\r
-+void\r
-+ae531x_unitLinkLost(int ethUnit)\r
-+{\r
-+    AE531X_PRINT(AE531X_DEBUG_LINK_CHANGE,\r
-+             ("enetmac%d link down\n", ethUnit));\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+* ae531x_unitLinkGained -- Called from PHY layer to notify the MAC layer\r
-+* that there are 1 or more live links associated with a MAC.\r
-+*/\r
-+void\r
-+ae531x_unitLinkGained(int ethUnit)\r
-+{\r
-+    AE531X_PRINT(AE531X_DEBUG_LINK_CHANGE,\r
-+             ("enet%d link up\n", ethUnit));\r
-+}\r
-+\r
-+/******************************************************************************\r
-+* ae531x_ethMacDefault -- Called from PHY layer to determine the default\r
-+* ethernet MAC.  On some "twisted" platforms, the only usable MAC is 1,\r
-+* while on others the usable MAC is 0.  Future boards may allow both MACs\r
-+* to be used; in this case, return -1 to indicate that there IS NO default\r
-+* MAC.\r
-+*\r
-+* Note: one some AR2312 platforms the PHY needs to be accessed through\r
-+* MAC 0, even though the MAC itself is addressed through MAC 1. Since this\r
-+* function is used by the PHY layer to determine which MAC it should use,\r
-+* the twisted case is limited to the one where the PHY is actually addressed\r
-+* through MAC 1 rather than MAC 0.\r
-+*/\r
-+int\r
-+ae531x_ethMacDefault(void)\r
-+{\r
-+    /*\r
-+     * Where there are two MACs, there is no real default\r
-+     */\r
-+    if (ar531x_num_enet_macs == 2)\r
-+        return -1;\r
-+\r
-+    /*\r
-+     * All single MAC platforms seem to address the PHY through MAC 0,\r
-+     * even when they use MAC 1 for the actual MAC functions.\r
-+     */\r
-+    return 0;\r
-+}\r
-diff -urN linux-2.4.32.new/arch/mips/ar531x/ae531xmac.h linux-2.4.32.new-eth/arch/mips/ar531x/ae531xmac.h\r
---- linux-2.4.32.new/arch/mips/ar531x/ae531xmac.h      1970-01-01 01:00:00.000000000 +0100\r
-+++ linux-2.4.32.new-eth/arch/mips/ar531x/ae531xmac.h  2005-12-25 11:54:20.819264376 +0000\r
-@@ -0,0 +1,208 @@\r
-+/*\r
-+ * This file is subject to the terms and conditions of the GNU General Public\r
-+ * License.  See the file "COPYING" in the main directory of this archive\r
-+ * for more details.\r
-+ *\r
-+ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
-+ */\r
-+\r
-+/*\r
-+ * See README to understand the decomposition of the ethernet driver.\r
-+ *\r
-+ * This file contains OS-independent pure software definitions for\r
-+ * ethernet support on the AR531X platform.\r
-+ */\r
-+\r
-+#ifndef _AE531XMAC_H_\r
-+#define _AE531XMAC_H_\r
-+\r
-+/*\r
-+ * DEBUG switches to control verbosity.\r
-+ * Just modify the value of ae531x_MAC_debug.\r
-+ */\r
-+#define AE531X_DEBUG_ALL         0xffffffff\r
-+#define AE531X_DEBUG_ERROR       0x00000001 /* Unusual conditions and Errors */\r
-+#define AE531X_DEBUG_ARRIVE      0x00000002 /* Arrive into a function */\r
-+#define AE531X_DEBUG_LEAVE       0x00000004 /* Leave a function */\r
-+#define AE531X_DEBUG_RESET       0x00000008 /* Reset */\r
-+#define AE531X_DEBUG_TX          0x00000010 /* Transmit */\r
-+#define AE531X_DEBUG_TX_REAP     0x00000020 /* Transmit Descriptor Reaping */\r
-+#define AE531X_DEBUG_RX          0x00000040 /* Receive */\r
-+#define AE531X_DEBUG_RX_STOP     0x00000080 /* Receive Early Stop */\r
-+#define AE531X_DEBUG_INT         0x00000100 /* Interrupts */\r
-+#define AE531X_DEBUG_LINK_CHANGE 0x00000200 /* PHY Link status changed */\r
-+\r
-+extern int ae531x_MAC_debug;\r
-+\r
-+extern int ar531x_num_enet_macs;\r
-+\r
-+#define AE531X_PRINT(FLG, X)                            \\r
-+{                                                   \\r
-+    if (ae531x_MAC_debug & (FLG)) {                  \\r
-+        DEBUG_PRINTF("%s#%d:%s ",                   \\r
-+                     __FILE__,                      \\r
-+                     __LINE__,                      \\r
-+                     __FUNCTION__);                 \\r
-+        DEBUG_PRINTF X;                             \\r
-+    }                                               \\r
-+}\r
-+\r
-+#define ARRIVE() AE531X_PRINT(AE531X_DEBUG_ARRIVE, ("Arrive{\n"))\r
-+#define LEAVE() AE531X_PRINT(AE531X_DEBUG_LEAVE, ("}Leave\n"))\r
-+\r
-+#define RegRead(addr) \\r
-+      (*(volatile unsigned int *)(addr))\r
-+\r
-+#define RegWrite(val,addr)    \\r
-+      ((*(volatile unsigned int *)(addr)) = (val))\r
-+\r
-+/*****************************************************************\r
-+ * Phy code is broken out into a separate layer, so that different\r
-+ * PHY hardware can easily be supported.\r
-+ *\r
-+ * These functions are provided by the PHY layer for use by the MAC layer.\r
-+ *   phySetup             -- Set phy hardware appropriately for a MAC unit\r
-+ *\r
-+ *   phyCheckStatusChange -- Look for dropped/initiated links on any\r
-+ *                           phy port associated with a MAC unit\r
-+ *\r
-+ *   phyIsSpeed100        -- Determines whether or not a PHY is up and\r
-+ *                           running at 100Mbit\r
-+ *\r
-+ *   phyIsFullDuplex      -- Determines whether or not a PHY is up and\r
-+ *                           running in Full Duplex mode\r
-+ *\r
-+ */\r
-+#ifdef CONFIG_MARVELL_ENET_PHY\r
-+/*\r
-+ * Mapping of generic phy APIs to Marvell Ethernet Switch phy functions.\r
-+ */\r
-+#include "mvPhy.h"\r
-+#define phySetup(ethUnit, phyBase)      mv_phySetup((ethUnit), (phyBase))\r
-+#define phyCheckStatusChange(ethUnit)   mv_phyCheckStatusChange(ethUnit)\r
-+#define phyIsSpeed100(ethUnit)          mv_phyIsSpeed100(ethUnit)\r
-+#define phyIsFullDuplex(ethUnit)        mv_phyIsFullDuplex(ethUnit)\r
-+\r
-+#ifdef CONFIG_VENETDEV\r
-+#define PHY_TRAILER_SIZE    MV_PHY_TRAILER_SIZE\r
-+extern int mv_phyDetermineSource(char *data, int len);\r
-+extern void mv_phySetDestinationPort(char *data, int len, int fromLAN);\r
-+#define phyDetermineSource(data, len) mv_phyDetermineSource((data), (len))\r
-+#define phySetDestinationPort(data, len, fromLAN) mv_phySetDestinationPort((data), (len), (fromLAN))\r
-+#else\r
-+#define PHY_TRAILER_SIZE    0\r
-+#endif\r
-+#endif /* CONFIG_MARVELL_ENET_PHY */\r
-+\r
-+#if defined(CONFIG_KENDIN_ENET_PHY) || defined(CONFIG_REALTEK_ENET_PHY)\r
-+/*\r
-+ * Mapping of generic phy APIs to Kendin KS8721B and RealTek RTL8201BL phys.\r
-+ */\r
-+#include "rtPhy.h"\r
-+#define phySetup(ethUnit, phyBase)      rt_phySetup((ethUnit), (phyBase))\r
-+#define phyCheckStatusChange(ethUnit)   rt_phyCheckStatusChange(ethUnit)\r
-+#define phyIsSpeed100(ethUnit)          rt_phyIsSpeed100(ethUnit)\r
-+#define phyIsFullDuplex(ethUnit)        rt_phyIsFullDuplex(ethUnit)\r
-+#endif\r
-+\r
-+#if !defined(PHY_TRAILER_SIZE)\r
-+#define PHY_TRAILER_SIZE    0\r
-+#endif\r
-+\r
-+/*****************************************************************\r
-+ * MAC-independent interface to be used by PHY code\r
-+ *\r
-+ * These functions are provided by the MAC layer for use by the PHY layer.\r
-+ */\r
-+#define phyRegRead ae531x_MiiRead\r
-+#define phyRegWrite ae531x_MiiWrite\r
-+#define phyLinkLost(ethUnit) ae531x_unitLinkLost(ethUnit)\r
-+#define phyLinkGained(ethUnit) ae531x_unitLinkGained(ethUnit)\r
-+#define phyEthMacDefault() ae531x_ethMacDefault()\r
-+\r
-+void ae531x_unitLinkLost(int unit);\r
-+void ae531x_unitLinkGained(int unit);\r
-+int ae531x_ethMacDefault(void);\r
-+\r
-+\r
-+/* RXBUFF_RESERVE enables building header on WLAN-side in place */\r
-+#define RXBUFF_RESERVE   96\r
-+#define ETH_CRC_LEN       4\r
-+\r
-+/*****************************************************************\r
-+ * Descriptor queue\r
-+ */\r
-+typedef struct ae531x_queue {\r
-+    VIRT_ADDR   firstDescAddr;  /* descriptor array address */\r
-+    VIRT_ADDR   lastDescAddr;   /* last descriptor address */\r
-+    VIRT_ADDR   curDescAddr;    /* current descriptor address */\r
-+    VIRT_ADDR   reapDescAddr;   /* current tail of tx descriptors reaped */\r
-+    UINT16      count;          /* number of elements */\r
-+} AE531X_QUEUE;\r
-+\r
-+/* Given a descriptor, return the next one in a circular list */\r
-+#define AE531X_QUEUE_ELE_NEXT_GET(q, descAddr)                          \\r
-+        ((descAddr) == (q)->lastDescAddr) ? (q)->firstDescAddr :    \\r
-+        (VIRT_ADDR)((UINT32)(descAddr) + AE531X_QUEUE_ELE_SIZE)\r
-+\r
-+/* Move the "current descriptor" forward to the next one */\r
-+#define AE531X_CONSUME_DESC(q)    \\r
-+         q->curDescAddr = AE531X_QUEUE_ELE_NEXT_GET(q, q->curDescAddr)\r
-+\r
-+/*****************************************************************\r
-+ * Per-ethernet-MAC OS-independent information\r
-+ */\r
-+typedef struct ae531x_MAC_s {\r
-+    u32             unit;          /* MAC unit ID */\r
-+    u32             macBase;       /* MAC base address */\r
-+    u32             dmaBase;       /* DMA base address */\r
-+    u32             phyBase;       /* PHY base address */\r
-+    AE531X_QUEUE    txQueue;       /* Transmit descriptor queue */\r
-+    AE531X_QUEUE    rxQueue;       /* Receive descriptor queue */\r
-+    UINT16          txDescCount;   /* Transmit descriptor count */\r
-+    UINT16          rxDescCount;   /* Receive descriptor count */\r
-+    BOOL            aeProcessRst;  /* flag to indicate reset in progress */\r
-+    BOOL            port_is_up;    /* flag to indicate port is up */\r
-+    void            *OSinfo;       /* OS-dependent data */\r
-+} ae531x_MAC_t;\r
-+\r
-+#define       AE531X_TX_DESC_COUNT_DEFAULT    64     /* Transmit descriptors */\r
-+#define AE531X_RX_DESC_COUNT_DEFAULT  64     /* Receive descriptors */\r
-+\r
-+\r
-+/*****************************************************************\r
-+ * Interfaces exported by the OS-independent MAC layer\r
-+ */\r
-+void ae531x_BeginResetMode(ae531x_MAC_t *MACInfo);\r
-+void ae531x_EndResetMode(ae531x_MAC_t *MACInfo);\r
-+BOOL ae531x_IsInResetMode(ae531x_MAC_t *MACInfo);\r
-+int ae531x_RxQueueCreate(ae531x_MAC_t *MACInfo, AE531X_QUEUE *q,\r
-+                  char *pMem, int count);\r
-+int ae531x_QueueDelete(struct ae531x_queue *q);\r
-+void ae531x_DmaReset(ae531x_MAC_t *MACInfo);\r
-+void ae531x_MACReset(ae531x_MAC_t *MACInfo);\r
-+void ae531x_EnableComm(ae531x_MAC_t *MACInfo);\r
-+void ae531x_DisableComm(ae531x_MAC_t *MACInfo);\r
-+void ae531x_reset(ae531x_MAC_t *MACInfo);\r
-+int ae531x_AllocateQueues(ae531x_MAC_t *MACInfo);\r
-+void ae531x_FreeQueues(ae531x_MAC_t *MACInfo);\r
-+void ae531x_QueueInit(AE531X_QUEUE *q, char *pMem, int count);\r
-+UINT32 ae531x_ReadMacReg(ae531x_MAC_t *MACInfo, UINT32 reg);\r
-+void ae531x_WriteMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data);\r
-+void ae531x_SetMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);\r
-+void ae531x_ClearMacReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);\r
-+void ae531x_SetDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);\r
-+void ae531x_ClearDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 val);\r
-+UINT32 ae531x_ReadDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg);\r
-+void ae531x_WriteDmaReg(ae531x_MAC_t *MACInfo, UINT32 reg, UINT32 data);\r
-+UINT32 ae531x_ReadMiiReg(UINT32 phyBase, UINT32 reg);\r
-+void ae531x_WriteMiiReg(UINT32 phyBase, UINT32 reg, UINT32 data);\r
-+UINT16 ae531x_MiiRead(UINT32 phyBase, UINT32 phyAddr, UINT8 reg);\r
-+void ae531x_MiiWrite(UINT32 phyBase, UINT32 phyAddr, UINT8 reg, UINT16 data);\r
-+void ae531x_DmaIntEnable(ae531x_MAC_t *MACInfo);\r
-+void ae531x_DmaIntDisable(ae531x_MAC_t *MACInfo);\r
-+void ae531x_AckIntr(ae531x_MAC_t *MACInfo, UINT32 val);\r
-+void *ae531x_rxbuf_alloc(ae531x_MAC_t *MACInfo, char **rxBptr, int *rxBSize);\r
-+void ae531x_swptr_free(VIRT_ADDR txDesc);\r
-+\r
-+#endif /* _AE531XMAC_H_ */\r
-diff -urN linux-2.4.32.new/arch/mips/ar531x/ae531xreg.h linux-2.4.32.new-eth/arch/mips/ar531x/ae531xreg.h\r
---- linux-2.4.32.new/arch/mips/ar531x/ae531xreg.h      1970-01-01 01:00:00.000000000 +0100\r
-+++ linux-2.4.32.new-eth/arch/mips/ar531x/ae531xreg.h  2005-12-25 11:54:20.834262096 +0000\r
-@@ -0,0 +1,437 @@\r
-+/*\r
-+ * This file is subject to the terms and conditions of the GNU General Public\r
-+ * License.  See the file "COPYING" in the main directory of this archive\r
-+ * for more details.\r
-+ *\r
-+ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
-+ */\r
-+\r
-+/*\r
-+ * See README to understand the decomposition of the ethernet driver.\r
-+ *\r
-+ * Register definitions for Atheros AR531X Ethernet MAC.\r
-+ */\r
-+\r
-+#ifndef _AE531XREG_H_\r
-+#define _AE531XREG_H_\r
-+\r
-+#define AE531X_MAC_OFFSET 0x0000\r
-+#define AE531X_PHY_OFFSET 0x0000 /* Same as MAC offset */\r
-+#define AE531X_DMA_OFFSET 0x1000\r
-+\r
-+/***********************************************************/\r
-+/* MAC110 registers, base address is BAR+AE531X_MAC_OFFSET */\r
-+/***********************************************************/\r
-+#define MacControl            0x00  /* control */\r
-+#define MacAddrHigh           0x04  /* address high */\r
-+#define MacAddrLow            0x08  /* address low */\r
-+#define MacMultiHashHigh      0x0C  /* multicast hash table high */\r
-+#define MacMultiHashLow       0x10  /* multicast hash table low */\r
-+#define MacMiiAddr            0x14  /* MII address */\r
-+#define MacMiiData            0x18  /* MII data */\r
-+#define MacFlowControl        0x1C  /* Flow control */\r
-+#define MacVlan1Tag           0x4C  /* VLAN1 tag */\r
-+#define MacVlan2Tag           0x50  /* VLAN2 tag */\r
-+\r
-+\r
-+/***************************************************************/\r
-+/* DMA engine registers, base address is BAR+AE531X_DMA_OFFSET */\r
-+/***************************************************************/\r
-+#define DmaBusMode      0x00 /* CSR0 - Bus Mode */\r
-+#define DmaTxPollDemand 0x04 /* CSR1 - Transmit Poll Demand */\r
-+#define DmaRxPollDemand 0x08 /* CSR2 - Receive Poll Demand */\r
-+#define DmaRxBaseAddr   0x0C /* CSR3 - Receive list base address */\r
-+#define DmaTxBaseAddr   0x10 /* CSR4 - Transmit list base address */\r
-+#define DmaStatus       0x14 /* CSR5 - Dma status */\r
-+#define DmaControl      0x18 /* CSR6 - Dma control */\r
-+#define DmaIntrEnb      0x1C /* CSR7 - Interrupt enable */\r
-+#define DmaOverflowCnt  0x20 /* CSR8 - Missed Frame and Buff Overflow counter */\r
-+#define DmaTxCurrAddr   0x50 /* CSR20 - Current host transmit buffer address */\r
-+#define DmaRxCurrAddr   0x54 /* CSR21 - Current host receive buffer address */\r
-+\r
-+/**********************************************************/\r
-+/* MAC Control register layout                            */\r
-+/**********************************************************/\r
-+#define MacFilterOff           0x80000000 /* Receive all incoming packets RW */\r
-+#define MacFilterOn                     0 /* Receive filtered packets only 0 */\r
-+#define MacBigEndian           0x40000000 /* Big endian mode RW */\r
-+#define MacLittleEndian                 0 /* Little endian 0 */\r
-+#define MacHeartBeatOff        0x10000000 /* Heartbeat signal qual disable RW*/\r
-+#define MacHeartBeatOn                  0 /* Heartbeat signal qual enable 0 */\r
-+#define MacSelectSrl           0x08000000 /* Select SRL port RW */\r
-+#define MacSelectMii                    0 /* Select MII port 0 */\r
-+#define MacDisableRxOwn        0x00800000 /* Disable receive own packets RW */\r
-+#define MacEnableRxOwn                  0 /* Enable receive own packets 0 */\r
-+#define MacLoopbackExt         0x00400000 /* External loopback RW */\r
-+#define MacLoopbackInt         0x00200000 /* Internal loopback */\r
-+#define MacLoopbackOff                  0 /* Normal mode 00 */\r
-+#define MacFullDuplex          0x00100000 /* Full duplex mode RW */\r
-+#define MacHalfDuplex                   0 /* Half duplex mode 0 */\r
-+#define MacMulticastFilterOff  0x00080000 /* Pass all multicast packets RW */\r
-+#define MacMulticastFilterOn            0 /* Pass filtered mcast packets 0 */\r
-+#define MacPromiscuousModeOn   0x00040000 /* Receive all valid packets RW 1 */\r
-+#define MacPromiscuousModeOff           0 /* Receive filtered packets only */\r
-+#define MacFilterInverse       0x00020000 /* Inverse filtering RW */\r
-+#define MacFilterNormal                 0 /* Normal filtering 0 */\r
-+#define MacBadFramesEnable     0x00010000 /* Pass bad frames RW */\r
-+#define MacBadFramesDisable             0 /* Do not pass bad frames 0 */\r
-+#define MacPerfectFilterOff    0x00008000 /* Hash filtering only RW */\r
-+#define MacPerfectFilterOn              0 /* Both perfect and hash filtering 0 */\r
-+#define MacHashFilterOn        0x00002000 /* perform hash filtering RW */\r
-+#define MacHashFilterOff                0 /* perfect filtering only 0 */\r
-+#define MacLateCollisionOn     0x00001000 /* Enable late collision control RW */\r
-+#define MacLateCollisionOff             0 /* Disable late collision control 0 */\r
-+#define MacBroadcastDisable    0x00000800 /* Disable reception of bcast frames RW */\r
-+#define MacBroadcastEnable              0 /* Enable broadcast frames 0 */\r
-+#define MacRetryDisable        0x00000400 /* Disable retransmission RW */\r
-+#define MacRetryEnable                  0 /* Enable retransmission 0 */\r
-+#define MacPadStripEnable      0x00000100 /* Pad stripping enable RW */\r
-+#define MacPadStripDisable              0 /* Pad stripping disable 0 */\r
-+#define MacBackoff                      0 /* Backoff Limit RW 00 */\r
-+#define MacDeferralCheckEnable 0x00000020 /* Deferral check enable RW */\r
-+#define MacDeferralCheckDisable         0 /* Deferral check disable 0 */\r
-+#define MacTxEnable            0x00000008 /* Transmitter enable RW */\r
-+#define MacTxDisable                    0 /* Transmitter disable 0 */\r
-+#define MacRxEnable            0x00000004 /* Receiver enable RW */\r
-+#define MacRxDisable                    0 /* Receiver disable 0 */\r
-+\r
-+\r
-+/**********************************************************/\r
-+/* MII address register layout                            */\r
-+/**********************************************************/\r
-+#define MiiDevMask   0x0000F800 /* MII device address */\r
-+#define MiiDevShift          11\r
-+#define MiiRegMask   0x000007C0 /* MII register */\r
-+#define MiiRegShift           6\r
-+#define MiiWrite     0x00000002 /* Write to register */\r
-+#define MiiRead               0 /* Read from register */\r
-+#define MiiBusy      0x00000001 /* MII interface is busy */\r
-+\r
-+/**********************************************************/\r
-+/* MII Data register layout                               */\r
-+/**********************************************************/\r
-+#define MiiDataMask  0x0000FFFF /* MII Data */\r
-+\r
-+/**********************************************************/\r
-+/* MAC flow control register layout                       */\r
-+/**********************************************************/\r
-+#define MacPauseTimeMask      0xFFFF0000  /* PAUSE TIME field in ctrl frame */\r
-+#define MacPauseTimeShift             15\r
-+#define MacControlFrameEnable 0x00000004  /* Enable pass ctrl frames to host */\r
-+#define MacControlFrameDisable         0  /* Do not pass ctrl frames to host */\r
-+#define MacFlowControlEnable  0x00000002  /* Enable flow control */\r
-+#define MacFlowControlDisable          0  /* Disable flow control */\r
-+#define MacSendPauseFrame     0x00000001  /* send pause frame */\r
-+\r
-+/**********************************************************/\r
-+/* DMA bus mode register layout                           */\r
-+/**********************************************************/\r
-+#define DmaRxAlign16            0x01000000 /* Force all rx buffers to align on odd hw bndry */\r
-+#define DmaBigEndianDes         0x00100000 /* Big endian data buffer descriptors RW */\r
-+#define DmaLittleEndianDesc              0 /* Little endian data descriptors */\r
-+#define DmaBurstLength32        0x00002000 /* Dma burst length 32 RW */\r
-+#define DmaBurstLength16        0x00001000 /* Dma burst length 16 */\r
-+#define DmaBurstLength8         0x00000800 /* Dma burst length 8 */\r
-+#define DmaBurstLength4         0x00000400 /* Dma burst length 4 */\r
-+#define DmaBurstLength2         0x00000200 /* Dma burst length 2 */\r
-+#define DmaBurstLength1         0x00000100 /* Dma burst length 1 */\r
-+#define DmaBurstLength0         0x00000000 /* Dma burst length 0 */\r
-+#define DmaBigEndianData        0x00000080 /* Big endian data buffers RW */\r
-+#define DmaLittleEndianData              0 /* Little endian data buffers 0 */\r
-+#define DmaDescriptorSkip16     0x00000040 /* number of dwords to skip RW */\r
-+#define DmaDescriptorSkip8      0x00000020 /* between two unchained descriptors */\r
-+#define DmaDescriptorSkip4      0x00000010\r
-+#define DmaDescriptorSkip2      0x00000008\r
-+#define DmaDescriptorSkip1      0x00000004\r
-+#define DmaDescriptorSkip0               0\r
-+#define DmaReceivePriorityOff   0x00000002 /* equal rx and tx priorities RW */\r
-+#define DmaReceivePriorityOn             0 /* Rx has prioryty over Tx 0 */\r
-+#define DmaResetOn              0x00000001 /* Reset DMA engine RW */\r
-+#define DmaResetOff                      0\r
-+\r
-+/**********************************************************/\r
-+/* DMA Status register layout                             */\r
-+/**********************************************************/\r
-+#define DmaRxAbort        0x01000000 /* receiver bus abort R 0 */\r
-+#define DmaTxAbort        0x00800000 /* transmitter bus abort R 0 */\r
-+#define DmaTxState        0x00700000 /* Transmit process state R 000 */\r
-+#define DmaTxStopped      0x00000000 /* Stopped */\r
-+#define DmaTxFetching     0x00100000 /* Running - fetching the descriptor */\r
-+#define DmaTxWaiting      0x00200000 /* Running - waiting for end of transmission */\r
-+#define DmaTxReading      0x00300000 /* Running - reading the data from memory */\r
-+#define DmaTxSuspended    0x00600000 /* Suspended */\r
-+#define DmaTxClosing      0x00700000 /* Running - closing descriptor */\r
-+#define DmaRxState        0x000E0000 /* Receive process state 000 */\r
-+#define DmaRxStopped      0x00000000 /* Stopped */\r
-+#define DmaRxFetching     0x00020000 /* Running - fetching the descriptor */\r
-+#define DmaRxChecking     0x00040000 /* Running - checking for end of packet */\r
-+#define DmaRxWaiting      0x00060000 /* Running - waiting for packet */\r
-+#define DmaRxSuspended    0x00080000 /* Suspended */\r
-+#define DmaRxClosing      0x000A0000 /* Running - closing descriptor */\r
-+#define DmaRxFlushing     0x000C0000 /* Running - flushing the current frame */\r
-+#define DmaRxQueuing      0x000E0000 /* Running - queuing the recieve frame into host memory */\r
-+#define DmaIntNormal      0x00010000 /* Normal interrupt summary RW 0 */\r
-+#define DmaIntAbnormal    0x00008000 /* Abnormal interrupt summary RW 0 */\r
-+#define DmaIntEarlyRx     0x00004000 /* Early receive interrupt (Normal) RW 0 */\r
-+#define DmaIntBusError    0x00002000 /* Fatal bus error (Abnormal) RW 0 */\r
-+#define DmaIntEarlyTx     0x00000400 /* Early transmit interrupt RW 0 */\r
-+#define DmaIntRxStopped   0x00000100 /* Receive process stopped (Abnormal) RW 0 */\r
-+#define DmaIntRxNoBuffer  0x00000080 /* Receive buffer unavailable (Abnormal) RW 0*/\r
-+#define DmaIntRxCompleted 0x00000040 /* Completion of frame reception(Normal) RW 0*/\r
-+#define DmaIntTxUnderflow 0x00000020 /* Transmit underflow (Abnormal) RW 0 */\r
-+#define DmaIntTxJabber    0x00000008 /* Transmit Jabber Timeout (Abnormal) RW 0 */ \r
-+#define DmaIntTxNoBuffer  0x00000004 /* Transmit buffer unavailable (Normal) RW 0*/\r
-+#define DmaIntTxStopped   0x00000002 /* Transmit process stopped (Abnormal) RW 0 */\r
-+#define DmaIntTxCompleted 0x00000001 /* Transmit completed (Normal) RW 0 */\r
-+\r
-+/**********************************************************/\r
-+/* DMA control register layout                            */\r
-+/**********************************************************/\r
-+#define DmaStoreAndForward 0x00200000 /* Store and forward RW 0 */\r
-+#define DmaTxThreshCtl256  0x0000c000 /* Non-SF threshold is 256 words */\r
-+#define DmaTxThreshCtl128  0x00008000 /* Non-SF threshold is 128 words */\r
-+#define DmaTxThreshCtl064  0x00004000 /* Non-SF threshold is 64 words */\r
-+#define DmaTxThreshCtl032  0x00000000 /* Non-SF threshold is 32 words */\r
-+#define DmaTxStart         0x00002000 /* Start/Stop transmission RW 0 */\r
-+#define DmaTxSecondFrame   0x00000004 /* Operate on second frame RW 0 */\r
-+#define DmaRxStart         0x00000002 /* Start/Stop reception RW 0 */\r
-+\r
-+/**********************************************************/\r
-+/* DMA interrupt enable register layout                   */\r
-+/**********************************************************/\r
-+#define DmaIeNormal      DmaIntNormal      /* Normal interrupt enable RW 0 */\r
-+#define DmaIeAbnormal    DmaIntAbnormal    /* Abnormal interrupt enable RW 0 */\r
-+#define DmaIeEarlyRx     DmaIntEarlyRx     /* Early receive interrupt enable RW 0 */\r
-+#define DmaIeBusError    DmaIntBusError    /* Fatal bus error enable RW 0 */\r
-+#define DmaIeEarlyTx     DmaIntEarlyTx     /* Early transmit interrupt enable RW 0 */\r
-+#define DmaIeRxStopped   DmaIntRxStopped   /* Receive process stopped enable RW 0 */\r
-+#define DmaIeRxNoBuffer  DmaIntRxNoBuffer  /* Receive buffer unavailable enable RW 0 */\r
-+#define DmaIeRxCompleted DmaIntRxCompleted /* Completion of frame reception enable RW 0 */\r
-+#define DmaIeTxUnderflow DmaIntTxUnderflow /* Transmit underflow enable RW 0 */\r
-+#define DmaIeTxJabber    DmaIntTxJabber    /* Transmit jabber timeout RW 0 */\r
-+#define DmaIeTxNoBuffer  DmaIntTxNoBuffer  /* Transmit buffer unavailable enable RW 0 */\r
-+#define DmaIeTxStopped   DmaIntTxStopped   /* Transmit process stopped enable RW 0 */\r
-+#define DmaIeTxCompleted DmaIntTxCompleted /* Transmit completed enable RW 0 */\r
-+\r
-+/****************************************************************/\r
-+/* DMA Missed Frame and Buffer Overflow Counter register layout */\r
-+/****************************************************************/\r
-+#define DmaRxBufferMissedFrame  0xffff0000  /* cleared on read */\r
-+#define DmaMissedFrameShift             16\r
-+#define DmaRxBufferOverflowCnt  0x0000ffff  /* cleared on read */\r
-+#define DmaMissedFrameCountMask 0x0000ffff\r
-+\r
-+/**********************************************************/\r
-+/* DMA Engine descriptor layout                           */\r
-+/**********************************************************/\r
-+/* status word of DMA descriptor */\r
-+#define DescOwnByDma         0x80000000 /* Descriptor is owned by DMA engine */\r
-+#define DescFrameLengthMask  0x3FFF0000 /* Receive descriptor frame length */\r
-+#define DescFrameLengthShift         16\r
-+#define DescError            0x00008000 /* Error summary bit OR of following bits */\r
-+#define DescRxTruncated      0x00004000 /* Rx - no more descs for receive frame */\r
-+#define DescRxLengthError    0x00001000 /* Rx - frame size not matching with length field */\r
-+#define DescRxRunt           0x00000800 /* Rx - runt frame, damaged by a\r
-+                                           collision or term before 64 bytes */\r
-+#define DescRxMulticast      0x00000400 /* Rx - received frame is multicast */\r
-+#define DescRxFirst          0x00000200 /* Rx - first descriptor of the frame */\r
-+#define DescRxLast           0x00000100 /* Rx - last descriptor of the frame */\r
-+#define DescRxLongFrame      0x00000080 /* Rx - frame is longer than 1518 bytes */\r
-+#define DescRxLateColl       0x00000040 /* Rx - frame was damaged by a late collision */\r
-+#define DescRxFrameEther     0x00000020 /* Rx - Frame type Ethernet 802.3*/ \r
-+#define DescRxMiiError       0x00000008 /* Rx - error reported by MII interface */\r
-+#define DescRxDribbling      0x00000004 /* Rx - frame contains noninteger multiple of 8 bits */\r
-+#define DescRxCrc            0x00000002 /* Rx - CRC error */\r
-+#define DescTxTimeout        0x00004000 /* Tx - Transmit jabber timeout */\r
-+#define DescTxLostCarrier    0x00000800 /* Tx - carrier lost during tramsmission */\r
-+#define DescTxNoCarrier      0x00000400 /* Tx - no carrier signal from tranceiver */\r
-+#define DescTxLateCollision  0x00000200 /* Tx - transmission aborted due to collision */\r
-+#define DescTxExcCollisions  0x00000100 /* Tx - transmission aborted after 16 collisions */\r
-+#define DescTxHeartbeatFail  0x00000080 /* Tx - heartbeat collision check failure */\r
-+#define DescTxCollMask       0x00000078 /* Tx - Collision count */\r
-+#define DescTxCollShift               3\r
-+#define DescTxExcDeferral    0x00000004 /* Tx - excessive deferral */\r
-+#define DescTxUnderflow      0x00000002 /* Tx - late data arrival from memory */\r
-+#define DescTxDeferred       0x00000001 /* Tx - frame transmision deferred */\r
-+\r
-+/* length word of DMA descriptor */\r
-+#define DescTxIntEnable      0x80000000 /* Tx - interrupt on completion */\r
-+#define DescTxLast           0x40000000 /* Tx - Last segment of the frame */\r
-+#define DescTxFirst          0x20000000 /* Tx - First segment of the frame */\r
-+#define DescTxDisableCrc     0x04000000 /* Tx - Add CRC disabled (first segment only) */\r
-+#define DescEndOfRing        0x02000000 /* End of descriptors ring */\r
-+#define DescChain            0x01000000 /* Second buffer address is chain address */\r
-+#define DescTxDisablePadd    0x00800000 /* disable padding */\r
-+#define DescSize2Mask        0x003FF800 /* Buffer 2 size */\r
-+#define DescSize2Shift               11\r
-+#define DescSize1Mask        0x000007FF /* Buffer 1 size */\r
-+#define DescSize1Shift                0\r
-+\r
-+/**********************************************************/\r
-+/* Initial register values                                */\r
-+/**********************************************************/\r
-+/* Full-duplex mode with perfect filter on */\r
-+#define MacControlInitFdx \\r
-+       ( MacFilterOn \\r
-+       | MacLittleEndian \\r
-+       | MacHeartBeatOn \\r
-+       | MacSelectMii \\r
-+       | MacEnableRxOwn \\r
-+       | MacLoopbackOff \\r
-+       | MacFullDuplex \\r
-+       | MacMulticastFilterOn \\r
-+       | MacPromiscuousModeOff \\r
-+       | MacFilterNormal \\r
-+       | MacBadFramesDisable \\r
-+       | MacPerfectFilterOn \\r
-+       | MacHashFilterOff \\r
-+       | MacLateCollisionOff \\r
-+       | MacBroadcastEnable \\r
-+       | MacRetryEnable \\r
-+       | MacPadStripDisable \\r
-+       | MacDeferralCheckDisable \\r
-+       | MacTxEnable \\r
-+       | MacRxEnable)\r
-+\r
-+/* Full-duplex mode */\r
-+#define MacFlowControlInitFdx \\r
-+        ( MacControlFrameDisable \\r
-+        | MacFlowControlEnable)\r
-+\r
-+/* Half-duplex mode with perfect filter on */\r
-+#define MacControlInitHdx \\r
-+       ( MacFilterOn \\r
-+       | MacLittleEndian \\r
-+       | MacHeartBeatOn \\r
-+       | MacSelectMii \\r
-+       | MacDisableRxOwn \\r
-+       | MacLoopbackOff \\r
-+       | MacHalfDuplex \\r
-+       | MacMulticastFilterOn \\r
-+       | MacPromiscuousModeOff \\r
-+       | MacFilterNormal \\r
-+       | MacBadFramesDisable \\r
-+       | MacPerfectFilterOn \\r
-+       | MacHashFilterOff \\r
-+       | MacLateCollisionOff \\r
-+       | MacBroadcastEnable \\r
-+       | MacRetryEnable \\r
-+       | MacPadStripDisable \\r
-+       | MacDeferralCheckDisable \\r
-+       | MacTxEnable \\r
-+       | MacRxEnable)\r
-+\r
-+/* Half-duplex mode */\r
-+#define MacFlowControlInitHdx \\r
-+        ( MacControlFrameDisable \\r
-+        | MacFlowControlDisable)\r
-+\r
-+/* Bus Mode Rx odd half word align */\r
-+#define DmaBusModeInit  \\r
-+       ( DmaLittleEndianDesc \\r
-+       | DmaRxAlign16 \\r
-+       | DmaBurstLength4 \\r
-+       | DmaBigEndianData \\r
-+       | DmaDescriptorSkip1 \\r
-+       | DmaReceivePriorityOn \\r
-+       | DmaResetOff)\r
-+\r
-+#define DmaControlInit (DmaStoreAndForward)\r
-+\r
-+/* Interrupt groups */\r
-+#define DmaIntEnable \\r
-+     ( DmaIeNormal \\r
-+     | DmaIeAbnormal \\r
-+     | DmaIntBusError \\r
-+     | DmaIntRxStopped \\r
-+     | DmaIntTxUnderflow \\r
-+     | DmaIntTxStopped)\r
-+\r
-+#define DmaIntDisable 0\r
-+\r
-+#define DmaAllIntCauseMask \\r
-+      ( DmaIeNormal  \\r
-+      | DmaIeAbnormal  \\r
-+      | DmaIntEarlyRx  \\r
-+      | DmaIntBusError \\r
-+      | DmaIntEarlyTx  \\r
-+      | DmaIntRxStopped \\r
-+      | DmaIntRxNoBuffer \\r
-+      | DmaIntRxCompleted \\r
-+      | DmaIntTxUnderflow \\r
-+      | DmaIntTxJabber \\r
-+      | DmaIntTxNoBuffer \\r
-+      | DmaIntTxStopped \\r
-+      | DmaIntTxCompleted)\r
-+\r
-+#define UnhandledIntrMask    \\r
-+       (DmaAllIntCauseMask   \\r
-+       & ~(DmaIntRxNoBuffer  \\r
-+         | DmaIntTxStopped   \\r
-+         | DmaIntTxJabber    \\r
-+         | DmaIntTxUnderflow \\r
-+         | DmaIntBusError    \\r
-+         | DmaIntRxCompleted ))\r
-+\r
-+#define DescRxErrors    \\r
-+      (DescRxTruncated  \\r
-+     | DescRxRunt       \\r
-+     | DescRxLateColl   \\r
-+     | DescRxMiiError   \\r
-+     | DescRxCrc)\r
-+\r
-+#define DescTxErrors        \\r
-+     ( DescTxTimeout        \\r
-+     | DescTxLateCollision  \\r
-+     | DescTxExcCollisions  \\r
-+     | DescTxExcDeferral    \\r
-+     | DescTxUnderflow)\r
-+\r
-+/**********************************************************/\r
-+/* Descriptor Layout                                      */\r
-+/**********************************************************/\r
-+#define AE531X_DESC_STATUS     0x00 /* Status offset */\r
-+#define AE531X_DESC_CTRLEN     0x04 /* Control and Length offset */ \r
-+#define AE531X_DESC_BUFPTR     0x08 /* Buffer pointer offset */\r
-+#define AE531X_DESC_LNKBUF     0x0c /* Link field offset, or ptr to 2nd buf */\r
-+#define AE531X_DESC_SWPTR      0x10 /* OS-Dependent software pointer */\r
-+\r
-+#define AE531X_DESC_SIZE       0x10 /* 4 words, 16 bytes */\r
-+#define AE531X_QUEUE_ELE_SIZE  0x14 /* with software pointer extension */\r
-+\r
-+/* Accessors to the dma descriptor fields */\r
-+#define AE531X_DESC_STATUS_GET(ptr) \\r
-+    *(volatile UINT32 *)((UINT32)(ptr) + AE531X_DESC_STATUS)\r
-+\r
-+#define AE531X_DESC_STATUS_SET(ptr, val)  \\r
-+    AE531X_DESC_STATUS_GET(ptr) = (val)\r
-+\r
-+#define AE531X_DESC_CTRLEN_GET(ptr) \\r
-+    *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_CTRLEN)\r
-+\r
-+#define AE531X_DESC_CTRLEN_SET(ptr, val)  \\r
-+    AE531X_DESC_CTRLEN_GET(ptr) = (val)\r
-+\r
-+#define AE531X_DESC_BUFPTR_GET(ptr) \\r
-+    *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_BUFPTR)\r
-+\r
-+#define AE531X_DESC_BUFPTR_SET(ptr,val)  \\r
-+    AE531X_DESC_BUFPTR_GET(ptr) = (UINT32)(val)\r
-+\r
-+#define AE531X_DESC_LNKBUF_GET(ptr)  \\r
-+    *(volatile UINT32 *)((UINT32)ptr + AE531X_DESC_LNKBUF)\r
-+\r
-+#define AE531X_DESC_LNKBUF_SET(ptr, val)  \\r
-+    AE531X_DESC_LNKBUF_GET(ptr) = (val)\r
-+\r
-+#define AE531X_DESC_SWPTR_GET(ptr) \\r
-+    (void *)(*(volatile UINT32 *) ((UINT32)ptr + AE531X_DESC_SWPTR))\r
-+\r
-+#define AE531X_DESC_SWPTR_SET(ptr,val)   \\r
-+    AE531X_DESC_SWPTR_GET(ptr) = (void *)(val)\r
-+\r
-+/* Get size of Rx data from desc, in bytes */\r
-+#define AE531X_DESC_STATUS_RX_SIZE(x) \\r
-+        (((x) & DescFrameLengthMask) >> DescFrameLengthShift)\r
-+\r
-+#endif /* _AE531XREG_H_ */\r
-diff -urN linux-2.4.32.new/arch/mips/ar531x/Makefile linux-2.4.32.new-eth/arch/mips/ar531x/Makefile\r
---- linux-2.4.32.new/arch/mips/ar531x/Makefile 2005-12-24 20:29:42.010325312 +0000\r
-+++ linux-2.4.32.new-eth/arch/mips/ar531x/Makefile     2005-12-25 12:03:16.213872024 +0000\r
-@@ -28,6 +28,13 @@\r
-       ar531xirq.o     \\r
-       ar531xintr.o    \\r
-       ar531xgpio.o    \\r
--      ar531xksyms.o\r
-+      ar531xksyms.o   \\r
-+       ae531xlnx.o     \\r
-+       ae531xmac.o\r
\r
- include $(TOPDIR)/Rules.make\r
-+obj-$(CONFIG_MARVELL_ENET_PHY)  += mvPhy.o\r
-+obj-$(CONFIG_KENDIN_ENET_PHY))  += rtPhy.o\r
-+obj-$(CONFIG_REALTEK_ENET_PHY)  += rtPhy.o\r
-+\r
-+\r
-diff -urN linux-2.4.32.new/arch/mips/ar531x/mvPhy.c linux-2.4.32.new-eth/arch/mips/ar531x/mvPhy.c\r
---- linux-2.4.32.new/arch/mips/ar531x/mvPhy.c  1970-01-01 01:00:00.000000000 +0100\r
-+++ linux-2.4.32.new-eth/arch/mips/ar531x/mvPhy.c      2005-12-25 11:54:39.730389448 +0000\r
-@@ -0,0 +1,1237 @@\r
-+/*\r
-+ * This file is subject to the terms and conditions of the GNU General Public\r
-+ * License.  See the file "COPYING" in the main directory of this archive\r
-+ * for more details.\r
-+ *\r
-+ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
-+ */\r
-+\r
-+/*\r
-+* Manage the ethernet PHY switch, Marvell 88E6060.\r
-+* \r
-+* This module is intended to be largely OS and platform-independent.\r
-+*/\r
-+\r
-+#if defined(linux)\r
-+#include <linux/config.h>\r
-+#include <linux/types.h>\r
-+#include <linux/netdevice.h>\r
-+#include <linux/etherdevice.h>\r
-+#include <linux/delay.h>\r
-+\r
-+#include "ar531xlnx.h"\r
-+#endif\r
-+\r
-+#if defined(__ECOS)\r
-+#include "ae531xecos.h"\r
-+#endif\r
-+\r
-+\r
-+#include "ae531xmac.h"\r
-+#include "ae531xreg.h"\r
-+#include "mvPhy.h"\r
-+\r
-+#if /* DEBUG */ 1\r
-+#define MV_DEBUG_ERROR     0x00000001\r
-+#define MV_DEBUG_PHYSETUP  0x00000002\r
-+#define MV_DEBUG_PHYCHANGE 0x00000004\r
-+\r
-+int mvPhyDebug = MV_DEBUG_ERROR;\r
-+\r
-+#define MV_PRINT(FLG, X)                            \\r
-+{                                                   \\r
-+    if (mvPhyDebug & (FLG)) {                       \\r
-+        DEBUG_PRINTF X;                             \\r
-+    }                                               \\r
-+}\r
-+#else\r
-+#define MV_PRINT(FLG, X)\r
-+#endif\r
-+\r
-+#ifdef CONFIG_VENETDEV\r
-+/*\r
-+ * On AR5312 with CONFIG_VENETDEV==1,\r
-+ *   ports 0..3 are LAN ports  (accessed through ae0)\r
-+ *   port 4 is the WAN port.   (accessed through ae1)\r
-+ * \r
-+ * The phy switch settings in the mvPhyInfo table are set accordingly.\r
-+ */\r
-+#define MV_WAN_PORT          4\r
-+#define MV_IS_LAN_PORT(port) ((port) <  MV_WAN_PORT)\r
-+#define MV_IS_WAN_PORT(port) ((port) == MV_WAN_PORT)\r
-+#endif\r
-+\r
-+/*\r
-+ * Track per-PHY port information.\r
-+ */\r
-+typedef struct {\r
-+    BOOL   isEnetPort;       /* normal enet port */\r
-+    BOOL   isPhyAlive;       /* last known state of link */\r
-+    int    ethUnit;          /* MAC associated with this phy port */\r
-+    UINT32 phyBase;\r
-+    UINT32 phyAddr;          /* PHY registers associated with this phy port */\r
-+    UINT32 switchPortAddr;   /* switch port regs assoc'ed with this phy port */\r
-+    UINT32 VLANTableSetting; /* Value to be written to VLAN table */\r
-+} mvPhyInfo_t;\r
-+\r
-+/******************************************************************************\r
-+ * Per-PHY information, indexed by PHY unit number.\r
-+ *\r
-+ * This table is board-dependent.  It includes information\r
-+ * about which enet MAC controls which PHY port.\r
-+ */\r
-+mvPhyInfo_t mvPhyInfo[] = {\r
-+    /*\r
-+     * On AP30/AR5312, all PHYs are associated with MAC0.\r
-+     * AP30/AR5312's MAC1 isn't used for anything.\r
-+     * CONFIG_VENETDEV==1 (router) configuration:\r
-+     *    Ports 0,1,2, and 3 are "LAN ports"\r
-+     *    Port 4 is a WAN port\r
-+     *    Port 5 connects to MAC0 in the AR5312\r
-+     * CONFIG_VENETDEV==0 (bridge) configuration:\r
-+     *    Ports 0,1,2,3,4 are "LAN ports"\r
-+     *    Port 5 connects to the MAC0 in the AR5312\r
-+     */\r
-+    {isEnetPort: TRUE,   /* phy port 0 -- LAN port 0 */\r
-+     isPhyAlive: FALSE,\r
-+     ethUnit: 0,\r
-+     phyBase: 0,\r
-+     phyAddr: 0x10,\r
-+     switchPortAddr: 0x18,\r
-+#ifdef CONFIG_VENETDEV\r
-+     VLANTableSetting: 0x2e\r
-+#else\r
-+     VLANTableSetting: 0x3e\r
-+#endif\r
-+    },\r
-+\r
-+    {isEnetPort: TRUE,   /* phy port 1 -- LAN port 1 */\r
-+     isPhyAlive: FALSE,\r
-+     ethUnit: 0,\r
-+     phyBase: 0,\r
-+     phyAddr: 0x11,\r
-+     switchPortAddr: 0x19,\r
-+#ifdef CONFIG_VENETDEV\r
-+     VLANTableSetting: 0x2d\r
-+#else\r
-+     VLANTableSetting: 0x3d\r
-+#endif\r
-+    },\r
-+\r
-+    {isEnetPort: TRUE,   /* phy port 2 -- LAN port 2 */\r
-+     isPhyAlive: FALSE,\r
-+     ethUnit: 0,\r
-+     phyBase: 0,\r
-+     phyAddr: 0x12, \r
-+     switchPortAddr: 0x1a,\r
-+#ifdef CONFIG_VENETDEV\r
-+     VLANTableSetting: 0x2b\r
-+#else\r
-+     VLANTableSetting: 0x3b\r
-+#endif\r
-+    },\r
-+\r
-+    {isEnetPort: TRUE,   /* phy port 3 -- LAN port 3 */\r
-+     isPhyAlive: FALSE,\r
-+     ethUnit: 0,\r
-+     phyBase: 0,\r
-+     phyAddr: 0x13, \r
-+     switchPortAddr: 0x1b,\r
-+#ifdef CONFIG_VENETDEV\r
-+     VLANTableSetting: 0x27\r
-+#else\r
-+     VLANTableSetting: 0x37\r
-+#endif\r
-+    },\r
-+\r
-+    {isEnetPort: TRUE,   /* phy port 4 -- WAN port or LAN port 4 */\r
-+     isPhyAlive: FALSE,\r
-+     ethUnit: 0,\r
-+     phyBase: 0,\r
-+     phyAddr: 0x14, \r
-+     switchPortAddr: 0x1c,\r
-+#ifdef CONFIG_VENETDEV\r
-+     VLANTableSetting: 0x1020  /* WAN port */\r
-+#else\r
-+     VLANTableSetting: 0x2f    /* LAN port 4 */\r
-+#endif\r
-+    },\r
-+\r
-+    {isEnetPort: FALSE,  /* phy port 5 -- CPU port (no RJ45 connector) */\r
-+     isPhyAlive: TRUE,\r
-+     ethUnit: 0,\r
-+     phyBase: 0,\r
-+     phyAddr: 0x15, \r
-+     switchPortAddr: 0x1d,\r
-+#ifdef CONFIG_VENETDEV\r
-+     VLANTableSetting: 0x0f    /* Send only to LAN ports */\r
-+#else\r
-+     VLANTableSetting: 0x1f    /* Send to all ports */\r
-+#endif\r
-+    },\r
-+};\r
-+\r
-+#define MV_PHY_MAX (sizeof(mvPhyInfo) / sizeof(mvPhyInfo[0]))\r
-+\r
-+/* Range of valid PHY IDs is [MIN..MAX] */\r
-+#define MV_ID_MIN 0\r
-+#define MV_ID_MAX (MV_PHY_MAX-1)\r
-+\r
-+/* Convenience macros to access myPhyInfo */\r
-+#define MV_IS_ENET_PORT(phyUnit) (mvPhyInfo[phyUnit].isEnetPort)\r
-+#define MV_IS_PHY_ALIVE(phyUnit) (mvPhyInfo[phyUnit].isPhyAlive)\r
-+#define MV_ETHUNIT(phyUnit) (mvPhyInfo[phyUnit].ethUnit)\r
-+#define MV_PHYBASE(phyUnit) (mvPhyInfo[phyUnit].phyBase)\r
-+#define MV_PHYADDR(phyUnit) (mvPhyInfo[phyUnit].phyAddr)\r
-+#define MV_SWITCH_PORT_ADDR(phyUnit) (mvPhyInfo[phyUnit].switchPortAddr)\r
-+#define MV_VLAN_TABLE_SETTING(phyUnit) (mvPhyInfo[phyUnit].VLANTableSetting)\r
-+\r
-+#define MV_IS_ETHUNIT(phyUnit, ethUnit) \\r
-+    (MV_IS_ENET_PORT(phyUnit) &&        \\r
-+    MV_ETHUNIT(phyUnit) == (ethUnit))\r
-+\r
-+\r
-+/* Forward references */\r
-+BOOL       mv_phyIsLinkAlive(int phyUnit);\r
-+LOCAL void mv_VLANInit(int ethUnit);\r
-+LOCAL void mv_enableConfiguredPorts(int ethUnit);\r
-+LOCAL void mv_verifyReady(int ethUnit);\r
-+BOOL       mv_phySetup(int ethUnit, UINT32 phyBase);\r
-+BOOL       mv_phyIsFullDuplex(int ethUnit);\r
-+BOOL       mv_phyIsSpeed100(int phyUnit);\r
-+LOCAL BOOL mv_validPhyId(int phyUnit);\r
-+void       mv_flushATUDB(int phyUnit);\r
-+void       mv_phyCheckStatusChange(int ethUnit);\r
-+#if DEBUG\r
-+void       mv_phyShow(int phyUnit);\r
-+void       mv_phySet(int phyUnit, UINT32 regnum, UINT32 value);\r
-+void       mv_switchPortSet(int phyUnit, UINT32 regnum, UINT32 value);\r
-+void       mv_switchGlobalSet(int phyUnit, UINT32 regnum, UINT32 value);\r
-+void       mv_showATUDB(int phyUnit);\r
-+void       mv_countGoodFrames(int phyUnit);\r
-+void       mv_countBadFrames(int phyUnit);\r
-+void       mv_showFrameCounts(int phyUnit);\r
-+#endif\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* mv_phyIsLinkAlive - test to see if the specified link is alive\r
-+*\r
-+* RETURNS:\r
-+*    TRUE  --> link is alive\r
-+*    FALSE --> link is down\r
-+*/\r
-+BOOL\r
-+mv_phyIsLinkAlive(int phyUnit)\r
-+{\r
-+    UINT16 phyHwStatus;\r
-+    UINT32 phyBase;\r
-+    UINT32 phyAddr;\r
-+\r
-+    phyBase = MV_PHYBASE(phyUnit);\r
-+    phyAddr = MV_PHYADDR(phyUnit);\r
-+\r
-+    phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);\r
-+\r
-+    if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) {\r
-+        return TRUE;\r
-+    } else {\r
-+        return FALSE;\r
-+    }\r
-+}\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* mv_VLANInit - initialize "port-based VLANs" for the specified enet unit.\r
-+*/\r
-+LOCAL void\r
-+mv_VLANInit(int ethUnit)\r
-+{\r
-+    int     phyUnit;\r
-+    UINT32  phyBase;\r
-+    UINT32  switchPortAddr;\r
-+\r
-+    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
-+        if (MV_ETHUNIT(phyUnit) != ethUnit) {\r
-+            continue;\r
-+        }\r
-+\r
-+        phyBase        = MV_PHYBASE(phyUnit);\r
-+        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);\r
-+\r
-+        phyRegWrite(phyBase, switchPortAddr, MV_PORT_BASED_VLAN_MAP,\r
-+                    MV_VLAN_TABLE_SETTING(phyUnit));\r
-+    }\r
-+}\r
-+\r
-+#define phyPortConfigured(phyUnit) TRUE /* TBDFREEDOM2 */\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* mv_enableConfiguredPorts - enable whichever PHY ports are supposed\r
-+* to be enabled according to administrative configuration.\r
-+*/\r
-+LOCAL void\r
-+mv_enableConfiguredPorts(int ethUnit)\r
-+{\r
-+    int     phyUnit;\r
-+    UINT32  phyBase;\r
-+    UINT32  switchPortAddr;\r
-+    UINT16  portControl;\r
-+    UINT16  portAssociationVector;\r
-+\r
-+    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
-+        if (MV_ETHUNIT(phyUnit) != ethUnit) {\r
-+            continue;\r
-+        }\r
-+\r
-+        phyBase        = MV_PHYBASE(phyUnit);\r
-+        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);\r
-+\r
-+        if (phyPortConfigured(phyUnit)) {\r
-+\r
-+            portControl = MV_PORT_CONTROL_PORT_STATE_FORWARDING;\r
-+#ifdef CONFIG_VENETDEV\r
-+            if (!MV_IS_ENET_PORT(phyUnit)) {       /* CPU port */\r
-+                portControl |= MV_PORT_CONTROL_INGRESS_TRAILER\r
-+                            | MV_PORT_CONTROL_EGRESS_MODE;\r
-+            }\r
-+#endif\r
-+            phyRegWrite(phyBase, switchPortAddr, MV_PORT_CONTROL, portControl);\r
-+\r
-+            if (MV_IS_ENET_PORT(phyUnit)) {\r
-+                portAssociationVector = 1 << phyUnit;\r
-+            } else {\r
-+                /* Disable learning on the CPU port */\r
-+                portAssociationVector = 0;\r
-+            }\r
-+            phyRegWrite(phyBase, switchPortAddr,\r
-+                MV_PORT_ASSOCIATION_VECTOR, portAssociationVector);\r
-+        }\r
-+    }\r
-+}\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* mv_verifyReady - validates that we're dealing with the device\r
-+* we think we're dealing with, and that it's ready.\r
-+*/\r
-+LOCAL void\r
-+mv_verifyReady(int ethUnit)\r
-+{\r
-+    int     phyUnit;\r
-+    UINT16  globalStatus;\r
-+    UINT32  phyBase = 0;\r
-+    UINT32  phyAddr;\r
-+    UINT32  switchPortAddr;\r
-+    UINT16  phyID1;\r
-+    UINT16  phyID2;\r
-+    UINT16  switchID;\r
-+\r
-+    /*\r
-+     * The first read to the Phy port registers always fails and\r
-+     * returns 0.   So get things started with a bogus read.\r
-+     */\r
-+    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
-+        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {\r
-+            continue;\r
-+        }\r
-+        phyBase = MV_PHYBASE(phyUnit);\r
-+        phyAddr = MV_PHYADDR(phyUnit);\r
-+    \r
-+        (void)phyRegRead(phyBase, phyAddr, MV_PHY_ID1); /* returns 0 */\r
-+        break;\r
-+    }\r
-+\r
-+    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
-+        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {\r
-+            continue;\r
-+        }\r
-+\r
-+        /*******************/\r
-+        /* Verify phy port */\r
-+        /*******************/\r
-+        phyBase = MV_PHYBASE(phyUnit);\r
-+        phyAddr = MV_PHYADDR(phyUnit);\r
-+    \r
-+        phyID1 = phyRegRead(phyBase, phyAddr, MV_PHY_ID1);\r
-+        if (phyID1 != MV_PHY_ID1_EXPECTATION) {\r
-+            MV_PRINT(MV_DEBUG_PHYSETUP,\r
-+                      ("Invalid PHY ID1 for ethmac%d port%d.  Expected 0x%04x, read 0x%04x\n",\r
-+                       ethUnit,\r
-+                       phyUnit,\r
-+                       MV_PHY_ID1_EXPECTATION,\r
-+                       phyID1));\r
-+            return;\r
-+        }\r
-+    \r
-+        phyID2 = phyRegRead(phyBase, phyAddr, MV_PHY_ID2);\r
-+        if ((phyID2 & MV_OUI_LSB_MASK) != MV_OUI_LSB_EXPECTATION) {\r
-+            MV_PRINT(MV_DEBUG_PHYSETUP,\r
-+                      ("Invalid PHY ID2 for ethmac%d port %d.  Expected 0x%04x, read 0x%04x\n",\r
-+                       ethUnit,\r
-+                       phyUnit,\r
-+                       MV_OUI_LSB_EXPECTATION,\r
-+                       phyID2));\r
-+            return;\r
-+        }\r
-+    \r
-+        MV_PRINT(MV_DEBUG_PHYSETUP,\r
-+                  ("Found PHY ethmac%d port%d: model 0x%x revision 0x%x\n",\r
-+                   ethUnit,\r
-+                   phyUnit,\r
-+                   (phyID2 & MV_MODEL_NUM_MASK) >> MV_MODEL_NUM_SHIFT,\r
-+                   (phyID2 & MV_REV_NUM_MASK) >> MV_REV_NUM_SHIFT));\r
-+    \r
-+    \r
-+        /**********************/\r
-+        /* Verify switch port */\r
-+        /**********************/\r
-+        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);\r
-+    \r
-+        switchID = phyRegRead(phyBase, switchPortAddr, MV_SWITCH_ID);\r
-+        if ((switchID & MV_SWITCH_ID_DEV_MASK) !=\r
-+            MV_SWITCH_ID_DEV_EXPECTATION) {\r
-+    \r
-+            MV_PRINT(MV_DEBUG_PHYSETUP,\r
-+                      ("Invalid switch ID for ethmac%d port %d.  Expected 0x%04x, read 0x%04x\n",\r
-+                       ethUnit,\r
-+                       phyUnit,\r
-+                       MV_SWITCH_ID_DEV_EXPECTATION,\r
-+                       switchID));\r
-+            return;\r
-+        }\r
-+    \r
-+        MV_PRINT(MV_DEBUG_PHYSETUP,\r
-+                  ("Found PHY switch for enet %d port %d deviceID 0x%x revision 0x%x\n",\r
-+                    ethUnit,\r
-+                    phyUnit,\r
-+                    (switchID & MV_SWITCH_ID_DEV_MASK) >> MV_SWITCH_ID_DEV_SHIFT,\r
-+                    (switchID & MV_SWITCH_ID_REV_MASK) >> MV_SWITCH_ID_REV_SHIFT))\r
-+    }\r
-+    \r
-+    /*******************************/\r
-+    /* Verify that switch is ready */\r
-+    /*******************************/\r
-+    if (phyBase) {\r
-+        globalStatus = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
-+                                  MV_SWITCH_GLOBAL_STATUS);\r
-+\r
-+        if (!(globalStatus & MV_SWITCH_STATUS_READY_MASK)) {\r
-+            MV_PRINT(MV_DEBUG_PHYSETUP,\r
-+                      ("PHY switch for ethmac%d NOT ready!\n",\r
-+                       ethUnit));\r
-+        }\r
-+    } else {\r
-+        MV_PRINT(MV_DEBUG_PHYSETUP,\r
-+                  ("No ports configured for ethmac%d\n", ethUnit));\r
-+    }\r
-+}\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* mv_phySetup - reset and setup the PHY switch.\r
-+*\r
-+* Resets each PHY port.\r
-+*\r
-+* RETURNS:\r
-+*    TRUE  --> at least 1 PHY with LINK\r
-+*    FALSE --> no LINKs on this ethernet unit\r
-+*/\r
-+BOOL\r
-+mv_phySetup(int ethUnit, UINT32 phyBase)\r
-+{\r
-+    int     phyUnit;\r
-+    int     liveLinks = 0;\r
-+    BOOL    foundPhy = FALSE;\r
-+    UINT32  phyAddr;\r
-+    UINT16  atuControl;\r
-+\r
-+    /*\r
-+     * Allow platform-specific code to determine the default Ethernet MAC\r
-+     * at run-time.  If phyEthMacDefault returns a negative value, use the\r
-+     * static mvPhyInfo table "as is".  But if phyEthMacDefault returns a\r
-+     * non-negative value, use it as the default ethernet unit.\r
-+     */\r
-+    {\r
-+        int ethMacDefault = phyEthMacDefault();\r
-+\r
-+        if (ethMacDefault >= 0) {\r
-+            for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
-+                MV_ETHUNIT(phyUnit)=ethMacDefault;\r
-+            }\r
-+        }\r
-+    }\r
-+\r
-+    /*\r
-+     * See if there's any configuration data for this enet,\r
-+     * and set up phyBase in table.\r
-+     */\r
-+    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
-+        if (MV_ETHUNIT(phyUnit) != ethUnit) {\r
-+            continue;\r
-+        }\r
-+\r
-+        MV_PHYBASE(phyUnit) = phyBase;\r
-+        foundPhy = TRUE;\r
-+    }\r
-+\r
-+    if (!foundPhy) {\r
-+        return FALSE; /* No PHY's configured for this ethUnit */\r
-+    }\r
-+\r
-+    /* Verify that the switch is what we think it is, and that it's ready */\r
-+    mv_verifyReady(ethUnit);\r
-+\r
-+    /* Initialize global switch settings */\r
-+    atuControl  = MV_ATUCTRL_AGE_TIME_DEFAULT << MV_ATUCTRL_AGE_TIME_SHIFT;\r
-+    atuControl |= MV_ATUCTRL_ATU_SIZE_DEFAULT << MV_ATUCTRL_ATU_SIZE_SHIFT;\r
-+    // atuControl |= MV_ATUCTRL_ATU_LEARNDIS;\r
-+    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_CONTROL, atuControl);\r
-+\r
-+    /* Reset PHYs and start autonegoation on each. */\r
-+    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
-+        if (MV_ETHUNIT(phyUnit) != ethUnit) {\r
-+            continue;\r
-+        }\r
-+\r
-+        phyBase = MV_PHYBASE(phyUnit);\r
-+        phyAddr = MV_PHYADDR(phyUnit);\r
-+\r
-+        phyRegWrite(phyBase, phyAddr, MV_PHY_CONTROL,\r
-+                    MV_CTRL_SOFTWARE_RESET | MV_CTRL_AUTONEGOTIATION_ENABLE);\r
-+    }\r
-+\r
-+    {\r
-+      int timeout;\r
-+      UINT16  phyHwStatus;\r
-+\r
-+      /*\r
-+       * Wait 5 seconds for ALL associated PHYs to finish autonegotiation.\r
-+       */\r
-+      timeout=50;\r
-+      for (phyUnit=0; (phyUnit < MV_PHY_MAX) && (timeout > 0); phyUnit++) {\r
-+          if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {\r
-+              continue;\r
-+          }\r
-+          for (;;) {\r
-+              phyBase = MV_PHYBASE(phyUnit);\r
-+              phyAddr = MV_PHYADDR(phyUnit);\r
-+\r
-+              phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);\r
-+\r
-+              if (MV_AUTONEG_DONE(phyHwStatus)) {\r
-+                  break;\r
-+              }\r
-+\r
-+              if (--timeout == 0) {\r
-+                  break;\r
-+              }\r
-+\r
-+              sysMsDelay(100);\r
-+          }\r
-+      }\r
-+    }\r
-+\r
-+    /*\r
-+     * All PHYs have had adequate time to autonegotiate.\r
-+     * Now initialize software status.\r
-+     *\r
-+     * It's possible that some ports may take a bit longer\r
-+     * to autonegotiate; but we can't wait forever.  They'll\r
-+     * get noticed by mv_phyCheckStatusChange during regular\r
-+     * polling activities.\r
-+     */\r
-+    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
-+        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {\r
-+            continue;\r
-+        }\r
-+\r
-+        if (mv_phyIsLinkAlive(phyUnit)) {\r
-+            liveLinks++;\r
-+            MV_IS_PHY_ALIVE(phyUnit) = TRUE;\r
-+#ifdef DEBUG\r
-+          mv_phyShow(phyUnit);\r
-+#endif\r
-+        } else {\r
-+            MV_IS_PHY_ALIVE(phyUnit) = FALSE;\r
-+        }\r
-+\r
-+        MV_PRINT(MV_DEBUG_PHYSETUP,\r
-+            ("ethmac%d: Phy Status=%4.4x\n",\r
-+            ethUnit, \r
-+            phyRegRead(MV_PHYBASE(phyUnit),\r
-+                       MV_PHYADDR(phyUnit),\r
-+                       MV_PHY_SPECIFIC_STATUS)));\r
-+\r
-+    }\r
-+\r
-+#ifdef DEBUG\r
-+    /* PHY 5 is the connection to the CPU */\r
-+    mv_phyShow(5);\r
-+#endif\r
-+\r
-+    mv_VLANInit(ethUnit);\r
-+\r
-+    mv_enableConfiguredPorts(ethUnit);\r
-+\r
-+    return (liveLinks > 0);\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* mv_phyIsDuplexFull - Determines whether the phy ports associated with the\r
-+* specified device are FULL or HALF duplex.\r
-+*\r
-+* RETURNS:\r
-+*    TRUE --> at least one associated PHY in FULL DUPLEX\r
-+*    FALSE --> all half duplex, or no links\r
-+*/\r
-+BOOL\r
-+mv_phyIsFullDuplex(int ethUnit)\r
-+{\r
-+    int     phyUnit;\r
-+    UINT32  phyBase;\r
-+    UINT32  phyAddr;\r
-+    UINT16  phyHwStatus;\r
-+\r
-+    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
-+\r
-+        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {\r
-+            continue;\r
-+        }\r
-+\r
-+        if (mv_phyIsLinkAlive(phyUnit)) {\r
-+\r
-+            phyBase = MV_PHYBASE(phyUnit);\r
-+            phyAddr = MV_PHYADDR(phyUnit);\r
-+\r
-+            phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);\r
-+\r
-+            if (phyHwStatus & MV_STATUS_RESOLVED_DUPLEX_FULL) {\r
-+                return TRUE;\r
-+            }\r
-+        }\r
-+    }\r
-+\r
-+    return FALSE;\r
-+}\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* mv_phyIsSpeed100 - Determines the speed of a phy port\r
-+*\r
-+* RETURNS:\r
-+*    TRUE --> PHY operating at 100 Mbit\r
-+*    FALSE --> link down, or not operating at 100 Mbit\r
-+*/\r
-+BOOL\r
-+mv_phyIsSpeed100(int phyUnit)\r
-+{\r
-+    UINT16  phyHwStatus;\r
-+    UINT32  phyBase;\r
-+    UINT32  phyAddr;\r
-+\r
-+    if (MV_IS_ENET_PORT(phyUnit)) {\r
-+        if (mv_phyIsLinkAlive(phyUnit)) {\r
-+\r
-+            phyBase = MV_PHYBASE(phyUnit);\r
-+            phyAddr = MV_PHYADDR(phyUnit);\r
-+\r
-+            phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);\r
-+\r
-+            if (phyHwStatus & MV_STATUS_RESOLVED_SPEED_100) {\r
-+                return TRUE;\r
-+            }\r
-+        }\r
-+    }\r
-+\r
-+    return FALSE;\r
-+}\r
-+\r
-+#ifdef CONFIG_VENETDEV\r
-+/******************************************************************************\r
-+*\r
-+* mv_phyDetermineSource - Examine a received frame's Egress Trailer\r
-+* to determine whether it came from a LAN or WAN port.\r
-+*\r
-+* RETURNS:\r
-+*    Returns 1-->LAN, 0-->WAN, -1-->ERROR\r
-+*/\r
-+int\r
-+mv_phyDetermineSource(char *data, int len)\r
-+{\r
-+    unsigned char *phyTrailer;\r
-+    unsigned char incomingPort;\r
-+\r
-+    phyTrailer = &data[len - MV_PHY_TRAILER_SIZE];\r
-+\r
-+    /* ASSERT(phyTrailer[0] == MV_EGRESS_TRAILER_VALID); */\r
-+    if (phyTrailer[0] != MV_EGRESS_TRAILER_VALID) {\r
-+      printk(KERN_ERR "PHY trailer invalid; got %#02x, expected %#02x\n",\r
-+             phyTrailer[0], MV_EGRESS_TRAILER_VALID);\r
-+      return -1;\r
-+    }\r
-+\r
-+    incomingPort = phyTrailer[1];\r
-+    if (MV_IS_LAN_PORT(incomingPort)) {\r
-+        return 1;\r
-+    } else {\r
-+        /* ASSERT(MV_IS_WAN_PORT(incomingPort)); */\r
-+      if (!MV_IS_WAN_PORT(incomingPort)) {\r
-+          printk(KERN_ERR "incoming port was %d; expected 0-4\n", incomingPort);\r
-+          return -1;\r
-+      }\r
-+        return 0;\r
-+    }\r
-+}\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* mv_phySetDestinationPort - Set the Ingress Trailer to force the\r
-+* frame to be sent to LAN or WAN, as specified.\r
-+*\r
-+*/\r
-+void\r
-+mv_phySetDestinationPort(char *data, int len, int fromLAN)\r
-+{\r
-+    char *phyTrailer;\r
-+\r
-+    phyTrailer = &data[len];\r
-+    if (fromLAN) {\r
-+        /* LAN ports: Use default settings, as per mvPhyInfo */\r
-+        phyTrailer[0] = 0x00;\r
-+        phyTrailer[1] = 0x00;\r
-+    } else {\r
-+        /* WAN port: Direct to WAN port */\r
-+        phyTrailer[0] = MV_INGRESS_TRAILER_OVERRIDE;\r
-+        phyTrailer[1] = 1 << MV_WAN_PORT;\r
-+    }\r
-+    phyTrailer[2] = 0x00;\r
-+    phyTrailer[3] = 0x00;\r
-+}\r
-+#endif\r
-+\r
-+\r
-+/*****************************************************************************\r
-+*\r
-+* Validate that the specified PHY unit number is a valid PHY ID.\r
-+* Print a message if it is invalid.\r
-+* RETURNS\r
-+*   TRUE  --> valid\r
-+*   FALSE --> invalid\r
-+*/\r
-+LOCAL BOOL\r
-+mv_validPhyId(int phyUnit)\r
-+{\r
-+    if ((phyUnit >= MV_ID_MIN) && (phyUnit <= MV_ID_MAX)) {\r
-+        return TRUE;\r
-+    } else {\r
-+        PRINTF("PHY unit number must be in the range [%d..%d]\n",\r
-+            MV_ID_MIN, MV_ID_MAX);\r
-+        return FALSE;\r
-+    } \r
-+}\r
-+\r
-+\r
-+/*****************************************************************************\r
-+*\r
-+* mv_waitWhileATUBusy - spins until the ATU completes\r
-+* its previous operation.\r
-+*/\r
-+LOCAL void\r
-+mv_waitWhileATUBusy(UINT32 phyBase)\r
-+{\r
-+    BOOL   isBusy;\r
-+    UINT16 ATUOperation;\r
-+\r
-+    do {\r
-+\r
-+        ATUOperation = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
-+                                  MV_ATU_OPERATION);\r
-+\r
-+        isBusy = (ATUOperation & MV_ATU_BUSY_MASK) == MV_ATU_IS_BUSY;\r
-+\r
-+    } while(isBusy);\r
-+}\r
-+\r
-+/*****************************************************************************\r
-+*\r
-+* mv_flushATUDB - flushes ALL entries in the Address Translation Unit\r
-+* DataBase associated with phyUnit.  [Since we use a single DB for\r
-+* all PHYs, this flushes the entire shared DataBase.]\r
-+*\r
-+* The current implementation flushes even more than absolutely needed --\r
-+* it flushes all entries for all phyUnits on the same ethernet as the\r
-+* specified phyUnit.\r
-+*\r
-+* It is called only when a link failure is detected on a port that was\r
-+* previously working.  In other words, when the cable is unplugged.\r
-+*/\r
-+void\r
-+mv_flushATUDB(int phyUnit)\r
-+{\r
-+    UINT32 phyBase;\r
-+\r
-+    if (!mv_validPhyId(phyUnit)) {\r
-+        PRINTF("Invalid port number: %d\n", phyUnit);\r
-+        return;\r
-+    }\r
-+\r
-+    phyBase = MV_PHYBASE(phyUnit);\r
-+    \r
-+    /* Wait for previous operation (if any) to complete */\r
-+    mv_waitWhileATUBusy(phyBase);\r
-+\r
-+    /* Tell hardware to flush all entries */\r
-+    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_OPERATION, \r
-+                MV_ATU_OP_FLUSH_ALL | MV_ATU_IS_BUSY);\r
-+\r
-+    mv_waitWhileATUBusy(phyBase);\r
-+}\r
-+ \r
-+/*****************************************************************************\r
-+*\r
-+* mv_phyCheckStatusChange -- checks for significant changes in PHY state.\r
-+*\r
-+* A "significant change" is:\r
-+*     dropped link (e.g. ethernet cable unplugged) OR\r
-+*     autonegotiation completed + link (e.g. ethernet cable plugged in)\r
-+*/\r
-+void\r
-+mv_phyCheckStatusChange(int ethUnit)\r
-+{\r
-+    int           phyUnit;\r
-+    UINT16        phyHwStatus;\r
-+    mvPhyInfo_t   *lastStatus;\r
-+    int           linkCount   = 0;\r
-+    int           lostLinks   = 0;\r
-+    int           gainedLinks = 0;\r
-+    UINT32        phyBase;\r
-+    UINT32        phyAddr;\r
-+\r
-+    for (phyUnit=0; phyUnit < MV_PHY_MAX; phyUnit++) {\r
-+        if (!MV_IS_ETHUNIT(phyUnit, ethUnit)) {\r
-+            continue;\r
-+        }\r
-+\r
-+        phyBase = MV_PHYBASE(phyUnit);\r
-+        phyAddr = MV_PHYADDR(phyUnit);\r
-+\r
-+        lastStatus = &mvPhyInfo[phyUnit];\r
-+        phyHwStatus = phyRegRead(phyBase, phyAddr, MV_PHY_SPECIFIC_STATUS);\r
-+\r
-+        if (lastStatus->isPhyAlive) { /* last known link status was ALIVE */\r
-+            /* See if we've lost link */\r
-+            if (phyHwStatus & MV_STATUS_REAL_TIME_LINK_UP) {\r
-+                linkCount++;\r
-+            } else {\r
-+                lostLinks++;\r
-+                mv_flushATUDB(phyUnit);\r
-+                MV_PRINT(MV_DEBUG_PHYCHANGE,("\nethmac%d port%d down\n",\r
-+                                               ethUnit, phyUnit));\r
-+                lastStatus->isPhyAlive = FALSE;\r
-+            }\r
-+        } else { /* last known link status was DEAD */\r
-+            /* Check for AutoNegotiation complete */\r
-+            if (MV_AUTONEG_DONE(phyHwStatus)) {\r
-+                gainedLinks++;\r
-+              linkCount++;\r
-+                MV_PRINT(MV_DEBUG_PHYCHANGE,("\nethmac%d port%d up\n",\r
-+                                               ethUnit, phyUnit));\r
-+                lastStatus->isPhyAlive = TRUE;\r
-+            }\r
-+        }\r
-+    }\r
-+\r
-+    if (linkCount == 0) {\r
-+        if (lostLinks) {\r
-+            /* We just lost the last link for this MAC */\r
-+            phyLinkLost(ethUnit);\r
-+        }\r
-+    } else {\r
-+        if (gainedLinks == linkCount) {\r
-+            /* We just gained our first link(s) for this MAC */\r
-+            phyLinkGained(ethUnit);\r
-+        }\r
-+    }\r
-+}\r
-+\r
-+#if DEBUG\r
-+\r
-+/* Define the registers of interest for a phyShow command */\r
-+typedef struct mvRegisterTableEntry_s {\r
-+    UINT32 regNum;\r
-+    char  *regIdString;\r
-+} mvRegisterTableEntry_t;\r
-+\r
-+mvRegisterTableEntry_t mvPhyRegisterTable[] = {\r
-+    {MV_PHY_CONTROL,                 "PHY Control                     "},\r
-+    {MV_PHY_STATUS,                  "PHY Status                      "},\r
-+    {MV_PHY_ID1,                     "PHY Identifier 1                "},\r
-+    {MV_PHY_ID2,                     "PHY Identifier 2                "},\r
-+    {MV_AUTONEG_ADVERT,              "Auto-Negotiation Advertisement  "},\r
-+    {MV_LINK_PARTNER_ABILITY,        "Link Partner Ability            "},\r
-+    {MV_AUTONEG_EXPANSION,           "Auto-Negotiation Expansion      "},\r
-+    {MV_NEXT_PAGE_TRANSMIT,          "Next Page Transmit              "},\r
-+    {MV_LINK_PARTNER_NEXT_PAGE,      "Link Partner Next Page          "},\r
-+    {MV_PHY_SPECIFIC_CONTROL_1,      "PHY-Specific Control Register 1 "},\r
-+    {MV_PHY_SPECIFIC_STATUS,         "PHY-Specific Status             "},\r
-+    {MV_PHY_INTERRUPT_ENABLE,        "PHY Interrupt Enable            "},\r
-+    {MV_PHY_INTERRUPT_STATUS,        "PHY Interrupt Status            "},\r
-+    {MV_PHY_INTERRUPT_PORT_SUMMARY,  "PHY Interrupt Port Summary      "},\r
-+    {MV_RECEIVE_ERROR_COUNTER,       "Receive Error Counter           "},\r
-+    {MV_LED_PARALLEL_SELECT,         "LED Parallel Select             "},\r
-+    {MV_LED_STREAM_SELECT_LEDS,      "LED Stream Select               "},\r
-+    {MV_PHY_LED_CONTROL,             "PHY LED Control                 "},\r
-+    {MV_PHY_MANUAL_LED_OVERRIDE,     "PHY Manual LED Override         "},\r
-+    {MV_VCT_CONTROL,                 "VCT Control                     "},\r
-+    {MV_VCT_STATUS,                  "VCT Status                      "},\r
-+    {MV_PHY_SPECIFIC_CONTROL_2,      "PHY-Specific Control Register 2 "},\r
-+};\r
-+int mvPhyNumRegs = sizeof(mvPhyRegisterTable) / sizeof(mvPhyRegisterTable[0]);\r
-+\r
-+\r
-+mvRegisterTableEntry_t mvSwitchPortRegisterTable[] = {\r
-+    {MV_PORT_STATUS,              "Port Status             "},\r
-+    {MV_SWITCH_ID,                "Switch ID               "},\r
-+    {MV_PORT_CONTROL,             "Port Control            "},\r
-+    {MV_PORT_BASED_VLAN_MAP,      "Port-Based VLAN Map     "},\r
-+    {MV_PORT_ASSOCIATION_VECTOR,  "Port Association Vector "},\r
-+    {MV_RX_COUNTER,               "RX Counter              "},\r
-+    {MV_TX_COUNTER,               "TX Counter              "},\r
-+};\r
-+int mvSwitchPortNumRegs =\r
-+    sizeof(mvSwitchPortRegisterTable) / sizeof(mvSwitchPortRegisterTable[0]);\r
-+\r
-+\r
-+mvRegisterTableEntry_t mvSwitchGlobalRegisterTable[] = {\r
-+    {MV_SWITCH_GLOBAL_STATUS,  "Switch Global Status  "},\r
-+    {MV_SWITCH_MAC_ADDR0,      "Switch MAC Addr 0 & 1 "},\r
-+    {MV_SWITCH_MAC_ADDR2,      "Switch MAC Addr 2 & 3 "},\r
-+    {MV_SWITCH_MAC_ADDR4,      "Switch MAC Addr 4 & 5 "},\r
-+    {MV_SWITCH_GLOBAL_CONTROL, "Switch Global Control "},\r
-+    {MV_ATU_CONTROL,           "ATU Control           "},\r
-+    {MV_ATU_OPERATION,         "ATU Operation         "},\r
-+    {MV_ATU_DATA,              "ATU Data              "},\r
-+    {MV_ATU_MAC_ADDR0,         "ATU MAC Addr 0 & 1    "},\r
-+    {MV_ATU_MAC_ADDR2,         "ATU MAC Addr 2 & 3    "},\r
-+    {MV_ATU_MAC_ADDR4,         "ATU MAC Addr 4 & 5    "},\r
-+};\r
-+int mvSwitchGlobalNumRegs =\r
-+    sizeof(mvSwitchGlobalRegisterTable) / sizeof(mvSwitchGlobalRegisterTable[0]);\r
-+\r
-+\r
-+/*****************************************************************************\r
-+*\r
-+* mv_phyShow - Dump the state of a PHY.\r
-+* There are two sets of registers for each phy port:\r
-+*  "phy registers" and\r
-+*  "switch port registers"\r
-+* We dump 'em all, plus the switch global registers.\r
-+*/\r
-+void\r
-+mv_phyShow(int phyUnit)\r
-+{\r
-+    int     i;\r
-+    UINT16  value;\r
-+    UINT32  phyBase;\r
-+    UINT32  phyAddr;\r
-+    UINT32  switchPortAddr;\r
-+\r
-+    if (!mv_validPhyId(phyUnit)) {\r
-+        return;\r
-+    }\r
-+\r
-+    phyBase        = MV_PHYBASE(phyUnit);\r
-+    phyAddr        = MV_PHYADDR(phyUnit);\r
-+    switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);\r
-+\r
-+    PRINTF("PHY state for PHY%d (ethmac%d, phyBase 0x%8x, phyAddr 0x%x, switchAddr 0x%x)\n",\r
-+           phyUnit,\r
-+           MV_ETHUNIT(phyUnit),\r
-+           MV_PHYBASE(phyUnit),\r
-+           MV_PHYADDR(phyUnit),\r
-+           MV_SWITCH_PORT_ADDR(phyUnit));\r
-+\r
-+    PRINTF("PHY Registers:\n");\r
-+    for (i=0; i < mvPhyNumRegs; i++) {\r
-+\r
-+        value = phyRegRead(phyBase, phyAddr, mvPhyRegisterTable[i].regNum);\r
-+\r
-+        PRINTF("Reg %02d (0x%02x) %s = 0x%08x\n",\r
-+               mvPhyRegisterTable[i].regNum,\r
-+               mvPhyRegisterTable[i].regNum,\r
-+               mvPhyRegisterTable[i].regIdString,\r
-+               value);\r
-+    }\r
-+\r
-+    PRINTF("Switch Port Registers:\n");\r
-+    for (i=0; i < mvSwitchPortNumRegs; i++) {\r
-+\r
-+        value = phyRegRead(phyBase, switchPortAddr,\r
-+                           mvSwitchPortRegisterTable[i].regNum);\r
-+\r
-+        PRINTF("Reg %02d (0x%02x) %s = 0x%08x\n",\r
-+               mvSwitchPortRegisterTable[i].regNum,\r
-+               mvSwitchPortRegisterTable[i].regNum,\r
-+               mvSwitchPortRegisterTable[i].regIdString,\r
-+               value);\r
-+    }\r
-+\r
-+    PRINTF("Switch Global Registers:\n");\r
-+    for (i=0; i < mvSwitchGlobalNumRegs; i++) {\r
-+\r
-+        value = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
-+                           mvSwitchGlobalRegisterTable[i].regNum);\r
-+\r
-+        PRINTF("Reg %02d (0x%02x) %s = 0x%08x\n",\r
-+               mvSwitchGlobalRegisterTable[i].regNum,\r
-+               mvSwitchGlobalRegisterTable[i].regNum,\r
-+               mvSwitchGlobalRegisterTable[i].regIdString,\r
-+               value);\r
-+    }\r
-+}\r
-+\r
-+/*****************************************************************************\r
-+*\r
-+* mv_phySet - Modify the value of a PHY register (debug only).\r
-+*/\r
-+void\r
-+mv_phySet(int phyUnit, UINT32 regnum, UINT32 value)\r
-+{\r
-+    UINT32  phyBase;\r
-+    UINT32  phyAddr;\r
-+\r
-+    if (mv_validPhyId(phyUnit)) {\r
-+\r
-+        phyBase = MV_PHYBASE(phyUnit);\r
-+        phyAddr = MV_PHYADDR(phyUnit);\r
-+\r
-+        phyRegWrite(phyBase, phyAddr, regnum, value);\r
-+    }\r
-+}\r
-+\r
-+\r
-+/*****************************************************************************\r
-+*\r
-+* mv_switchPortSet - Modify the value of a switch port register (debug only).\r
-+*/\r
-+void\r
-+mv_switchPortSet(int phyUnit, UINT32 regnum, UINT32 value)\r
-+{\r
-+    UINT32  phyBase;\r
-+    UINT32  switchPortAddr;\r
-+\r
-+    if (mv_validPhyId(phyUnit)) {\r
-+\r
-+        phyBase = MV_PHYBASE(phyUnit);\r
-+        switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);\r
-+\r
-+        phyRegWrite(phyBase, switchPortAddr, regnum, value);\r
-+    }\r
-+}\r
-+ \r
-+/*****************************************************************************\r
-+*\r
-+* mv_switchGlobalSet - Modify the value of a switch global register\r
-+* (debug only).\r
-+*/\r
-+void\r
-+mv_switchGlobalSet(int phyUnit, UINT32 regnum, UINT32 value)\r
-+{\r
-+    UINT32  phyBase;\r
-+\r
-+    if (mv_validPhyId(phyUnit)) {\r
-+\r
-+        phyBase = MV_PHYBASE(phyUnit);\r
-+\r
-+        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, regnum, value);\r
-+    }\r
-+}\r
-+\r
-+/*****************************************************************************\r
-+*\r
-+* mv_showATUDB - Dump the contents of the Address Translation Unit DataBase\r
-+* for the PHY switch associated with the specified phy.\r
-+*/\r
-+void\r
-+mv_showATUDB(int phyUnit)\r
-+{\r
-+    UINT32 phyBase;\r
-+    UINT16 ATUData;\r
-+    UINT16 ATUMac0;\r
-+    UINT16 ATUMac2;\r
-+    UINT16 ATUMac4;\r
-+    int portVec;\r
-+    int entryState;\r
-+\r
-+    if (!mv_validPhyId(phyUnit)) {\r
-+        PRINTF("Invalid port number: %d\n", phyUnit);\r
-+        return;\r
-+    }\r
-+\r
-+    phyBase = MV_PHYBASE(phyUnit);\r
-+    \r
-+    /* Wait for previous operation (if any) to complete */\r
-+    mv_waitWhileATUBusy(phyBase);\r
-+\r
-+    /* Initialize ATU MAC to all 1's */\r
-+    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0, 0xffff);\r
-+    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2, 0xffff);\r
-+    phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4, 0xffff);\r
-+\r
-+    PRINTF("   MAC ADDRESS    EntryState PortVector\n");\r
-+\r
-+    for(;;) {\r
-+        /* Tell hardware to get next MAC info */\r
-+        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_OPERATION, \r
-+                    MV_ATU_OP_GET_NEXT | MV_ATU_IS_BUSY);\r
-+\r
-+        mv_waitWhileATUBusy(phyBase);\r
-+\r
-+        ATUData = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_DATA);\r
-+        entryState = (ATUData & MV_ENTRYSTATE_MASK) >> MV_ENTRYSTATE_SHIFT;\r
-+\r
-+        if (entryState == 0) {\r
-+            /* We've hit the end of the list */\r
-+            break;\r
-+        }\r
-+\r
-+        ATUMac0 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR0);\r
-+        ATUMac2 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR2);\r
-+        ATUMac4 = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR, MV_ATU_MAC_ADDR4);\r
-+\r
-+        portVec    = (ATUData & MV_PORTVEC_MASK) >> MV_PORTVEC_SHIFT;\r
-+\r
-+        PRINTF("%02x:%02x:%02x:%02x:%02x:%02x    0x%02x       0x%02x\n",\r
-+               ATUMac0 >> 8,    /* MAC byte 0 */\r
-+               ATUMac0 & 0xff,  /* MAC byte 1 */\r
-+               ATUMac2 >> 8,    /* MAC byte 2 */\r
-+               ATUMac2 & 0xff,  /* MAC byte 3 */\r
-+               ATUMac4 >> 8,    /* MAC byte 4 */\r
-+               ATUMac4 & 0xff,  /* MAC byte 5 */\r
-+               entryState,\r
-+               portVec);\r
-+    }\r
-+}\r
-+\r
-+LOCAL BOOL countingGoodFrames;\r
-+\r
-+/*****************************************************************************\r
-+*\r
-+* mv_countGoodFrames - starts counting GOOD RX/TX frames per port\r
-+*/\r
-+void\r
-+mv_countGoodFrames(int phyUnit)\r
-+{\r
-+    UINT32 phyBase;\r
-+    UINT16 globalControl;\r
-+\r
-+    if (mv_validPhyId(phyUnit)) {\r
-+        /*\r
-+         * Guarantee that counters are cleared by\r
-+         * forcing CtrMode to toggle and end on GOODFRAMES.\r
-+         */\r
-+\r
-+        phyBase = MV_PHYBASE(phyUnit);\r
-+\r
-+        /* Read current Switch Global Control Register */\r
-+        globalControl = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
-+                                   MV_SWITCH_GLOBAL_CONTROL);\r
-+\r
-+        /* Set CtrMode to count BAD frames */\r
-+        globalControl = ((globalControl & ~MV_CTRMODE_MASK) |\r
-+                         MV_CTRMODE_BADFRAMES);\r
-+\r
-+        /* Push new value out to hardware */\r
-+        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
-+                    MV_SWITCH_GLOBAL_CONTROL, globalControl);\r
-+\r
-+        /* Now toggle CtrMode to count GOOD frames */\r
-+        globalControl = ((globalControl & ~MV_CTRMODE_MASK) |\r
-+                         MV_CTRMODE_GOODFRAMES);\r
-+\r
-+        /* Push new value out to hardware */\r
-+        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
-+                    MV_SWITCH_GLOBAL_CONTROL, globalControl);\r
-+\r
-+        countingGoodFrames = TRUE;\r
-+    }\r
-+}\r
-+\r
-+/*****************************************************************************\r
-+*\r
-+* mv_countBadFrames - starts counting BAD RX/TX frames per port\r
-+*/\r
-+void\r
-+mv_countBadFrames(int phyUnit)\r
-+{\r
-+    UINT32 phyBase;\r
-+    UINT16 globalControl;\r
-+\r
-+    if (mv_validPhyId(phyUnit)) {\r
-+        /*\r
-+         * Guarantee that counters are cleared by\r
-+         * forcing CtrMode to toggle and end on BADFRAMES.\r
-+         */\r
-+\r
-+        phyBase = MV_PHYBASE(phyUnit);\r
-+\r
-+        /* Read current Switch Global Control Register */\r
-+        globalControl = phyRegRead(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
-+                                   MV_SWITCH_GLOBAL_CONTROL);\r
-+\r
-+        /* Set CtrMode to count GOOD frames */\r
-+        globalControl = ((globalControl & ~MV_CTRMODE_MASK) |\r
-+                         MV_CTRMODE_GOODFRAMES);\r
-+\r
-+        /* Push new value out to hardware */\r
-+        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
-+                    MV_SWITCH_GLOBAL_CONTROL, globalControl);\r
-+\r
-+        /* Now toggle CtrMode to count BAD frames */\r
-+        globalControl = ((globalControl & ~MV_CTRMODE_MASK) |\r
-+                         MV_CTRMODE_BADFRAMES);\r
-+\r
-+        /* Push new value out to hardware */\r
-+        phyRegWrite(phyBase, MV_SWITCH_GLOBAL_ADDR,\r
-+                    MV_SWITCH_GLOBAL_CONTROL, globalControl);\r
-+\r
-+        countingGoodFrames = FALSE;\r
-+    }\r
-+}\r
-+\r
-+/*****************************************************************************\r
-+*\r
-+* mv_showFrameCounts - shows current GOOD/BAD Frame counts\r
-+*/\r
-+void\r
-+mv_showFrameCounts(int phyUnit)\r
-+{\r
-+    UINT16 rxCounter;\r
-+    UINT16 txCounter;\r
-+    UINT32 phyBase;\r
-+    UINT32 switchPortAddr;\r
-+\r
-+    if (!mv_validPhyId(phyUnit)) {\r
-+        return;\r
-+    }\r
-+\r
-+    phyBase = MV_PHYBASE(phyUnit);\r
-+    switchPortAddr = MV_SWITCH_PORT_ADDR(phyUnit);\r
-+\r
-+    rxCounter = phyRegRead(phyBase, switchPortAddr, MV_RX_COUNTER);\r
-+\r
-+    txCounter = phyRegRead(phyBase, switchPortAddr, MV_TX_COUNTER);\r
-+\r
-+    PRINTF("port%d %s frames: receive: %05d   transmit: %05d\n",\r
-+           phyUnit,\r
-+           (countingGoodFrames ? "good" : "error"),\r
-+           rxCounter,\r
-+           txCounter);\r
-+}\r
-+#endif\r
-diff -urN linux-2.4.32.new/arch/mips/ar531x/mvPhy.h linux-2.4.32.new-eth/arch/mips/ar531x/mvPhy.h\r
---- linux-2.4.32.new/arch/mips/ar531x/mvPhy.h  1970-01-01 01:00:00.000000000 +0100\r
-+++ linux-2.4.32.new-eth/arch/mips/ar531x/mvPhy.h      2005-12-25 11:54:39.775382608 +0000\r
-@@ -0,0 +1,160 @@\r
-+/*\r
-+ * This file is subject to the terms and conditions of the GNU General Public\r
-+ * License.  See the file "COPYING" in the main directory of this archive\r
-+ * for more details.\r
-+ *\r
-+ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
-+ */\r
-+\r
-+/*\r
-+ * mvPhy.h - definitions for the ethernet PHY -- Marvell 88E6060\r
-+ * All definitions in this file are operating system independent!\r
-+ */\r
-+\r
-+#ifndef MVPHY_H\r
-+#define MVPHY_H\r
-+\r
-+/*****************/\r
-+/* PHY Registers */\r
-+/*****************/\r
-+#define MV_PHY_CONTROL                 0\r
-+#define MV_PHY_STATUS                  1\r
-+#define MV_PHY_ID1                     2\r
-+#define MV_PHY_ID2                     3\r
-+#define MV_AUTONEG_ADVERT              4\r
-+#define MV_LINK_PARTNER_ABILITY        5\r
-+#define MV_AUTONEG_EXPANSION           6\r
-+#define MV_NEXT_PAGE_TRANSMIT          7\r
-+#define MV_LINK_PARTNER_NEXT_PAGE      8\r
-+#define MV_PHY_SPECIFIC_CONTROL_1     16\r
-+#define MV_PHY_SPECIFIC_STATUS        17\r
-+#define MV_PHY_INTERRUPT_ENABLE       18\r
-+#define MV_PHY_INTERRUPT_STATUS       19\r
-+#define MV_PHY_INTERRUPT_PORT_SUMMARY 20\r
-+#define MV_RECEIVE_ERROR_COUNTER      21\r
-+#define MV_LED_PARALLEL_SELECT        22\r
-+#define MV_LED_STREAM_SELECT_LEDS     23\r
-+#define MV_PHY_LED_CONTROL            24\r
-+#define MV_PHY_MANUAL_LED_OVERRIDE    25\r
-+#define MV_VCT_CONTROL                26\r
-+#define MV_VCT_STATUS                 27\r
-+#define MV_PHY_SPECIFIC_CONTROL_2     28\r
-+\r
-+/* MV_PHY_CONTROL fields */\r
-+#define MV_CTRL_SOFTWARE_RESET                    0x8000\r
-+#define MV_CTRL_AUTONEGOTIATION_ENABLE            0x1000\r
-+\r
-+/* MV_PHY_ID1 fields */\r
-+#define MV_PHY_ID1_EXPECTATION                    0x0141 /* OUI >> 6 */\r
-+\r
-+/* MV_PHY_ID2 fields */\r
-+#define MV_OUI_LSB_MASK                           0xfc00\r
-+#define MV_OUI_LSB_EXPECTATION                    0x0c00\r
-+#define MV_OUI_LSB_SHIFT                              10\r
-+#define MV_MODEL_NUM_MASK                         0x03f0\r
-+#define MV_MODEL_NUM_SHIFT                             4\r
-+#define MV_REV_NUM_MASK                           0x000f\r
-+#define MV_REV_NUM_SHIFT                               0\r
-+\r
-+/* MV_PHY_SPECIFIC_STATUS fields */\r
-+#define MV_STATUS_RESOLVED_SPEED_100              0x4000\r
-+#define MV_STATUS_RESOLVED_DUPLEX_FULL            0x2000\r
-+#define MV_STATUS_RESOLVED                        0x0800\r
-+#define MV_STATUS_REAL_TIME_LINK_UP               0x0400\r
-+\r
-+/* Check if autonegotiation is complete and link is up */\r
-+#define MV_AUTONEG_DONE(mv_phy_specific_status)                   \\r
-+    (((mv_phy_specific_status) &                                  \\r
-+        (MV_STATUS_RESOLVED | MV_STATUS_REAL_TIME_LINK_UP)) ==    \\r
-+        (MV_STATUS_RESOLVED | MV_STATUS_REAL_TIME_LINK_UP))\r
-+\r
-+\r
-+/*************************/\r
-+/* Switch Port Registers */\r
-+/*************************/\r
-+#define MV_PORT_STATUS                 0\r
-+#define MV_SWITCH_ID                   3\r
-+#define MV_PORT_CONTROL                4\r
-+#define MV_PORT_BASED_VLAN_MAP         6\r
-+#define MV_PORT_ASSOCIATION_VECTOR    11\r
-+#define MV_RX_COUNTER                 16\r
-+#define MV_TX_COUNTER                 17\r
-+\r
-+/* MV_SWITCH_ID fields */\r
-+#define MV_SWITCH_ID_DEV_MASK                       0xfff0\r
-+#define MV_SWITCH_ID_DEV_EXPECTATION                0x0600\r
-+#define MV_SWITCH_ID_DEV_SHIFT                           4\r
-+#define MV_SWITCH_ID_REV_MASK                       0x000f\r
-+#define MV_SWITCH_ID_REV_SHIFT                           0\r
-+\r
-+/* MV_PORT_CONTROL fields */\r
-+#define MV_PORT_CONTROL_PORT_STATE_MASK             0x0003\r
-+#define MV_PORT_CONTROL_PORT_STATE_DISABLED         0x0000\r
-+#define MV_PORT_CONTROL_PORT_STATE_FORWARDING       0x0003\r
-+\r
-+#define MV_PORT_CONTROL_EGRESS_MODE                 0x0100 /* Receive */\r
-+#define MV_PORT_CONTROL_INGRESS_TRAILER             0x4000 /* Transmit */\r
-+\r
-+#define MV_EGRESS_TRAILER_VALID                       0x80\r
-+#define MV_INGRESS_TRAILER_OVERRIDE                   0x80\r
-+\r
-+#define MV_PHY_TRAILER_SIZE                              4\r
-+\r
-+\r
-+/***************************/\r
-+/* Switch Global Registers */\r
-+/***************************/\r
-+#define MV_SWITCH_GLOBAL_STATUS        0\r
-+#define MV_SWITCH_MAC_ADDR0            1\r
-+#define MV_SWITCH_MAC_ADDR2            2\r
-+#define MV_SWITCH_MAC_ADDR4            3\r
-+#define MV_SWITCH_GLOBAL_CONTROL       4\r
-+#define MV_ATU_CONTROL                10\r
-+#define MV_ATU_OPERATION              11\r
-+#define MV_ATU_DATA                   12\r
-+#define MV_ATU_MAC_ADDR0              13\r
-+#define MV_ATU_MAC_ADDR2              14\r
-+#define MV_ATU_MAC_ADDR4              15\r
-+\r
-+/* MV_SWITCH_GLOBAL_STATUS fields */\r
-+#define MV_SWITCH_STATUS_READY_MASK  0x0800\r
-+\r
-+/* MV_SWITCH_GLOBAL_CONTROL fields */\r
-+#define MV_CTRMODE_MASK              0x0100\r
-+#define MV_CTRMODE_GOODFRAMES        0x0000\r
-+#define MV_CTRMODE_BADFRAMES         0x0100\r
-+\r
-+/* MV_ATU_CONTROL fields */\r
-+#define MV_ATUCTRL_ATU_LEARNDIS            0x4000\r
-+#define MV_ATUCTRL_ATU_SIZE_MASK     0x3000\r
-+#define MV_ATUCTRL_ATU_SIZE_SHIFT        12\r
-+#define MV_ATUCTRL_ATU_SIZE_DEFAULT       2 /* 1024 entry database */\r
-+#define MV_ATUCTRL_AGE_TIME_MASK     0x0ff0\r
-+#define MV_ATUCTRL_AGE_TIME_SHIFT         4\r
-+#define MV_ATUCTRL_AGE_TIME_DEFAULT      19 /* 19 * 16 = 304 seconds */\r
-+\r
-+/* MV_ATU_OPERATION fields */\r
-+#define MV_ATU_BUSY_MASK             0x8000\r
-+#define MV_ATU_IS_BUSY               0x8000\r
-+#define MV_ATU_IS_FREE               0x0000\r
-+#define MV_ATU_OP_MASK               0x7000\r
-+#define MV_ATU_OP_FLUSH_ALL          0x1000\r
-+#define MV_ATU_OP_GET_NEXT           0x4000\r
-+\r
-+/* MV_ATU_DATA fields */\r
-+#define MV_ENTRYPRI_MASK             0xc000\r
-+#define MV_ENTRYPRI_SHIFT                14\r
-+#define MV_PORTVEC_MASK              0x03f0\r
-+#define MV_PORTVEC_SHIFT                  4\r
-+#define MV_ENTRYSTATE_MASK           0x000f\r
-+#define MV_ENTRYSTATE_SHIFT               0\r
-+\r
-+/* PHY Address for the switch itself */\r
-+#define MV_SWITCH_GLOBAL_ADDR 0x1f\r
-+\r
-+BOOL    mv_phySetup(int ethUnit, UINT32 phyBase);\r
-+void    mv_phyCheckStatusChange(int ethUnit);\r
-+BOOL    mv_phyIsSpeed100(int ethUnit);\r
-+BOOL    mv_phyIsFullDuplex(int ethUnit);\r
-+\r
-+#endif /* MVPHY_H */\r
-diff -urN linux-2.4.32.new/arch/mips/ar531x/rtPhy.c linux-2.4.32.new-eth/arch/mips/ar531x/rtPhy.c\r
---- linux-2.4.32.new/arch/mips/ar531x/rtPhy.c  1970-01-01 01:00:00.000000000 +0100\r
-+++ linux-2.4.32.new-eth/arch/mips/ar531x/rtPhy.c      2005-12-25 11:54:46.086423184 +0000\r
-@@ -0,0 +1,272 @@\r
-+/*\r
-+ * This file is subject to the terms and conditions of the GNU General Public\r
-+ * License.  See the file "COPYING" in the main directory of this archive\r
-+ * for more details.\r
-+ *\r
-+ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
-+ */\r
-+\r
-+/*\r
-+ * Manage the ethernet PHY.\r
-+ * This code supports a simple 1-port ethernet phy, Realtek RTL8201BL,\r
-+ * and compatible PHYs, such as the Kendin KS8721B.\r
-+ * All definitions in this file are operating system independent!\r
-+ */\r
-+\r
-+#if defined(linux)\r
-+#include <linux/config.h>\r
-+#include <linux/types.h>\r
-+#include <linux/netdevice.h>\r
-+#include <linux/etherdevice.h>\r
-+#include <linux/delay.h>\r
-+\r
-+#include "ar531xlnx.h"\r
-+#endif\r
-+\r
-+#if defined(__ECOS)\r
-+#include "ae531xecos.h"\r
-+#endif\r
-+\r
-+\r
-+#include "ae531xmac.h"\r
-+#include "ae531xreg.h"\r
-+#include "rtPhy.h"\r
-+\r
-+#if /* DEBUG */ 1\r
-+#define RT_DEBUG_ERROR     0x00000001\r
-+#define RT_DEBUG_PHYSETUP  0x00000002\r
-+#define RT_DEBUG_PHYCHANGE 0x00000004\r
-+\r
-+int rtPhyDebug = RT_DEBUG_ERROR;\r
-+\r
-+#define RT_PRINT(FLG, X)                            \\r
-+{                                                   \\r
-+    if (rtPhyDebug & (FLG)) {                       \\r
-+        DEBUG_PRINTF X;                             \\r
-+    }                                               \\r
-+}\r
-+#else\r
-+#define RT_PRINT(FLG, X)\r
-+#endif\r
-+\r
-+/*\r
-+ * Track per-PHY port information.\r
-+ */\r
-+typedef struct {\r
-+    BOOL   phyAlive;    /* last known state of link */\r
-+    UINT32 phyBase;\r
-+    UINT32 phyAddr;\r
-+} rtPhyInfo_t;\r
-+\r
-+#define ETH_PHY_ADDR          1\r
-+\r
-+/*\r
-+ * This table defines the mapping from phy units to\r
-+ * per-PHY information.\r
-+ *\r
-+ * This table is somewhat board-dependent.\r
-+ */\r
-+rtPhyInfo_t rtPhyInfo[] = {\r
-+    {phyAlive: FALSE,  /* PHY 0 */\r
-+     phyBase: 0,       /* filled in by rt_phySetup */\r
-+     phyAddr: ETH_PHY_ADDR},                             \r
-+\r
-+    {phyAlive: FALSE,  /* PHY 1 */\r
-+     phyBase: 0,       /* filled in by rt_phySetup */\r
-+     phyAddr: ETH_PHY_ADDR}\r
-+};\r
-+\r
-+/* Convert from phy unit# to (phyBase, phyAddr) pair */\r
-+#define RT_PHYBASE(phyUnit) (rtPhyInfo[phyUnit].phyBase)\r
-+#define RT_PHYADDR(phyUnit) (rtPhyInfo[phyUnit].phyAddr)\r
-+\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* rt_phySetup - reset and setup the PHY associated with\r
-+* the specified MAC unit number.\r
-+*\r
-+* Resets the associated PHY port.\r
-+*\r
-+* RETURNS:\r
-+*    TRUE  --> associated PHY is alive\r
-+*    FALSE --> no LINKs on this ethernet unit\r
-+*/\r
-+\r
-+BOOL\r
-+rt_phySetup(int ethUnit, UINT32 phyBase)\r
-+{\r
-+    BOOL    linkAlive = FALSE;\r
-+    UINT32  phyAddr;\r
-+\r
-+    RT_PHYBASE(ethUnit) = phyBase;\r
-+\r
-+    phyAddr = RT_PHYADDR(ethUnit);\r
-+\r
-+    /* Reset phy */\r
-+    phyRegWrite(phyBase, phyAddr, GEN_ctl, PHY_SW_RST | AUTONEGENA);\r
-+\r
-+    sysMsDelay(1500);\r
-+\r
-+    return linkAlive;\r
-+}\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* rt_phyIsDuplexFull - Determines whether the phy ports associated with the\r
-+* specified device are FULL or HALF duplex.\r
-+*\r
-+* RETURNS:\r
-+*    TRUE  --> FULL\r
-+*    FALSE --> HALF\r
-+*/\r
-+BOOL\r
-+rt_phyIsFullDuplex(int ethUnit)\r
-+{\r
-+    UINT16  phyCtl;\r
-+    UINT32  phyBase;\r
-+    UINT32  phyAddr;\r
-+\r
-+    phyBase = RT_PHYBASE(ethUnit);\r
-+    phyAddr = RT_PHYADDR(ethUnit);\r
-+\r
-+    phyCtl = phyRegRead(phyBase, phyAddr, GEN_ctl);\r
-+\r
-+    if (phyCtl & DUPLEX) {\r
-+        return TRUE;\r
-+    } else {\r
-+        return FALSE;\r
-+    }\r
-+}\r
-+\r
-+/******************************************************************************\r
-+*\r
-+* rt_phyIsSpeed100 - Determines the speed of phy ports associated with the\r
-+* specified device.\r
-+*\r
-+* RETURNS:\r
-+*    TRUE --> 100Mbit\r
-+*    FALSE --> 10Mbit\r
-+*/\r
-+BOOL\r
-+rt_phyIsSpeed100(int phyUnit)\r
-+{\r
-+    UINT16  phyLpa;\r
-+    UINT32  phyBase;\r
-+    UINT32  phyAddr;\r
-+\r
-+    phyBase = RT_PHYBASE(phyUnit);\r
-+    phyAddr = RT_PHYADDR(phyUnit);\r
-+\r
-+    phyLpa = phyRegRead(phyBase, phyAddr, AN_lpa);\r
-+\r
-+    if (phyLpa & (LPA_TXFD | LPA_TX)) {\r
-+        return TRUE;\r
-+    } else {\r
-+        return FALSE;\r
-+    }\r
-+}\r
-+\r
-+/*****************************************************************************\r
-+*\r
-+* rt_phyCheckStatusChange -- checks for significant changes in PHY state.\r
-+*\r
-+* A "significant change" is:\r
-+*     dropped link (e.g. ethernet cable unplugged) OR\r
-+*     autonegotiation completed + link (e.g. ethernet cable plugged in)\r
-+*\r
-+* On AR5311, there is a 1-to-1 mapping of ethernet units to PHYs.\r
-+* When a PHY is plugged in, phyLinkGained is called.\r
-+* When a PHY is unplugged, phyLinkLost is called.\r
-+*/\r
-+void\r
-+rt_phyCheckStatusChange(int ethUnit)\r
-+{\r
-+    UINT16          phyHwStatus;\r
-+    rtPhyInfo_t     *lastStatus = &rtPhyInfo[ethUnit];\r
-+    UINT32          phyBase;\r
-+    UINT32          phyAddr;\r
-+\r
-+    phyBase = RT_PHYBASE(ethUnit);\r
-+    phyAddr = RT_PHYADDR(ethUnit);\r
-+\r
-+    phyHwStatus = phyRegRead(phyBase, phyAddr, GEN_sts);\r
-+\r
-+    if (lastStatus->phyAlive) { /* last known status was ALIVE */\r
-+        /* See if we've lost link */\r
-+        if (!(phyHwStatus & LINK)) {\r
-+            RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link down\n", ethUnit));\r
-+            lastStatus->phyAlive = FALSE;\r
-+            phyLinkLost(ethUnit);\r
-+        }\r
-+    } else { /* last known status was DEAD */\r
-+        /* Check for AN complete */\r
-+        if ((phyHwStatus & (AUTOCMPLT | LINK)) == (AUTOCMPLT | LINK)) {\r
-+            RT_PRINT(RT_DEBUG_PHYCHANGE,("\nethmac%d link up\n", ethUnit));\r
-+            lastStatus->phyAlive = TRUE;\r
-+            phyLinkGained(ethUnit);\r
-+        }\r
-+    }\r
-+}\r
-+\r
-+#if DEBUG\r
-+\r
-+/* Define the PHY registers of interest for a phyShow command */\r
-+struct rtRegisterTable_s {\r
-+    UINT32 regNum;\r
-+    char  *regIdString;\r
-+} rtRegisterTable[] =\r
-+{\r
-+    {GEN_ctl,    "Basic Mode Control (GEN_ctl)    "},\r
-+    {GEN_sts,    "Basic Mode Status (GEN_sts)     "},\r
-+    {GEN_id_hi,  "PHY Identifier 1 (GET_id_hi)    "},\r
-+    {GEN_id_lo,  "PHY Identifier 2 (GET_id_lo)    "},\r
-+    {AN_adv,     "Auto-Neg Advertisement (AN_adv) "},\r
-+    {AN_lpa,     "Auto-Neg Link Partner Ability   "},\r
-+    {AN_exp,     "Auto-Neg Expansion              "},\r
-+};\r
-+\r
-+int rtNumRegs = sizeof(rtRegisterTable) / sizeof(rtRegisterTable[0]);\r
-+\r
-+/*\r
-+ * Dump the state of a PHY.\r
-+ */\r
-+void\r
-+rt_phyShow(int phyUnit)\r
-+{\r
-+    int i;\r
-+    UINT16  value;\r
-+    UINT32  phyBase;\r
-+    UINT32  phyAddr;\r
-+\r
-+    phyBase = RT_PHYBASE(phyUnit);\r
-+    phyAddr = RT_PHYADDR(phyUnit);\r
-+\r
-+    printf("PHY state for ethphy%d\n", phyUnit);\r
-+\r
-+    for (i=0; i<rtNumRegs; i++) {\r
-+\r
-+        value = phyRegRead(phyBase, phyAddr, rtRegisterTable[i].regNum);\r
-+\r
-+        printf("Reg %02d (0x%02x) %s = 0x%08x\n",\r
-+            rtRegisterTable[i].regNum, rtRegisterTable[i].regNum,\r
-+            rtRegisterTable[i].regIdString, value);\r
-+    }\r
-+}\r
-+\r
-+/*\r
-+ * Modify the value of a PHY register.\r
-+ * This makes it a bit easier to modify PHY values during debug.\r
-+ */\r
-+void\r
-+rt_phySet(int phyUnit, UINT32 regnum, UINT32 value)\r
-+{\r
-+    UINT32  phyBase;\r
-+    UINT32  phyAddr;\r
-+\r
-+    phyBase = RT_PHYBASE(phyUnit);\r
-+    phyAddr = RT_PHYADDR(phyUnit);\r
-+\r
-+    phyRegWrite(phyBase, phyAddr, regnum, value);\r
-+}\r
-+#endif\r
-diff -urN linux-2.4.32.new/arch/mips/ar531x/rtPhy.h linux-2.4.32.new-eth/arch/mips/ar531x/rtPhy.h\r
---- linux-2.4.32.new/arch/mips/ar531x/rtPhy.h  1970-01-01 01:00:00.000000000 +0100\r
-+++ linux-2.4.32.new-eth/arch/mips/ar531x/rtPhy.h      2005-12-25 11:54:46.089422728 +0000\r
-@@ -0,0 +1,50 @@\r
-+/*\r
-+ * This file is subject to the terms and conditions of the GNU General Public\r
-+ * License.  See the file "COPYING" in the main directory of this archive\r
-+ * for more details.\r
-+ *\r
-+ * Copyright © 2003 Atheros Communications, Inc.,  All Rights Reserved.\r
-+ */\r
-+\r
-+/*\r
-+ * rtPhy.h - definitions for the ethernet PHY.\r
-+ * This code supports a simple 1-port ethernet phy, Realtek RTL8201BL,\r
-+ * and compatible PHYs, such as the Kendin KS8721B.\r
-+ * All definitions in this file are operating system independent!\r
-+ */\r
-+\r
-+#ifndef RTPHY_H\r
-+#define RTPHY_H\r
-+\r
-+/* MII Registers */\r
-+\r
-+#define       GEN_ctl         00\r
-+#define       GEN_sts         01\r
-+#define       GEN_id_hi       02\r
-+#define       GEN_id_lo       03\r
-+#define       AN_adv          04\r
-+#define       AN_lpa          05\r
-+#define       AN_exp          06\r
-+\r
-+/* GEN_ctl */ \r
-+#define       PHY_SW_RST      0x8000\r
-+#define       LOOPBACK        0x4000\r
-+#define       SPEED           0x2000  /* 100 Mbit/s */\r
-+#define       AUTONEGENA      0x1000\r
-+#define       DUPLEX          0x0100  /* Duplex mode */\r
-+\r
-+              \r
-+/* GEN_sts */\r
-+#define       AUTOCMPLT       0x0020  /* Autonegotiation completed */\r
-+#define       LINK            0x0004  /* Link status */\r
-+\r
-+/* GEN_ids */\r
-+#define RT_PHY_ID1_EXPECTATION  0x22\r
-+\r
-+/* AN_lpa */\r
-+#define       LPA_TXFD        0x0100  /* Link partner supports 100 TX Full Duplex */\r
-+#define       LPA_TX          0x0080  /* Link partner supports 100 TX Half Duplex */\r
-+#define       LPA_10FD        0x0040  /* Link partner supports 10 BT Full Duplex */\r
-+#define       LPA_10          0x0020  /* Link partner supports 10 BT Half Duplex */\r
-+\r
-+#endif /* RTPHY_H */\r