/*
* 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
* 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:
* info@netxen.com
* NetXen,
void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno,
u32 link)
{
- struct netxen_port *pport = adapter->port[portno];
- struct net_device *netdev = pport->netdev;
+ struct net_device *netdev = (adapter->port[portno])->netdev;
if (link)
netif_carrier_on(netdev);
void netxen_handle_port_int(struct netxen_adapter *adapter, u32 portno,
u32 enable)
{
- __le32 int_src;
+ __u32 int_src;
struct netxen_port *port;
/* This should clear the interrupt source */
- if (adapter->ops->phy_read)
- adapter->ops->phy_read(adapter, portno,
- NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
- &int_src);
+ if (adapter->phy_read)
+ adapter->phy_read(adapter, portno,
+ NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
+ &int_src);
if (int_src == 0) {
DPRINTK(INFO, "No phy interrupts for port #%d\n", portno);
return;
}
- if (adapter->ops->disable_phy_interrupts)
- adapter->ops->disable_phy_interrupts(adapter, portno);
+ if (adapter->disable_phy_interrupts)
+ adapter->disable_phy_interrupts(adapter, portno);
port = adapter->port[portno];
if (netxen_get_phy_int_jabber(int_src))
- DPRINTK(INFO, "NetXen: %s Jabber interrupt \n",
- port->netdev->name);
+ DPRINTK(INFO, "Jabber interrupt \n");
if (netxen_get_phy_int_polarity_changed(int_src))
- DPRINTK(INFO, "NetXen: %s POLARITY CHANGED int \n",
- port->netdev->name);
+ DPRINTK(INFO, "POLARITY CHANGED int \n");
if (netxen_get_phy_int_energy_detect(int_src))
- DPRINTK(INFO, "NetXen: %s ENERGY DETECT INT \n",
- port->netdev->name);
+ DPRINTK(INFO, "ENERGY DETECT INT \n");
if (netxen_get_phy_int_downshift(int_src))
- DPRINTK(INFO, "NetXen: %s DOWNSHIFT INT \n",
- port->netdev->name);
+ DPRINTK(INFO, "DOWNSHIFT INT \n");
/* write it down later.. */
if ((netxen_get_phy_int_speed_changed(int_src))
|| (netxen_get_phy_int_link_status_changed(int_src))) {
- __le32 status;
+ __u32 status;
- DPRINTK(INFO, "NetXen: %s SPEED CHANGED OR"
- " LINK STATUS CHANGED \n", port->netdev->name);
+ DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n");
- if (adapter->ops->phy_read
- && adapter->ops->phy_read(adapter, portno,
- NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
- &status) == 0) {
+ if (adapter->phy_read
+ && adapter->phy_read(adapter, portno,
+ NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+ &status) == 0) {
if (netxen_get_phy_int_link_status_changed(int_src)) {
if (netxen_get_phy_link(status)) {
netxen_niu_gbe_init_port(adapter,
}
}
}
- if (adapter->ops->enable_phy_interrupts)
- adapter->ops->enable_phy_interrupts(adapter, portno);
+ if (adapter->enable_phy_interrupts)
+ adapter->enable_phy_interrupts(adapter, portno);
}
void netxen_nic_isr_other(struct netxen_adapter *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(INFO, "I2Q is the source of INT \n");
+ u32 portno;
+ u32 val, linkup, qg_linksup;
/* verify the offset */
- i2qhi = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_I2Q_CLR_PCI_HI));
-
- DPRINTK(INFO, "isr NETXEN_I2Q_CLR_PCI_HI = 0x%x \n", i2qhi);
+ val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
+ if (val == adapter->ahw.qg_linksup)
+ return;
- if (i2qhi & 0x4000) {
- for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) {
- DPRINTK(INFO, "External PHY interrupt ON PORT %d\n",
- portno);
+ qg_linksup = adapter->ahw.qg_linksup;
+ adapter->ahw.qg_linksup = val;
+ DPRINTK(INFO, "link update 0x%08x\n", val);
+ for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++) {
+ linkup = val & 1;
+ if (linkup != (qg_linksup & 1)) {
+ printk(KERN_INFO "%s: %s PORT %d link %s\n",
+ adapter->port[portno]->netdev->name,
+ netxen_nic_driver_name, portno,
+ ((linkup == 0) ? "down" : "up"));
+ netxen_indicate_link_status(adapter, portno, linkup);
+ if (linkup)
+ netxen_nic_set_link_parameters(adapter->
+ port[portno]);
- enable = 1;
- netxen_handle_port_int(adapter, portno, enable);
}
+ val = val >> 1;
+ qg_linksup = qg_linksup >> 1;
+ }
- /* Clear the interrupt on I2Q */
- writel((u32) i2qhi,
- NETXEN_CRB_NORMALIZE(adapter, NETXEN_I2Q_CLR_PCI_HI));
+ adapter->stats.otherints++;
- }
}
void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter)
{
- u32 val;
- val = readl(NETXEN_CRB_NORMALIZE(adapter, ISR_INT_VECTOR));
- if (val & 0x4) {
- adapter->stats.otherints++;
- netxen_nic_isr_other(adapter);
- }
+ netxen_nic_isr_other(adapter);
}
void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter)