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

📄 fec.c

📁 linux驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			s |= PHY_STAT_10HDX;	}	fep->phy_status = s;}static phy_info_t phy_info_lxt970 = {	0x07810000,	"LXT970",	(const phy_cmd_t []) {  /* config */#if 0//		{ mk_mii_write(MII_REG_ANAR, 0x0021), NULL },		/* Set default operation of 100-TX....for some reason		 * some of these bits are set on power up, which is wrong.		 */		{ mk_mii_write(MII_LXT970_CONFIG, 0), NULL },#endif		{ mk_mii_read(MII_REG_CR), mii_parse_cr },		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* startup - enable interrupts */		{ mk_mii_write(MII_LXT970_IER, 0x0002), NULL },		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */		{ mk_mii_end, }	},	(const phy_cmd_t []) { /* ack_int */		/* read SR and ISR to acknowledge */		{ mk_mii_read(MII_REG_SR), mii_parse_sr },		{ mk_mii_read(MII_LXT970_ISR), NULL },		/* find out the current status */		{ mk_mii_read(MII_LXT970_CSR), mii_parse_lxt970_csr },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* shutdown - disable interrupts */		{ mk_mii_write(MII_LXT970_IER, 0x0000), NULL },		{ mk_mii_end, }	},};#endif /* CONFIG_FEC_LXT970 *//* ------------------------------------------------------------------------- *//* The Level one LXT971 is used on some of my custom boards                  */#ifdef CONFIG_FEC_LXT971/* register definitions for the 971 */#define MII_LXT971_PCR       16  /* Port Control Register     */#define MII_LXT971_SR2       17  /* Status Register 2         */#define MII_LXT971_IER       18  /* Interrupt Enable Register */#define MII_LXT971_ISR       19  /* Interrupt Status Register */#define MII_LXT971_LCR       20  /* LED Control Register      */#define MII_LXT971_TCR       30  /* Transmit Control Register *//* * I had some nice ideas of running the MDIO faster... * The 971 should support 8MHz and I tried it, but things acted really * weird, so 2.5 MHz ought to be enough for anyone... */static void mii_parse_lxt971_sr2(uint mii_reg, struct net_device *dev, uint data){	volatile struct fec_enet_private *fep = dev->priv;	uint s = fep->phy_status;	s &= ~(PHY_STAT_SPMASK);	if (mii_reg & 0x4000) {		if (mii_reg & 0x0200)			s |= PHY_STAT_100FDX;		else			s |= PHY_STAT_100HDX;	} else {		if (mii_reg & 0x0200)			s |= PHY_STAT_10FDX;		else			s |= PHY_STAT_10HDX;	}	if (mii_reg & 0x0008)		s |= PHY_STAT_FAULT;	fep->phy_status = s;}static phy_info_t phy_info_lxt971 = {	0x0001378e,	"LXT971",	(const phy_cmd_t []) {  /* config *///		{ mk_mii_write(MII_REG_ANAR, 0x021), NULL }, /* 10  Mbps, HD */		{ mk_mii_read(MII_REG_CR), mii_parse_cr },		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* startup - enable interrupts */		{ mk_mii_write(MII_LXT971_IER, 0x00f2), NULL },		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */		/* Somehow does the 971 tell me that the link is down		 * the first read after power-up.		 * read here to get a valid value in ack_int */		{ mk_mii_read(MII_REG_SR), mii_parse_sr },		{ mk_mii_end, }	},	(const phy_cmd_t []) { /* ack_int */		/* find out the current status */		{ mk_mii_read(MII_REG_SR), mii_parse_sr },		{ mk_mii_read(MII_LXT971_SR2), mii_parse_lxt971_sr2 },		/* we only need to read ISR to acknowledge */		{ mk_mii_read(MII_LXT971_ISR), NULL },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* shutdown - disable interrupts */		{ mk_mii_write(MII_LXT971_IER, 0x0000), NULL },		{ mk_mii_end, }	},};#endif /* CONFIG_FEC_LXT971 *//* ------------------------------------------------------------------------- *//* The Quality Semiconductor QS6612 is used on the RPX CLLF                  */#ifdef CONFIG_FEC_QS6612/* register definitions */#define MII_QS6612_MCR       17  /* Mode Control Register      */#define MII_QS6612_FTR       27  /* Factory Test Register      */#define MII_QS6612_MCO       28  /* Misc. Control Register     */#define MII_QS6612_ISR       29  /* Interrupt Source Register  */#define MII_QS6612_IMR       30  /* Interrupt Mask Register    */#define MII_QS6612_PCR       31  /* 100BaseTx PHY Control Reg. */static void mii_parse_qs6612_pcr(uint mii_reg, struct net_device *dev, uint data){	volatile struct fec_enet_private *fep = dev->priv;	uint s = fep->phy_status;	s &= ~(PHY_STAT_SPMASK);	switch((mii_reg >> 2) & 7) {	case 1: s |= PHY_STAT_10HDX;  break;	case 2: s |= PHY_STAT_100HDX; break;	case 5: s |= PHY_STAT_10FDX;  break;	case 6: s |= PHY_STAT_100FDX; break;	}	fep->phy_status = s;}static phy_info_t phy_info_qs6612 = {	0x00181440,	"QS6612",	(const phy_cmd_t []) {  /* config *///	{ mk_mii_write(MII_REG_ANAR, 0x061), NULL }, /* 10  Mbps */		/* The PHY powers up isolated on the RPX,		 * so send a command to allow operation.		 */		{ mk_mii_write(MII_QS6612_PCR, 0x0dc0), NULL },		/* parse cr and anar to get some info */		{ mk_mii_read(MII_REG_CR), mii_parse_cr },		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* startup - enable interrupts */		{ mk_mii_write(MII_QS6612_IMR, 0x003a), NULL },		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */		{ mk_mii_end, }	},	(const phy_cmd_t []) { /* ack_int */		/* we need to read ISR, SR and ANER to acknowledge */		{ mk_mii_read(MII_QS6612_ISR), NULL },		{ mk_mii_read(MII_REG_SR), mii_parse_sr },		{ mk_mii_read(MII_REG_ANER), NULL },		/* read pcr to get info */		{ mk_mii_read(MII_QS6612_PCR), mii_parse_qs6612_pcr },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* shutdown - disable interrupts */		{ mk_mii_write(MII_QS6612_IMR, 0x0000), NULL },		{ mk_mii_end, }	},};#endif /* CONFIG_FEC_QS6612 *//* ------------------------------------------------------------------------- *//* The Advanced Micro Devices AM79C874 is used on the ICU862		     */#ifdef CONFIG_FEC_AM79C874/* register definitions for the 79C874 */#define MII_AM79C874_MFR	16  /* Miscellaneous Features Register      */#define MII_AM79C874_ICSR	17  /* Interrupt Control/Status Register    */#define MII_AM79C874_DR		18  /* Diagnostic Register		    */#define MII_AM79C874_PMLR	19  /* Power Management & Loopback Register */#define MII_AM79C874_MCR	21  /* Mode Control Register		    */#define MII_AM79C874_DC		23  /* Disconnect Counter		    */#define MII_AM79C874_REC	24  /* Receiver Error Counter		    */static void mii_parse_amd79c874_dr(uint mii_reg, struct net_device *dev){	volatile struct fec_enet_private *fep = dev->priv;	uint s = fep->phy_status;	s &= ~(PHY_STAT_SPMASK);	/* Register 18: Bit 10 is data rate, 11 is Duplex */	switch ((mii_reg >> 10) & 3) {	case 0:	s |= PHY_STAT_10HDX;	break;	case 1:	s |= PHY_STAT_100HDX;	break;	case 2:	s |= PHY_STAT_10FDX;	break;	case 3:	s |= PHY_STAT_100FDX;	break;	}	fep->phy_status = s;}static phy_info_t phy_info_amd79c874 = {	0x00022561,	"AM79C874",	(const phy_cmd_t []) {  /* config *///		{ mk_mii_write(MII_REG_ANAR, 0x021), NULL }, /* 10  Mbps, HD */		{ mk_mii_read(MII_REG_CR), mii_parse_cr },		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* startup - enable interrupts */		{ mk_mii_write(MII_AM79C874_ICSR, 0xff00), NULL },		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */		{ mk_mii_end, }	},	(const phy_cmd_t []) { /* ack_int */		/* find out the current status */		{ mk_mii_read(MII_REG_SR), mii_parse_sr },		{ mk_mii_read(MII_AM79C874_DR), mii_parse_amd79c874_dr },		/* we only need to read ICSR to acknowledge */		{ mk_mii_read(MII_AM79C874_ICSR), NULL },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* shutdown - disable interrupts */		{ mk_mii_write(MII_AM79C874_ICSR, 0x0000), NULL },		{ mk_mii_end, }	},};#endif /* CONFIG_FEC_AM79C874 *//* -------------------------------------------------------------------- *//* The National Semiconductor DP83843BVJE is used on a Mediatrix board  *//* -------------------------------------------------------------------- */#ifdef CONFIG_FEC_DP83843/* Register definitions */#define MII_DP83843_PHYSTS 0x10  /* PHY Status Register */#define MII_DP83843_MIPSCR 0x11  /* Specific Status Register */#define MII_DP83843_MIPGSR 0x12  /* Generic Status Register */static void mii_parse_dp83843_physts(uint mii_reg, struct net_device *dev, uint data){	struct fec_enet_private *fep = dev->priv;	volatile uint *s = &(fep->phy_status);	*s &= ~(PHY_STAT_SPMASK);	if (mii_reg & 0x0002)	{		if (mii_reg & 0x0004)			*s |= PHY_STAT_10FDX;		else			*s |= PHY_STAT_10HDX;	}	else	{		if (mii_reg & 0x0004)			*s |= PHY_STAT_100FDX;		else			*s |= PHY_STAT_100HDX;	}}static phy_info_t phy_info_dp83843 = {	0x020005c1,	"DP83843BVJE",	(const phy_cmd_t []) {  /* config */		{ mk_mii_write(MII_REG_ANAR, 0x01E1), NULL  }, /* Auto-Negociation Register Control set to    */		                                               /* auto-negociate 10/100MBps, Half/Full duplex */		{ mk_mii_read(MII_REG_CR),   mii_parse_cr   },		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* startup */		{ mk_mii_write(MII_DP83843_MIPSCR, 0x0002), NULL }, /* Enable interrupts */		{ mk_mii_write(MII_REG_CR, 0x1200), NULL         }, /* Enable and Restart Auto-Negotiation */		{ mk_mii_read(MII_REG_SR), mii_parse_sr	         },		{ mk_mii_read(MII_REG_CR), mii_parse_cr },		{ mk_mii_read(MII_DP83843_PHYSTS), mii_parse_dp83843_physts },		{ mk_mii_end, }	},	(const phy_cmd_t []) { /* ack_int */		{ mk_mii_read(MII_DP83843_MIPGSR), NULL },  /* Acknowledge interrupts */		{ mk_mii_read(MII_REG_SR), mii_parse_sr },  /* Find out the current status */		{ mk_mii_read(MII_REG_CR), mii_parse_cr },		{ mk_mii_read(MII_DP83843_PHYSTS), mii_parse_dp83843_physts },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* shutdown - disable interrupts */		{ mk_mii_end, }	}};#endif /* CONFIG_FEC_DP83843 *//* ----------------------------------------------------------------- *//* The National Semiconductor DP83846A is used on a Mediatrix board  *//* ----------------------------------------------------------------- */#ifdef CONFIG_FEC_DP83846A/* Register definitions */#define MII_DP83846A_PHYSTS 0x10  /* PHY Status Register */static void mii_parse_dp83846a_physts(uint mii_reg, struct net_device *dev, uint data){	struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv;	volatile uint *s = &(fep->phy_status);	int link_change_mask;	*s &= ~(PHY_STAT_SPMASK);	if (mii_reg & 0x0002) {		if (mii_reg & 0x0004)			*s |= PHY_STAT_10FDX;		else			*s |= PHY_STAT_10HDX;	}	else {		if (mii_reg & 0x0004)			*s |= PHY_STAT_100FDX;		else			*s |= PHY_STAT_100HDX;	}	link_change_mask = PHY_STAT_LINK | PHY_STAT_10FDX | PHY_STAT_10HDX | PHY_STAT_100FDX | PHY_STAT_100HDX;	if(fep->old_status != (link_change_mask & *s))	{		fep->old_status = (link_change_mask & *s);		mii_queue_relink(mii_reg, dev, 0);	}}static phy_info_t phy_info_dp83846a = {	0x020005c2,	"DP83846A",	(const phy_cmd_t []) {  /* config */		{ mk_mii_write(MII_REG_ANAR, 0x01E1), NULL  }, /* Auto-Negociation Register Control set to    */		                                               /* auto-negociate 10/100MBps, Half/Full duplex */		{ mk_mii_read(MII_REG_CR),   mii_parse_cr   },		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* startup */		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* Enable and Restart Auto-Negotiation */		{ mk_mii_read(MII_REG_SR), mii_parse_sr },		{ mk_mii_read(MII_REG_CR), mii_parse_cr   },		{ mk_mii_read(MII_DP83846A_PHYSTS), mii_parse_dp83846a_physts },		{ mk_mii_end, }	},	(const phy_cmd_t []) { /* ack_int */		{ mk_mii_read(MII_REG_SR), mii_parse_sr },		{ mk_mii_read(MII_REG_CR), mii_parse_cr   },		{ mk_mii_read(MII_DP83846A_PHYSTS), mii_parse_dp83846a_physts },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* shutdown - disable interrupts */		{ mk_mii_end, }	}};#endif /* CONFIG_FEC_DP83846A */static phy_info_t *phy_info[] = {#ifdef CONFIG_FEC_LXT970	&phy_info_lxt970,#endif /* CONFIG_FEC_LXT970 */#ifdef CONFIG_FEC_LXT971	&phy_info_lxt971,#endif /* CONFIG_FEC_LXT971 */#ifdef CONFIG_FEC_QS6612	&phy_info_qs6612,#endif /* CONFIG_FEC_QS6612 */#ifdef CONFIG_FEC_AM79C874	&phy_info_amd79c874,#endif /* CONFIG_FEC_AM79C874 */#ifdef CONFIG_FEC_DP83843	&phy_info_dp83843,#endif /* CONFIG_FEC_DP83843 */#ifdef CONFIG_FEC_DP83846A	&phy_info_dp83846a,#endif /* CONFIG_FEC_DP83846A */	NULL};static void mii_display_status(struct net_device *dev){	volatile struct fec_enet_private *fep = dev->priv;	uint s = fep->phy_status;	if (!fep->link && !fep->old_link) {		/* Link is still down - don't print anything */		return;	}	printk("%s: status: ", dev->name);	if (!fep->link) {		printk("link down");	} else {		printk("link up");		switch(s & PHY_STAT_SPMASK) {		case PHY_STAT_100FDX: printk(", 100 Mbps Full Duplex"); break;		case PHY_STAT_100HDX: printk(", 100 Mbps Half Duplex"); break;		case PHY_STAT_10FDX:  printk(", 10 Mbps Full Duplex");  break;		case PHY_STAT_10HDX:  printk(", 10 Mbps Half Duplex");  break;		default:			printk(", Unknown speed/duplex");		}		if (s & PHY_STAT_ANC)			printk(", auto-negotiation complete");	}	if (s & PHY_STAT_FAULT)		printk(", remote fault");	printk(".\n");}static void mii_display_config(struct net_device *dev){	volatile struct fec_enet_private *fep = dev->priv;	uint s = fep->phy_status;	printk("%s: config: auto-negotiation ", dev->name);	if (s & PHY_CONF_ANE)		printk("on");	else		printk("off");	if (s & PHY_CONF_100FDX)		printk(", 100FDX");	if (s & PHY_CONF_100HDX)		printk(", 100HDX");	if (s & PHY_CONF_10FDX)		printk(", 10FDX");	if (s & PHY_CONF_10HDX)

⌨️ 快捷键说明

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