diff -Naru linux-2.6.16_orig/drivers/net/netxen/netxen_nic_isr.c 
linux-2.6.16/drivers/net/netxen/netxen_nic_isr.c
--- linux-2.6.16_orig/drivers/net/netxen/netxen_nic_isr.c       1969-12-31 
16:00:00.000000000 -0800
+++ linux-2.6.16/drivers/net/netxen/netxen_nic_isr.c    2006-03-24 
14:13:57.000000000 -0800
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2003 - 2006 NetXen Inc.
+ * All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *                            
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *                                   
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ * 
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.
+ * 
+ * Contact Information:
+ *    [EMAIL PROTECTED]
+ * NetXen, 3965 Freedom Circle, Fourth Floor,
+ * Santa Clara, CA 95054
+ */
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+
+#include "netxen_nic.h"
+#include "netxen_nic_hw.h"
+#include "nic_cmn.h"
+#include "nic_phan_reg.h"
+
+extern struct netxen_adapter_s  *g_adapter;
+extern  spinlock_t            hal_lock;
+
+long
+netxen_nic_enable_phy_interrupts (netxen_adapter *adapter, long portno)
+{
+        long result = 0;
+       unsigned long flags;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                result = netxen_niu_gbe_enable_phy_interrupts (portno);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        case NetXen_NIC_XGBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                result = netxen_niu_xg_enable_phy_interrupts (portno);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return result;
+}
+
+long
+netxen_nic_disable_phy_interrupts (netxen_adapter *adapter, long portno)
+{
+        long result = 0;
+       unsigned long flags;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                result = netxen_niu_gbe_disable_phy_interrupts (portno);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        case NetXen_NIC_XGBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                result = netxen_niu_xg_disable_phy_interrupts (portno);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return result;
+}
+
+long
+netxen_nic_clear_phy_interrupts (netxen_adapter *adapter, long portno)
+{
+        long result = 0;
+       unsigned long flags;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                result = netxen_niu_gbe_clear_phy_interrupts (portno);
+                spin_unlock_irqrestore(&hal_lock, flags);
+
+                break;
+
+        case NetXen_NIC_XGBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                result = netxen_niu_xg_disable_phy_interrupts (portno);
+                spin_unlock_irqrestore(&hal_lock, flags);
+
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return result;
+}
+
+void
+netxen_nic_set_mii_mode (netxen_adapter *adapter, long portno, long enable)
+{
+       unsigned long flags;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                netxen_niu_gbe_set_mii_mode (portno, enable);
+                spin_unlock_irqrestore(&hal_lock, flags);
+
+                break;
+
+        case NetXen_NIC_XGBE:
+                printk(KERN_ERR "%s: Function %s is not implemented for XG\n",
+                                netxen_nic_driver_name,__FUNCTION__);
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return;
+}
+
+void
+netxen_nic_set_gmii_mode(netxen_adapter *adapter, long portno, long enable)
+{
+        unsigned long flags;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                spin_lock_irqsave(&hal_lock, flags);
+                g_adapter = adapter;
+                netxen_niu_gbe_set_gmii_mode (portno, enable);
+                spin_unlock_irqrestore(&hal_lock, flags);
+                break;
+
+        case NetXen_NIC_XGBE:
+                printk(KERN_ERR "%s: Function %s is not implemented for XG\n",
+                                netxen_nic_driver_name,__FUNCTION__);
+                break;
+
+        default:
+                printk(KERN_ERR "%s: Unknown board 
type\n",netxen_nic_driver_name);
+        }
+
+        return;
+}
+
+void
+netxen_indicate_link_status(netxen_adapter *adapter, u32 portno, u32 link)
+{
+        struct netxen_port *pport = adapter->port[portno];
+        struct net_device        *netdev = pport->netdev;
+
+        if(link)
+                netif_carrier_on(netdev);
+        else
+                netif_carrier_off(netdev);
+}
+
+void
+netxen_handle_port_int(netxen_adapter *adapter,u32 portno, u32 enable)
+{
+        u32                      intr;
+        netxen_niu_phy_interrupt_t *int_src;
+        struct netxen_port         *port;
+       unsigned long            flags;
+
+        DPRINTK(1,INFO,"INSIDE handle port int for Port = %d \n",portno);
+
+        /*  This should clear the interrupt source */
+        
netxen_nic_phy_read(adapter,portno,NetXen_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
+                                &intr);
+        if (intr == 0) {
+                DPRINTK(1, INFO, "No phy interrupts for port #%d\n", portno);
+                return;
+        }
+        int_src = (netxen_niu_phy_interrupt_t *)&intr;
+       netxen_nic_disable_phy_interrupts (adapter, portno);
+
+        port = adapter->port[portno];
+
+        /* IND for testing print out all the interrupts received */
+        if(int_src->jabber)
+                DPRINTK(2,INFO,"NetXen: %s Jabber interrupt \n",
+                                port->netdev->name);
+
+        if(int_src->polarity_changed)
+                DPRINTK(2,INFO,"NetXen: %s POLARITY CHANGED int \n",
+                                port->netdev->name);
+
+        if(int_src->energy_detect)
+                DPRINTK(2,INFO,"NetXen: %s ENERGY DETECT INT \n",
+                                port->netdev->name);
+
+        if(int_src->downshift)
+                DPRINTK(2,INFO,"NetXen: %s DOWNSHIFT INT \n",
+                                port->netdev->name);
+        // write it down later..
+
+        if ((int_src->speed_changed) || (int_src->link_status_changed)) {
+                netxen_niu_phy_status_t status;
+
+                DPRINTK(2, INFO, "NetXen: %s SPEED CHANGED OR"
+                                        " LINK STATUS CHANGED \n",
+                                        port->netdev->name);
+
+                if (netxen_nic_phy_read(adapter,portno,
+                                        NetXen_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+                                        (netxen_crbword_t *)&status) == 0) {
+                        if(int_src->link_status_changed) {
+                                if(status.link) {
+                                       spin_lock_irqsave(&hal_lock, flags);
+                                       g_adapter = adapter;
+                                       netxen_niu_gbe_init_port(portno);
+                                       spin_unlock_irqrestore(&hal_lock, 
flags);
+                                        printk("%s: %s Link UP\n",
+                                               netxen_nic_driver_name,
+                                               port->netdev->name);
+
+                                } else {
+                                        printk("%s: %s Link DOWN\n",
+                                               netxen_nic_driver_name,
+                                                port->netdev->name);
+                                }
+                                netxen_indicate_link_status(adapter, portno,
+                                                                status.link);
+                        }
+                }
+        }
+        netxen_nic_enable_phy_interrupts (adapter, portno);
+}
+
+void
+netxen_nic_isr_other(struct netxen_adapter_s *adapter)
+{
+        u32 enable, portno;
+        u32 i2qhi;
+
+        /*
+         * bit 3 is for i2qInt, if high its enabled
+         * check for phy interrupts
+         * read vector and check for bit 45 for phy
+         * clear int by writing the same value into ISR_INT_VECTOR REG
+         */
+
+        DPRINTK(1, INFO, "I2Q is the source of INT \n");
+
+        // IND verify the offset
+        //netxen_nic_hw_read(adapter,NetXen_I2Q_CLR_PCI_HI,&i2qhi,4);
+        read_lock(&adapter->adapter_lock);
+        i2qhi = 
NetXen_NIC_PCI_READ_32(CRB_NORMALIZE(adapter,NetXen_I2Q_CLR_PCI_HI));
+        read_unlock(&adapter->adapter_lock);
+
+        DPRINTK(1, INFO, "isr NetXen_I2Q_CLR_PCI_HI = 0x%x \n",i2qhi);
+
+        if (i2qhi & 0x4000) {
+                for (portno = 0; portno < NetXen_NIU_MAX_GBE_PORTS; portno++) {
+                        DPRINTK(1, INFO, "External PHY interrupt ON PORT %d\n",
+                                                portno);
+
+                        enable = 1;
+                        netxen_handle_port_int(adapter, portno, enable);
+                }
+
+                /* Clear the interrupt on I2Q */
+                //netxen_nic_hw_write(adapter,NetXen_I2Q_CLR_PCI_HI ,&i2qhi,4);
+                read_lock(&adapter->adapter_lock);
+                NetXen_NIC_PCI_WRITE_32((__uint32_t) i2qhi,
+                                CRB_NORMALIZE(adapter, NetXen_I2Q_CLR_PCI_HI));
+                read_unlock(&adapter->adapter_lock);
+
+        }
+}
+
+void
+netxen_nic_handle_phy_intr(struct netxen_adapter_s *adapter)
+{
+        uint32_t  val, val1;
+
+        switch (adapter->ahw.board_type) {
+        case NetXen_NIC_GBE:
+                //_netxen_nic_read_crb_wx(adapter, ISR_INT_VECTOR, &val);
+               val = NetXen_NIC_PCI_READ_32(CRB_NORMALIZE(adapter, 
ISR_INT_VECTOR));
+                if (val & 0x4) {
+                        adapter->stats.otherints++;
+                        netxen_nic_isr_other(adapter);
+                }
+                break;
+
+        case NetXen_NIC_XGBE:
+                {
+                struct net_device  *netdev = adapter->port[0]->netdev;
+
+                /* WINDOW = 1 */
+                //netxen_nic_read_crb_w1(adapter, CRB_XG_STATE, &val1);
+                read_lock(&adapter->adapter_lock);
+                val1 = NetXen_NIC_PCI_READ_32(
+                                        CRB_NORMALIZE(adapter, CRB_XG_STATE));
+                read_unlock(&adapter->adapter_lock);
+
+                if (adapter->ahw.xg_linkup == 1 && val1 != XG_LINK_UP) {
+                        printk(KERN_INFO "%s: %s NIC Link is down\n",
+                               netxen_nic_driver_name, netdev->name);
+                        adapter->ahw.xg_linkup= 0;
+                        /* read twice to clear sticky bits */
+                        /* WINDOW = 0 */
+                        /*netxen_nic_read_crb_w0(adapter, NetXen_NIU_XG_STATUS,
+                                                        &val1);
+                        netxen_nic_read_crb_w0(adapter, NetXen_NIU_XG_STATUS,
+                                                        &val1);*/
+                        netxen_nic_read_w0(adapter, NetXen_NIU_XG_STATUS,
+                                                        &val1);
+                        netxen_nic_read_w0(adapter, NetXen_NIU_XG_STATUS,
+                                                        &val1);
+
+                        if ((val1 & 0xffb ) != 0xffb) {
+                                printk(KERN_INFO "%s ISR: Sync/Align BAD: 
0x%08x\n",
+                                       netxen_nic_driver_name, val1);
+                        }
+
+                } else if(adapter->ahw.xg_linkup == 0 && val1 == XG_LINK_UP) {
+                        printk(KERN_INFO "%s: %s NIC Link is up\n",
+                                        netxen_nic_driver_name, netdev->name);
+                        adapter->ahw.xg_linkup= 1;
+                }
+
+                }
+                break;
+
+        default:
+                printk(KERN_ERR "%s ISR: Unknown board type\n",
+                               netxen_nic_driver_name);
+        }
+
+        return;
+}
diff -Naru linux-2.6.16_orig/drivers/net/netxen/xge_mdio.c 
linux-2.6.16/drivers/net/netxen/xge_mdio.c
--- linux-2.6.16_orig/drivers/net/netxen/xge_mdio.c     1969-12-31 
16:00:00.000000000 -0800
+++ linux-2.6.16/drivers/net/netxen/xge_mdio.c  2006-03-24 14:13:57.000000000 
-0800
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2003 - 2006 NetXen Inc.
+ * All rights reserved.
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *                            
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *                                   
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA  02111-1307, USA.
+ * 
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.
+ * 
+ * Contact Information:
+ *    [EMAIL PROTECTED]
+ * NetXen, 3965 Freedom Circle, Fourth Floor,
+ * Santa Clara, CA 95054
+ */
+/******************************************************************************
+*
+*  xge_mdio.c   Routines to control the Management Data Input Ouput (MDIO) port
+*               for the Aeluros 10Gps Transceiver connected to Phantom II's
+*               XGe interface.
+*
+*******************************************************************************
+*/
+
+#include "netxen_inc.h"
+
+/* opcodes defines by Aerulos */
+#define OPCODE_ADDR  0
+#define OPCODE_WRITE 1
+#define OPCODE_RINCR 2
+#define OPCODE_READ  3
+
+/* The MDC/MDIO signals are hooked up to the follwing Phantom GPIO signals */
+#define MDC_GPIO 7
+#define MDIO_GPIO 8
+
+/* Bit 1 of the GPIO reg is Output Enable */
+#define GPIO_OE 2
+
+/* Bit 0 of GPIO reg is data bit */
+#define GPIO_LO 0
+#define GPIO_HI 1
+
+/* Set MDC high or low for clocking data */
+#define MDC_LOW() NetXen_CRB_WRITELIT(NetXen_ROMUSB_GPIO(MDC_GPIO),(GPIO_OE | 
GPIO_LO))
+#define MDC_HI() NetXen_CRB_WRITELIT(NetXen_ROMUSB_GPIO(MDC_GPIO), (GPIO_OE | 
GPIO_HI))
+
+/* set the data bit */
+#define SET_MDIO(bit) 
NetXen_CRB_WRITELIT(NetXen_ROMUSB_GPIO(MDIO_GPIO),(GPIO_OE | (bit)))
+
+/* If necessary, delay beteen each clock */
+#define MDIO_DELAY()
+
+/* The preamble is 32 clocks of high data */
+void PREAMBLE(void) {
+    long i;
+    for (i=0; i< 32;i++) {
+        MDC_LOW();
+        SET_MDIO(1);
+        MDIO_DELAY();
+        MDC_HI();
+        MDIO_DELAY();
+    }
+}
+
+/* data transitions when MDC is low */
+void CLOCK_IN_BITS(long data,long len) {
+    long i;
+    for (i=0;i<len;i++) {
+        MDC_LOW();
+        SET_MDIO((data >>(len - (i + 1))) & 1);
+        MDIO_DELAY();
+        MDC_HI();
+        MDIO_DELAY();
+    }
+}
+
+#define GET_BIT() ((NetXen_CRB_READ_VAL(NetXen_ROMUSB_GLB_PAD_GPIO_I) >> 
MDIO_GPIO) & 1)
+
+/* data transitions when MDC is low */
+long CLOCK_OUT_BITS(void) {
+    long i;
+    long result=0;
+
+    /* Don't drive MDIO output */
+    NetXen_CRB_WRITELIT(NetXen_ROMUSB_GPIO(MDIO_GPIO),0x0);\
+
+    for (i=0;i<16;i++) {
+        MDC_LOW();
+        MDIO_DELAY();
+        result |= (GET_BIT() << (15-i));
+        MDIO_DELAY();
+        MDC_HI();
+        MDIO_DELAY();
+    }
+    return result;
+}
+
+/* Turn off Output Enable on the GPIO */
+#define HI_Z()  \
+    do {\
+        NetXen_CRB_WRITELIT(NetXen_ROMUSB_GPIO(MDC_GPIO),0x0);\
+        NetXen_CRB_WRITELIT(NetXen_ROMUSB_GPIO(MDIO_GPIO),0x0);\
+    } while(0)
+
+
+/* The STart of Frame (SOF) is two clocks of low data */
+#define SOF() CLOCK_IN_BITS(0,2)
+
+/* The opcode is two bits, high bit first  */
+#define OPCODE(opcode)  CLOCK_IN_BITS((opcode),2)
+
+/* The port is five bits, high bit first  */
+#define PORT_ADDRESS(port)  CLOCK_IN_BITS((port),5)
+
+/* The devaddr is five bits, high bit first  */
+#define DEV_ADDRESS(dev)  CLOCK_IN_BITS((dev),5)
+
+/* The turnaround is two clocks - high, then low */
+#define TURNAROUND() CLOCK_IN_BITS(2,2)
+
+#define ADDR_DATA(addr_data) CLOCK_IN_BITS((addr_data),16)
+
+#define MDIO_WR_CYCLE(opcode, port, dev, addr_data) \
+    do { \
+        PREAMBLE(); \
+        SOF(); \
+        OPCODE((opcode)); \
+        PORT_ADDRESS((port)); \
+        DEV_ADDRESS((dev)); \
+        TURNAROUND(); \
+        ADDR_DATA((addr_data)); \
+    } while (0)
+
+#define RD_DATA() CLOCK_OUT_BITS()
+
+#define MDIO_RD_CYCLE(opcode, port, dev, data) \
+    do { \
+        PREAMBLE(); \
+        SOF(); \
+        OPCODE((opcode)); \
+        PORT_ADDRESS((port)); \
+        DEV_ADDRESS((dev)); \
+        TURNAROUND(); \
+        data = RD_DATA(); \
+    } while (0)
+
+void netxen_xge_mdio_wr (long devaddr, long addr, long data) {
+
+    /* first, write the address */
+    MDIO_WR_CYCLE(OPCODE_ADDR,0,devaddr,addr);
+
+    /* then, write the data */
+    MDIO_WR_CYCLE(OPCODE_WRITE,0,devaddr,data);
+}
+
+long netxen_xge_mdio_rd (long devaddr, long addr) {
+    long data;
+
+    /* first, write the address */
+    MDIO_WR_CYCLE(OPCODE_ADDR,0,devaddr,addr);
+
+    /* then, read the data */
+    MDIO_RD_CYCLE(OPCODE_READ,0,devaddr,data);
+
+    return data;
+}
+
+
+/* AEL1002 supports 3 device addresses: 1(PMA/PMD), 3(PCS), and 4(PHY XS) */
+#define DEV_PMA_PMD 1
+#define DEV_PCS     3
+#define DEV_PHY_XS  4
+
+/* Aeluros-specific registers use device address 1 */
+#define AEL_POWERDOWN_REG   0xc011
+#define AEL_TX_CONFIG_REG_1 0xc002
+#define AEL_LOOPBACK_EN_REG 0xc017
+#define AEL_MODE_SEL_REG    0xc001
+
+#define PMD_RESET          0
+#define PMD_STATUS         1
+#define PMD_IDENTIFIER     2
+#define PCS_STATUS_REG     0x20
+
+#define PMD_ID_QUAKE 0x43
+#define PMD_ID_MYSTICOM 0x240
+#define PCS_CONTROL 0
+
+#define PHY_XS_LANE_STATUS_REG 0x18
+
+/* Turn on the GPIO lines used for MDC/MDIO. They can alternately be used as
+ *  test mux data.
+ */
+void  netxen_xge_mdio_enable(void) {
+    long data;
+
+    /* GPIO bits are [31:16] in the test mux sel register */
+    /* Turn off the bit to enable GPIO */
+    data = NetXen_CRB_READ_VAL(NetXen_ROMUSB_GLB_TEST_MUX_SEL);
+    data &= ~(0x10000 << MDC_GPIO);
+    data &= ~(0x10000 << MDIO_GPIO);
+    NetXen_CRB_WRITELIT(NetXen_ROMUSB_GLB_TEST_MUX_SEL,data);
+
+    /* Turn off OE for MDC and MDIO */
+    HI_Z();
+}
+
+long xge_link_status (void) {
+    long rv = XG_LINK_DOWN;
+    long data;
+    data = netxen_xge_mdio_rd(DEV_PMA_PMD,PMD_IDENTIFIER);
+    if (data == PMD_ID_QUAKE || data == PMD_ID_MYSTICOM) {
+        /* Quake PHY */
+
+        /* check link - read twice to clear sticky bits */
+        data = netxen_xge_mdio_rd(DEV_PMA_PMD,PMD_STATUS);
+        data = netxen_xge_mdio_rd(DEV_PMA_PMD,PMD_STATUS);
+
+        if (data & 0x4) {
+            /* Rx link is up */
+            rv = XG_LINK_UP;
+        } else {
+            rv = XG_LINK_DOWN;
+        }
+
+    } else {
+        data = netxen_xge_mdio_rd(DEV_PCS,PCS_STATUS_REG);
+        if ((data & 0x1000) == 0x1000) {
+            rv = XG_LINK_UP;
+        }
+    }
+    return rv;
+}
+
+/* For Mysticom M3128 */
+void xge_m3128_clear_int(void) {
+    /* For Mysticom M3128, clear 3.c005 that shows link up/down event. */
+    netxen_xge_mdio_wr(3, 0xc005, -1);
+}
+/* Initialize the Aeluros device. To be done when link first comes up */
+long xge_mdio_init(void) {
+    long rv=0;
+    long data;
+
+    netxen_xge_mdio_enable();
+    data = netxen_xge_mdio_rd(DEV_PMA_PMD,PMD_IDENTIFIER);
+    if (data == PMD_ID_QUAKE ) {
+        /* Quake PHY */
+        /* reset PHY */
+        netxen_xge_mdio_wr(DEV_PCS,PCS_CONTROL, 0x8000 );
+
+        /* check link - read twice to clear sticky bits */
+        data = netxen_xge_mdio_rd(DEV_PMA_PMD,PMD_STATUS);
+        data = netxen_xge_mdio_rd(DEV_PMA_PMD,PMD_STATUS);
+
+        if(! (data & 0x4)) {
+            rv |= 2;
+        }
+
+    } else if (data == PMD_ID_MYSTICOM) {
+        /* Mysticom PHY */
+        /* reset PHY */
+        netxen_xge_mdio_wr(DEV_PCS,PCS_CONTROL, 0x8000 );
+
+        /* check link - read twice to clear sticky bits */
+        data = netxen_xge_mdio_rd(DEV_PMA_PMD,PMD_STATUS);
+        data = netxen_xge_mdio_rd(DEV_PMA_PMD,PMD_STATUS);
+
+        if(!(data & 0x4)) {
+            rv |= 2;
+        }
+
+        xge_m3128_clear_int();
+
+        /* Enable the mask for link up/down events in 3.c006 */
+        netxen_xge_mdio_wr(3, 0xc006, 0xc000);
+
+    } else {
+
+        netxen_xge_mdio_wr(DEV_PMA_PMD,AEL_POWERDOWN_REG,  0);
+        netxen_xge_mdio_wr(DEV_PMA_PMD,AEL_TX_CONFIG_REG_1,1);
+        netxen_xge_mdio_wr(DEV_PMA_PMD,AEL_LOOPBACK_EN_REG,0xfe30);
+        netxen_xge_mdio_wr(DEV_PMA_PMD,AEL_MODE_SEL_REG,   0x24);
+
+        data = netxen_xge_mdio_rd(DEV_PCS,PCS_STATUS_REG);
+
+        if (!(data & 0x1000)) {
+            rv |= 2;
+        }
+
+        data = netxen_xge_mdio_rd(DEV_PHY_XS,PHY_XS_LANE_STATUS_REG);
+
+        if (!(data & 0x000f)) {
+            rv |= 1;
+        }
+
+    }
+
+    return rv;
+
+}
+
+void xge_loopback(int on)
+{
+    long data;
+    data = netxen_xge_mdio_rd(DEV_PMA_PMD,PMD_IDENTIFIER);
+
+       switch (data) {
+               case PMD_ID_QUAKE:
+                       if (on) {
+                               data = netxen_xge_mdio_rd(DEV_PMA_PMD, 0);
+                               netxen_xge_mdio_wr(DEV_PMA_PMD, 0, data | 1);
+                               data = netxen_xge_mdio_rd(DEV_PMA_PMD, 0xC001);
+                               netxen_xge_mdio_wr(DEV_PMA_PMD, 0xC001, data | 
0x8000);
+                       } else {
+                               data = netxen_xge_mdio_rd(DEV_PMA_PMD, 0xC001);
+                               netxen_xge_mdio_wr(DEV_PMA_PMD, 0xC001, data & 
~0x8000);
+                               data = netxen_xge_mdio_rd(DEV_PMA_PMD, 0);
+                               netxen_xge_mdio_wr(DEV_PMA_PMD, 0, data & ~1);
+                       }
+                       break;
+
+               case PMD_ID_MYSTICOM:
+                       if (on) {
+                               data = netxen_xge_mdio_rd(DEV_PMA_PMD, 0);
+                               netxen_xge_mdio_wr(DEV_PMA_PMD, 0, data | 0x40);
+                       } else {
+                               netxen_xge_mdio_wr(DEV_PMA_PMD, 0, data & 
~0x40);
+                       }
+                       break;
+
+                       /* Puma PHY */
+               default:
+                       if (on) {
+                               /* Get  - read twice to clear sticky bits */
+                               data = netxen_xge_mdio_rd(DEV_PMA_PMD, 
AEL_LOOPBACK_EN_REG);
+                               netxen_xge_mdio_wr(DEV_PMA_PMD, 
AEL_LOOPBACK_EN_REG, data | 4);
+                               data = netxen_xge_mdio_rd(DEV_PHY_XS, 0xC000);
+                               netxen_xge_mdio_wr(DEV_PHY_XS, 0xC000, data | 
0x8000);
+                       } else {
+                               data = netxen_xge_mdio_rd(DEV_PHY_XS, 0xC000);
+                               netxen_xge_mdio_wr(DEV_PHY_XS, 0xC000, data & 
~0x8000);
+                               data = netxen_xge_mdio_rd(DEV_PMA_PMD, 
AEL_LOOPBACK_EN_REG);
+                               netxen_xge_mdio_wr(DEV_PMA_PMD, 
AEL_LOOPBACK_EN_REG, data & ~4);
+                       }
+                       break;
+       }
+}
+

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to