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

📄 tulip.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	case DC21041:		if (tulip_debug > 2)			printk(KERN_DEBUG "%s: 21041 media tick  CSR12 %8.8x.\n",				   dev->name, csr12);		switch (dev->if_port) {		case 0: case 3: case 4:		  if (csr12 & 0x0004) { /*LnkFail */			/* 10baseT is dead.  Check for activity on alternate port. */			tp->mediasense = 1;			if (csr12 & 0x0200)				dev->if_port = 2;			else				dev->if_port = 1;			printk(KERN_INFO "%s: No 21041 10baseT link beat, Media switched to %s.\n",				   dev->name, medianame[dev->if_port]);			outl(0, ioaddr + CSR13); /* Reset */			outl(t21041_csr14[dev->if_port], ioaddr + CSR14);			outl(t21041_csr15[dev->if_port], ioaddr + CSR15);			outl(t21041_csr13[dev->if_port], ioaddr + CSR13);			next_tick = 10*HZ;			/* 2.4 sec. */		  } else			next_tick = 30*HZ;		  break;		case 1:					/* 10base2 */		case 2:					/* AUI */		  if (csr12 & 0x0100) {			next_tick = (30*HZ);			/* 30 sec. */			tp->mediasense = 0;		  } else if ((csr12 & 0x0004) == 0) {			printk(KERN_INFO "%s: 21041 media switched to 10baseT.\n", dev->name);			dev->if_port = 0;			select_media(dev, 0);			next_tick = (24*HZ)/10;				/* 2.4 sec. */		  } else if (tp->mediasense || (csr12 & 0x0002)) {			dev->if_port = 3 - dev->if_port; /* Swap ports. */			select_media(dev, 0);			next_tick = 20*HZ;		  } else {			next_tick = 20*HZ;		  }		  break;		}		break;	case DC21140:  case DC21142: case MX98713: default: {		struct medialeaf *mleaf;		unsigned char *p;		if (tp->mtable == NULL) {	/* No EEPROM info, use generic code. */			/* Not much that can be done.			   Assume this a generic MII or SYM transceiver. */			next_tick = 60*HZ;			if (tulip_debug > 2)				printk(KERN_DEBUG "%s: network media monitor CSR6 %8.8x "					   "CSR12 0x%2.2x.\n",					   dev->name, inl(ioaddr + CSR6), csr12 & 0xff);			break;		}		mleaf = &tp->mtable->mleaf[tp->cur_index];		p = mleaf->leafdata;		switch (mleaf->type) {		case 0: case 4: {			/* Type 0 serial or 4 SYM transceiver.  Check the link beat bit. */			int offset = mleaf->type == 4 ? 5 : 2;			s8 bitnum = p[offset];			if (p[offset+1] & 0x80) {				if (tulip_debug > 1)					printk(KERN_DEBUG"%s: Transceiver monitor tick "						   "CSR12=%#2.2x, no media sense.\n",						   dev->name, csr12);				if (mleaf->type == 4) {					if (mleaf->media == 3 && (csr12 & 0x02))						goto select_next_media;				}				break;			}			if (tulip_debug > 2)				printk(KERN_DEBUG "%s: Transceiver monitor tick: CSR12=%#2.2x"					   " bit %d is %d, expecting %d.\n",					   dev->name, csr12, (bitnum >> 1) & 7,					   (csr12 & (1 << ((bitnum >> 1) & 7))) != 0,					   (bitnum >= 0));			/* Check that the specified bit has the proper value. */			if ((bitnum < 0) !=				((csr12 & (1 << ((bitnum >> 1) & 7))) != 0)) {				if (tulip_debug > 1)					printk(KERN_DEBUG "%s: Link beat detected for %s.\n", dev->name,						   medianame[mleaf->media]);				if ((p[2] & 0x61) == 0x01)	/* Bogus Znyx board. */					goto actually_mii;				break;			}			if (tp->medialock)				break;	  select_next_media:			if (--tp->cur_index < 0) {				/* We start again, but should instead look for default. */				tp->cur_index = tp->mtable->leafcount - 1;			}			dev->if_port = tp->mtable->mleaf[tp->cur_index].media;			if (media_cap[dev->if_port] & MediaIsFD)				goto select_next_media; /* Skip FD entries. */			if (tulip_debug > 1)				printk(KERN_DEBUG "%s: No link beat on media %s,"					   " trying transceiver type %s.\n",					   dev->name, medianame[mleaf->media & 15],					   medianame[tp->mtable->mleaf[tp->cur_index].media]);			select_media(dev, 0);			/* Restart the transmit process. */			outl(tp->csr6 | 0x0002, ioaddr + CSR6);			outl(tp->csr6 | 0x2002, ioaddr + CSR6);			next_tick = (24*HZ)/10;			break;		}		case 1:  case 3: {		/* 21140, 21142 MII */			int mii_reg1, mii_reg5;		actually_mii:			mii_reg1 = mdio_read(dev, tp->phys[0], 1);			mii_reg5 = mdio_read(dev, tp->phys[0], 5);			if (tulip_debug > 1)				printk(KERN_INFO "%s: MII status %4.4x, Link partner report "					   "%4.4x, CSR12 %2.2x, %cD.\n",					   dev->name, mii_reg1, mii_reg5, csr12,					   tp->full_duplex ? 'F' : 'H');			if (mii_reg1 != 0xffff  &&  (mii_reg1 & 0x0004) == 0) {				int new_reg1 = mdio_read(dev, tp->phys[0], 1);				if ((new_reg1 & 0x0004) == 0) {					printk(KERN_INFO "%s: No link beat on the MII interface,"						   " status then %4.4x now %4.4x.\n",						   dev->name, mii_reg1, new_reg1);					if (tp->mtable  &&  tp->mtable->has_nonmii)						goto select_next_media;				}			}			if (mii_reg5 == 0xffff  ||  mii_reg5 == 0x0000)				;				/* No MII device or no link partner report */			else if (tp->full_duplex_lock)				;			else {				int negotiated = mii_reg5 & tp->advertising[0];				int duplex = ((negotiated & 0x0100) != 0							  || (negotiated & 0x00C0) == 0x0040);				/* 100baseTx-FD  or  10T-FD, but not 100-HD */				if (tp->full_duplex != duplex) {					tp->full_duplex = duplex;					if (tp->full_duplex)						tp->csr6 |= 0x0200;					else						tp->csr6 &= ~0x0200;					outl(tp->csr6 | 0x0002, ioaddr + CSR6);					outl(tp->csr6 | 0x2002, ioaddr + CSR6);					if (tulip_debug > 0) /* Gurppp, should be >1 */						printk(KERN_INFO "%s: Setting %s-duplex based on MII"							   " Xcvr #%d parter capability of %4.4x.\n",							   dev->name, tp->full_duplex ? "full" : "half",							   tp->phys[0], mii_reg5);				}			}			next_tick = 60*HZ;			break;		}		case 2:					/* 21142 serial block has no link beat. */		default:			break;		}	}	break;	}	if (next_tick) {		tp->timer.expires = RUN_AT(next_tick);		add_timer(&tp->timer);	}}/* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list   of available transceivers.  */static void t21142_timer(unsigned long data){	struct device *dev = (struct device *)data;	struct tulip_private *tp = (struct tulip_private *)dev->priv;	long ioaddr = dev->base_addr;	int csr12 = inl(ioaddr + CSR12);	int next_tick = 60*HZ;	int new_csr6 = 0;	if (tulip_debug > 1)		printk(KERN_INFO"%s: 21142 negotiation status %8.8x, %s.\n",			   dev->name, csr12, medianame[dev->if_port]);	if (dev->if_port == 3) {		if (csr12 & 2) {		/* No 100mbps link beat, revert to 10mbps. */			new_csr6 = 0x82420200;			outl(new_csr6, ioaddr + CSR6);			outl(0x0000, ioaddr + CSR13);			outl(0x0003FFFF, ioaddr + CSR14);			outl(0x0008, ioaddr + CSR15);			outl(0x0001, ioaddr + CSR13);			outl(0x1301, ioaddr + CSR12); /* Start NWay. */		}	} else if ((csr12 & 0x7000) != 0x5000) {		/* Negotiation failed.  Search media types. */		if (tulip_debug > 1)			printk(KERN_INFO"%s: 21142 negotiation failed, status %8.8x.\n",				   dev->name, csr12);		if (!(csr12 & 4)) {		/* 10mbps link beat good. */			new_csr6 = 0x82420000;			dev->if_port = 0;			outl(0, ioaddr + CSR13);			outl(0x0003FFFF, ioaddr + CSR14);			outl(t21142_csr15[dev->if_port], ioaddr + CSR15);			outl(t21142_csr13[dev->if_port], ioaddr + CSR13);		} else if (csr12 & 0x100) {			new_csr6 = 0x82420200;			dev->if_port = 2;			outl(0, ioaddr + CSR13);			outl(0x0003FFFF, ioaddr + CSR14);			outl(0x0008, ioaddr + CSR15);			outl(0x0001, ioaddr + CSR13);		} else {			/* Select 100mbps port to check for link beat. */			new_csr6 = 0x83860000;			dev->if_port = 3;			outl(0, ioaddr + CSR13);			outl(0x0003FF7F, ioaddr + CSR14);			outl(8, ioaddr + CSR15);			outl(1, ioaddr + CSR13);		}		if (tulip_debug > 1)			printk(KERN_INFO"%s: Testing new 21142 media %s.\n",				   dev->name, medianame[dev->if_port]);		if (new_csr6 != (tp->csr6 & ~0x00D5)) {			tp->csr6 &= 0x00D5;			tp->csr6 |= new_csr6;			outl(0x0301, ioaddr + CSR12);			outl(tp->csr6 | 0x0002, ioaddr + CSR6);			outl(tp->csr6 | 0x2002, ioaddr + CSR6);		}	}	tp->timer.expires = RUN_AT(next_tick);	add_timer(&tp->timer);}static void t21142_lnk_change( struct device *dev){	struct tulip_private *tp = (struct tulip_private *)dev->priv;	long ioaddr = dev->base_addr;	int csr12 = inl(ioaddr + CSR12);	if (tulip_debug > 1)		printk(KERN_INFO"%s: 21142 link status interrupt %8.8x, CSR5 %x.\n",			   dev->name, csr12, inl(ioaddr + CSR5));	if ((csr12 & 0x7000) == 0x5000) {		if (csr12 & 0x01800000) {			/* Switch to 100mbps mode. */			outl(tp->csr6 | 0x0002, ioaddr + CSR6);			if (csr12 & 0x01000000) {				dev->if_port = 5;				tp->csr6 = 0x83860200;			} else {				dev->if_port = 3;				tp->csr6 = 0x83860000;			}			outl(tp->csr6 | 0x2002, ioaddr + CSR6);		} /* Else 10baseT-FD is handled automatically. */	} else if (dev->if_port == 3) {		if (!(csr12 & 2))			printk(KERN_INFO"%s: 21142 100baseTx link beat good.\n",				   dev->name);		else			dev->if_port = 0;	} else if (dev->if_port == 0) {		if (!(csr12 & 4))			printk(KERN_INFO"%s: 21142 10baseT link beat good.\n",				   dev->name);	} else if (!(csr12 & 4)) {		/* 10mbps link beat good. */			printk(KERN_INFO"%s: 21142 10mpbs sensed media.\n",				   dev->name);			dev->if_port = 0;	} else  {		/* 100mbps link beat good. */		printk(KERN_INFO"%s: 21142 100baseTx sensed media.\n",			   dev->name);		dev->if_port = 3;		tp->csr6 = 0x83860000;		outl(0x0003FF7F, ioaddr + CSR14);		outl(0x0301, ioaddr + CSR12);		outl(tp->csr6 | 0x0002, ioaddr + CSR6);		outl(tp->csr6 | 0x2002, ioaddr + CSR6);	}}	static void mxic_timer(unsigned long data){	struct device *dev = (struct device *)data;	struct tulip_private *tp = (struct tulip_private *)dev->priv;	long ioaddr = dev->base_addr;	int next_tick = 60*HZ;	if (tulip_debug > 3) {		printk(KERN_INFO"%s: MXIC negotiation status %8.8x.\n", dev->name,			   inl(ioaddr + CSR12));	}	if (next_tick) {		tp->timer.expires = RUN_AT(next_tick);		add_timer(&tp->timer);	}}static void pnic_timer(unsigned long data){	struct device *dev = (struct device *)data;	struct tulip_private *tp = (struct tulip_private *)dev->priv;	long ioaddr = dev->base_addr;	int csr12 = inl(ioaddr + CSR12);	int next_tick = 60*HZ;	int new_csr6 = tp->csr6 & ~0x40C40200;	if (media_cap[dev->if_port] & MediaIsMII) {		int negotiated = mdio_read(dev, tp->phys[0], 5) & tp->advertising[0];		if (tulip_debug > 1)			printk(KERN_DEBUG "%s: LC82C168 negotiated capability %8.8x, "				   "CSR5 %8.8x.\n",				   dev->name, negotiated, inl(ioaddr + CSR5));		if (negotiated & 0x0380) 				/* 10 vs 100mbps */			new_csr6 |= 0x812E0000;		else			new_csr6 |= 0x816E0000;		if (((negotiated & 0x0300) == 0x0100)			/* Duplex */			|| (negotiated & 0x00C0) == 0x0040			|| tp->full_duplex_lock) {			tp->full_duplex = 1;			new_csr6 |= 0x0200;		}		if (tulip_debug > 1)			printk(KERN_DEBUG "%s: LC82C168 MII PHY status %4.4x, Link "				   "partner report %4.4x, csr6 %8.8x/%8.8x.\n",			   dev->name, mdio_read(dev, tp->phys[0], 1), negotiated,				   tp->csr6, inl(ioaddr + CSR6));	} else {		int phy_reg = inl(ioaddr + 0xB8);		int csr5 = inl(ioaddr + CSR5);		if (tulip_debug > 1)			printk(KERN_DEBUG "%s: LC82C168 phy status %8.8x, CSR5 %8.8x.\n",				   dev->name, phy_reg, csr5);		if (phy_reg & 0x04000000) {	/* Remote link fault */			/*outl(0x0201F078, ioaddr + 0xB8);*/			next_tick = 3*HZ;		}		if (inl(ioaddr + CSR5) & TPLnkFail) { /* 100baseTx link beat */			if (tulip_debug > 1)				printk(KERN_DEBUG "%s: %s link beat failed, CSR12 %4.4x, "					   "CSR5 %8.8x, PHY %3.3x.\n",					   dev->name, medianame[dev->if_port], csr12,					   inl(ioaddr + CSR5), inl(ioaddr + 0xB8));			if (tp->medialock) {			} else if (dev->if_port == 0) {				dev->if_port = 3;				outl(0x33, ioaddr + CSR12);				new_csr6 = 0x01860000;				outl(0x1F868, ioaddr + 0xB8);			} else {				dev->if_port = 0;				outl(0x32, ioaddr + CSR12);				new_csr6 = 0x00420000;				outl(0x1F078, ioaddr + 0xB8);			}			new_csr6 |= (tp->csr6 & 0xfdff);			next_tick = 3*HZ;		} else			new_csr6 = tp->csr6;		if (tp->full_duplex_lock  ||  (phy_reg & 0x30000000) != 0) {			tp->full_duplex = 1;			new_csr6 |= 0x00000200;		}	}	if (tp->csr6 != new_csr6) {		tp->csr6 = new_csr6;		outl(tp->csr6 | 0x0002, ioaddr + CSR6);	/* Restart Tx */		outl(tp->csr6 | 0x2002, ioaddr + CSR6);		dev->trans_start = jiffies;		if (tulip_debug > 0) /* Gurppp, should be >1 */			printk(KERN_INFO "%s: Changing PNIC configuration to %s-duplex, "				   "CSR6 %8.8x.\n",				   dev->name, tp->full_duplex ? "full" : "half", new_csr6);	}	tp->timer.expires = RUN_AT(next_tick);	add_timer(&tp->timer);}static void tulip_tx_timeout(struct dev

⌨️ 快捷键说明

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