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

📄 rtl_e100.c

📁 最新rtlinux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	private_data.intr_mask = 0;	e100_set_intr_mask();	e100_force_config();        e100_mdi_read( MII_BMSR,private_data.phy_addr, &int_reg);        e100_mdi_read( MII_BMSR,private_data.phy_addr, &int_reg);        e100_mdi_read( MII_ADVERTISE,private_data.phy_addr, &int_reg);        e100_mdi_read( MII_ADVERTISE,private_data.phy_addr, &int_reg);	private_data.next_cu_cmd = START_WAIT;	goto exit;err_exit:	e100_clear_pools();exit:	return rc;}static inteth_close(struct pci_dev *dev){	e100_disable_clear_intr();	if(private_data.must_free_irq){	  rtl_free_irq(dev->irq);	  private_data.must_free_irq = 0;	}	private_data.intr_mask = SCB_INT_MASK;	private_data.cur_line_speed = 0;	private_data.cur_dplx_mode = 0;	e100_clear_pools();	return 0;}/** * e100init - initialize the adapter * @private_data: atapter's private data struct * * This routine is called when this driver is loaded. This is the initialization * routine which allocates memory, configures the adapter and determines the * system resources. * * Returns: *      true: if successful *      false: otherwise */static unsigned chare100_init(){	u32 st_timeout = 0;	u32 st_result = 0;	e100_sw_init();	if (!e100_selftest( &st_timeout, &st_result)) {        	if (st_timeout) {			rtl_printf(KERN_ERR "e100: selftest timeout\n");		} else {			rtl_printf(KERN_ERR "e100: selftest failed. Results: %x\n",					st_result);		}		return false;	}	/* read the MAC address from the eprom */	e100_rd_eaddr();	if (!is_valid_ether_addr(private_data.dev_addr)) {		rtl_printf(KERN_ERR "e100: Invalid Ethernet address\n");		return false;	}	/* read NIC's part number */	e100_rd_pwa_no();	if (!e100_hw_init()) {		rtl_printf(KERN_ERR "e100: hw init failed\n");		return false;	}	/* Interrupts are enabled after device reset */	e100_disable_clear_intr();	return true;}/** * e100_sw_init - initialize software structs * @private_data: atapter's private data struct *  * This routine initializes all software structures. Sets up the * circular structures for the RFD's & TCB's. Allocates the per board * structure for storing adapter information. The CSR is also memory  * mapped in this routine. * * Returns : *      true: if S/W was successfully initialized *      false: otherwise */static unsigned chare100_sw_init(){  /*for the first TX command*/	private_data.next_cu_cmd = START_WAIT;	// init the next cu state	/* 	 * Set the value for # of good xmits per underrun. the value assigned	 * here is an intelligent  suggested default. Nothing magical about it.	 */	private_data.tx_per_underrun = DEFAULT_TX_PER_UNDERRUN;	/* get the default transmit threshold value */	private_data.tx_thld = TX_THRSHLD;	/* get the EPROM size */	private_data.eeprom_size = e100_eeprom_size();	/* Initialize our spinlocks */	spin_lock_init(&(private_data.bd_lock));	spin_lock_init(&(private_data.bd_non_tx_lock));	spin_lock_init(&(private_data.config_lock));	spin_lock_init(&(private_data.mdi_access_lock));	return 1;}static void e100_tco_workaround(){	int i;	/* Do software reset */	e100_sw_reset( PORT_SOFTWARE_RESET);	/* Do a dummy LOAD CU BASE command. */	/* This gets us out of pre-driver to post-driver. */	e100_exec_cmplx( 0, SCB_CUC_LOAD_BASE);	/* Wait 20 msec for reset to take effect *///BUG:	set_current_state(TASK_UNINTERRUPTIBLE);	rtl_printf("usleep 1\n");	usleep(20000);//BUG:	schedule_timeout(HZ / 50 + 1);	/* disable interrupts since they are enabled */	/* after device reset                        */	e100_disable_clear_intr();	/* Wait for command to be cleared up to 1 sec */	for (i=0; i<100; i++) {		if (!readb(&private_data.scb->scb_cmd_low))			break;//BUG:		set_current_state(TASK_UNINTERRUPTIBLE);		rtl_printf("usleep 2\n");		usleep(1000000);//BUG:		schedule_timeout(HZ / 100 + 1);	}	/* Wait for TCO request bit in PMDR register to be clear */	for (i=0; i<50; i++) {		if (!(readb(&private_data.scb->scb_ext.d101m_scb.scb_pmdr) & BIT_1))			break;//BUG:		set_current_state(TASK_UNINTERRUPTIBLE);		rtl_printf("usleep 3\n");		usleep(1000000);//BUG:		schedule_timeout(HZ / 100 + 1);	}}/** * e100_hw_init - initialized tthe hardware * @private_data: atapter's private data struct * * This routine performs a reset on the adapter, and configures the adapter. * This includes configuring the 82557 LAN controller, validating and setting * the node address, detecting and configuring the Phy chip on the adapter, * and initializing all of the on chip counters. * * Returns: *      true - If the adapter was initialized *      false - If the adapter failed initialization */unsigned char e100_hw_init(){  /**set params in rtl_e100main_phy.c***/	if (!e100_phy_init())		return false;	e100_sw_reset(PORT_SELECTIVE_RESET);	/* Only 82559 or above needs TCO workaround */	if (private_data.rev_id >= D101MA_REV_ID)		{		  e100_tco_workaround();		  rtl_printf(KERN_ERR "***e100_tco_workaround Finished\n");		}	/* Load the CU BASE (set to 0, because we use linear mode) */	if (!e100_wait_exec_cmplx( 0, SCB_CUC_LOAD_BASE, 0))		return false;	if (!e100_wait_exec_cmplx( 0, SCB_RUC_LOAD_BASE, 0))		return false;	/* Load interrupt microcode  */	if (e100_load_microcode()) {		private_data.flags |= DF_UCODE_LOADED;	}	e100_config_init();	if (!e100_config()) {		return false;	}	if (!e100_setup_iaaddr( private_data.dev_addr))		return false;	/* Clear the internal counters */	if (!e100_clr_cntrs())		return false;	/* Change for 82558 enhancement */	/* If 82558/9 and if the user has enabled flow control, set up the	 * Flow Control Reg. in the CSR */	if ((private_data.flags & IS_BACHELOR)	    && (private_data.params.b_params & PRM_FC)) {		writeb(DFLT_FC_THLD, &private_data.scb->scb_ext.d101_scb.scb_fc_thld);		writeb(DFLT_FC_CMD,		       &private_data.scb->scb_ext.d101_scb.scb_fc_xon_xoff);		//rtl_printf(KERN_ERR "***FC done\n");	}	return true;}/** * e100_setup_tcb_pool - setup TCB circular list *and initialize each TCB  * @head: Pointer to head of the allocated TCBs * @qlen: Number of elements in the queue * @private_data: atapter's private data struct *  * This routine arranges the contigiously allocated TCB's in a circular list. * Also does the one time initialization of the TCBs. */static voide100_setup_tcb_pool(tcb_t *head, unsigned int qlen){	int ele_no;	tcb_t *pcurr_tcb;	/* point to current tcb */	u32 next_phys;		/* the next phys addr */	u16 txcommand = CB_S_BIT | CB_TX_SF_BIT;	unsigned char *skb;	private_data.tx_count = 0;	if (private_data.flags & USE_IPCB) {		txcommand |= CB_IPCB_TRANSMIT | CB_CID_DEFAULT;	} else if (private_data.flags & IS_BACHELOR) {		txcommand |= CB_TRANSMIT | CB_CID_DEFAULT;	} else {		txcommand |= CB_TRANSMIT;	}	for (ele_no = 0, next_phys = private_data.tcb_phys, pcurr_tcb = head;	     ele_no < qlen; ele_no++, pcurr_tcb++) {		/* set the phys addr for this TCB, next_phys has not incr. yet */		pcurr_tcb->tcb_phys = next_phys;		next_phys += sizeof (tcb_t);		/* set up the circular tcb list */		if (ele_no == (qlen - 1))			pcurr_tcb->tcb_hdr.cb_lnk_ptr =				cpu_to_le32(private_data.tcb_phys);		else			pcurr_tcb->tcb_hdr.cb_lnk_ptr = cpu_to_le32(next_phys);		pcurr_tcb->tcb_hdr.cb_status = 0;		pcurr_tcb->tcb_hdr.cb_cmd = cpu_to_le16(txcommand);		pcurr_tcb->tcb_cnt = 0;			pcurr_tcb->tcb_thrshld = private_data.tx_thld;			pcurr_tcb->tcb_tbd_num = 1;		if (private_data.flags & IS_BACHELOR) {			pcurr_tcb->tcb_tbd_ptr =				__constant_cpu_to_le32(0xFFFFFFFF);		} else {			pcurr_tcb->tcb_tbd_ptr =				cpu_to_le32(pcurr_tcb->tcb_phys + 0x10);		}		if (private_data.flags & IS_BACHELOR) {			pcurr_tcb->tcb_tbd_expand_ptr =				cpu_to_le32(pcurr_tcb->tcb_phys + 0x20);		} else {			pcurr_tcb->tcb_tbd_expand_ptr =				cpu_to_le32(pcurr_tcb->tcb_phys + 0x10);		}		pcurr_tcb->tcb_tbd_dflt_ptr = pcurr_tcb->tcb_tbd_ptr;		if (private_data.flags & USE_IPCB) {			pcurr_tcb->tbd_ptr = &(pcurr_tcb->tcbu.tbd_array[1]);			pcurr_tcb->tcbu.ipcb.ip_activation_high =				IPCB_IP_ACTIVATION_DEFAULT;			pcurr_tcb->tcbu.ipcb.vlan = 0;		} else {			pcurr_tcb->tbd_ptr = &(pcurr_tcb->tcbu.tbd_array[0]);		}		/*alloc skb to the curr tcb*/		skb = rtl_malloc(PKT_BUF_SZ);		pcurr_tcb->tcb_skb = skb;		if (skb == NULL)		  break;                  /* Bad news!  */		(pcurr_tcb->tbd_ptr)->tbd_buf_addr =		  cpu_to_le32(pci_map_single(private_data.pdev, skb, PKT_BUF_SZ,					     PCI_DMA_TODEVICE));	} /* for */	wmb();	if (ele_no < qlen) {	  rtl_printf(KERN_EMERG "ele_no = %d: no enough memory for tx ring\n",ele_no);	  rtl_printf(KERN_EMERG "\nPlease unload the module and try again\n\n");	}}/***************************************************************************//***************************************************************************//*       Memory Management Routines                                        *//***************************************************************************//** * e100_alloc_space - allocate private driver data * @private_data: atapter's private data struct * * This routine allocates memory for the driver. Memory allocated is for the * selftest and statistics structures. * * Returns: *      0: if the operation was successful *      %-ENOMEM: if memory allocation failed */unsigned char e100_alloc_space(){	unsigned long off;	/* allocate all the dma-able structures in one call:	 * selftest results, adapter stats, and non-tx cb commands */	if (!(private_data.dma_able =	      pci_alloc_consistent(private_data.pdev, sizeof (bd_dma_able_t),				   &(private_data.dma_able_phys)))) {		goto err;	}	/* now assign the various pointers into the struct we've just allocated */	off = offsetof(bd_dma_able_t, selftest);	private_data.selftest = (self_test_t *) (private_data.dma_able + off);	private_data.selftest_phys = private_data.dma_able_phys + off;	off = offsetof(bd_dma_able_t, stats_counters);	private_data.stats_counters = (max_counters_t *) (private_data.dma_able + off);	private_data.stat_cnt_phys = private_data.dma_able_phys + off;	return 0;err:	rtl_printf(KERN_ERR	       "e100: Failed to allocate memory\n");	return -ENOMEM;}/** * e100_alloc_tcb_pool - allocate TCB circular list * @private_data: atapter's private data struct * * This routine allocates memory for the circular list of transmit descriptors. * * Returns: *       0: if allocation has failed. *       1: Otherwise.  */inte100_alloc_tcb_pool(){	int stcb = sizeof (tcb_t) * private_data.params.TxDescriptors;	/* allocate space for the TCBs */	if (!(private_data.tcb_pool.data =	      pci_alloc_consistent(private_data.pdev, stcb, &private_data.tcb_phys)))		return 0;	memset(private_data.tcb_pool.data, 0x00, stcb);	return 1;}voide100_free_tcb_pool(){  int i;  tcb_t * tcb;  /*skb has to be free*/  for (i = 0; i < private_data.params.TxDescriptors; i++)     {      tcb = private_data.tcb_pool.data;      tcb += i;      mb();      e100_tx_skb_free(tcb);      mb();      }	pci_free_consistent(private_data.pdev,			    sizeof (tcb_t) * private_data.params.TxDescriptors,			    private_data.tcb_pool.data, private_data.tcb_phys);	private_data.tcb_phys = 0;}static voide100_dealloc_space(){	if (private_data.dma_able) {		pci_free_consistent(private_data.pdev, sizeof (bd_dma_able_t),				    private_data.dma_able, private_data.dma_able_phys);	}	private_data.selftest_phys = 0;	private_data.stat_cnt_phys = 0;	private_data.dma_able_phys = 0;	private_data.dma_able = 0;}static voide100_free_rfd_pool(){	struct rx_list_elem *rx_struct;	while (!list_empty(&(private_data.active_rx_list))) {		rx_struct = list_entry(private_data.active_rx_list.next,				       struct rx_list_elem, list_elem);

⌨️ 快捷键说明

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