netxen_nic_isr.c

来自「linux 内核源代码」· C语言 代码 · 共 225 行

C
225
字号
/* * 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: *    info@netxen.com * 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 "netxen_nic_phan_reg.h"/* * netxen_nic_get_stats - Get System Network Statistics * @netdev: network interface device structure */struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev){	struct netxen_adapter *adapter = netdev_priv(netdev);	struct net_device_stats *stats = &adapter->net_stats;	memset(stats, 0, sizeof(*stats));	/* total packets received   */	stats->rx_packets = adapter->stats.no_rcv;	/* total packets transmitted    */	stats->tx_packets = adapter->stats.xmitedframes + 		adapter->stats.xmitfinished;	/* total bytes received     */	stats->rx_bytes = adapter->stats.rxbytes;	/* total bytes transmitted  */	stats->tx_bytes = adapter->stats.txbytes;	/* bad packets received     */	stats->rx_errors = adapter->stats.rcvdbadskb;	/* packet transmit problems */	stats->tx_errors = adapter->stats.nocmddescriptor;	/* no space in linux buffers    */	stats->rx_dropped = adapter->stats.updropped;	/* no space available in linux  */	stats->tx_dropped = adapter->stats.txdropped;	return stats;}void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link){	struct net_device *netdev = adapter->netdev;	if (link)		netif_carrier_on(netdev);	else		netif_carrier_off(netdev);}void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable){	__u32 int_src;	/*  This should clear the interrupt source */	if (adapter->phy_read)		adapter->phy_read(adapter, 				  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->disable_phy_interrupts)		adapter->disable_phy_interrupts(adapter);	if (netxen_get_phy_int_jabber(int_src))		DPRINTK(INFO, "Jabber interrupt \n");	if (netxen_get_phy_int_polarity_changed(int_src))		DPRINTK(INFO, "POLARITY CHANGED int \n");	if (netxen_get_phy_int_energy_detect(int_src))		DPRINTK(INFO, "ENERGY DETECT INT \n");	if (netxen_get_phy_int_downshift(int_src))		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))) {		__u32 status;		DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n");		if (adapter->phy_read		    && adapter->phy_read(adapter, 					 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)) {					printk(KERN_INFO "%s: %s Link UP\n",					       netxen_nic_driver_name,					       adapter->netdev->name);				} else {					printk(KERN_INFO "%s: %s Link DOWN\n",					       netxen_nic_driver_name,					       adapter->netdev->name);				}				netxen_indicate_link_status(adapter, 							    netxen_get_phy_link							    (status));			}		}	}	if (adapter->enable_phy_interrupts)		adapter->enable_phy_interrupts(adapter);}void netxen_nic_isr_other(struct netxen_adapter *adapter){	int portno = adapter->portnum;	u32 val, linkup, qg_linksup;	/* verify the offset */	val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));	val = val >> physical_port[adapter->portnum];	if (val == adapter->ahw.qg_linksup)		return;	qg_linksup = adapter->ahw.qg_linksup;	adapter->ahw.qg_linksup = val;	DPRINTK(INFO, "link update 0x%08x\n", val);	linkup = val & 1;	if (linkup != (qg_linksup & 1)) {		printk(KERN_INFO "%s: %s PORT %d link %s\n",		       adapter->netdev->name,		       netxen_nic_driver_name, portno,		       ((linkup == 0) ? "down" : "up"));		netxen_indicate_link_status(adapter, linkup);		if (linkup)			netxen_nic_set_link_parameters(adapter);	}}void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter){	netxen_nic_isr_other(adapter);}int netxen_nic_link_ok(struct netxen_adapter *adapter){	switch (adapter->ahw.board_type) {	case NETXEN_NIC_GBE:		return ((adapter->ahw.qg_linksup) & 1);	case NETXEN_NIC_XGBE:		return ((adapter->ahw.xg_linkup) & 1);	default:		printk(KERN_ERR"%s: Function: %s, Unknown board type\n",			netxen_nic_driver_name, __FUNCTION__);		break;	}	return 0;}void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter){	struct net_device *netdev = adapter->netdev;	u32 val, val1;	/* WINDOW = 1 */	val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));	val >>= (physical_port[adapter->portnum] * 8);	val1 = val & 0xff;	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;		if (netif_running(netdev)) {			netif_carrier_off(netdev);			netif_stop_queue(netdev);		}		/* read twice to clear sticky bits */		/* WINDOW = 0 */		netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1);		netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1);		if ((val & 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;		netif_carrier_on(netdev);		netif_wake_queue(netdev);	}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?