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

📄 smc91113.c

📁 SMSC lan91c113 uclinux driver source
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	return 0;}/*------------------------------------------------------------ . Cleanup when module is removed with rmmod .-------------------------------------------------------------*/void EV44b0_cleanup_module(void){	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */	unregister_netdev(&devSMC91113);	free_irq(devSMC91113.irq, &devSMC91113);	release_region(devSMC91113.base_addr, SMC_IO_EXTENT);	if (devSMC91113.priv)		kfree(devSMC91113.priv); /* Kernel 2.4 Changes - Pramod */}#ifdef CONFIG_SYSCTL/*------------------------------------------------------------ . Modify a bit in the LAN91C113 register set .-------------------------------------------------------------*/static word smc_modify_regbit(int bank, int ioaddr, int reg,	unsigned int bit, int val){	word regval;	SMC_SELECT_BANK( bank );	regval = inw( ioaddr+reg );	if (val)		regval |= bit;	else		regval &= ~bit;	outw( regval, ioaddr );	return(regval);}/*------------------------------------------------------------ . Retrieve a bit in the LAN91C113 register set .-------------------------------------------------------------*/static int smc_get_regbit(int bank, int ioaddr, int reg, unsigned int bit){	SMC_SELECT_BANK( bank );	if ( inw( ioaddr+reg ) & bit)		return(1);	else		return(0);}/*------------------------------------------------------------ . Modify a LAN91C113 register (word access only) .-------------------------------------------------------------*/static void smc_modify_reg(int bank, int ioaddr, int reg, word val){	SMC_SELECT_BANK( bank );	outw( val, ioaddr+reg );}/*------------------------------------------------------------ . Retrieve a LAN91C113 register (word access only) .-------------------------------------------------------------*/static int smc_get_reg(int bank, int ioaddr, int reg){	SMC_SELECT_BANK( bank );	return(inw( ioaddr+reg ));}static const char smc_info_string[] ="\n""info           Provides this information blurb\n""swver          Prints the software version information of this driver\n""autoneg        Auto-negotiate Mode = 1\n""rspeed         Requested Speed, 100=100Mbps, 10=10Mpbs\n""rfduplx        Requested Full Duplex Operation\n""aspeed         Actual Speed, 100=100Mbps, 10=10Mpbs\n""afduplx        Actual Full Duplex Operation\n""lnkfail        PHY Link Failure when 1\n""miiop          External MII when 1, Internal PHY when 0\n""swfdup         Switched Full Duplex Mode (allowed only in MII operation)\n""ephloop        EPH Block Loopback\n""forcol         Force a collision\n""filtcar        Filter leading edge of carrier sense for 12 bit times\n""freemem        Free buffer memory in bytes\n""totmem         Total buffer memory in bytes\n""leda           Output of LED-A (green)\n""ledb           Output of LED-B (yellow)\n""chiprev        Revision ID of the LAN91C113 chip\n""";/*------------------------------------------------------------ . Sysctl handler for all integer parameters .-------------------------------------------------------------*/static int smc_sysctl_handler(ctl_table *ctl, int write, struct file * filp,				void *buffer, size_t *lenp){	struct net_device *dev = (struct net_device*)ctl->extra1;	struct smc_local *lp = (struct smc_local *)ctl->extra2;	int ioaddr = dev->base_addr;	int *valp = ctl->data;	int val;	int ret;	// Update parameters from the real registers	switch (ctl->ctl_name)	{	case CTL_SMC_FORCOL:		*valp = smc_get_regbit(0, ioaddr, TCR_REG, TCR_FORCOL);		break;	case CTL_SMC_FREEMEM:		*valp = ( (word)smc_get_reg(0, ioaddr, MIR_REG) >> 8 )			* LAN91C113_MEMORY_MULTIPLIER;		break;	case CTL_SMC_TOTMEM:		*valp = ( smc_get_reg(0, ioaddr, MIR_REG) & (word)0x00ff )			* LAN91C113_MEMORY_MULTIPLIER;		break;	case CTL_SMC_CHIPREV:		*valp = smc_get_reg(3, ioaddr, REV_REG);		break;	case CTL_SMC_AFDUPLX:		*valp = (lp->lastPhy18 & PHY_INT_DPLXDET) ? 1 : 0;		break;	case CTL_SMC_ASPEED:		*valp = (lp->lastPhy18 & PHY_INT_SPDDET) ? 100 : 10;		break;	case CTL_SMC_LNKFAIL:		*valp = (lp->lastPhy18 & PHY_INT_LNKFAIL) ? 1 : 0;		break;	case CTL_SMC_LEDA:		*valp = (lp->rpc_cur_mode >> RPC_LSXA_SHFT) & (word)0x0007;		break;	case CTL_SMC_LEDB:		*valp = (lp->rpc_cur_mode >> RPC_LSXB_SHFT) & (word)0x0007;		break;	case CTL_SMC_MIIOP:		*valp = smc_get_regbit(1, ioaddr, CONFIG_REG, CONFIG_EXT_PHY);		break;#ifdef SMC_DEBUG	case CTL_SMC_REG_BSR:	// Bank Select		*valp = smc_get_reg(0, ioaddr, BSR_REG);		break;	case CTL_SMC_REG_TCR:	// Transmit Control		*valp = smc_get_reg(0, ioaddr, TCR_REG);		break;	case CTL_SMC_REG_ESR:	// EPH Status		*valp = smc_get_reg(0, ioaddr, EPH_STATUS_REG);		break;	case CTL_SMC_REG_RCR:	// Receive Control		*valp = smc_get_reg(0, ioaddr, RCR_REG);		break;	case CTL_SMC_REG_CTRR:	// Counter		*valp = smc_get_reg(0, ioaddr, COUNTER_REG);		break;	case CTL_SMC_REG_MIR:	// Memory Information		*valp = smc_get_reg(0, ioaddr, MIR_REG);		break;	case CTL_SMC_REG_RPCR:	// Receive/Phy Control		*valp = smc_get_reg(0, ioaddr, RPC_REG);		break;	case CTL_SMC_REG_CFGR:	// Configuration		*valp = smc_get_reg(1, ioaddr, CONFIG_REG);		break;	case CTL_SMC_REG_BAR:	// Base Address		*valp = smc_get_reg(1, ioaddr, BASE_REG);		break;	case CTL_SMC_REG_IAR0:	// Individual Address		*valp = smc_get_reg(1, ioaddr, ADDR0_REG);		break;	case CTL_SMC_REG_IAR1:	// Individual Address		*valp = smc_get_reg(1, ioaddr, ADDR1_REG);		break;	case CTL_SMC_REG_IAR2:	// Individual Address		*valp = smc_get_reg(1, ioaddr, ADDR2_REG);		break;	case CTL_SMC_REG_GPR:	// General Purpose		*valp = smc_get_reg(1, ioaddr, GP_REG);		break;	case CTL_SMC_REG_CTLR:	// Control		*valp = smc_get_reg(1, ioaddr, CTL_REG);		break;	case CTL_SMC_REG_MCR:	// MMU Command		*valp = smc_get_reg(2, ioaddr, MMU_CMD_REG);		break;	case CTL_SMC_REG_PNR:	// Packet Number		*valp = smc_get_reg(2, ioaddr, PN_REG);		break;	case CTL_SMC_REG_FPR:	// Allocation Result/FIFO Ports		*valp = smc_get_reg(2, ioaddr, RXFIFO_REG);		break;	case CTL_SMC_REG_PTR:	// Pointer		*valp = smc_get_reg(2, ioaddr, PTR_REG);		break;	case CTL_SMC_REG_DR:	// Data 		*valp = smc_get_reg(2, ioaddr, DATA_REG);		break;	case CTL_SMC_REG_ISR:	// Interrupt Status/Mask		*valp = smc_get_reg(2, ioaddr, INT_REG);		break;	case CTL_SMC_REG_MTR1:	// Multicast Table Entry 1		*valp = smc_get_reg(3, ioaddr, MCAST_REG1);		break;	case CTL_SMC_REG_MTR2:	// Multicast Table Entry 2		*valp = smc_get_reg(3, ioaddr, MCAST_REG2);		break;	case CTL_SMC_REG_MTR3:	// Multicast Table Entry 3		*valp = smc_get_reg(3, ioaddr, MCAST_REG3);		break;	case CTL_SMC_REG_MTR4:	// Multicast Table Entry 4		*valp = smc_get_reg(3, ioaddr, MCAST_REG4);		break;	case CTL_SMC_REG_MIIR:	// Management Interface		*valp = smc_get_reg(3, ioaddr, MII_REG);		break;	case CTL_SMC_REG_REVR:	// Revision		*valp = smc_get_reg(3, ioaddr, REV_REG);		break;	case CTL_SMC_REG_ERCVR:	// Early RCV		*valp = smc_get_reg(3, ioaddr, ERCV_REG);		break;	case CTL_SMC_REG_EXTR:	// External		*valp = smc_get_reg(7, ioaddr, EXT_REG);		break;	case CTL_SMC_PHY_CTRL:		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,			PHY_CNTL_REG);		break;	case CTL_SMC_PHY_STAT:		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,			PHY_STAT_REG);		break;	case CTL_SMC_PHY_ID1:		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,			PHY_ID1_REG);		break;	case CTL_SMC_PHY_ID2:		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,			PHY_ID2_REG);		break;	case CTL_SMC_PHY_ADC:		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,			PHY_AD_REG);		break;	case CTL_SMC_PHY_REMC:		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,			PHY_RMT_REG);		break;	case CTL_SMC_PHY_CFG1:		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,			PHY_CFG1_REG);		break;	case CTL_SMC_PHY_CFG2:		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,			PHY_CFG2_REG);		break;	case CTL_SMC_PHY_INT:		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,			PHY_INT_REG);		break;	case CTL_SMC_PHY_MASK:		*valp = smc_read_phy_register(ioaddr, lp->phyaddr,			PHY_MASK_REG);		break;#endif // SMC_DEBUG	default:		// Just ignore unsupported parameters		break;	}	// Save old state	val = *valp;	// Perform the generic integer operation		if ((ret = proc_dointvec(ctl, write, filp, buffer, lenp)) != 0)		return(ret);	// Write changes out to the registers	if (write && *valp != val) {		val = *valp;		switch (ctl->ctl_name) {		case CTL_SMC_SWFDUP:			if (val)				lp->tcr_cur_mode |= TCR_SWFDUP;			else				lp->tcr_cur_mode &= ~TCR_SWFDUP;			smc_modify_regbit(0, ioaddr, TCR_REG, TCR_SWFDUP, val);			break;		case CTL_SMC_EPHLOOP:			if (val)				lp->tcr_cur_mode |= TCR_EPH_LOOP;			else				lp->tcr_cur_mode &= ~TCR_EPH_LOOP;			smc_modify_regbit(0, ioaddr, TCR_REG, TCR_EPH_LOOP, val);			break;		case CTL_SMC_FORCOL:			if (val)				lp->tcr_cur_mode |= TCR_FORCOL;			else				lp->tcr_cur_mode &= ~TCR_FORCOL;			// Update the EPH block			smc_modify_regbit(0, ioaddr, TCR_REG, TCR_FORCOL, val);			break;		case CTL_SMC_FILTCAR:			if (val)				lp->rcr_cur_mode |= RCR_FILT_CAR;			else				lp->rcr_cur_mode &= ~RCR_FILT_CAR;			// Update the EPH block			smc_modify_regbit(0, ioaddr, RCR_REG, RCR_FILT_CAR, val);			break;		case CTL_SMC_RFDUPLX:			// Disallow changes if in auto-negotiation mode			if (lp->ctl_autoneg)				break;			if (val)				{				lp->rpc_cur_mode |= RPC_DPLX;				}			else				{				lp->rpc_cur_mode &= ~RPC_DPLX;				}			// Reconfigure the PHY			smc_phy_configure(dev);			break;		case CTL_SMC_RSPEED:			// Disallow changes if in auto-negotiation mode			if (lp->ctl_autoneg)				break;			if (val > 10)				lp->rpc_cur_mode |= RPC_SPEED;			else				lp->rpc_cur_mode &= ~RPC_SPEED;			// Reconfigure the PHY			smc_phy_configure(dev);			break;		case CTL_SMC_AUTONEG:			if (val)				lp->rpc_cur_mode |= RPC_ANEG;			else				lp->rpc_cur_mode &= ~RPC_ANEG;			// Reconfigure the PHY			smc_phy_configure(dev);			break;		case CTL_SMC_LEDA:			val &= 0x07; // Restrict to 3 ls bits			lp->rpc_cur_mode &= ~(word)(0x07<<RPC_LSXA_SHFT);			lp->rpc_cur_mode |= (word)(val<<RPC_LSXA_SHFT);			// Update the Internal PHY block			smc_modify_reg(0, ioaddr, RPC_REG, lp->rpc_cur_mode);			break;		case CTL_SMC_LEDB:			val &= 0x07; // Restrict to 3 ls bits			lp->rpc_cur_mode &= ~(word)(0x07<<RPC_LSXB_SHFT);			lp->rpc_cur_mode |= (word)(val<<RPC_LSXB_SHFT);			// Update the Internal PHY block			smc_modify_reg(0, ioaddr, RPC_REG, lp->rpc_cur_mode);			break;		case CTL_SMC_MIIOP:			// Update the Internal PHY block			smc_modify_regbit(1, ioaddr, CONFIG_REG,				CONFIG_EXT_PHY, val);			break;#ifdef SMC_DEBUG		case CTL_SMC_REG_BSR:	// Bank Select			smc_modify_reg(0, ioaddr, BSR_REG, val);			break;		case CTL_SMC_REG_TCR:	// Transmit Control			smc_modify_reg(0, ioaddr, TCR_REG, val);			break;		case CTL_SMC_REG_ESR:	// EPH Status			smc_modify_reg(0, ioaddr, EPH_STATUS_REG, val);			break;		case CTL_SMC_REG_RCR:	// Receive Control			smc_modify_reg(0, ioaddr, RCR_REG, val);			break;		case CTL_SMC_REG_CTRR:	// Counter			smc_modify_reg(0, ioaddr, COUNTER_REG, val);			break;		case CTL_SMC_REG_MIR:	// Memory Information			smc_modify_reg(0, ioaddr, MIR_REG, val);			break;		case CTL_SMC_REG_RPCR:	// Receive/Phy Control	

⌨️ 快捷键说明

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