ixgb_ethtool.c

来自「linux 内核源代码」· C语言 代码 · 共 732 行 · 第 1/2 页

C
732
字号
/*******************************************************************************  Intel PRO/10GbE Linux driver  Copyright(c) 1999 - 2006 Intel Corporation.  This program is free software; you can redistribute it and/or modify it  under the terms and conditions of the GNU General Public License,  version 2, as published by the Free Software Foundation.  This program is distributed in the hope 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.,  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.  The full GNU General Public License is included in this distribution in  the file called "COPYING".  Contact Information:  Linux NICS <linux.nics@intel.com>  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497*******************************************************************************//* ethtool support for ixgb */#include "ixgb.h"#include <asm/uaccess.h>extern int ixgb_up(struct ixgb_adapter *adapter);extern void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog);extern void ixgb_reset(struct ixgb_adapter *adapter);extern int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);extern int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);extern void ixgb_free_rx_resources(struct ixgb_adapter *adapter);extern void ixgb_free_tx_resources(struct ixgb_adapter *adapter);extern void ixgb_update_stats(struct ixgb_adapter *adapter);#define IXGB_ALL_RAR_ENTRIES 16struct ixgb_stats {	char stat_string[ETH_GSTRING_LEN];	int sizeof_stat;	int stat_offset;};#define IXGB_STAT(m) sizeof(((struct ixgb_adapter *)0)->m), \		      offsetof(struct ixgb_adapter, m)static struct ixgb_stats ixgb_gstrings_stats[] = {	{"rx_packets", IXGB_STAT(net_stats.rx_packets)},	{"tx_packets", IXGB_STAT(net_stats.tx_packets)},	{"rx_bytes", IXGB_STAT(net_stats.rx_bytes)},	{"tx_bytes", IXGB_STAT(net_stats.tx_bytes)},	{"rx_errors", IXGB_STAT(net_stats.rx_errors)},	{"tx_errors", IXGB_STAT(net_stats.tx_errors)},	{"rx_dropped", IXGB_STAT(net_stats.rx_dropped)},	{"tx_dropped", IXGB_STAT(net_stats.tx_dropped)},	{"multicast", IXGB_STAT(net_stats.multicast)},	{"collisions", IXGB_STAT(net_stats.collisions)},/*	{ "rx_length_errors", IXGB_STAT(net_stats.rx_length_errors) },	*/	{"rx_over_errors", IXGB_STAT(net_stats.rx_over_errors)},	{"rx_crc_errors", IXGB_STAT(net_stats.rx_crc_errors)},	{"rx_frame_errors", IXGB_STAT(net_stats.rx_frame_errors)},	{"rx_fifo_errors", IXGB_STAT(net_stats.rx_fifo_errors)},	{"rx_missed_errors", IXGB_STAT(net_stats.rx_missed_errors)},	{"tx_aborted_errors", IXGB_STAT(net_stats.tx_aborted_errors)},	{"tx_carrier_errors", IXGB_STAT(net_stats.tx_carrier_errors)},	{"tx_fifo_errors", IXGB_STAT(net_stats.tx_fifo_errors)},	{"tx_heartbeat_errors", IXGB_STAT(net_stats.tx_heartbeat_errors)},	{"tx_window_errors", IXGB_STAT(net_stats.tx_window_errors)},	{"tx_deferred_ok", IXGB_STAT(stats.dc)},	{"tx_timeout_count", IXGB_STAT(tx_timeout_count) },	{"tx_restart_queue", IXGB_STAT(restart_queue) },	{"rx_long_length_errors", IXGB_STAT(stats.roc)},	{"rx_short_length_errors", IXGB_STAT(stats.ruc)},	{"tx_tcp_seg_good", IXGB_STAT(stats.tsctc)},	{"tx_tcp_seg_failed", IXGB_STAT(stats.tsctfc)},	{"rx_flow_control_xon", IXGB_STAT(stats.xonrxc)},	{"rx_flow_control_xoff", IXGB_STAT(stats.xoffrxc)},	{"tx_flow_control_xon", IXGB_STAT(stats.xontxc)},	{"tx_flow_control_xoff", IXGB_STAT(stats.xofftxc)},	{"rx_csum_offload_good", IXGB_STAT(hw_csum_rx_good)},	{"rx_csum_offload_errors", IXGB_STAT(hw_csum_rx_error)},	{"tx_csum_offload_good", IXGB_STAT(hw_csum_tx_good)},	{"tx_csum_offload_errors", IXGB_STAT(hw_csum_tx_error)}};#define IXGB_STATS_LEN	ARRAY_SIZE(ixgb_gstrings_stats)static intixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd){	struct ixgb_adapter *adapter = netdev_priv(netdev);	ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);	ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);	ecmd->port = PORT_FIBRE;	ecmd->transceiver = XCVR_EXTERNAL;	if(netif_carrier_ok(adapter->netdev)) {		ecmd->speed = SPEED_10000;		ecmd->duplex = DUPLEX_FULL;	} else {		ecmd->speed = -1;		ecmd->duplex = -1;	}	ecmd->autoneg = AUTONEG_DISABLE;	return 0;}static void ixgb_set_speed_duplex(struct net_device *netdev){	struct ixgb_adapter *adapter = netdev_priv(netdev);	/* be optimistic about our link, since we were up before */	adapter->link_speed = 10000;	adapter->link_duplex = FULL_DUPLEX;	netif_carrier_on(netdev);	netif_wake_queue(netdev);}static intixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd){	struct ixgb_adapter *adapter = netdev_priv(netdev);	if(ecmd->autoneg == AUTONEG_ENABLE ||	   ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)		return -EINVAL;		if(netif_running(adapter->netdev)) {		ixgb_down(adapter, TRUE);		ixgb_reset(adapter);		ixgb_up(adapter);		ixgb_set_speed_duplex(netdev);	} else		ixgb_reset(adapter);	return 0;}static voidixgb_get_pauseparam(struct net_device *netdev,			 struct ethtool_pauseparam *pause){	struct ixgb_adapter *adapter = netdev_priv(netdev);	struct ixgb_hw *hw = &adapter->hw;		pause->autoneg = AUTONEG_DISABLE;			if(hw->fc.type == ixgb_fc_rx_pause)		pause->rx_pause = 1;	else if(hw->fc.type == ixgb_fc_tx_pause)		pause->tx_pause = 1;	else if(hw->fc.type == ixgb_fc_full) {		pause->rx_pause = 1;		pause->tx_pause = 1;	}}static intixgb_set_pauseparam(struct net_device *netdev,			 struct ethtool_pauseparam *pause){	struct ixgb_adapter *adapter = netdev_priv(netdev);	struct ixgb_hw *hw = &adapter->hw;		if(pause->autoneg == AUTONEG_ENABLE)		return -EINVAL;	if(pause->rx_pause && pause->tx_pause)		hw->fc.type = ixgb_fc_full;	else if(pause->rx_pause && !pause->tx_pause)		hw->fc.type = ixgb_fc_rx_pause;	else if(!pause->rx_pause && pause->tx_pause)		hw->fc.type = ixgb_fc_tx_pause;	else if(!pause->rx_pause && !pause->tx_pause)		hw->fc.type = ixgb_fc_none;	if(netif_running(adapter->netdev)) {		ixgb_down(adapter, TRUE);		ixgb_up(adapter);		ixgb_set_speed_duplex(netdev);	} else		ixgb_reset(adapter);			return 0;}static uint32_tixgb_get_rx_csum(struct net_device *netdev){	struct ixgb_adapter *adapter = netdev_priv(netdev);	return adapter->rx_csum;}static intixgb_set_rx_csum(struct net_device *netdev, uint32_t data){	struct ixgb_adapter *adapter = netdev_priv(netdev);	adapter->rx_csum = data;	if(netif_running(netdev)) {		ixgb_down(adapter,TRUE);		ixgb_up(adapter);		ixgb_set_speed_duplex(netdev);	} else		ixgb_reset(adapter);	return 0;}	static uint32_tixgb_get_tx_csum(struct net_device *netdev){	return (netdev->features & NETIF_F_HW_CSUM) != 0;}static intixgb_set_tx_csum(struct net_device *netdev, uint32_t data){	if (data)		netdev->features |= NETIF_F_HW_CSUM;	else		netdev->features &= ~NETIF_F_HW_CSUM;	return 0;}static intixgb_set_tso(struct net_device *netdev, uint32_t data){	if(data)		netdev->features |= NETIF_F_TSO;	else		netdev->features &= ~NETIF_F_TSO;	return 0;} static uint32_tixgb_get_msglevel(struct net_device *netdev){	struct ixgb_adapter *adapter = netdev_priv(netdev);	return adapter->msg_enable;}static voidixgb_set_msglevel(struct net_device *netdev, uint32_t data){	struct ixgb_adapter *adapter = netdev_priv(netdev);	adapter->msg_enable = data;}#define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_static int ixgb_get_regs_len(struct net_device *netdev){#define IXGB_REG_DUMP_LEN  136*sizeof(uint32_t)	return IXGB_REG_DUMP_LEN;}static voidixgb_get_regs(struct net_device *netdev,		   struct ethtool_regs *regs, void *p){	struct ixgb_adapter *adapter = netdev_priv(netdev);	struct ixgb_hw *hw = &adapter->hw;	uint32_t *reg = p;	uint32_t *reg_start = reg;	uint8_t i;	/* the 1 (one) below indicates an attempt at versioning, if the	 * interface in ethtool or the driver changes, this 1 should be	 * incremented */	regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id;	/* General Registers */	*reg++ = IXGB_READ_REG(hw, CTRL0);	/*   0 */	*reg++ = IXGB_READ_REG(hw, CTRL1);	/*   1 */	*reg++ = IXGB_READ_REG(hw, STATUS);	/*   2 */	*reg++ = IXGB_READ_REG(hw, EECD);	/*   3 */	*reg++ = IXGB_READ_REG(hw, MFS);	/*   4 */	/* Interrupt */	*reg++ = IXGB_READ_REG(hw, ICR);	/*   5 */	*reg++ = IXGB_READ_REG(hw, ICS);	/*   6 */	*reg++ = IXGB_READ_REG(hw, IMS);	/*   7 */	*reg++ = IXGB_READ_REG(hw, IMC);	/*   8 */	/* Receive */	*reg++ = IXGB_READ_REG(hw, RCTL);	/*   9 */	*reg++ = IXGB_READ_REG(hw, FCRTL);	/*  10 */	*reg++ = IXGB_READ_REG(hw, FCRTH);	/*  11 */	*reg++ = IXGB_READ_REG(hw, RDBAL);	/*  12 */	*reg++ = IXGB_READ_REG(hw, RDBAH);	/*  13 */	*reg++ = IXGB_READ_REG(hw, RDLEN);	/*  14 */	*reg++ = IXGB_READ_REG(hw, RDH);	/*  15 */	*reg++ = IXGB_READ_REG(hw, RDT);	/*  16 */	*reg++ = IXGB_READ_REG(hw, RDTR);	/*  17 */	*reg++ = IXGB_READ_REG(hw, RXDCTL);	/*  18 */	*reg++ = IXGB_READ_REG(hw, RAIDC);	/*  19 */	*reg++ = IXGB_READ_REG(hw, RXCSUM);	/*  20 */	/* there are 16 RAR entries in hardware, we only use 3 */	for(i = 0; i < IXGB_ALL_RAR_ENTRIES; i++) {		*reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */		*reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */	}	/* Transmit */	*reg++ = IXGB_READ_REG(hw, TCTL);	/*  53 */	*reg++ = IXGB_READ_REG(hw, TDBAL);	/*  54 */	*reg++ = IXGB_READ_REG(hw, TDBAH);	/*  55 */	*reg++ = IXGB_READ_REG(hw, TDLEN);	/*  56 */	*reg++ = IXGB_READ_REG(hw, TDH);	/*  57 */	*reg++ = IXGB_READ_REG(hw, TDT);	/*  58 */	*reg++ = IXGB_READ_REG(hw, TIDV);	/*  59 */	*reg++ = IXGB_READ_REG(hw, TXDCTL);	/*  60 */	*reg++ = IXGB_READ_REG(hw, TSPMT);	/*  61 */	*reg++ = IXGB_READ_REG(hw, PAP);	/*  62 */	/* Physical */	*reg++ = IXGB_READ_REG(hw, PCSC1);	/*  63 */	*reg++ = IXGB_READ_REG(hw, PCSC2);	/*  64 */	*reg++ = IXGB_READ_REG(hw, PCSS1);	/*  65 */	*reg++ = IXGB_READ_REG(hw, PCSS2);	/*  66 */	*reg++ = IXGB_READ_REG(hw, XPCSS);	/*  67 */	*reg++ = IXGB_READ_REG(hw, UCCR);	/*  68 */	*reg++ = IXGB_READ_REG(hw, XPCSTC);	/*  69 */	*reg++ = IXGB_READ_REG(hw, MACA);	/*  70 */	*reg++ = IXGB_READ_REG(hw, APAE);	/*  71 */	*reg++ = IXGB_READ_REG(hw, ARD);	/*  72 */	*reg++ = IXGB_READ_REG(hw, AIS);	/*  73 */	*reg++ = IXGB_READ_REG(hw, MSCA);	/*  74 */	*reg++ = IXGB_READ_REG(hw, MSRWD);	/*  75 */	/* Statistics */	*reg++ = IXGB_GET_STAT(adapter, tprl);	/*  76 */	*reg++ = IXGB_GET_STAT(adapter, tprh);	/*  77 */	*reg++ = IXGB_GET_STAT(adapter, gprcl);	/*  78 */	*reg++ = IXGB_GET_STAT(adapter, gprch);	/*  79 */	*reg++ = IXGB_GET_STAT(adapter, bprcl);	/*  80 */	*reg++ = IXGB_GET_STAT(adapter, bprch);	/*  81 */	*reg++ = IXGB_GET_STAT(adapter, mprcl);	/*  82 */	*reg++ = IXGB_GET_STAT(adapter, mprch);	/*  83 */	*reg++ = IXGB_GET_STAT(adapter, uprcl);	/*  84 */	*reg++ = IXGB_GET_STAT(adapter, uprch);	/*  85 */	*reg++ = IXGB_GET_STAT(adapter, vprcl);	/*  86 */	*reg++ = IXGB_GET_STAT(adapter, vprch);	/*  87 */	*reg++ = IXGB_GET_STAT(adapter, jprcl);	/*  88 */	*reg++ = IXGB_GET_STAT(adapter, jprch);	/*  89 */	*reg++ = IXGB_GET_STAT(adapter, gorcl);	/*  90 */	*reg++ = IXGB_GET_STAT(adapter, gorch);	/*  91 */	*reg++ = IXGB_GET_STAT(adapter, torl);	/*  92 */	*reg++ = IXGB_GET_STAT(adapter, torh);	/*  93 */	*reg++ = IXGB_GET_STAT(adapter, rnbc);	/*  94 */	*reg++ = IXGB_GET_STAT(adapter, ruc);	/*  95 */	*reg++ = IXGB_GET_STAT(adapter, roc);	/*  96 */	*reg++ = IXGB_GET_STAT(adapter, rlec);	/*  97 */

⌨️ 快捷键说明

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