netxen_nic_ethtool.c

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

C
770
字号
		}	}}static u32 netxen_nic_test_link(struct net_device *dev){	struct netxen_adapter *adapter = netdev_priv(dev);	__u32 status;	int val;	/* read which mode */	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {		if (adapter->phy_read		    && adapter->phy_read(adapter,					 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,					 &status) != 0)			return -EIO;		else {			val = netxen_get_phy_link(status);			return !val;		}	} else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {		val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));		return (val == XG_LINK_UP) ? 0 : 1;	}	return -EIO;}static intnetxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,		      u8 * bytes){	struct netxen_adapter *adapter = netdev_priv(dev);	int offset;	int ret;	if (eeprom->len == 0)		return -EINVAL;	eeprom->magic = (adapter->pdev)->vendor | 			((adapter->pdev)->device << 16);	offset = eeprom->offset;	ret = netxen_rom_fast_read_words(adapter, offset, bytes, 						eeprom->len);	if (ret < 0)		return ret;	return 0;}static intnetxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,			u8 * bytes){	struct netxen_adapter *adapter = netdev_priv(dev);	int offset = eeprom->offset;	static int flash_start;	static int ready_to_flash;	int ret;	if (flash_start == 0) {		netxen_halt_pegs(adapter);		ret = netxen_flash_unlock(adapter);		if (ret < 0) {			printk(KERN_ERR "%s: Flash unlock failed.\n",				netxen_nic_driver_name);			return ret;		}		printk(KERN_INFO "%s: flash unlocked. \n", 			netxen_nic_driver_name);		last_schedule_time = jiffies;		ret = netxen_flash_erase_secondary(adapter);		if (ret != FLASH_SUCCESS) {			printk(KERN_ERR "%s: Flash erase failed.\n", 				netxen_nic_driver_name);			return ret;		}		printk(KERN_INFO "%s: secondary flash erased successfully.\n", 			netxen_nic_driver_name);		flash_start = 1;		return 0;	}	if (offset == NETXEN_BOOTLD_START) {		ret = netxen_flash_erase_primary(adapter);		if (ret != FLASH_SUCCESS) {			printk(KERN_ERR "%s: Flash erase failed.\n", 				netxen_nic_driver_name);			return ret;		}		ret = netxen_rom_se(adapter, NETXEN_USER_START);		if (ret != FLASH_SUCCESS)			return ret;		ret = netxen_rom_se(adapter, NETXEN_FIXED_START);		if (ret != FLASH_SUCCESS)			return ret;		printk(KERN_INFO "%s: primary flash erased successfully\n", 			netxen_nic_driver_name);		ret = netxen_backup_crbinit(adapter);		if (ret != FLASH_SUCCESS) {			printk(KERN_ERR "%s: CRBinit backup failed.\n", 				netxen_nic_driver_name);			return ret;		}		printk(KERN_INFO "%s: CRBinit backup done.\n", 			netxen_nic_driver_name);		ready_to_flash = 1;	}	if (!ready_to_flash) {		printk(KERN_ERR "%s: Invalid write sequence, returning...\n",			netxen_nic_driver_name);		return -EINVAL;	}	return netxen_rom_fast_write_words(adapter, offset, bytes, eeprom->len);}static voidnetxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring){	struct netxen_adapter *adapter = netdev_priv(dev);	int i;	ring->rx_pending = 0;	ring->rx_jumbo_pending = 0;	for (i = 0; i < MAX_RCV_CTX; ++i) {		ring->rx_pending += adapter->recv_ctx[i].		    rcv_desc[RCV_DESC_NORMAL_CTXID].max_rx_desc_count;		ring->rx_jumbo_pending += adapter->recv_ctx[i].		    rcv_desc[RCV_DESC_JUMBO_CTXID].max_rx_desc_count;	}	ring->tx_pending = adapter->max_tx_desc_count;	ring->rx_max_pending = MAX_RCV_DESCRIPTORS;	ring->tx_max_pending = MAX_CMD_DESCRIPTORS_HOST;	ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS;	ring->rx_mini_max_pending = 0;	ring->rx_mini_pending = 0;}static voidnetxen_nic_get_pauseparam(struct net_device *dev,			  struct ethtool_pauseparam *pause){	struct netxen_adapter *adapter = netdev_priv(dev);	__u32 val;	int port = physical_port[adapter->portnum];	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {		if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))			return;		/* get flow control settings */		netxen_nic_read_w0(adapter,NETXEN_NIU_GB_MAC_CONFIG_0(port),				&val);		pause->rx_pause = netxen_gb_get_rx_flowctl(val);		netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);		switch (port) {			case 0:				pause->tx_pause = !(netxen_gb_get_gb0_mask(val));				break;			case 1:				pause->tx_pause = !(netxen_gb_get_gb1_mask(val));				break;			case 2:				pause->tx_pause = !(netxen_gb_get_gb2_mask(val));				break;			case 3:			default:				pause->tx_pause = !(netxen_gb_get_gb3_mask(val));				break;		}	} else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {		if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))			return;		pause->rx_pause = 1;		netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);		if (port == 0)			pause->tx_pause = !(netxen_xg_get_xg0_mask(val));		else			pause->tx_pause = !(netxen_xg_get_xg1_mask(val));	} else {		printk(KERN_ERR"%s: Unknown board type: %x\n", 				netxen_nic_driver_name, adapter->ahw.board_type);	}}static intnetxen_nic_set_pauseparam(struct net_device *dev,			  struct ethtool_pauseparam *pause){	struct netxen_adapter *adapter = netdev_priv(dev);	__u32 val;	int port = physical_port[adapter->portnum];	/* read mode */	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {		if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))			return -EIO;		/* set flow control */		netxen_nic_read_w0(adapter,					NETXEN_NIU_GB_MAC_CONFIG_0(port), &val);				if (pause->rx_pause)			netxen_gb_rx_flowctl(val);		else			netxen_gb_unset_rx_flowctl(val);		netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),				val);		/* set autoneg */		netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);		switch (port) {			case 0:				if (pause->tx_pause)					netxen_gb_unset_gb0_mask(val);				else					netxen_gb_set_gb0_mask(val);				break;			case 1:				if (pause->tx_pause)					netxen_gb_unset_gb1_mask(val);				else					netxen_gb_set_gb1_mask(val);				break;			case 2:				if (pause->tx_pause)					netxen_gb_unset_gb2_mask(val);				else					netxen_gb_set_gb2_mask(val);				break;			case 3:			default:				if (pause->tx_pause)					netxen_gb_unset_gb3_mask(val);				else					netxen_gb_set_gb3_mask(val);				break;		}		netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);	} else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {		if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))			return -EIO;		netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);		if (port == 0) {			if (pause->tx_pause)				netxen_xg_unset_xg0_mask(val);			else				netxen_xg_set_xg0_mask(val);		} else {			if (pause->tx_pause)				netxen_xg_unset_xg1_mask(val);			else				netxen_xg_set_xg1_mask(val);		}		netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);				} else {		printk(KERN_ERR "%s: Unknown board type: %x\n",				netxen_nic_driver_name, 				adapter->ahw.board_type);	}	return 0;}static int netxen_nic_reg_test(struct net_device *dev){	struct netxen_adapter *adapter = netdev_priv(dev);	u32 data_read, data_written;	netxen_nic_read_w0(adapter, NETXEN_PCIX_PH_REG(0), &data_read);	if ((data_read & 0xffff) != PHAN_VENDOR_ID)	return 1;	data_written = (u32)0xa5a5a5a5;	netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written);	data_read = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_SCRATCHPAD_TEST));	if (data_written != data_read)		return 1;	return 0;}static int netxen_get_sset_count(struct net_device *dev, int sset){	switch (sset) {	case ETH_SS_TEST:		return NETXEN_NIC_TEST_LEN;	case ETH_SS_STATS:		return NETXEN_NIC_STATS_LEN;	default:		return -EOPNOTSUPP;	}}static voidnetxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,		     u64 * data){	memset(data, 0, sizeof(uint64_t) * NETXEN_NIC_TEST_LEN);	if ((data[0] = netxen_nic_reg_test(dev)))		eth_test->flags |= ETH_TEST_FL_FAILED;	/* link test */	if ((data[1] = (u64) netxen_nic_test_link(dev)))		eth_test->flags |= ETH_TEST_FL_FAILED;}static voidnetxen_nic_get_strings(struct net_device *dev, u32 stringset, u8 * data){	int index;	switch (stringset) {	case ETH_SS_TEST:		memcpy(data, *netxen_nic_gstrings_test,		       NETXEN_NIC_TEST_LEN * ETH_GSTRING_LEN);		break;	case ETH_SS_STATS:		for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {			memcpy(data + index * ETH_GSTRING_LEN,			       netxen_nic_gstrings_stats[index].stat_string,			       ETH_GSTRING_LEN);		}		break;	}}static voidnetxen_nic_get_ethtool_stats(struct net_device *dev,			     struct ethtool_stats *stats, u64 * data){	struct netxen_adapter *adapter = netdev_priv(dev);	int index;	for (index = 0; index < NETXEN_NIC_STATS_LEN; index++) {		char *p =		    (char *)adapter +		    netxen_nic_gstrings_stats[index].stat_offset;		data[index] =		    (netxen_nic_gstrings_stats[index].sizeof_stat ==		     sizeof(u64)) ? *(u64 *) p : *(u32 *) p;	}}static u32 netxen_nic_get_rx_csum(struct net_device *dev){	struct netxen_adapter *adapter = netdev_priv(dev);	return adapter->rx_csum;}static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data){	struct netxen_adapter *adapter = netdev_priv(dev);	adapter->rx_csum = !!data;	return 0;}struct ethtool_ops netxen_nic_ethtool_ops = {	.get_settings = netxen_nic_get_settings,	.set_settings = netxen_nic_set_settings,	.get_drvinfo = netxen_nic_get_drvinfo,	.get_regs_len = netxen_nic_get_regs_len,	.get_regs = netxen_nic_get_regs,	.get_link = ethtool_op_get_link,	.get_eeprom_len = netxen_nic_get_eeprom_len,	.get_eeprom = netxen_nic_get_eeprom,	.set_eeprom = netxen_nic_set_eeprom,	.get_ringparam = netxen_nic_get_ringparam,	.get_pauseparam = netxen_nic_get_pauseparam,	.set_pauseparam = netxen_nic_set_pauseparam,	.set_tx_csum = ethtool_op_set_tx_csum,	.set_sg = ethtool_op_set_sg,	.set_tso = ethtool_op_set_tso,	.self_test = netxen_nic_diag_test,	.get_strings = netxen_nic_get_strings,	.get_ethtool_stats = netxen_nic_get_ethtool_stats,	.get_sset_count = netxen_get_sset_count,	.get_rx_csum = netxen_nic_get_rx_csum,	.set_rx_csum = netxen_nic_set_rx_csum,};

⌨️ 快捷键说明

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