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

📄 e100.c

📁 网卡的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			if(err == -ENOSPC) {				//request a reset				schedule_work(&nic->tx_timeout_task);			}			break;		} else {			nic->cuc_cmd = cuc_resume;			nic->cb_to_send = nic->cb_to_send->next;		}	}err_unlock:	spin_unlock_irqrestore(&nic->cb_lock, flags);	return err;}/********************************************************//*  Micro code for 8086:1229 Rev 8                      *//********************************************************//*  Parameter values for the D101M B-step  */#define D101M_CPUSAVER_TIMER_DWORD		78#define D101M_CPUSAVER_BUNDLE_DWORD		65#define D101M_CPUSAVER_MIN_SIZE_DWORD		126#define D101M_B_RCVBUNDLE_UCODE \{\0x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \0x000C0001, 0x00101312, 0x000C0008, 0x00380216, \0x0010009C, 0x00204056, 0x002380CC, 0x00380056, \0x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \0x00380438, 0x00000000, 0x00140000, 0x00380555, \0x00308000, 0x00100662, 0x00100561, 0x000E0408, \0x00134861, 0x000C0002, 0x00103093, 0x00308000, \0x00100624, 0x00100561, 0x000E0408, 0x00100861, \0x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \0x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \0x003A0437, 0x00044010, 0x0038078A, 0x00000000, \0x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \0x00130824, 0x000C0001, 0x00101213, 0x00260C75, \0x00041000, 0x00010004, 0x00130826, 0x000C0006, \0x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00080600, 0x00101B10, 0x00050004, 0x00100826, \0x00101210, 0x00380C34, 0x00000000, 0x00000000, \0x0021155B, 0x00100099, 0x00206559, 0x0010009C, \0x00244559, 0x00130836, 0x000C0000, 0x00220C62, \0x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \0x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \0x00214C0E, 0x00380555, 0x00010004, 0x00041000, \0x00278C67, 0x00040800, 0x00018100, 0x003A0437, \0x00130826, 0x000C0001, 0x00220559, 0x00101313, \0x00380559, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00130831, 0x0010090B, 0x00124813, \0x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \0x003806A8, 0x00000000, 0x00000000, 0x00000000, \}/********************************************************//*  Micro code for 8086:1229 Rev 9                      *//********************************************************//*  Parameter values for the D101S  */#define D101S_CPUSAVER_TIMER_DWORD		78#define D101S_CPUSAVER_BUNDLE_DWORD		67#define D101S_CPUSAVER_MIN_SIZE_DWORD		128#define D101S_RCVBUNDLE_UCODE \{\0x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \0x000C0001, 0x00101312, 0x000C0008, 0x00380243, \0x0010009C, 0x00204056, 0x002380D0, 0x00380056, \0x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \0x0038047F, 0x00000000, 0x00140000, 0x003805A3, \0x00308000, 0x00100610, 0x00100561, 0x000E0408, \0x00134861, 0x000C0002, 0x00103093, 0x00308000, \0x00100624, 0x00100561, 0x000E0408, 0x00100861, \0x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \0x00380F90, 0x00080000, 0x00103090, 0x00380F90, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \0x003A047E, 0x00044010, 0x00380819, 0x00000000, \0x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \0x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \0x00101213, 0x00260FF7, 0x00041000, 0x00010004, \0x00130826, 0x000C0006, 0x00220700, 0x0013C926, \0x00101313, 0x00380700, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00080600, 0x00101B10, 0x00050004, 0x00100826, \0x00101210, 0x00380FB6, 0x00000000, 0x00000000, \0x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \0x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \0x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \0x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \0x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \0x00010004, 0x00041000, 0x00278FE9, 0x00040800, \0x00018100, 0x003A047E, 0x00130826, 0x000C0001, \0x002205A7, 0x00101313, 0x003805A7, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00130831, \0x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \0x00041000, 0x00010004, 0x00380700  \}/********************************************************//*  Micro code for the 8086:1229 Rev F/10               *//********************************************************//*  Parameter values for the D102 E-step  */#define D102_E_CPUSAVER_TIMER_DWORD		42#define D102_E_CPUSAVER_BUNDLE_DWORD		54#define D102_E_CPUSAVER_MIN_SIZE_DWORD		46#define     D102_E_RCVBUNDLE_UCODE \{\0x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x0EF70E36, 0x1FFF1FFF, \0x00E014B9, 0x00000000, 0x00000000, 0x00000000, \0x00E014BD, 0x00000000, 0x00000000, 0x00000000, \0x00E014D5, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00E014C1, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00E014C8, 0x00000000, 0x00000000, 0x00000000, \0x00200600, 0x00E014EE, 0x00000000, 0x00000000, \0x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \0x00E00E43, 0x00000000, 0x00000000, 0x00000000, \0x00300006, 0x00E014FB, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, \0x00906EFD, 0x00900EFD, 0x00E00EF8, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \0x00000000, 0x00000000, 0x00000000, 0x00000000, \}static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb){/* *INDENT-OFF* */	static struct {		u32 ucode[UCODE_SIZE + 1];		u8 mac;		u8 timer_dword;		u8 bundle_dword;		u8 min_size_dword;	} ucode_opts[] = {		{ D101M_B_RCVBUNDLE_UCODE,		  mac_82559_D101M,		  D101M_CPUSAVER_TIMER_DWORD,		  D101M_CPUSAVER_BUNDLE_DWORD,		  D101M_CPUSAVER_MIN_SIZE_DWORD },		{ D101S_RCVBUNDLE_UCODE,		  mac_82559_D101S,		  D101S_CPUSAVER_TIMER_DWORD,		  D101S_CPUSAVER_BUNDLE_DWORD,		  D101S_CPUSAVER_MIN_SIZE_DWORD },		{ D102_E_RCVBUNDLE_UCODE,		  mac_82551_F,		  D102_E_CPUSAVER_TIMER_DWORD,		  D102_E_CPUSAVER_BUNDLE_DWORD,		  D102_E_CPUSAVER_MIN_SIZE_DWORD },		{ D102_E_RCVBUNDLE_UCODE,		  mac_82551_10,		  D102_E_CPUSAVER_TIMER_DWORD,		  D102_E_CPUSAVER_BUNDLE_DWORD,		  D102_E_CPUSAVER_MIN_SIZE_DWORD },		{ {0}, 0, 0, 0, 0}	}, *opts;/* *INDENT-ON* *//**************************************************************************  CPUSaver parameters**  All CPUSaver parameters are 16-bit literals that are part of a*  "move immediate value" instruction.  By changing the value of*  the literal in the instruction before the code is loaded, the*  driver can change the algorithm.**  INTDELAY - This loads the dead-man timer with its inital value.*    When this timer expires the interrupt is asserted, and the*    timer is reset each time a new packet is received.  (see*    BUNDLEMAX below to set the limit on number of chained packets)*    The current default is 0x600 or 1536.  Experiments show that*    the value should probably stay within the 0x200 - 0x1000.**  BUNDLEMAX -*    This sets the maximum number of frames that will be bundled.  In*    some situations, such as the TCP windowing algorithm, it may be*    better to limit the growth of the bundle size than let it go as*    high as it can, because that could cause too much added latency.*    The default is six, because this is the number of packets in the*    default TCP window size.  A value of 1 would make CPUSaver indicate*    an interrupt for every frame received.  If you do not want to put*    a limit on the bundle size, set this value to xFFFF.**  BUNDLESMALL -*    This contains a bit-mask describing the minimum size frame that*    will be bundled.  The default masks the lower 7 bits, which means*    that any frame less than 128 bytes in length will not be bundled,*    but will instead immediately generate an interrupt.  This does*    not affect the current bundle in any way.  Any frame that is 128*    bytes or large will be bundled normally.  This feature is meant*    to provide immediate indication of ACK frames in a TCP environment.*    Customers were seeing poor performance when a machine with CPUSaver*    enabled was sending but not receiving.  The delay introduced when*    the ACKs were received was enough to reduce total throughput, because*    the sender would sit idle until the ACK was finally seen.**    The current default is 0xFF80, which masks out the lower 7 bits.*    This means that any frame which is x7F (127) bytes or smaller*    will cause an immediate interrupt.  Because this value must be a*    bit mask, there are only a few valid values that can be used.  To*    turn this feature off, the driver can write the value xFFFF to the*    lower word of this instruction (in the same way that the other*    parameters are used).  Likewise, a value of 0xF800 (2047) would*    cause an interrupt to be generated for every frame, because all*    standard Ethernet frames are <= 2047 bytes in length.*************************************************************************//* if you wish to disable the ucode functionality, while maintaining the * workarounds it provides, set the following defines to: * BUNDLESMALL 0 * BUNDLEMAX 1 * INTDELAY 1 */#define BUNDLESMALL 1#define BUNDLEMAX (u16)6#define INTDELAY (u16)1536 /* 0x600 */	/* do not load u-code for ICH devices */	if (nic->flags & ich)		goto noloaducode;	/* Search for ucode match against h/w rev_id */	for (opts = ucode_opts; opts->mac; opts++) {		int i;		u32 *ucode = opts->ucode;		if (nic->mac != opts->mac)			continue;		/* Insert user-tunable settings */		ucode[opts->timer_dword] &= 0xFFFF0000;		ucode[opts->timer_dword] |= INTDELAY;		ucode[opts->bundle_dword] &= 0xFFFF0000;		ucode[opts->bundle_dword] |= BUNDLEMAX;		ucode[opts->min_size_dword] &= 0xFFFF0000;		ucode[opts->min_size_dword] |= (BUNDLESMALL) ? 0xFFFF : 0xFF80;		for (i = 0; i < UCODE_SIZE; i++)			cb->u.ucode[i] = cpu_to_le32(ucode[i]);		cb->command = cpu_to_le16(cb_ucode | cb_el);		return;	}noloaducode:	cb->command = cpu_to_le16(cb_nop | cb_el);}static inline int e100_exec_cb_wait(struct nic *nic, struct sk_buff *skb,	void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *)){	int err = 0, counter = 50;	struct cb *cb = nic->cb_to_clean;	if ((err = e100_exec_cb(nic, NULL, e100_setup_ucode)))		DPRINTK(PROBE,ERR, "ucode cmd failed with error %d\n", err);	/* must restart cuc */	nic->cuc_cmd = cuc_start;	/* wait for completion */	e100_write_flush(nic);	udelay(10);	/* wait for possibly (ouch) 500ms */	while (!(cb->status & cpu_to_le16(cb_complete))) {		msleep(10);		if (!--counter) break;	}	/* ack any interupts, something could have been set */	writeb(~0, &nic->csr->scb.stat_ack);	/* if the command failed, or is not OK, notify and return */	if (!counter || !(cb->status & cpu_to_le16(cb_ok))) {		DPRINTK(PROBE,ERR, "ucode load failed\n");		err = -EPERM;	}	return err;}static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data){	u32 data_out = 0;	unsigned int i;	unsigned long flags;	/*	 * Stratus87247: we shouldn't be writing the MDI control	 * register until the Ready bit shows True.  Also, since	 * manipulation of the MDI control registers is a multi-step	 * procedure it should be done under lock.	 */	spin_lock_irqsave(&nic->mdio_lock, flags);	for (i = 100; i; --i) {		if (readl(&nic->csr->mdi_ctrl) & mdi_ready)			break;		udelay(20);	}	if (unlikely(!i)) {		printk("e100.mdio_ctrl(%s) won't go Ready\n",			nic->netdev->name );		spin_unlock_irqrestore(&nic->mdio_lock, flags);		return 0;		/* No way to indicate timeout error */	}	writel((reg << 16) | (addr << 21) | dir | data, &nic->csr->mdi_ctrl);	for (i = 0; i < 100; i++) {		udelay(20);		if ((data_out = readl(&nic->csr->mdi_ctrl)) & mdi_ready)			break;	}	spin_unlock_irqrestore(&nic->mdio_lock, flags);	DPRINTK(HW, DEBUG,		"%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n",		dir == mdi_read ? "READ" : "WRITE", addr, reg, data, data_out);	return (u16)data_out;}static int mdio_read(struct net_device *netdev, int addr, int reg){	return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0);}static void mdio_write(struct net_device *netdev, int addr, int reg, int data){	mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);}static void e100_get_defaults(struct nic *nic){	struct param_range rfds = { .min = 16, .max = 256, .count = 256 };	struct param_range cbs  = { .min = 64, .max = 256, .count = 128 };	pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);	/* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */	nic->mac = (nic->flags & ich) ? mac_82559_D101M : nic->rev_id;	if(nic->mac == mac_unknown)		nic->mac = mac_82557_D100_A;	nic->params.rfds = rfds;	nic->params.cbs = cbs;	/* Quadwords to DMA into FIFO before starting frame transmit */	nic->tx_threshold = 0xE0;	/* no interrupt for every tx completion, delay = 256us if not 557*/	nic->tx_command = cpu_to_le16(cb_tx | cb_tx_sf |		((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i));	/* Template for a freshly allocated RFD */	nic->blank_rfd.command = cpu_to_le16(cb_el);	nic->blank_rfd.rbd = 0xFFFFFFFF;	nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);	/* MII setup */	nic->mii.phy_id_mask = 0x1F;	nic->mii.reg_num_mask = 0x1F;	nic->mii.dev = nic->netdev;	nic->mii.mdio_read = mdio_read;	nic->mii.mdio_write = mdio_write;}static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb){	struct config *config = &cb->u.config;	u8 *c = (u8 *)config;	cb->command = cpu_to_le16(cb_config);	memset(config, 0, sizeof(struct config));	config->byte_count = 0x16;		/* bytes in this struct */	config->rx_fifo_limit = 0x8;		/* bytes in FIFO before DMA */	config->direct_rx_dma = 0x1;		/* reserved */	config->standard_tcb = 0x1;		/* 1=standard, 0=extended */	config->standard_stat_counter = 0x1;	/* 1=standard, 0=extended */	config->rx_discard_short_frames = 0x1;	/* 1=discard, 0=pass */	config->tx_underrun_retry = 0x3;	/* # of underrun retries */	config->mii_mode = 0x1;			/* 1=MII mode, 0=503 mode */	config->pad10 = 0x6;	config->no_source_addr_insertion = 0x1;	/* 1=no, 0=yes */	config->preamble_length = 0x2;		/* 0=1, 1=3, 2=7, 3=15 bytes */	config->ifs = 0x6;			/* x16 = inter frame spacing */	config->ip_addr_hi = 0xF2;		/* ARP IP filter - not used */	config->pad15_1 = 0x1;	config->pad15_2 = 0x1;	config->crs_or_cdt = 0x0;		/* 0=CRS only, 1=CRS or CDT */	config->fc_delay_hi = 0x40;		/* time delay for fc frame */	config->tx_padding = 0x1;		/* 1=pad short frames */	config->fc_priority_threshold = 0x7;	/* 7=priority fc disabled */	config->pad18 = 0x1;	config->full_duplex_pin = 0x1;		/* 1=examine FDX# pin */	config->pad20_1 = 0x1F;	config->fc_priority_location = 0x1;	/* 1=byte#31, 0=byte#19 */	config->pad21_1 = 0x5;	config->adaptive_ifs = nic->adaptive_ifs;	config->loopback = nic->loopback;	if(nic->mii.force_media && nic->mii.full_duplex)		config->full_duplex_force = 0x1;	/* 1=force, 0=auto */	if(nic->flags & promiscuous || nic->loopback) {		config->rx_save_bad_frames = 0x1;	/* 1=save, 0=discard */

⌨️ 快捷键说明

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