diff -Naru linux-2.6.16_orig/drivers/net/netxen/niu.c 
linux-2.6.16/drivers/net/netxen/niu.c
--- linux-2.6.16_orig/drivers/net/netxen/niu.c  1969-12-31 16:00:00.000000000 
-0800
+++ linux-2.6.16/drivers/net/netxen/niu.c       2006-03-24 14:13:57.000000000 
-0800
@@ -0,0 +1,858 @@
+/*
+ * 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
+ */
+/*
+ * Provides access to the Network Interface Unit h/w block.
+ */
+#include "netxen_inc.h"
+
+int netxen_niu_init_test(void);
+
+/* 
+ * netxen_niu_gbe_phy_read - read a register from the GbE PHY via
+ * mii management interface.
+ *
+ * Note: The MII management interface goes through port 0.
+ *       Individual phys are addressed as follows:
+ *       [15:8]  phy id
+ *       [7:0]   register number
+ *
+ * Returns:  0 success
+ *          -1 error
+ *
+ */
+long netxen_niu_gbe_phy_read (long phy, long reg, netxen_crbword_t *readval) {
+    netxen_niu_gb_mii_mgmt_address_t address;
+    netxen_niu_gb_mii_mgmt_command_t command;
+    netxen_niu_gb_mii_mgmt_indicators_t status;
+    netxen_niu_gb_mii_mgmt_config_t mii_cfg;
+
+    long timeout=0;
+    long result = 0;
+    long restore = 0;
+    netxen_niu_gb_mac_config_0_t mac_cfg0;
+
+    /* MII mgmt all goes through port 0 MAC interface, so it cannot be in 
reset */
+    NetXen_CRB_READ_CHECK(NetXen_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0);
+    if (mac_cfg0.soft_reset) {
+        netxen_niu_gb_mac_config_0_t temp;
+        *(netxen_crbword_t *)&temp = 0;    
+        temp.tx_reset_pb = 1;
+        temp.rx_reset_pb = 1;
+        temp.tx_reset_mac = 1;
+        temp.rx_reset_mac = 1;
+        NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MAC_CONFIG_0(0), &temp );
+        restore = 1;
+    }
+
+    /* reset MII management interface */
+    *(netxen_crbword_t *)&mii_cfg = 0;
+    mii_cfg.clockselect = 7;
+    mii_cfg.reset = 1;
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MII_MGMT_CONFIG(0), &mii_cfg);
+    mii_cfg.reset = 0;
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MII_MGMT_CONFIG(0), &mii_cfg);
+
+    *(netxen_crbword_t *)&address = 0;
+    address.reg_addr = reg;
+    address.phy_addr = phy;
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MII_MGMT_ADDR(0), &address);
+    
+    *(netxen_crbword_t *)&command = 0;    /* turn off any prior activity */
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MII_MGMT_COMMAND(0), &command);
+
+    /* send read command */
+    command.read_cycle=1;
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MII_MGMT_COMMAND(0), &command);
+
+    *(netxen_crbword_t *)&status = 0;   
+    do {
+        NetXen_CRB_READ_CHECK(NetXen_NIU_GB_MII_MGMT_INDICATE(0),&status);
+        timeout++;
+    } while ((status.busy || status.notvalid) && (timeout++ < 
NetXen_NIU_PHY_WAITMAX));
+
+    if (timeout < NetXen_NIU_PHY_WAITMAX) {
+        NetXen_CRB_READ_CHECK(NetXen_NIU_GB_MII_MGMT_STATUS(0),readval);
+        result = 0;
+    }else {
+        result = -1;
+    }
+
+    if (restore) 
+        NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0);
+
+    return (result);
+
+}
+/* 
+ * netxen_niu_gbe_phy_write - write a register to the GbE PHY via
+ * mii management interface.
+ *
+ * Note: The MII management interface goes through port 0.
+ *       Individual phys are addressed as follows:
+ *       [15:8]  phy id
+ *       [7:0]   register number
+ *
+ * Returns:  0 success
+ *          -1 error
+ *
+ */
+long netxen_niu_gbe_phy_write (long phy, long reg, netxen_crbword_t val) {
+    netxen_niu_gb_mii_mgmt_address_t address;
+    netxen_niu_gb_mii_mgmt_command_t command;
+    netxen_niu_gb_mii_mgmt_indicators_t status;
+    long timeout=0;
+    long result = 0;
+    long restore = 0;
+    netxen_niu_gb_mac_config_0_t mac_cfg0;
+
+    /* MII mgmt all goes through port 0 MAC interface, so it cannot be in 
reset */
+    NetXen_CRB_READ_CHECK(NetXen_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0);
+    if (mac_cfg0.soft_reset) {
+        netxen_niu_gb_mac_config_0_t temp;
+        *(netxen_crbword_t *)&temp = 0;    
+        temp.tx_reset_pb = 1;
+        temp.rx_reset_pb = 1;
+        temp.tx_reset_mac = 1;
+        temp.rx_reset_mac = 1;
+        NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MAC_CONFIG_0(0), &temp );
+        restore = 1;
+    }
+
+    *(netxen_crbword_t *)&command = 0;    /* turn off any prior activity */
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MII_MGMT_COMMAND(0), &command);
+
+    *(netxen_crbword_t *)&address = 0;
+    address.reg_addr = reg;
+    address.phy_addr = phy;
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MII_MGMT_ADDR(0), &address);
+    
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MII_MGMT_CTRL(0), &val);
+
+
+    *(netxen_crbword_t *)&status = 0;   
+    do {
+        NetXen_CRB_READ_CHECK(NetXen_NIU_GB_MII_MGMT_INDICATE(0),&status);
+        timeout++;
+    } while ((status.busy) && (timeout++ < NetXen_NIU_PHY_WAITMAX));
+
+    if (timeout < NetXen_NIU_PHY_WAITMAX) {
+        result = 0;
+    }else {
+        result = -1;
+    }
+
+    /* restore the state of port 0 MAC in case we tampered with it */
+    if (restore) 
+        NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0);
+
+    return (result);
+
+}
+
+long netxen_niu_gbe_enable_phy_interrupts(long port) {
+    long result = 0;
+    netxen_niu_phy_interrupt_t enable;
+    *(netxen_crbword_t *)&enable = 0;
+    enable.link_status_changed = 1;   
+    enable.autoneg_completed= 1;   
+    enable.speed_changed = 1;
+    if (0 != 
netxen_niu_gbe_phy_write(port,NetXen_NIU_GB_MII_MGMT_ADDR_INT_ENABLE,*(netxen_crbword_t
 *)&enable)) {
+        result = -1;
+    }
+    return result;
+}
+
+long netxen_niu_gbe_disable_phy_interrupts(long port) {
+    long result = 0;
+    if (0 != 
netxen_niu_gbe_phy_write(port,NetXen_NIU_GB_MII_MGMT_ADDR_INT_ENABLE,0)) {
+        result = -1;
+    }
+    return result;
+}
+long netxen_niu_gbe_clear_phy_interrupts(long port) {
+    long result = 0;
+    if (0 != 
netxen_niu_gbe_phy_write(port,NetXen_NIU_GB_MII_MGMT_ADDR_INT_STATUS,-1)) {
+        result = -1;
+    }
+    return result;
+}
+
+/* 
+ * netxen_niu_gbe_set_mii_mode- Set 10/100 Mbit Mode for GbE MAC
+ *
+ */
+void netxen_niu_gbe_set_mii_mode(long port, long enable) {
+
+    NetXen_CRB_WRITELIT(NetXen_NIU_MODE, 0x2); /* Set mode to 2 */
+    NetXen_CRB_WRITELIT(NetXen_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
+    NetXen_CRB_WRITELIT(NetXen_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
+    NetXen_CRB_WRITELIT(NetXen_NIU_GB_MAC_CONFIG_1(port), 0xf1ff);
+    NetXen_CRB_WRITELIT(NetXen_NIU_GB0_GMII_MODE + (port << 3), 0);
+    NetXen_CRB_WRITELIT(NetXen_NIU_GB0_MII_MODE  + (port << 3), 1);
+    NetXen_CRB_WRITELIT((NetXen_NIU_GB0_HALF_DUPLEX + port *4), 0);
+    NetXen_CRB_WRITELIT(NetXen_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
+
+    if (enable) {
+       /* Do NOT enable flow control until a suitable solution for 
+        *  shutting down pause frames is found. 
+        */
+        //NetXen_CRB_WRITELIT(NetXen_NIU_GB_MAC_CONFIG_0(port), 0x35);
+        NetXen_CRB_WRITELIT(NetXen_NIU_GB_MAC_CONFIG_0(port), 0x5);
+    }
+
+    if (netxen_niu_gbe_enable_phy_interrupts(port))
+        printf_0("ERROR enabling PHY interrupts\n");
+    if (netxen_niu_gbe_clear_phy_interrupts(port))
+        printf_0("ERROR clearing PHY interrupts\n");
+}
+
+/* 
+ * netxen_niu_gbe_set_gmii_mode- Set GbE Mode for GbE MAC
+ */
+void netxen_niu_gbe_set_gmii_mode(long port, long enable) {
+    NetXen_CRB_WRITELIT(NetXen_NIU_MODE, 0x2); /* Set mode to 2 */
+    NetXen_CRB_WRITELIT(NetXen_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
+    NetXen_CRB_WRITELIT(NetXen_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
+    NetXen_CRB_WRITELIT(NetXen_NIU_GB_MAC_CONFIG_1(port), 0xf2ff);
+    NetXen_CRB_WRITELIT(NetXen_NIU_GB0_MII_MODE  + (port << 3), 0);
+    NetXen_CRB_WRITELIT(NetXen_NIU_GB0_GMII_MODE + (port << 3), 1);
+    NetXen_CRB_WRITELIT((NetXen_NIU_GB0_HALF_DUPLEX + port *4), 0);
+    NetXen_CRB_WRITELIT(NetXen_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
+
+    if (enable) {
+       /* Do NOT enable flow control until a suitable solution for 
+        *  shutting down pause frames is found. 
+        */
+        //NetXen_CRB_WRITELIT(NetXen_NIU_GB_MAC_CONFIG_0(port), 0x35);
+        NetXen_CRB_WRITELIT(NetXen_NIU_GB_MAC_CONFIG_0(port), 0x5);
+    }
+
+    if (netxen_niu_gbe_enable_phy_interrupts(port))
+        printf_0("ERROR enabling PHY interrupts\n");
+    if (netxen_niu_gbe_clear_phy_interrupts(port))
+        printf_0("ERROR clearing PHY interrupts\n");
+}
+
+long netxen_niu_gbe_init_port(long port) {
+    long result = 0;
+
+    netxen_niu_phy_status_t status;
+#ifdef PHANTOM_PROTO_BOARD
+    /* no interrupts on proto board, so just enable it */
+    netxen_niu_gbe_set_gmii_mode(port, 1); 
+#else
+    if (0 == 
netxen_niu_gbe_phy_read(port,NetXen_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+                                      (netxen_crbword_t *)&status)) {
+        if (status.link) {
+            if (status.speed == 2) {
+                netxen_niu_gbe_set_gmii_mode(port, 1); 
+            } else if ((status.speed == 1) || (status.speed == 0)) {
+                netxen_niu_gbe_set_mii_mode(port, 1); 
+            } else {
+                result = -1;
+            }
+
+        } else {
+            /* We don't have link. Cable  must be unconnected. */
+            /* Enable phy interrupts so we take action when plugged in */
+            NetXen_CRB_WRITELIT(NetXen_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
+            NetXen_CRB_WRITELIT(NetXen_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
+            if (netxen_niu_gbe_clear_phy_interrupts(port))
+                printf_0("ERROR clearing PHY interrupts\n");
+            if (netxen_niu_gbe_enable_phy_interrupts(port))
+                printf_0("ERROR enabling PHY interrupts\n");
+            if (netxen_niu_gbe_clear_phy_interrupts(port))
+                printf_0("ERROR clearing PHY interrupts\n");
+            result = -1;
+        }
+    } else {
+       result = -1; 
+
+    }
+#endif /* ifdef PHANTOM_PROTO_BOARD */
+    return result;
+}
+
+/* 
+ *   netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts
+ *   enable - 0 means don't enable the port
+ *            1 means enable (or re-enable) the port
+ */
+long
+netxen_niu_gbe_handle_phy_interrupt(long port, long enable) {
+    long result = 0;
+    netxen_niu_phy_interrupt_t int_src;
+
+    printf_2("HAL: Handling PHY interrupt on port %d (device enable = 
%d)\n",(int)port, (int) enable);
+
+    /* The read of the PHY INT status will clear the pending interrupt status 
*/
+    if (netxen_niu_gbe_phy_read(port,NetXen_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
+                             (netxen_crbword_t *)&int_src) != 0) {
+        result = -1;
+    } else {
+        printf_1("PHY Interrupt source = 0x%x \n",
+                                  *(__uint32_t*)&int_src);
+        if (int_src.jabber) {
+            printf_0("jabber Interrupt ");
+        }
+        if (int_src.polarity_changed) {
+            printf_0("polarity changed ");
+        }
+        if (int_src.energy_detect) {
+            printf_0("energy detect \n");
+        }
+        if (int_src.downshift) {
+            printf_0("downshift \n");
+        }
+        if (int_src.mdi_xover_changed) {
+            printf_0("mdi_xover_changed ");
+        }
+        if (int_src.fifo_over_underflow) {
+            printf_0("fifo_over_underflow ");
+        }
+        if (int_src.false_carrier) {
+            printf_0("false_carrier ");
+        }
+        if (int_src.symbol_error) {
+            printf_0("symbol_error ");
+        }
+        if (int_src.autoneg_completed) {
+            printf_0("autoneg_completed ");
+        }
+        if (int_src.page_received) {
+            printf_0("page_received ");
+        }
+        if (int_src.duplex_changed) {
+            printf_0("duplex_changed ");
+        }
+        if (int_src.autoneg_error) {
+            printf_0("autoneg_error ");
+        }
+        if ((int_src.speed_changed) || (int_src.link_status_changed)){
+            netxen_niu_phy_status_t status;
+            
+            printf_0("speed_changed or link status changed");
+            if 
(netxen_niu_gbe_phy_read(port,NetXen_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+                                      (netxen_crbword_t *)&status) == 0) {
+                printf_0("\n");
+                if (status.speed == 2) {
+                    printf_0("Link speed changed to 1000 Mbps\n");
+                    netxen_niu_gbe_set_gmii_mode(port,enable);
+                } else if (status.speed == 1) {
+                    printf_0("Link speed changed to 100 Mbps\n");
+                    netxen_niu_gbe_set_mii_mode(port,enable);
+                } else if (status.speed == 0) {
+                    printf_0("Link speed changed to 10 Mbps\n");
+                    netxen_niu_gbe_set_mii_mode(port, enable);
+                } else {
+                    printf_0("ERROR reading PHY status. Illegal speed 
setting.\n");
+                    result = -1;
+                }
+            } else {
+                printf_0("ERROR reading PHY status.\n");
+                result = -1;
+            }
+
+        }
+        printf_0("\n");
+    }
+    return result;
+}
+
+/*
+ * Return the current station MAC address.
+ * Note that the passed-in value must already be in network byte order.
+ */
+int
+netxen_niu_macaddr_get(int phy, netxen_ethernet_macaddr_t *addr)
+{
+    netxen_niu_gb_station_address_high_t stationhigh;
+    netxen_niu_gb_station_address_low_t stationlow;
+    __uint64_t result;
+    unsigned long flags;
+
+    if (addr == NULL)
+        return -1;
+    if ((phy < 0) || (phy > 3))
+        return -1;
+
+    flags= netxen_xport_lock();
+#if !defined(XG_MAC)
+    NetXen_CRB_READ_CHECK(NetXen_NIU_GB_STATION_ADDR_0(phy), &stationhigh);
+    NetXen_CRB_READ_CHECK(NetXen_NIU_GB_STATION_ADDR_1(phy), &stationlow);
+#else
+    NetXen_CRB_READ_CHECK(NetXen_NIU_XGE_STATION_ADDR_0_HI, &stationhigh);
+    NetXen_CRB_READ_CHECK(NetXen_NIU_XGE_STATION_ADDR_0_1, &stationlow);
+#endif /* XG_MAC */
+
+    result = (__uint64_t)stationlow.address;
+    result |= (__uint64_t)stationhigh.address << 16;
+    memcpy(*addr,&result,sizeof(netxen_ethernet_macaddr_t));
+    netxen_xport_unlock(flags);
+
+    return 0;
+}
+
+/*
+ * Set the station MAC address.
+ * Note that the passed-in value must already be in network byte order.
+ */
+int
+netxen_niu_macaddr_set(int phy, netxen_ethernet_macaddr_t addr)
+{
+    netxen_crbword_t temp = 0;
+    unsigned long flags;
+
+    if ((phy < 0) || (phy > 3))
+        return -1;
+
+    flags=netxen_xport_lock();
+
+    memcpy(&temp,addr,2);
+    temp <<= 16;
+#if !defined(XG_MAC)
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_STATION_ADDR_1(phy), &temp);
+#else
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_XGE_STATION_ADDR_0_1, &temp);
+#endif /* XG_MAC */
+
+    temp = 0;
+
+    memcpy(&temp,((__uint8_t *)addr)+2,sizeof(netxen_crbword_t));
+#if !defined(XG_MAC)
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_STATION_ADDR_0(phy), &temp);
+#else
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_XGE_STATION_ADDR_0_HI, &temp);
+#endif /* XG_MAC */
+
+    netxen_xport_unlock(flags);
+
+    return 0;
+}
+
+/* Enable a GbE interface */
+native_t netxen_niu_enable_gbe_port(native_t port, netxen_niu_gbe_ifmode_t 
mode) {
+    netxen_niu_gb_mac_config_0_t mac_cfg0;
+    netxen_niu_gb_mac_config_1_t mac_cfg1;
+    netxen_niu_gb_mii_mgmt_config_t mii_cfg;
+
+    if ((port < 0) || (port > NetXen_NIU_MAX_GBE_PORTS)) {
+        return -1;
+    }
+    *(netxen_crbword_t *)&mac_cfg0 = 0;
+    mac_cfg0.soft_reset = 1;
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0);
+
+    *(netxen_crbword_t *)&mac_cfg0 = 0;
+    mac_cfg0.tx_enable = 1;
+    mac_cfg0.rx_enable = 1;
+    mac_cfg0.rx_flowctl = 0;
+    mac_cfg0.tx_reset_pb = 1;
+    mac_cfg0.rx_reset_pb = 1;
+    mac_cfg0.tx_reset_mac = 1;
+    mac_cfg0.rx_reset_mac = 1;
+
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0);
+
+    *(netxen_crbword_t *)&mac_cfg1 = 0;
+    mac_cfg1.preamblelen = 0xf;
+    mac_cfg1.duplex=1;
+    mac_cfg1.crc_enable=1;
+    mac_cfg1.padshort=1;
+    mac_cfg1.checklength=1;
+    mac_cfg1.hugeframes=1;
+
+    if (mode == NetXen_NIU_10_100_MB) {
+        mac_cfg1.intfmode=1;
+        NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MAC_CONFIG_1(port), &mac_cfg1);
+
+        /* set mii mode */
+        NetXen_CRB_WRITELIT(NetXen_NIU_GB0_GMII_MODE + (port << 3), 0);
+        NetXen_CRB_WRITELIT(NetXen_NIU_GB0_MII_MODE  + (port << 3), 1);
+        
+    } else if (mode == NetXen_NIU_1000_MB) {
+        mac_cfg1.intfmode=2;
+        NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MAC_CONFIG_1(port), &mac_cfg1);
+        /* set gmii mode */
+        NetXen_CRB_WRITELIT(NetXen_NIU_GB0_MII_MODE  + (port << 3), 0);
+        NetXen_CRB_WRITELIT(NetXen_NIU_GB0_GMII_MODE + (port << 3), 1);
+    }
+    *(netxen_crbword_t *)&mii_cfg = 0;
+    mii_cfg.clockselect = 7;
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MII_MGMT_CONFIG(port), &mii_cfg);
+
+    *(netxen_crbword_t *)&mac_cfg0 = 0;
+    mac_cfg0.tx_enable = 1;
+    mac_cfg0.rx_enable = 1;
+    mac_cfg0.tx_flowctl = 0;
+    mac_cfg0.rx_flowctl = 0;
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0);
+    return 0;
+}
+
+/* Disable a GbE interface */
+native_t netxen_niu_disable_gbe_port(native_t port) {
+    netxen_niu_gb_mac_config_0_t mac_cfg0;
+    if ((port < 0) || (port > NetXen_NIU_MAX_GBE_PORTS)) {
+        return -1;
+    }
+    *(netxen_crbword_t *)&mac_cfg0 = 0;
+    mac_cfg0.soft_reset = 1;
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0);
+    return 0;
+}
+
+/* Disable an XG interface */
+native_t netxen_niu_disable_xg_port(native_t port) {
+    netxen_niu_xg_mac_config_0_t mac_cfg;
+    if (port != 0) {
+        return -1;
+    }
+    *(netxen_crbword_t *)&mac_cfg = 0;
+    mac_cfg.soft_reset = 1;
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_XGE_CONFIG_0, &mac_cfg);
+    return 0;
+}
+
+
+/* Set promiscuous mode for a GbE interface */
+native_t netxen_niu_set_promiscuous_mode(native_t port, netxen_niu_prom_mode_t 
mode) {
+    netxen_niu_gb_drop_crc_t reg;
+    native_t data;
+    if ((port < 0) || (port > NetXen_NIU_MAX_GBE_PORTS)) {
+        return -1;
+    }
+    if (mode == NetXen_NIU_PROMISCOUS_MODE) {
+        data = 0;
+    } else {
+        data = 1;
+    }
+    /* save previous contents */
+    NetXen_CRB_READ_CHECK(NetXen_NIU_GB_DROP_WRONGADDR, &reg);
+    switch (port) {
+        case 0:
+            reg.drop_gb0 = data;
+            break;
+        case 1:
+            reg.drop_gb0 = data;
+            break;
+        case 2:
+            reg.drop_gb0 = data;
+            break;
+        case 3:
+            reg.drop_gb0 = data;
+            break;
+        default:
+            return -1;
+    } 
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_GB_DROP_WRONGADDR, &reg);
+    return 0;
+}
+/******************************************************************************
+*
+*    Initialize the XG interface
+*
+*******************************************************************************
+*/
+long netxen_niu_xginit(void) {
+    long i, timeout, val;
+    long rv=0;
+    long srebufctl;
+
+    // select the xg interface serdes
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_SEL,0);
+
+    //big fifo rst
+    NetXen_CRB_WRITELIT(NetXen_NIU_RESET_SYS_FIFOS,0x80000001);
+
+    //setting for b0
+    //wrreg 0x006000a0 0xc80
+    NetXen_CRB_WRITELIT(NetXen_CRB_NIU+0xa0, 0xc80);
+      //setting for a2
+    //wrreg 0x006000a0 0x300
+    //NetXen_CRB_WRITELIT(NetXen_CRB_NIU+0xa0, 0x300);
+
+    //xg mode
+    NetXen_CRB_WRITELIT(NetXen_NIU_MODE,1);
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_SINGLE_TERM,1);
+
+    // do byte allign
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_DO_BYTE_ALIGN,0xf);
+    // Word allign
+
+    // Equalization setting for copper
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_DEQ,0x7777);
+
+
+    // reset the MAC
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_CONFIG_0,0xf8000010);
+
+
+    //---------------- Serdes Bring up -------------
+    // xg PwrdnAB
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_POWER_DOWN,0xfffe);
+    DELAY(10000);
+
+    //xg resetPLLAB
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_RESET_PLL,0xfffe);
+    DELAY(10000);
+
+    // xg ResetAB
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_RESET,0xfffe);
+    DELAY(10000);
+
+    // xg PwrdnCD
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_POWER_DOWN,0xfffc);
+    DELAY(10000);
+    
+    // xg resetPLLCD
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_RESET_PLL,0xfffc);
+    DELAY(10000);
+
+    // xg ResetCD
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_RESET,0xfffc);
+    DELAY(10000);
+
+    //Enable  xgmii_xaui Tx, Rx FIFOs 
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_TX_ENABLE,1);
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_RX_ENABLE,1);
+
+
+    // turn on free-run in SRE for next part 
+    srebufctl = NetXen_CRB_READ_VAL(NetXen_SRE_BUF_CTL);
+    NetXen_CRB_WRITELIT(NetXen_SRE_BUF_CTL, srebufctl | 0x2);
+
+    // Enable Tx only
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_CONFIG_0,1);
+
+
+    val=0;
+    timeout= 1000000;
+    for (i=0; i < timeout;i++) {
+        long prev=val;
+        
+        val=NetXen_CRB_READ_VAL(NetXen_NIU_XG_STATUS);
+
+        if ((val & 0xf0) == 0xf0) {
+             break;
+        } else {
+            if (prev != val) {
+                printf_1("Reg 0x38 == 0x%08lx\n",val);
+            }
+            
+        }
+    }
+
+    if ((val & 0xf0) == 0xf0) {
+    } else {
+        printf_0("NetXen NIU XGINIT: NIU ERROR! Lanes Not Synced!\n");
+        return -1;
+    }
+
+    val=0;
+    timeout= 10;
+    for (i=0; i < timeout;i++) {
+        long prev=val;
+        
+        val=NetXen_CRB_READ_VAL(NetXen_NIU_XG_STATUS);
+
+        if ((val & 0xfff) == 0xffb) {
+             break;
+        } else {
+            if (prev != val) {
+                printf_1("Reg 0x38 == 0x%08lx\n",val);
+            }
+            
+        }
+    }
+    //reset the rambus serdes parallel interface
+    //wrreg 0x0060001c 0x3
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_RESET, 0x3);
+    //wrreg 0x0060001c 0x0
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_RESET, 0x0);
+
+/*    if ((val & 0xfff) == 0xffb) {
+        printf_1("NetXen NIU XGINIT: Byte Align Done after %ld iterations!\n", 
i);
+    } else {
+        printf_0("NetXen NIU XGINIT: NIU ERROR! Byte Align not done!\n");
+        rv = -1;
+    }*/
+    if ((val & 0xfff) != 0xffb) {
+        printf_0("NetXen NIU XGINIT: NIU ERROR! Byte Align not done!\n");
+        rv = -1;
+    }
+
+    // unreset the MAC
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_CONFIG_0,0);
+
+    // Enable Tx only
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_CONFIG_0,1);
+
+
+    // XG Config 1 reg
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_CONFIG_1,0x1467);
+    // Back to back IPG 
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_IPG,3);
+
+    // default mac addresses
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_STATION_ADDR_0_HI,0xffffffff);
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_STATION_ADDR_0_1,0xffffffff);
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_STATION_ADDR_1_LO,0xdeadbeaf);
+
+    // Max frame size
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_MAX_FRAME_SIZE,0x00001f40);
+
+    // pause on to pause off time gap
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_PAUSE_THRESHOLD,0x00200020);
+
+    // disable pause frames
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_PAUSE_CTL,0x9);
+
+    // pause frame value
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_PAUSE_FRAME_VALUE,0x100);
+
+    // tx pause frame count
+    NetXen_CRB_WRITELIT(NetXen_NIU_XG_PAUSE_LEVEL,0x400);
+
+    //  Reset and unreset ingress and egress afifos
+    //  enable MAC and Tx/Rx
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_CONFIG_0,0xc0000000);
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_CONFIG_0,0xe5);
+
+
+    // check the MAC ready state
+    NetXen_CRB_WRITELIT(NetXen_NIU_TEST_MUX_CTL,0xc);
+    val=NetXen_CRB_READ_VAL(NetXen_CRB_NIU+0xc0);
+    //printf_1("MAC ready test mux is 0x%lx\n", val);
+
+    //big fifo rst
+    NetXen_CRB_WRITELIT(NetXen_NIU_RESET_SYS_FIFOS,0);
+
+    // undo the SRE Free run enable
+    NetXen_CRB_WRITELIT(NetXen_SRE_BUF_CTL, srebufctl );
+
+    return rv;
+}
+
+/*
+ * Set the MAC address for an XG port
+ * Note that the passed-in value must already be in network byte order.
+ */
+int
+netxen_niu_xg_macaddr_set(int phy, netxen_ethernet_macaddr_t addr)
+{
+    netxen_crbword_t temp = 0;
+    unsigned long flags;
+
+    if ((phy < 0) || (phy > 3))
+        return -1;
+
+    flags=netxen_xport_lock();
+
+    memcpy(&temp, addr, 2);
+    temp <<= 16;
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_XGE_STATION_ADDR_0_1, &temp);
+
+    temp = 0;
+
+    memcpy(&temp,((__uint8_t *)addr)+2,sizeof(netxen_crbword_t));
+    NetXen_CRB_WRITE_CHECK(NetXen_NIU_XGE_STATION_ADDR_0_HI, &temp);
+
+    netxen_xport_unlock(flags);
+
+    return 0;
+}
+/*
+ * Return the current station MAC address.
+ * Note that the passed-in value must already be in network byte order.
+ */
+int
+netxen_niu_xg_macaddr_get(int phy, netxen_ethernet_macaddr_t *addr)
+{
+    netxen_crbword_t stationhigh;
+    netxen_crbword_t stationlow;
+    __uint64_t result;
+    unsigned long flags;
+
+    if (addr == NULL)
+        return -1;
+    if (phy != 0)
+        return -1;
+
+    flags= netxen_xport_lock();
+    NetXen_CRB_READ_CHECK(NetXen_NIU_XGE_STATION_ADDR_0_HI, &stationhigh);
+    NetXen_CRB_READ_CHECK(NetXen_NIU_XGE_STATION_ADDR_0_1, &stationlow);
+
+    result = ((__uint64_t)stationlow) >> 16;
+    result |= (__uint64_t)stationhigh << 16;
+    memcpy(*addr,&result,sizeof(netxen_ethernet_macaddr_t));
+    netxen_xport_unlock(flags);
+
+    return 0;
+}
+
+
+native_t
+netxen_niu_xg_set_promiscuous_mode(native_t port, netxen_niu_prom_mode_t mode)
+{
+    unsigned long flags;
+    long  reg;
+
+    flags=netxen_xport_lock();
+
+    if ((port < 0) || (port > NetXen_NIU_MAX_GBE_PORTS)) {
+        return -1;
+    }
+
+    NetXen_CRB_READ_CHECK(NetXen_NIU_XGE_CONFIG_1, &reg);
+    if (mode == NetXen_NIU_PROMISCOUS_MODE) {
+        reg = (reg | 0x2000UL);
+    } else { /* FIXME  use the correct mode value here*/
+        reg = (reg & ~0x2000UL);
+    }
+    NetXen_CRB_WRITELIT(NetXen_NIU_XGE_CONFIG_1, reg);
+
+    netxen_xport_unlock(flags);
+
+    return 0;
+}
+
+long netxen_niu_xg_enable_phy_interrupts(long port) {
+    NetXen_CRB_WRITELIT(NetXen_NIU_INT_MASK, 0x3f);
+    return 0;
+}
+
+long netxen_niu_xg_disable_phy_interrupts(long port) {
+    NetXen_CRB_WRITELIT(NetXen_NIU_INT_MASK, 0x7f);
+    return 0;
+}
+
+long netxen_niu_xg_clear_phy_interrupts(long port) {
+    NetXen_CRB_WRITELIT(NetXen_NIU_ACTIVE_INT, -1);
+    return 0;
+}

-
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