⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s2io.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/************************************************************************ * s2io.c: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC * Copyright(c) 2002-2007 Neterion Inc. * This software may be used and distributed according to the terms of * the GNU General Public License (GPL), incorporated herein by reference. * Drivers based on or derived from this code fall under the GPL and must * retain the authorship, copyright and license notice.  This file is not * a complete program and may only be used when the entire operating * system is licensed under the GPL. * See the file COPYING in this distribution for more information. * * Credits: * Jeff Garzik		: For pointing out the improper error condition *			  check in the s2io_xmit routine and also some *			  issues in the Tx watch dog function. Also for *			  patiently answering all those innumerable *			  questions regaring the 2.6 porting issues. * Stephen Hemminger	: Providing proper 2.6 porting mechanism for some *			  macros available only in 2.6 Kernel. * Francois Romieu	: For pointing out all code part that were *			  deprecated and also styling related comments. * Grant Grundler	: For helping me get rid of some Architecture *			  dependent code. * Christopher Hellwig	: Some more 2.6 specific issues in the driver. * * The module loadable parameters that are supported by the driver and a brief * explaination of all the variables. * * rx_ring_num : This can be used to program the number of receive rings used * in the driver. * rx_ring_sz: This defines the number of receive blocks each ring can have. *     This is also an array of size 8. * rx_ring_mode: This defines the operation mode of all 8 rings. The valid *		values are 1, 2. * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. * tx_fifo_len: This too is an array of 8. Each element defines the number of * Tx descriptors that can be associated with each corresponding FIFO. * intr_type: This defines the type of interrupt. The values can be 0(INTA), *     2(MSI_X). Default value is '2(MSI_X)' * lro_enable: Specifies whether to enable Large Receive Offload (LRO) or not. *     Possible values '1' for enable '0' for disable. Default is '0' * lro_max_pkts: This parameter defines maximum number of packets can be *     aggregated as a single large packet * napi: This parameter used to enable/disable NAPI (polling Rx) *     Possible values '1' for enable and '0' for disable. Default is '1' * ufo: This parameter used to enable/disable UDP Fragmentation Offload(UFO) *      Possible values '1' for enable and '0' for disable. Default is '0' * vlan_tag_strip: This can be used to enable or disable vlan stripping. *                 Possible values '1' for enable , '0' for disable. *                 Default is '2' - which means disable in promisc mode *                 and enable in non-promiscuous mode. ************************************************************************/#include <linux/module.h>#include <linux/types.h>#include <linux/errno.h>#include <linux/ioport.h>#include <linux/pci.h>#include <linux/dma-mapping.h>#include <linux/kernel.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/stddef.h>#include <linux/ioctl.h>#include <linux/timex.h>#include <linux/ethtool.h>#include <linux/workqueue.h>#include <linux/if_vlan.h>#include <linux/ip.h>#include <linux/tcp.h>#include <net/tcp.h>#include <asm/system.h>#include <asm/uaccess.h>#include <asm/io.h>#include <asm/div64.h>#include <asm/irq.h>/* local include */#include "s2io.h"#include "s2io-regs.h"#define DRV_VERSION "2.0.26.17"/* S2io Driver name & version. */static char s2io_driver_name[] = "Neterion";static char s2io_driver_version[] = DRV_VERSION;static int rxd_size[2] = {32,48};static int rxd_count[2] = {127,85};static inline int RXD_IS_UP2DT(struct RxD_t *rxdp){	int ret;	ret = ((!(rxdp->Control_1 & RXD_OWN_XENA)) &&		(GET_RXD_MARKER(rxdp->Control_2) != THE_RXD_MARK));	return ret;}/* * Cards with following subsystem_id have a link state indication * problem, 600B, 600C, 600D, 640B, 640C and 640D. * macro below identifies these cards given the subsystem_id. */#define CARDS_WITH_FAULTY_LINK_INDICATORS(dev_type, subid) \	(dev_type == XFRAME_I_DEVICE) ?			\		((((subid >= 0x600B) && (subid <= 0x600D)) || \		 ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0) : 0#define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \				      ADAPTER_STATUS_RMAC_LOCAL_FAULT)))#define TASKLET_IN_USE test_and_set_bit(0, (&sp->tasklet_status))#define PANIC	1#define LOW	2static inline int rx_buffer_level(struct s2io_nic * sp, int rxb_size, int ring){	struct mac_info *mac_control;	mac_control = &sp->mac_control;	if (rxb_size <= rxd_count[sp->rxd_mode])		return PANIC;	else if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16)		return  LOW;	return 0;}static inline int is_s2io_card_up(const struct s2io_nic * sp){	return test_bit(__S2IO_STATE_CARD_UP, &sp->state);}/* Ethtool related variables and Macros. */static char s2io_gstrings[][ETH_GSTRING_LEN] = {	"Register test\t(offline)",	"Eeprom test\t(offline)",	"Link test\t(online)",	"RLDRAM test\t(offline)",	"BIST Test\t(offline)"};static char ethtool_xena_stats_keys[][ETH_GSTRING_LEN] = {	{"tmac_frms"},	{"tmac_data_octets"},	{"tmac_drop_frms"},	{"tmac_mcst_frms"},	{"tmac_bcst_frms"},	{"tmac_pause_ctrl_frms"},	{"tmac_ttl_octets"},	{"tmac_ucst_frms"},	{"tmac_nucst_frms"},	{"tmac_any_err_frms"},	{"tmac_ttl_less_fb_octets"},	{"tmac_vld_ip_octets"},	{"tmac_vld_ip"},	{"tmac_drop_ip"},	{"tmac_icmp"},	{"tmac_rst_tcp"},	{"tmac_tcp"},	{"tmac_udp"},	{"rmac_vld_frms"},	{"rmac_data_octets"},	{"rmac_fcs_err_frms"},	{"rmac_drop_frms"},	{"rmac_vld_mcst_frms"},	{"rmac_vld_bcst_frms"},	{"rmac_in_rng_len_err_frms"},	{"rmac_out_rng_len_err_frms"},	{"rmac_long_frms"},	{"rmac_pause_ctrl_frms"},	{"rmac_unsup_ctrl_frms"},	{"rmac_ttl_octets"},	{"rmac_accepted_ucst_frms"},	{"rmac_accepted_nucst_frms"},	{"rmac_discarded_frms"},	{"rmac_drop_events"},	{"rmac_ttl_less_fb_octets"},	{"rmac_ttl_frms"},	{"rmac_usized_frms"},	{"rmac_osized_frms"},	{"rmac_frag_frms"},	{"rmac_jabber_frms"},	{"rmac_ttl_64_frms"},	{"rmac_ttl_65_127_frms"},	{"rmac_ttl_128_255_frms"},	{"rmac_ttl_256_511_frms"},	{"rmac_ttl_512_1023_frms"},	{"rmac_ttl_1024_1518_frms"},	{"rmac_ip"},	{"rmac_ip_octets"},	{"rmac_hdr_err_ip"},	{"rmac_drop_ip"},	{"rmac_icmp"},	{"rmac_tcp"},	{"rmac_udp"},	{"rmac_err_drp_udp"},	{"rmac_xgmii_err_sym"},	{"rmac_frms_q0"},	{"rmac_frms_q1"},	{"rmac_frms_q2"},	{"rmac_frms_q3"},	{"rmac_frms_q4"},	{"rmac_frms_q5"},	{"rmac_frms_q6"},	{"rmac_frms_q7"},	{"rmac_full_q0"},	{"rmac_full_q1"},	{"rmac_full_q2"},	{"rmac_full_q3"},	{"rmac_full_q4"},	{"rmac_full_q5"},	{"rmac_full_q6"},	{"rmac_full_q7"},	{"rmac_pause_cnt"},	{"rmac_xgmii_data_err_cnt"},	{"rmac_xgmii_ctrl_err_cnt"},	{"rmac_accepted_ip"},	{"rmac_err_tcp"},	{"rd_req_cnt"},	{"new_rd_req_cnt"},	{"new_rd_req_rtry_cnt"},	{"rd_rtry_cnt"},	{"wr_rtry_rd_ack_cnt"},	{"wr_req_cnt"},	{"new_wr_req_cnt"},	{"new_wr_req_rtry_cnt"},	{"wr_rtry_cnt"},	{"wr_disc_cnt"},	{"rd_rtry_wr_ack_cnt"},	{"txp_wr_cnt"},	{"txd_rd_cnt"},	{"txd_wr_cnt"},	{"rxd_rd_cnt"},	{"rxd_wr_cnt"},	{"txf_rd_cnt"},	{"rxf_wr_cnt"}};static char ethtool_enhanced_stats_keys[][ETH_GSTRING_LEN] = {	{"rmac_ttl_1519_4095_frms"},	{"rmac_ttl_4096_8191_frms"},	{"rmac_ttl_8192_max_frms"},	{"rmac_ttl_gt_max_frms"},	{"rmac_osized_alt_frms"},	{"rmac_jabber_alt_frms"},	{"rmac_gt_max_alt_frms"},	{"rmac_vlan_frms"},	{"rmac_len_discard"},	{"rmac_fcs_discard"},	{"rmac_pf_discard"},	{"rmac_da_discard"},	{"rmac_red_discard"},	{"rmac_rts_discard"},	{"rmac_ingm_full_discard"},	{"link_fault_cnt"}};static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {	{"\n DRIVER STATISTICS"},	{"single_bit_ecc_errs"},	{"double_bit_ecc_errs"},	{"parity_err_cnt"},	{"serious_err_cnt"},	{"soft_reset_cnt"},	{"fifo_full_cnt"},	{"ring_0_full_cnt"},	{"ring_1_full_cnt"},	{"ring_2_full_cnt"},	{"ring_3_full_cnt"},	{"ring_4_full_cnt"},	{"ring_5_full_cnt"},	{"ring_6_full_cnt"},	{"ring_7_full_cnt"},	{"alarm_transceiver_temp_high"},	{"alarm_transceiver_temp_low"},	{"alarm_laser_bias_current_high"},	{"alarm_laser_bias_current_low"},	{"alarm_laser_output_power_high"},	{"alarm_laser_output_power_low"},	{"warn_transceiver_temp_high"},	{"warn_transceiver_temp_low"},	{"warn_laser_bias_current_high"},	{"warn_laser_bias_current_low"},	{"warn_laser_output_power_high"},	{"warn_laser_output_power_low"},	{"lro_aggregated_pkts"},	{"lro_flush_both_count"},	{"lro_out_of_sequence_pkts"},	{"lro_flush_due_to_max_pkts"},	{"lro_avg_aggr_pkts"},	{"mem_alloc_fail_cnt"},	{"pci_map_fail_cnt"},	{"watchdog_timer_cnt"},	{"mem_allocated"},	{"mem_freed"},	{"link_up_cnt"},	{"link_down_cnt"},	{"link_up_time"},	{"link_down_time"},	{"tx_tcode_buf_abort_cnt"},	{"tx_tcode_desc_abort_cnt"},	{"tx_tcode_parity_err_cnt"},	{"tx_tcode_link_loss_cnt"},	{"tx_tcode_list_proc_err_cnt"},	{"rx_tcode_parity_err_cnt"},	{"rx_tcode_abort_cnt"},	{"rx_tcode_parity_abort_cnt"},	{"rx_tcode_rda_fail_cnt"},	{"rx_tcode_unkn_prot_cnt"},	{"rx_tcode_fcs_err_cnt"},	{"rx_tcode_buf_size_err_cnt"},	{"rx_tcode_rxd_corrupt_cnt"},	{"rx_tcode_unkn_err_cnt"},	{"tda_err_cnt"},	{"pfc_err_cnt"},	{"pcc_err_cnt"},	{"tti_err_cnt"},	{"tpa_err_cnt"},	{"sm_err_cnt"},	{"lso_err_cnt"},	{"mac_tmac_err_cnt"},	{"mac_rmac_err_cnt"},	{"xgxs_txgxs_err_cnt"},	{"xgxs_rxgxs_err_cnt"},	{"rc_err_cnt"},	{"prc_pcix_err_cnt"},	{"rpa_err_cnt"},	{"rda_err_cnt"},	{"rti_err_cnt"},	{"mc_err_cnt"}};#define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN#define S2IO_ENHANCED_STAT_LEN sizeof(ethtool_enhanced_stats_keys)/ \					ETH_GSTRING_LEN#define S2IO_DRIVER_STAT_LEN sizeof(ethtool_driver_stats_keys)/ ETH_GSTRING_LEN#define XFRAME_I_STAT_LEN (S2IO_XENA_STAT_LEN + S2IO_DRIVER_STAT_LEN )#define XFRAME_II_STAT_LEN (XFRAME_I_STAT_LEN + S2IO_ENHANCED_STAT_LEN )#define XFRAME_I_STAT_STRINGS_LEN ( XFRAME_I_STAT_LEN * ETH_GSTRING_LEN )#define XFRAME_II_STAT_STRINGS_LEN ( XFRAME_II_STAT_LEN * ETH_GSTRING_LEN )#define S2IO_TEST_LEN	sizeof(s2io_gstrings) / ETH_GSTRING_LEN#define S2IO_STRINGS_LEN	S2IO_TEST_LEN * ETH_GSTRING_LEN#define S2IO_TIMER_CONF(timer, handle, arg, exp)		\			init_timer(&timer);			\			timer.function = handle;		\			timer.data = (unsigned long) arg;	\			mod_timer(&timer, (jiffies + exp))	\/* copy mac addr to def_mac_addr array */static void do_s2io_copy_mac_addr(struct s2io_nic *sp, int offset, u64 mac_addr){	sp->def_mac_addr[offset].mac_addr[5] = (u8) (mac_addr);	sp->def_mac_addr[offset].mac_addr[4] = (u8) (mac_addr >> 8);	sp->def_mac_addr[offset].mac_addr[3] = (u8) (mac_addr >> 16);	sp->def_mac_addr[offset].mac_addr[2] = (u8) (mac_addr >> 24);	sp->def_mac_addr[offset].mac_addr[1] = (u8) (mac_addr >> 32);	sp->def_mac_addr[offset].mac_addr[0] = (u8) (mac_addr >> 40);}/* Add the vlan */static void s2io_vlan_rx_register(struct net_device *dev,					struct vlan_group *grp){	struct s2io_nic *nic = dev->priv;	unsigned long flags;	spin_lock_irqsave(&nic->tx_lock, flags);	nic->vlgrp = grp;	spin_unlock_irqrestore(&nic->tx_lock, flags);}/* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */static int vlan_strip_flag;/* * Constants to be programmed into the Xena's registers, to configure * the XAUI. */#define	END_SIGN	0x0static const u64 herc_act_dtx_cfg[] = {	/* Set address */	0x8000051536750000ULL, 0x80000515367500E0ULL,	/* Write data */	0x8000051536750004ULL, 0x80000515367500E4ULL,	/* Set address */	0x80010515003F0000ULL, 0x80010515003F00E0ULL,	/* Write data */	0x80010515003F0004ULL, 0x80010515003F00E4ULL,	/* Set address */	0x801205150D440000ULL, 0x801205150D4400E0ULL,	/* Write data */	0x801205150D440004ULL, 0x801205150D4400E4ULL,	/* Set address */	0x80020515F2100000ULL, 0x80020515F21000E0ULL,	/* Write data */	0x80020515F2100004ULL, 0x80020515F21000E4ULL,	/* Done */	END_SIGN};static const u64 xena_dtx_cfg[] = {	/* Set address */	0x8000051500000000ULL, 0x80000515000000E0ULL,	/* Write data */	0x80000515D9350004ULL, 0x80000515D93500E4ULL,	/* Set address */	0x8001051500000000ULL, 0x80010515000000E0ULL,	/* Write data */	0x80010515001E0004ULL, 0x80010515001E00E4ULL,	/* Set address */	0x8002051500000000ULL, 0x80020515000000E0ULL,	/* Write data */	0x80020515F2100004ULL, 0x80020515F21000E4ULL,	END_SIGN};/* * Constants for Fixing the MacAddress problem seen mostly on * Alpha machines. */static const u64 fix_mac[] = {	0x0060000000000000ULL, 0x0060600000000000ULL,	0x0040600000000000ULL, 0x0000600000000000ULL,	0x0020600000000000ULL, 0x0060600000000000ULL,	0x0020600000000000ULL, 0x0060600000000000ULL,	0x0020600000000000ULL, 0x0060600000000000ULL,	0x0020600000000000ULL, 0x0060600000000000ULL,	0x0020600000000000ULL, 0x0060600000000000ULL,	0x0020600000000000ULL, 0x0060600000000000ULL,	0x0020600000000000ULL, 0x0060600000000000ULL,	0x0020600000000000ULL, 0x0060600000000000ULL,	0x0020600000000000ULL, 0x0060600000000000ULL,	0x0020600000000000ULL, 0x0060600000000000ULL,	0x0020600000000000ULL, 0x0000600000000000ULL,	0x0040600000000000ULL, 0x0060600000000000ULL,	END_SIGN};

⌨️ 快捷键说明

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