2006-06-07 Amit S. Kale <[EMAIL PROTECTED]>
        * Add netxen driver niu (hardware phy interface component)
          handling routines
        * Add netxen hardware CRB register definitions

diff -Naru linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_niu.c 
linux-2.6.16.20/drivers/net/netxen/netxen_nic_niu.c
--- linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_niu.c    1969-12-31 
16:00:00.000000000 -0800
+++ linux-2.6.16.20/drivers/net/netxen/netxen_nic_niu.c 2006-06-06 
06:58:11.000000000 -0700
@@ -0,0 +1,761 @@
+/*
+ * 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_nic.h"
+#include <linux/delay.h>
+
+/** + * 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:
+ * @param phy  [15:8]  phy id
+ * @param reg  [7:0]   register number
+ *
+ * @returns  0 on success
+ *          -1 on error
+ *
+ **/
+long netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy,
+                            long reg, netxen_crbword_t * readval)
+{
+       long timeout = 0;
+       long result = 0;
+       long restore = 0;
+       struct netxen_niu_gb_mii_mgmt_address address;
+       struct netxen_niu_gb_mii_mgmt_command command;
+       struct netxen_niu_gb_mii_mgmt_indicators status;
+       struct netxen_niu_gb_mii_mgmt_config mii_cfg;
+       struct netxen_niu_gb_mac_config_0_t mac_cfg0;
+
+       /* MII mgmt all goes through port 0 MAC interface, so it cannot be in 
reset */
+       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
+                                 &mac_cfg0, 4))
+               return -EIO;
+       if (mac_cfg0.soft_reset) {
+               struct 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;
+               if (netxen_nic_hw_write_wx(adapter,
+                                          NETXEN_NIU_GB_MAC_CONFIG_0(0),
+                                          &temp, 4))
+                       return -EIO;
+               restore = 1;
+       }
+
+       /* reset MII management interface */
+       *(netxen_crbword_t *) & mii_cfg = 0;
+       mii_cfg.clockselect = 7;
+       mii_cfg.reset = 1;
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(0),
+                                  &mii_cfg, 4))
+               return -EIO;
+       mii_cfg.reset = 0;
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(0),
+                                  &mii_cfg, 4))
+               return -EIO;
+
+       *(netxen_crbword_t *) & address = 0;
+       address.reg_addr = reg;
+       address.phy_addr = phy;
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
+                                  &address, 4))
+               return -EIO;
+       *(netxen_crbword_t *) & command = 0;        /* turn off any prior 
activity */
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
+                                  &command, 4))
+               return -EIO;
+       /* send read command */
+       command.read_cycle = 1;
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
+                                  &command, 4))
+               return -EIO;
+
+       *(netxen_crbword_t *) & status = 0;
+       do {
+               if (netxen_nic_hw_read_wx(adapter,
+                                         NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
+                                         &status, 4))
+                       return -EIO;
+               timeout++;
+       } while ((status.busy || status.notvalid)
+                && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
+
+       if (timeout < NETXEN_NIU_PHY_WAITMAX) {
+               if (netxen_nic_hw_read_wx(adapter,
+                                         NETXEN_NIU_GB_MII_MGMT_STATUS(0),
+                                         readval, 4))
+                       return -EIO;
+               result = 0;
+       } else
+               result = -1;
+
+       if (restore)
+               if (netxen_nic_hw_write_wx(adapter,
+                                          NETXEN_NIU_GB_MAC_CONFIG_0(0),
+                                          &mac_cfg0, 4))
+                       return -EIO;
+
+       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:
+ * @param phy      [15:8]  phy id
+ * @param reg      [7:0]   register number
+ *
+ * @returns  0 on success
+ *          -1 on error
+ *
+ **/
+long netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
+                             long phy, long reg, netxen_crbword_t val)
+{
+       long timeout = 0;
+       long result = 0;
+       long restore = 0;
+       struct netxen_niu_gb_mii_mgmt_address address;
+       struct netxen_niu_gb_mii_mgmt_command command;
+       struct netxen_niu_gb_mii_mgmt_indicators status;
+       struct netxen_niu_gb_mac_config_0_t mac_cfg0;
+
+       /* MII mgmt all goes through port 0 MAC interface, so it cannot be in 
reset */
+       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
+                                 &mac_cfg0, 4))
+               return -EIO;
+       if (mac_cfg0.soft_reset) {
+               struct 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;
+               if (netxen_nic_hw_write_wx(adapter,
+                                          NETXEN_NIU_GB_MAC_CONFIG_0(0),
+                                          &temp, 4))
+                       return -EIO;
+               restore = 1;
+       }
+
+       *(netxen_crbword_t *) & command = 0;        /* turn off any prior 
activity */
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
+                                  &command, 4))
+               return -EIO;
+
+       *(netxen_crbword_t *) & address = 0;
+       address.reg_addr = reg;
+       address.phy_addr = phy;
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
+                                  &address, 4))
+               return -EIO;
+
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0),
+                                  &val, 4))
+               return -EIO;
+
+       *(netxen_crbword_t *) & status = 0;
+       do {
+               if (netxen_nic_hw_read_wx(adapter,
+                                         NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
+                                         &status, 4))
+                       return -EIO;
+               timeout++;
+       } while ((status.busy) && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
+
+       if (timeout < NETXEN_NIU_PHY_WAITMAX)
+               result = 0;
+       else
+               result = -EIO;
+
+       /* restore the state of port 0 MAC in case we tampered with it */
+       if (restore)
+               if (netxen_nic_hw_write_wx(adapter,
+                                          NETXEN_NIU_GB_MAC_CONFIG_0(0),
+                                          &mac_cfg0, 4))
+                       return -EIO;
+
+       return result;
+}
+
+long netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter,
+                                         long port)
+{
+       long result = 0;
+       struct netxen_niu_phy_interrupt 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(adapter, port,
+                                    NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE,
+                                    *(netxen_crbword_t *) & enable))
+               result = -EIO;
+
+       return result;
+}
+
+long netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter,
+                                          long port)
+{
+       long result = 0;
+       if (0 !=
+           netxen_niu_gbe_phy_write(adapter, port,
+                                    NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, 0))
+               result = -EIO;
+
+       return result;
+}
+
+long netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter,
+                                        long port)
+{
+       long result = 0;
+       if (0 !=
+           netxen_niu_gbe_phy_write(adapter, port,
+                                    NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
+                                    -EIO))
+               result = -EIO;
+
+       return result;
+}
+
+/** + * netxen_niu_gbe_set_mii_mode- Set 10/100 Mbit Mode for GbE MAC
+ *
+ **/
+void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
+                                long port, long enable)
+{
+       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
+       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                                   0x80000000);
+       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                                   0x0000f0025);
+       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
+                                   0xf1ff);
+       netxen_crb_writelit_adapter(adapter,
+                                   NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
+       netxen_crb_writelit_adapter(adapter,
+                                   NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
+       netxen_crb_writelit_adapter(adapter,
+                                   (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
+       netxen_crb_writelit_adapter(adapter,
+                                   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_adapter(adapter,
+                                           NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                                           0x5);
+       }
+
+       if (netxen_niu_gbe_enable_phy_interrupts(adapter, port))
+               printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
+       if (netxen_niu_gbe_clear_phy_interrupts(adapter, port))
+               printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
+}
+
+/** + * netxen_niu_gbe_set_gmii_mode- Set GbE Mode for GbE MAC
+ **/
+void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter,
+                                 long port, long enable)
+{
+       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
+       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                                   0x80000000);
+       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                                   0x0000f0025);
+       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
+                                   0xf2ff);
+       netxen_crb_writelit_adapter(adapter,
+                                   NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
+       netxen_crb_writelit_adapter(adapter,
+                                   NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
+       netxen_crb_writelit_adapter(adapter,
+                                   (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
+       netxen_crb_writelit_adapter(adapter,
+                                   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_adapter(adapter,
+                                           NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                                           0x5);
+       }
+
+       if (netxen_niu_gbe_enable_phy_interrupts(adapter, port))
+               printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
+       if (netxen_niu_gbe_clear_phy_interrupts(adapter, port))
+               printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
+}
+
+long netxen_niu_gbe_init_port(struct netxen_adapter *adapter, long port)
+{
+       long result = 0;
+       struct netxen_niu_phy_status status;
+
+       if (0 ==
+           netxen_niu_gbe_phy_read(adapter, 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(adapter, port, 1);
+                       } else if ((status.speed == 1) || (status.speed == 0)) {
+                               netxen_niu_gbe_set_mii_mode(adapter, 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_adapter(adapter,
+                                                   NETXEN_NIU_GB_MAC_CONFIG_0
+                                                   (port), 0x80000000);
+                       netxen_crb_writelit_adapter(adapter,
+                                                   NETXEN_NIU_GB_MAC_CONFIG_0
+                                                   (port), 0x0000f0025);
+                       if (netxen_niu_gbe_clear_phy_interrupts(adapter, port))
+                               printk(KERN_ERR PFX
+                                      "ERROR clearing PHY interrupts\n");
+                       if (netxen_niu_gbe_enable_phy_interrupts(adapter, port))
+                               printk(KERN_ERR PFX
+                                      "ERROR enabling PHY interrupts\n");
+                       if (netxen_niu_gbe_clear_phy_interrupts(adapter, port))
+                               printk(KERN_ERR PFX
+                                      "ERROR clearing PHY interrupts\n");
+                       result = -1;
+               }
+       } else {
+               result = -EIO;
+       }
+       return result;
+}
+
+/** + * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts
+ * @param enable 0 means don't enable the port
+ *               1 means enable (or re-enable) the port
+ **/
+long netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter,
+                                        long port, long enable)
+{
+       long result = 0;
+       struct netxen_niu_phy_interrupt int_src;
+
+       printk(KERN_INFO PFX "NETXEN: 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(adapter, port,
+                                   NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
+                                   (netxen_crbword_t *) & int_src) != 0)
+               result = -EINVAL;
+       else {
+               printk(KERN_INFO PFX "PHY Interrupt source = 0x%x \n",
+                      *(u32 *) & int_src);
+               if (int_src.jabber)
+                       printk(KERN_INFO PFX "jabber Interrupt ");
+               if (int_src.polarity_changed)
+                       printk(KERN_INFO PFX "polarity changed ");
+               if (int_src.energy_detect)
+                       printk(KERN_INFO PFX "energy detect \n");
+               if (int_src.downshift)
+                       printk(KERN_INFO PFX "downshift \n");
+               if (int_src.mdi_xover_changed)
+                       printk(KERN_INFO PFX "mdi_xover_changed ");
+               if (int_src.fifo_over_underflow)
+                       printk(KERN_INFO PFX "fifo_over_underflow ");
+               if (int_src.false_carrier)
+                       printk(KERN_INFO PFX "false_carrier ");
+               if (int_src.symbol_error)
+                       printk(KERN_INFO PFX "symbol_error ");
+               if (int_src.autoneg_completed)
+                       printk(KERN_INFO PFX "autoneg_completed ");
+               if (int_src.page_received)
+                       printk(KERN_INFO PFX "page_received ");
+               if (int_src.duplex_changed)
+                       printk(KERN_INFO PFX "duplex_changed ");
+               if (int_src.autoneg_error)
+                       printk(KERN_INFO PFX "autoneg_error ");
+               if ((int_src.speed_changed) || (int_src.link_status_changed)) {
+                       struct netxen_niu_phy_status status;
+
+                       printk(KERN_INFO PFX
+                              "speed_changed or link status changed");
+                       if (netxen_niu_gbe_phy_read
+                           (adapter, port,
+                            NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+                            (netxen_crbword_t *) & status) == 0) {
+                               if (status.speed == 2) {
+                                       printk
+                                           (KERN_INFO PFX "Link speed changed"
+                                            " to 1000 Mbps\n");
+                                       netxen_niu_gbe_set_gmii_mode(adapter,
+                                                                    port,
+                                                                    enable);
+                               } else if (status.speed == 1) {
+                                       printk
+                                           (KERN_INFO PFX "Link speed changed"
+                                            " to 100 Mbps\n");
+                                       netxen_niu_gbe_set_mii_mode(adapter,
+                                                                   port,
+                                                                   enable);
+                               } else if (status.speed == 0) {
+                                       printk
+                                           (KERN_INFO PFX "Link speed changed"
+                                            " to 10 Mbps\n");
+                                       netxen_niu_gbe_set_mii_mode(adapter,
+                                                                   port,
+                                                                   enable);
+                               } else {
+                                       printk(KERN_ERR PFX "ERROR reading"
+                                              "PHY status. Illegal speed.\n");
+                                       result = -1;
+                               }
+                       } else {
+                               printk(KERN_ERR PFX
+                                      "ERROR reading PHY status.\n");
+                               result = -1;
+                       }
+
+               }
+               printk(KERN_INFO "\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(struct netxen_adapter *adapter,
+                          int phy, netxen_ethernet_macaddr_t * addr)
+{
+       u64 result = 0;
+       struct netxen_niu_gb_station_address_high stationhigh;
+       struct netxen_niu_gb_station_address_low stationlow;
+
+       if (addr == NULL)
+               return -EINVAL;
+       if ((phy < 0) || (phy > 3))
+               return -EINVAL;
+
+       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy),
+                                 &stationhigh, 4))
+               return -EIO;
+       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy),
+                                 &stationlow, 4))
+               return -EIO;
+
+       result = (u64) stationlow.address;
+       result |= (u64) stationhigh.address << 16;
+       memcpy(*addr, &result, sizeof(netxen_ethernet_macaddr_t));
+
+       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(struct netxen_adapter *adapter, int phy,
+                          netxen_ethernet_macaddr_t addr)
+{
+       netxen_crbword_t temp = 0;
+
+       if ((phy < 0) || (phy > 3))
+               return -EINVAL;
+
+       memcpy(&temp, addr, 2);
+       temp <<= 16;
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy),
+                                  &temp, 4))
+               return -EIO;
+
+       temp = 0;
+
+       memcpy(&temp, ((u8 *) addr) + 2, sizeof(netxen_crbword_t));
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy),
+                                  &temp, 4))
+               return -2;
+
+       return 0;
+}
+
+/* Enable a GbE interface */
+long netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
+                               long port, netxen_niu_gbe_ifmode_t mode)
+{
+       struct netxen_niu_gb_mac_config_0_t mac_cfg0;
+       struct netxen_niu_gb_mac_config_1_t mac_cfg1;
+       struct netxen_niu_gb_mii_mgmt_config mii_cfg;
+
+       if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+               return -EINVAL;
+
+       *(netxen_crbword_t *) & mac_cfg0 = 0;
+       mac_cfg0.soft_reset = 1;
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                                  &mac_cfg0, 4))
+               return -EIO;
+       *(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;
+
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                                  &mac_cfg0, 4))
+               return -EIO;
+       *(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;
+               if (netxen_nic_hw_write_wx(adapter,
+                                          NETXEN_NIU_GB_MAC_CONFIG_1(port),
+                                          &mac_cfg1, 4))
+                       return -EIO;
+
+               /* set mii mode */
+               netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE +
+                                           (port << 3), 0);
+               netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE +
+                                           (port << 3), 1);
+
+       } else if (mode == NETXEN_NIU_1000_MB) {
+               mac_cfg1.intfmode = 2;
+               if (netxen_nic_hw_write_wx(adapter,
+                                          NETXEN_NIU_GB_MAC_CONFIG_1(port),
+                                          &mac_cfg1, 4))
+                       return -EIO;
+               /* set gmii mode */
+               netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE +
+                                           (port << 3), 0);
+               netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE +
+                                           (port << 3), 1);
+       }
+       *(netxen_crbword_t *) & mii_cfg = 0;
+       mii_cfg.clockselect = 7;
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port),
+                                  &mii_cfg, 4))
+               return -EIO;
+
+       *(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;
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                                  &mac_cfg0, 4))
+               return -EIO;
+       return 0;
+}
+
+/* Disable a GbE interface */
+long netxen_niu_disable_gbe_port(struct netxen_adapter *adapter, long port)
+{
+       struct netxen_niu_gb_mac_config_0_t mac_cfg0;
+
+       if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+               return -EINVAL;
+
+       *(netxen_crbword_t *) & mac_cfg0 = 0;
+       mac_cfg0.soft_reset = 1;
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                                  &mac_cfg0, 4))
+               return -EIO;
+       return 0;
+}
+
+/* Disable an XG interface */
+long netxen_niu_disable_xg_port(struct netxen_adapter *adapter, long port)
+{
+       struct netxen_niu_xg_mac_config_0_t mac_cfg;
+
+       if (port != 0)
+               return -EINVAL;
+
+       *(netxen_crbword_t *) & mac_cfg = 0;
+       mac_cfg.soft_reset = 1;
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_CONFIG_0,
+                                  &mac_cfg, 4))
+               return -EIO;
+       return 0;
+}
+
+/* Set promiscuous mode for a GbE interface */
+long netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, long port,
+                                    netxen_niu_prom_mode_t mode)
+{
+       struct netxen_niu_gb_drop_crc reg;
+       long data;
+
+       if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+               return -EINVAL;
+
+       if (mode == NETXEN_NIU_PROMISCOUS_MODE)
+               data = 0;
+       else
+               data = 1;
+
+       /* save previous contents */
+       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
+                                 &reg, 4))
+               return -EIO;
+       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 -EIO;
+       }
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
+                                  &reg, 4))
+               return -EIO;
+       return 0;
+}
+
+/**
+ * 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(struct netxen_adapter *adapter, int phy,
+                             netxen_ethernet_macaddr_t addr)
+{
+       netxen_crbword_t temp = 0;
+
+       if ((phy < 0) || (phy > 3))
+               return -EINVAL;
+
+       memcpy(&temp, addr, 2);
+       temp <<= 16;
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
+                                  &temp, 4))
+               return -EIO;
+
+       temp = 0;
+
+       memcpy(&temp, ((u8 *) addr) + 2, sizeof(netxen_crbword_t));
+       if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
+                                  &temp, 4))
+               return -EIO;
+
+       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(struct netxen_adapter *adapter, int phy,
+                             netxen_ethernet_macaddr_t * addr)
+{
+       netxen_crbword_t stationhigh;
+       netxen_crbword_t stationlow;
+       u64 result;
+
+       if (addr == NULL)
+               return -EINVAL;
+       if (phy != 0)
+               return -EINVAL;
+
+       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
+                                 &stationhigh, 4))
+               return -EIO;
+       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
+                                 &stationlow, 4))
+               return -EIO;
+
+       result = ((u64) stationlow) >> 16;
+       result |= (u64) stationhigh << 16;
+       memcpy(*addr, &result, sizeof(netxen_ethernet_macaddr_t));
+
+       return 0;
+}
+
+long netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
+                                       long port, netxen_niu_prom_mode_t mode)
+{
+       long reg;
+
+       if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
+               return -EINVAL;
+
+       if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_CONFIG_1, &reg, 4))
+               return -EIO;
+       if (mode == NETXEN_NIU_PROMISCOUS_MODE)
+               reg = (reg | 0x2000UL);
+       else
+               reg = (reg & ~0x2000UL);
+
+       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_XGE_CONFIG_1, reg);
+
+       return 0;
+}
diff -Naru linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_phan_reg.h 
linux-2.6.16.20/drivers/net/netxen/netxen_nic_phan_reg.h
--- linux-2.6.16.20.orig/drivers/net/netxen/netxen_nic_phan_reg.h       
1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.16.20/drivers/net/netxen/netxen_nic_phan_reg.h    2006-06-06 
06:58:11.000000000 -0700
@@ -0,0 +1,293 @@
+/*
+ * 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
+ */
+
+#ifndef __NIC_PHAN_REG_H_
+#define __NIC_PHAN_REG_H_
+
+/** + * CRB Registers or queue message done only at initialization time....
+ **/
+
+/**
+ * The following 2 are the base adresses for the CRB registers and their
+ * offsets will be added to get addresses for the index addresses.......
+ **/
+#define NIC_CRB_BASE_PORT1     NETXEN_CAM_RAM(0x200)
+#define NIC_CRB_BASE_PORT2     NETXEN_CAM_RAM(0x250)
+
+#define NETXEN_NIC_REG(X)      (NIC_CRB_BASE_PORT1+(X))
+
+/**
+ * CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address
+ * which can be read by the Phantom host to get producer/consumer indexes from
+ * Phantom/Casper. If it is not HOST_SHARED_MEMORY, then the following
+ * registers will be used for the addresses of the ring's shared memory
+ * on the Phantom.
+ **/
+
+#define CRB_PHAN_CNTRL_LO_OFFSET       NETXEN_NIC_REG(0x00)
+#define CRB_PHAN_CNTRL_HI_OFFSET       NETXEN_NIC_REG(0x04)
+
+/* point to the indexes */
+#define CRB_CMD_PRODUCER_OFFSET                NETXEN_NIC_REG(0x08)
+#define CRB_CMD_CONSUMER_OFFSET                NETXEN_NIC_REG(0x0c)
+
+/* address of command descriptors in the host memory */
+#define CRB_HOST_CMD_ADDR_HI           NETXEN_NIC_REG(0x30)
+#define CRB_HOST_CMD_ADDR_LO           NETXEN_NIC_REG(0x34)
+
+/* The following 4 CRB registers are for doing performance coal */
+#define CRB_CMD_INTR_LOOP              NETXEN_NIC_REG(0x38)
+#define CRB_CMD_DMA_LOOP               NETXEN_NIC_REG(0x3c)
+#define CRB_RCV_INTR_LOOP              NETXEN_NIC_REG(0x40)
+#define CRB_RCV_DMA_LOOP               NETXEN_NIC_REG(0x44)
+
+/* Needed by the host to find out the state of Phantom's initialization */
+#define CRB_ENABLE_TX_INTR             NETXEN_NIC_REG(0x4c)
+#define CRB_CMDPEG_STATE               NETXEN_NIC_REG(0x50)
+#define CRB_CMDPEG_CMDRING             NETXEN_NIC_REG(0x54)
+
+/* Interrupt coalescing parameters */
+#define CRB_GLOBAL_INT_COAL            NETXEN_NIC_REG(0x80)
+#define CRB_INT_COAL_MODE              NETXEN_NIC_REG(0x84)
+#define CRB_MAX_RCV_BUFS               NETXEN_NIC_REG(0x88)
+#define CRB_TX_INT_THRESHOLD           NETXEN_NIC_REG(0x8c)
+#define CRB_RX_PKT_TIMER               NETXEN_NIC_REG(0x90)
+#define CRB_TX_PKT_TIMER               NETXEN_NIC_REG(0x94)
+#define CRB_RX_PKT_CNT                 NETXEN_NIC_REG(0x98)
+#define CRB_RX_TMR_CNT                 NETXEN_NIC_REG(0x9c)
+
+/* Register for communicating XG link status */
+#define CRB_XG_STATE                   NETXEN_NIC_REG(0xa0)
+
+/* Debug registers for controlling NIC pkt gen agent */
+#define CRB_AGENT_GO                   NETXEN_NIC_REG(0xb0)
+#define CRB_AGENT_TX_SIZE              NETXEN_NIC_REG(0xb4)
+#define CRB_AGENT_TX_TYPE              NETXEN_NIC_REG(0xb8)
+#define CRB_AGENT_TX_ADDR              NETXEN_NIC_REG(0xbc)
+#define CRB_AGENT_TX_MSS               NETXEN_NIC_REG(0xc0)
+
+/* Debug registers for observing NIC performance */
+#define CRB_TX_STATE                   NETXEN_NIC_REG(0xd0)
+#define CRB_TX_COUNT                   NETXEN_NIC_REG(0xd4)
+#define CRB_RX_STATE                   NETXEN_NIC_REG(0xd8)
+#define CRB_CMD_RING_SIZE              NETXEN_NIC_REG(0xe0)
+#define CRB_CTX_ADDR_REG               NETXEN_NIC_REG(0xd0)
+#define CRB_CTX_SIGNATURE_REG          NETXEN_NIC_REG(0xd4)
+
+#define NETXEN_CMD_PRODUCER_DB_PAGE(ctx)           ((ctx) * 4)
+#define NETXEN_RCV_STATUS_CONSUMER_DB_PAGE(ctx)    (1 + ((ctx) * 4))
+#define NETXEN_RCV_PRODUCER_DB_PAGE(ctx,ring)      (2 + (ring) + ((ctx) * 4))
+
+/* CRB registers per Rcv Descriptor ring */
+struct netxen_rcv_desc_crb {
+       u32 crb_rcv_producer_offset __attribute__ ((aligned(512)));
+       u32 crb_rcv_consumer_offset;
+       u32 crb_globalrcv_ring;
+       u32 crb_rcv_ring_size;
+};
+
+/*
+ * CRB registers used by the receive peg logic. One instance of these
+ * needs to be instantiated per instance of the receive peg.
+ */
+
+struct netxen_recv_crb {
+       struct netxen_rcv_desc_crb rcv_desc_crb[NUM_RCV_DESC_RINGS];
+       u32 crb_rcvstatus_ring;
+       u32 crb_rcv_status_producer;
+       u32 crb_rcv_status_consumer;
+       u32 crb_rcvpeg_state;
+       u32 crb_status_ring_size;
+};
+
+#if defined(DEFINE_GLOBAL_RECV_CRB)
+struct netxen_recv_crb recv_crb_registers[] = {
+       /*
+        * Instance 0.
+        */
+       {
+        /* rcv_desc_crb: */
+        {
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x18),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x1c),
+          /* crb_gloablrcv_ring: */
+          NETXEN_NIC_REG(0x20),
+          /* crb_rcv_ring_size: */
+          NETXEN_NIC_REG(0xe4),
+          },
+         /* Jumbo frames */
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x100),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x104),
+          /* crb_gloablrcv_ring: */
+          NETXEN_NIC_REG(0x108),
+          /* crb_rcv_ring_size: */
+          NETXEN_NIC_REG(0xe8),
+          }
+         },
+        /* crb_rcvstatus_ring: */
+        NETXEN_NIC_REG(0x24),
+        /* crb_rcv_status_producer: */
+        NETXEN_NIC_REG(0x28),
+        /* crb_rcv_status_consumer: */
+        NETXEN_NIC_REG(0x2c),
+        /* crb_rcvpeg_state: */
+        NETXEN_NIC_REG(0x48),
+        /* crb_status_ring_size: */
+        NETXEN_NIC_REG(0xec),
+        },
+       /*
+        * Instance 1,
+        */
+       {
+        /* rcv_desc_crb: */
+        {
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x80),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x84),
+          /* crb_globalrcv_ring: */
+          NETXEN_NIC_REG(0x88),
+          /* crb_rcv_ring_size: */
+          NETXEN_NIC_REG(0xf0),
+          },
+         /* Jumbo frames */
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x10C),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x110),
+          /* crb_globalrcv_ring: */
+          NETXEN_NIC_REG(0x114),
+          /* crb_rcv_ring_size: */
+          NETXEN_NIC_REG(0xf4),
+          }
+         },
+        /* crb_rcvstatus_ring: */
+        NETXEN_NIC_REG(0x8c),
+        /* crb_rcv_status_producer: */
+        NETXEN_NIC_REG(0x90),
+        /* crb_rcv_status_consumer: */
+        NETXEN_NIC_REG(0x94),
+        /* crb_rcvpeg_state: */
+        NETXEN_NIC_REG(0x98),
+        /* crb_status_ring_size: */
+        NETXEN_NIC_REG(0xf8),
+        },
+       /*
+        * Instance 2.
+        */
+       {
+        /* rcv_desc_crb: */
+        {
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x18),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x1c),
+          /* crb_globalrcv_ring: */
+          NETXEN_NIC_REG(0x20),
+          /* crb_rcv_ring_size: */
+          NETXEN_NIC_REG(0xe4),
+          },
+         /* Jumbo frames */
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x100),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x104),
+          /* crb_globalrcv_ring: */
+          NETXEN_NIC_REG(0x108),
+          /* crb_rcv_ring_size: */
+          NETXEN_NIC_REG(0xe8),
+          }
+         },
+        /* crb_rcvstatus_ring: */
+        NETXEN_NIC_REG(0x24),
+        /*  crb_rcv_status_producer: */
+        NETXEN_NIC_REG(0x28),
+        /*  crb_rcv_status_consumer: */
+        NETXEN_NIC_REG(0x2c),
+        /*  crb_rcvpeg_state: */
+        NETXEN_NIC_REG(0x48),
+        /* crb_status_ring_size: */
+        NETXEN_NIC_REG(0xec),
+        },
+       /*
+        * Instance 3,
+        */
+       {
+        /* rcv_desc_crb: */
+        {
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x80),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x84),
+          /* crb_globalrcv_ring: */
+          NETXEN_NIC_REG(0x88),
+          /* crb_rcv_ring_size: */
+          NETXEN_NIC_REG(0xf0),
+          },
+         /* Jumbo frames */
+         {
+          /* crb_rcv_producer_offset: */
+          NETXEN_NIC_REG(0x10C),
+          /* crb_rcv_consumer_offset: */
+          NETXEN_NIC_REG(0x110),
+          /* crb_globalrcv_ring: */
+          NETXEN_NIC_REG(0x114),
+          /* crb_rcv_ring_size: */
+          NETXEN_NIC_REG(0xf4),
+          }
+         },
+        /* crb_rcvstatus_ring: */
+        NETXEN_NIC_REG(0x8c),
+        /* crb_rcv_status_producer: */
+        NETXEN_NIC_REG(0x90),
+        /*  crb_rcv_status_consumer: */
+        NETXEN_NIC_REG(0x94),
+        /* crb_rcvpeg_state */
+        NETXEN_NIC_REG(0x98),
+        /* crb_status_ring_size: */
+        NETXEN_NIC_REG(0xf8),
+        },
+};
+#else
+extern struct netxen_recv_crb recv_crb_registers[];
+#endif                         /* DEFINE_GLOBAL_RECEIVE_CRB */
+
+#endif                         /* __NIC_PHAN_REG_H_ */

-
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