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

📄 wavelan.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	       mmc_in(ioaddr, mmroff(0, mmr_fee_data_l)));#endif				/* DOESNT_SEEM_TO_WORK */	/* Enable protected register. */	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PREN);	fee_wait(ioaddr, 10, 100);	/* Unprotect area. */	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n);	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);#ifdef DOESNT_SEEM_TO_WORK	/* disabled */	/* or use: */	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRCLEAR);#endif				/* DOESNT_SEEM_TO_WORK */	fee_wait(ioaddr, 10, 100);#endif				/* EEPROM_IS_PROTECTED */	/* Write enable. */	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WREN);	fee_wait(ioaddr, 10, 100);	/* Write the EEPROM address. */	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n - 1);	/* Loop on all buffer */	while (n-- > 0) {		/* Write the value. */		mmc_out(ioaddr, mmwoff(0, mmw_fee_data_h), (*--b) >> 8);		mmc_out(ioaddr, mmwoff(0, mmw_fee_data_l), *b & 0xFF);		/* Write the write command. */		mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),			MMW_FEE_CTRL_WRITE);		/* WaveLAN documentation says to wait at least 10 ms for EEBUSY = 0 */		mdelay(10);		fee_wait(ioaddr, 10, 100);	}	/* Write disable. */	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_DS);	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WDS);	fee_wait(ioaddr, 10, 100);#ifdef EEPROM_IS_PROTECTED	/* disabled */	/* Reprotect EEPROM. */	mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x00);	mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);	fee_wait(ioaddr, 10, 100);#endif				/* EEPROM_IS_PROTECTED */}#endif				/* WIRELESS_EXT *//************************ I82586 SUBROUTINES *************************//* * Useful subroutines to manage the Ethernet controller *//*------------------------------------------------------------------*//* * Read bytes from the on-board RAM. * Why does inlining this function make it fail? */static /*inline */ void obram_read(unsigned long ioaddr,				   u16 o, u8 * b, int n){	outw(o, PIOR1(ioaddr));	insw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1);}/*------------------------------------------------------------------*//* * Write bytes to the on-board RAM. */static inline void obram_write(unsigned long ioaddr, u16 o, u8 * b, int n){	outw(o, PIOR1(ioaddr));	outsw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1);}/*------------------------------------------------------------------*//* * Acknowledge the reading of the status issued by the i82586. */static void wv_ack(struct net_device * dev){	net_local *lp = (net_local *) dev->priv;	unsigned long ioaddr = dev->base_addr;	u16 scb_cs;	int i;	obram_read(ioaddr, scboff(OFFSET_SCB, scb_status),		   (unsigned char *) &scb_cs, sizeof(scb_cs));	scb_cs &= SCB_ST_INT;	if (scb_cs == 0)		return;	obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),		    (unsigned char *) &scb_cs, sizeof(scb_cs));	set_chan_attn(ioaddr, lp->hacr);	for (i = 1000; i > 0; i--) {		obram_read(ioaddr, scboff(OFFSET_SCB, scb_command),			   (unsigned char *) &scb_cs, sizeof(scb_cs));		if (scb_cs == 0)			break;		udelay(10);	}	udelay(100);#ifdef DEBUG_CONFIG_ERROR	if (i <= 0)		printk(KERN_INFO		       "%s: wv_ack(): board not accepting command.\n",		       dev->name);#endif}/*------------------------------------------------------------------*//* * Set channel attention bit and busy wait until command has * completed, then acknowledge completion of the command. */static inline int wv_synchronous_cmd(struct net_device * dev, const char *str){	net_local *lp = (net_local *) dev->priv;	unsigned long ioaddr = dev->base_addr;	u16 scb_cmd;	ach_t cb;	int i;	scb_cmd = SCB_CMD_CUC & SCB_CMD_CUC_GO;	obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),		    (unsigned char *) &scb_cmd, sizeof(scb_cmd));	set_chan_attn(ioaddr, lp->hacr);	for (i = 1000; i > 0; i--) {		obram_read(ioaddr, OFFSET_CU, (unsigned char *) &cb,			   sizeof(cb));		if (cb.ac_status & AC_SFLD_C)			break;		udelay(10);	}	udelay(100);	if (i <= 0 || !(cb.ac_status & AC_SFLD_OK)) {#ifdef DEBUG_CONFIG_ERROR		printk(KERN_INFO "%s: %s failed; status = 0x%x\n",		       dev->name, str, cb.ac_status);#endif#ifdef DEBUG_I82586_SHOW		wv_scb_show(ioaddr);#endif		return -1;	}	/* Ack the status */	wv_ack(dev);	return 0;}/*------------------------------------------------------------------*//* * Configuration commands completion interrupt. * Check if done, and if OK. */static inline intwv_config_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp){	unsigned short mcs_addr;	unsigned short status;	int ret;#ifdef DEBUG_INTERRUPT_TRACE	printk(KERN_DEBUG "%s: ->wv_config_complete()\n", dev->name);#endif	mcs_addr = lp->tx_first_in_use + sizeof(ac_tx_t) + sizeof(ac_nop_t)	    + sizeof(tbd_t) + sizeof(ac_cfg_t) + sizeof(ac_ias_t);	/* Read the status of the last command (set mc list). */	obram_read(ioaddr, acoff(mcs_addr, ac_status),		   (unsigned char *) &status, sizeof(status));	/* If not completed -> exit */	if ((status & AC_SFLD_C) == 0)		ret = 0;	/* Not ready to be scrapped */	else {#ifdef DEBUG_CONFIG_ERROR		unsigned short cfg_addr;		unsigned short ias_addr;		/* Check mc_config command */		if ((status & AC_SFLD_OK) != AC_SFLD_OK)			printk(KERN_INFO			       "%s: wv_config_complete(): set_multicast_address failed; status = 0x%x\n",			       dev->name, status);		/* check ia-config command */		ias_addr = mcs_addr - sizeof(ac_ias_t);		obram_read(ioaddr, acoff(ias_addr, ac_status),			   (unsigned char *) &status, sizeof(status));		if ((status & AC_SFLD_OK) != AC_SFLD_OK)			printk(KERN_INFO			       "%s: wv_config_complete(): set_MAC_address failed; status = 0x%x\n",			       dev->name, status);		/* Check config command. */		cfg_addr = ias_addr - sizeof(ac_cfg_t);		obram_read(ioaddr, acoff(cfg_addr, ac_status),			   (unsigned char *) &status, sizeof(status));		if ((status & AC_SFLD_OK) != AC_SFLD_OK)			printk(KERN_INFO			       "%s: wv_config_complete(): configure failed; status = 0x%x\n",			       dev->name, status);#endif	/* DEBUG_CONFIG_ERROR */		ret = 1;	/* Ready to be scrapped */	}#ifdef DEBUG_INTERRUPT_TRACE	printk(KERN_DEBUG "%s: <-wv_config_complete() - %d\n", dev->name,	       ret);#endif	return ret;}/*------------------------------------------------------------------*//* * Command completion interrupt. * Reclaim as many freed tx buffers as we can. * (called in wavelan_interrupt()). * Note : the spinlock is already grabbed for us. */static int wv_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp){	int nreaped = 0;#ifdef DEBUG_INTERRUPT_TRACE	printk(KERN_DEBUG "%s: ->wv_complete()\n", dev->name);#endif	/* Loop on all the transmit buffers */	while (lp->tx_first_in_use != I82586NULL) {		unsigned short tx_status;		/* Read the first transmit buffer */		obram_read(ioaddr, acoff(lp->tx_first_in_use, ac_status),			   (unsigned char *) &tx_status,			   sizeof(tx_status));		/* If not completed -> exit */		if ((tx_status & AC_SFLD_C) == 0)			break;		/* Hack for reconfiguration */		if (tx_status == 0xFFFF)			if (!wv_config_complete(dev, ioaddr, lp))				break;	/* Not completed */		/* We now remove this buffer */		nreaped++;		--lp->tx_n_in_use;/*if (lp->tx_n_in_use > 0)	printk("%c", "0123456789abcdefghijk"[lp->tx_n_in_use]);*/		/* Was it the last one? */		if (lp->tx_n_in_use <= 0)			lp->tx_first_in_use = I82586NULL;		else {			/* Next one in the chain */			lp->tx_first_in_use += TXBLOCKZ;			if (lp->tx_first_in_use >=			    OFFSET_CU +			    NTXBLOCKS * TXBLOCKZ) lp->tx_first_in_use -=				    NTXBLOCKS * TXBLOCKZ;		}		/* Hack for reconfiguration */		if (tx_status == 0xFFFF)			continue;		/* Now, check status of the finished command */		if (tx_status & AC_SFLD_OK) {			int ncollisions;			lp->stats.tx_packets++;			ncollisions = tx_status & AC_SFLD_MAXCOL;			lp->stats.collisions += ncollisions;#ifdef DEBUG_TX_INFO			if (ncollisions > 0)				printk(KERN_DEBUG				       "%s: wv_complete(): tx completed after %d collisions.\n",				       dev->name, ncollisions);#endif		} else {			lp->stats.tx_errors++;			if (tx_status & AC_SFLD_S10) {				lp->stats.tx_carrier_errors++;#ifdef DEBUG_TX_FAIL				printk(KERN_DEBUG				       "%s: wv_complete(): tx error: no CS.\n",				       dev->name);#endif			}			if (tx_status & AC_SFLD_S9) {				lp->stats.tx_carrier_errors++;#ifdef DEBUG_TX_FAIL				printk(KERN_DEBUG				       "%s: wv_complete(): tx error: lost CTS.\n",				       dev->name);#endif			}			if (tx_status & AC_SFLD_S8) {				lp->stats.tx_fifo_errors++;#ifdef DEBUG_TX_FAIL				printk(KERN_DEBUG				       "%s: wv_complete(): tx error: slow DMA.\n",				       dev->name);#endif			}			if (tx_status & AC_SFLD_S6) {				lp->stats.tx_heartbeat_errors++;#ifdef DEBUG_TX_FAIL				printk(KERN_DEBUG				       "%s: wv_complete(): tx error: heart beat.\n",				       dev->name);#endif			}			if (tx_status & AC_SFLD_S5) {				lp->stats.tx_aborted_errors++;#ifdef DEBUG_TX_FAIL				printk(KERN_DEBUG				       "%s: wv_complete(): tx error: too many collisions.\n",				       dev->name);#endif			}		}#ifdef DEBUG_TX_INFO		printk(KERN_DEBUG		       "%s: wv_complete(): tx completed, tx_status 0x%04x\n",		       dev->name, tx_status);#endif	}#ifdef DEBUG_INTERRUPT_INFO	if (nreaped > 1)		printk(KERN_DEBUG "%s: wv_complete(): reaped %d\n",		       dev->name, nreaped);#endif	/*	 * Inform upper layers.	 */	if (lp->tx_n_in_use < NTXBLOCKS - 1) {		netif_wake_queue(dev);	}#ifdef DEBUG_INTERRUPT_TRACE	printk(KERN_DEBUG "%s: <-wv_complete()\n", dev->name);#endif	return nreaped;}/*------------------------------------------------------------------*//* * Reconfigure the i82586, or at least ask for it. * Because wv_82586_config uses a transmission buffer, we must do it * when we are sure that there is one left, so we do it now * or in wavelan_packet_xmit() (I can't find any better place, * wavelan_interrupt is not an option), so you may experience * delays sometimes. */static inline void wv_82586_reconfig(struct net_device * dev){	net_local *lp = (net_local *) dev->priv;	unsigned long flags;	/* Arm the flag, will be cleard in wv_82586_config() */	lp->reconfig_82586 = 1;	/* Check if we can do it now ! */	if((netif_running(dev)) && !(netif_queue_stopped(dev))) {		spin_lock_irqsave(&lp->spinlock, flags);		/* May fail */		wv_82586_config(dev);		spin_unlock_irqrestore(&lp->spinlock, flags);	}	else {#ifdef DEBUG_CONFIG_INFO		printk(KERN_DEBUG		       "%s: wv_82586_reconfig(): delayed (state = %lX)\n",			       dev->name, dev->state);#endif	}}/********************* DEBUG & INFO SUBROUTINES *********************//* * This routine is used in the code to show information for debugging. * Most of the time, it dumps the contents of hardware structures. */#ifdef DEBUG_PSA_SHOW/*------------------------------------------------------------------*//* * Print the formatted contents of the Parameter Storage Area. */static void wv_psa_show(psa_t * p){	printk(KERN_DEBUG "##### WaveLAN PSA contents: #####\n");	printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",	       p->psa_io_base_addr_1,	       p->psa_io_base_addr_2,	       p->psa_io_base_addr_3, p->psa_io_base_addr_4);	printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02X\n",	       p->psa_rem_boot_addr_1,	       p->psa_rem_boot_addr_2, p->psa_rem_boot_addr_3);	printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);	printk("psa_int_req_no: %d\n", p->psa_int_req_no);#ifdef DEBUG_SHOW_UNUSED	printk(KERN_DEBUG	       "psa_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X\n",	       p->psa_unused0[0], p->psa_unused0[1], p->psa_unused0[2],	       p->psa_unused0[3], p->psa_unused0[4], p->psa_unused0[5],	       p->psa_unused0[6]);#endif				/* DEBUG_SHOW_UNUSED */	printk(KERN_DEBUG	       "psa_univ_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n",	       p->psa_univ_mac_addr[0], p->psa_univ_mac_addr[1],	       p->psa_univ_mac_addr[2], p->psa_univ_mac_addr[3],	       p->psa_univ_mac_addr[4], p->psa_univ_mac_addr[5]);	printk(KERN_DEBUG	       "psa_local_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n",	       p->psa_local_mac_addr[0], p->psa_local_mac_addr[1],	       p->psa_local_mac_addr[2], p->psa_local_mac_addr[3],	       p->psa_local_mac_addr[4], p->psa_local_mac_addr[5]);	printk(KERN_DEBUG "psa_univ_local_sel: %d, ",	       p->psa_univ_local_sel);	printk("psa_comp_number: %d, ", p->psa_comp_number);	printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set);	printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ",

⌨️ 快捷键说明

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