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

📄 rtl_e100.c

📁 最新rtlinux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (st_timeout)			*st_timeout = !(le32_to_cpu(private_data.selftest->st_sign));		if (st_result)			*st_result = le32_to_cpu(private_data.selftest->st_result);		return false;	}	return true;}/** * e100_setup_iaaddr - issue IA setup sommand * @private_data: atapter's private data struct * @eaddr: new ethernet address * * This routine will issue the IA setup command. This command * will notify the 82557 (e100) of what its individual (node) * address is. This command will be executed in polled mode. * * Returns: *      true: if the IA setup command was successfully issued and completed *      false: otherwise */unsigned chare100_setup_iaaddr(u8 *eaddr){	unsigned int i;	cb_header_t *ntcb_hdr;	unsigned char res;	nxmit_cb_entry_t *cmd;	if ((cmd = e100_alloc_non_tx_cmd()) == NULL) {		res = false;		goto exit;	}	ntcb_hdr = (cb_header_t *) cmd->non_tx_cmd;	ntcb_hdr->cb_cmd = 0;	ntcb_hdr->cb_cmd = __constant_cpu_to_le16(CB_IA_ADDRESS);	for (i = 0; i < ETH_ALEN; i++) {		(cmd->non_tx_cmd)->ntcb.setup.ia_addr[i] = eaddr[i];	}	res = e100_exec_non_cu_cmd( cmd);	if (!res)		rtl_printf(KERN_WARNING "e100: %s: IA setup failed\n", 		       private_data.ifname);exit:	return res;}/** * e100_start_ru - start the RU if needed * @private_data: atapter's private data struct * * This routine checks the status of the 82557's receive unit(RU), * and starts the RU if it was not already active.  However, * before restarting the RU, the driver gives the RU the buffers * it freed up during the servicing of the ISR. If there are * have reached a * no resource condition) the RU will not be started till the * next ISR. */voide100_start_ru(){	struct rx_list_elem *rx_struct = private_data.rvhead;	spin_lock(&private_data.bd_lock);	if (!e100_wait_exec_cmplx( rx_struct->dma_addr, SCB_RUC_START, 0)) {		rtl_printf(KERN_DEBUG		       "e100: start_ru: wait_scb failed\n");		e100_exec_cmplx( rx_struct->dma_addr, SCB_RUC_START);	}	if (private_data.next_cu_cmd == RESUME_NO_WAIT) {		private_data.next_cu_cmd = RESUME_WAIT;	}	spin_unlock(&private_data.bd_lock);}/** * e100_cmd_complete_location * @private_data: atapter's private data struct * * This routine returns a pointer to the location of the command-complete * DWord in the dump statistical counters area, according to the statistical * counters mode (557 - basic, 558 - extended, or 559 - TCO mode). * See e100_config_init() for the setting of the statistical counters mode. */static u32 *e100_cmd_complete_location(void){	u32 *cmd_complete;	max_counters_t *stats = private_data.stats_counters;	switch (private_data.stat_mode) {	case E100_EXTENDED_STATS:		cmd_complete =			(u32 *) &(((err_cntr_558_t *) (stats))->cmd_complete);		break;	case E100_TCO_STATS:		cmd_complete =			(u32 *) &(((err_cntr_559_t *) (stats))->cmd_complete);		break;	case E100_BASIC_STATS:	default:				cmd_complete =			(u32 *) &(((err_cntr_557_t *) (stats))->cmd_complete);		break;	}	return cmd_complete;}/** * e100_clr_cntrs - clear statistics counters * @private_data: atapter's private data struct * * This routine will clear the adapter error statistic counters. * * Returns: *      true: if successfully cleared stat counters *      false: otherwise */static unsigned chare100_clr_cntrs(){	volatile u32 *pcmd_complete;	/* clear the dump counter complete word */	pcmd_complete = e100_cmd_complete_location();	*pcmd_complete = 0;	wmb();	if (!e100_wait_exec_cmplx( private_data.stat_cnt_phys, SCB_CUC_DUMP_ADDR, 0))		return false;	/* wait 10 microseconds for the command to complete */	udelay(10);	if (!e100_wait_exec_simple( SCB_CUC_DUMP_RST_STAT))		return false;	if (private_data.next_cu_cmd == RESUME_NO_WAIT) {		private_data.next_cu_cmd = RESUME_WAIT;	}	return true;}/** * e100_exec_non_cu_cmd * @private_data: atapter's private data struct * @command: the non-cu command to execute * * This routine will submit a command block to be executed, *delay exe or exe immediately */unsigned chare100_exec_non_cu_cmd( nxmit_cb_entry_t *command){	cb_header_t *ntcb_hdr;	unsigned long lock_flag;	//unsigned long expiration_time;	unsigned char rc = true;	u8 sub_cmd;	ntcb_hdr = (cb_header_t *) command->non_tx_cmd;	/* get hdr of non tcb cmd */	sub_cmd = cpu_to_le16(ntcb_hdr->cb_cmd);	/* Set the Command Block to be the last command block */	/*set EL is VIP since CU will go from active to idle*/	/*after the completion*/	ntcb_hdr->cb_cmd |= __constant_cpu_to_le16(CB_EL_BIT);	ntcb_hdr->cb_status = 0;	ntcb_hdr->cb_lnk_ptr = 0;	wmb();	spin_lock_bh(&(private_data.bd_non_tx_lock));	/*if has tx command, delay exe*/	if (private_data.last_tcb) {		rmb();		while ((private_data.last_tcb->tcb_hdr.cb_status &		     __constant_cpu_to_le16(CB_STATUS_COMPLETE)) == 0)		  {		    rmb();		    mdelay(10);				  }			//goto delayed_exec;	}	/*if CU is busy, delay exe*/	while ((readw(&private_data.scb->scb_status) & SCB_CUS_MASK) == SCB_CUS_ACTIVE) {	  rmb();	  	  mdelay(10);	  //goto delayed_exec;	}	spin_lock_irqsave(&private_data.bd_lock, lock_flag);	/* otherwise, exe non-tx command*/	if (!e100_wait_exec_cmplx( command->dma_addr, SCB_CUC_START, sub_cmd)) {		spin_unlock_irqrestore(&(private_data.bd_lock), lock_flag);		rc = false;		goto exit;	}	private_data.next_cu_cmd = START_WAIT;	spin_unlock_irqrestore(&(private_data.bd_lock), lock_flag);	/* now wait for completion of non-cu CB up to 20 msec */	rmb();	while (!(ntcb_hdr->cb_status &		     __constant_cpu_to_le16(CB_STATUS_COMPLETE))) {	  rmb();	  mdelay(20);	}exit:	e100_free_non_tx_cmd( command);	spin_unlock_bh(&(private_data.bd_non_tx_lock));	return rc;}/** * e100_sw_reset * @private_data: atapter's private data struct * @reset_cmd: s/w reset or selective reset * * This routine will issue a software reset to the adapter. It  * will also disable interrupts, as the are enabled after reset. */voide100_sw_reset( u32 reset_cmd){	/* Do  a selective reset first to avoid a potential PCI hang */	writel(PORT_SELECTIVE_RESET, &private_data.scb->scb_port);	readw(&(private_data.scb->scb_status));	/* flushes last write, read-safe */	/* wait for the reset to take effect */	udelay(20);	if (reset_cmd == PORT_SOFTWARE_RESET) {		writel(PORT_SOFTWARE_RESET, &private_data.scb->scb_port);		/* wait 20 micro seconds for the reset to take effect */		udelay(20);	}	/* Mask off our interrupt line -- it is unmasked after reset */	e100_disable_clear_intr();#ifdef E100_CU_DEBUG		private_data.last_cmd = 0;	private_data.last_sub_cmd = 0;#endif	}/** * e100_load_microcode - Download microsocde to controller. * @private_data: atapter's private data struct * * This routine downloads microcode on to the controller. This * microcode is available for the 82558/9, 82550. Currently the * microcode handles interrupt bundling and TCO workaround. * * Returns: *      true: if successfull *      false: otherwise */static unsigned chare100_load_microcode(){	static struct {		u8 rev_id;		u32 ucode[UCODE_MAX_DWORDS + 1];		int timer_dword;		int bundle_dword;		int min_size_dword;	} ucode_opts[] = {		{ D101A4_REV_ID,		  D101_A_RCVBUNDLE_UCODE,		  D101_CPUSAVER_TIMER_DWORD,		  D101_CPUSAVER_BUNDLE_DWORD,		  D101_CPUSAVER_MIN_SIZE_DWORD },		{ D101B0_REV_ID,		  D101_B0_RCVBUNDLE_UCODE,		  D101_CPUSAVER_TIMER_DWORD,		  D101_CPUSAVER_BUNDLE_DWORD,		  D101_CPUSAVER_MIN_SIZE_DWORD },		{ D101MA_REV_ID,		  D101M_B_RCVBUNDLE_UCODE,		  D101M_CPUSAVER_TIMER_DWORD,		  D101M_CPUSAVER_BUNDLE_DWORD,		  D101M_CPUSAVER_MIN_SIZE_DWORD },		{ D101S_REV_ID,		  D101S_RCVBUNDLE_UCODE,		  D101S_CPUSAVER_TIMER_DWORD,		  D101S_CPUSAVER_BUNDLE_DWORD,		  D101S_CPUSAVER_MIN_SIZE_DWORD },		{ D102_REV_ID,		  D102_B_RCVBUNDLE_UCODE,		  D102_B_CPUSAVER_TIMER_DWORD,		  D102_B_CPUSAVER_BUNDLE_DWORD,		  D102_B_CPUSAVER_MIN_SIZE_DWORD },		{ D102C_REV_ID,		  D102_C_RCVBUNDLE_UCODE,		  D102_C_CPUSAVER_TIMER_DWORD,		  D102_C_CPUSAVER_BUNDLE_DWORD,		  D102_C_CPUSAVER_MIN_SIZE_DWORD },		{ D102E_REV_ID,		  D102_E_RCVBUNDLE_UCODE,		  D102_E_CPUSAVER_TIMER_DWORD,		  D102_E_CPUSAVER_BUNDLE_DWORD,		  D102_E_CPUSAVER_MIN_SIZE_DWORD },		{ 0, {0}, 0, 0, 0}	}, *opts;	opts = ucode_opts;	/* User turned ucode loading off */	if (!(private_data.params.b_params & PRM_UCODE))		return false;	/* These controllers do not need ucode */	if (private_data.flags & IS_ICH)		return false;	/* Search for ucode match against h/w rev_id */	while (opts->rev_id) {		if (private_data.rev_id == opts->rev_id) {			int i;			u32 *ucode_dword;			load_ucode_cb_t *ucode_cmd_ptr;			nxmit_cb_entry_t *cmd = e100_alloc_non_tx_cmd();			if (cmd != NULL) {				ucode_cmd_ptr =					(load_ucode_cb_t *) cmd->non_tx_cmd;				ucode_dword = ucode_cmd_ptr->ucode_dword;				rtl_printf(KERN_ERR "***e100_alloc_non_tx_cmd succeed\n");			} else {			  rtl_printf(KERN_ERR "***e100_alloc_non_tx_cmd failed\n");				return false;			}			memcpy(ucode_dword, opts->ucode, sizeof (opts->ucode));			/* Insert user-tunable settings */			ucode_dword[opts->timer_dword] &= 0xFFFF0000;			ucode_dword[opts->timer_dword] |=				(u16) private_data.params.IntDelay;			ucode_dword[opts->bundle_dword] &= 0xFFFF0000;			ucode_dword[opts->bundle_dword] |=				(u16) private_data.params.BundleMax;			ucode_dword[opts->min_size_dword] &= 0xFFFF0000;			ucode_dword[opts->min_size_dword] |=				(private_data.params.b_params & PRM_BUNDLE_SMALL) ?				0xFFFF : 0xFF80;			for (i = 0; i < UCODE_MAX_DWORDS; i++)				cpu_to_le32s(&(ucode_dword[i]));			ucode_cmd_ptr->load_ucode_cbhdr.cb_cmd =				__constant_cpu_to_le16(CB_LOAD_MICROCODE);			return e100_exec_non_cu_cmd( cmd);		}		opts++;	}	return false;}/***************************************************************************//***************************************************************************//*       EEPROM  Functions                                                 *//***************************************************************************//* Read PWA (printed wired assembly) number */void e100_rd_pwa_no(){	private_data.pwa_no = e100_eeprom_read( EEPROM_PWA_NO);	private_data.pwa_no <<= 16;	private_data.pwa_no |= e100_eeprom_read( EEPROM_PWA_NO + 1);}/* Read the permanent ethernet address from the eprom. */void e100_rd_eaddr(){	int i;	u16 eeprom_word;	for (i = 0; i < 6; i += 2) {		eeprom_word =			e100_eeprom_read(					 EEPROM_NODE_ADDRESS_BYTE_0 + (i / 2));		private_data.dev_addr[i] =			private_data.perm_node_address[i] = (u8) eeprom_word;		private_data.dev_addr[i + 1] =			private_data.perm_node_address[i + 1] = (u8) (eeprom_word >> 8);	}}/***************************************************************************//***************************************************************************//***************************************************************************//***************************************************************************//*       Auxilary Functions                                                *//***************************************************************************//* Print the board's configuration */void rt_e100_print_brd_conf(){  /*Print the string if checksum Offloading was enabled*/   if (private_data.flags & DF_CSUM_OFFLOAD)    rtl_printf(KERN_NOTICE "  Hardware receive checksums enabled\n");  else {    if (private_data.rev_id >= D101MA_REV_ID)       rtl_printf(KERN_NOTICE "  Hardware receive checksums disabled\n");  }    if ((private_data.flags & DF_UCODE_LOADED))    rtl_printf(KERN_NOTICE "  cpu cycle saver enabled\n");}/** * e100_pci_setup - setup the adapter's PCI information * @pcid: adapter's pci_dev struct * @private_data: atapter's private data struct * * This routine sets up all PCI information for the adapter. It enables the bus * master bit (some BIOS don't do this), requests memory ans I/O regions, and * calls ioremap() on the adapter's memory region. * * Returns: *      true: if successfull *      false: otherwise */int e

⌨️ 快捷键说明

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