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

📄 fcc_enet.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
static phy_info_t phy_info_lxt970 = {	0x07810000,	"LXT970",	(const phy_cmd_t []) {  /* config */#if 0//		{ mk_mii_write(MII_ADVERTISE, 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_BMCR), mii_parse_cr },		{ mk_mii_read(MII_ADVERTISE), 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_BMCR, 0x1200), NULL }, /* autonegotiate */		{ mk_mii_end, }	},	(const phy_cmd_t []) { /* ack_int */		/* read SR and ISR to acknowledge */		{ mk_mii_read(MII_BMSR), 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_FCC_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){	volatile struct fcc_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 */		/* configure link capabilities to advertise */		{ mk_mii_write(MII_ADVERTISE, MII_ADVERTISE_DEFAULT),			mii_parse_anar },		/* enable auto-negotiation */		{ mk_mii_write(MII_BMCR, BMCR_ANENABLE), mii_parse_cr },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* startup - enable interrupts */		{ mk_mii_write(MII_LXT971_IER, 0x00f2), NULL },		/* restart auto-negotiation */		{ mk_mii_write(MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART),			NULL },		{ mk_mii_end, }	},	(const phy_cmd_t []) { /* ack_int */		/* find out the current status */		{ mk_mii_read(MII_BMSR), NULL },		{ mk_mii_read(MII_BMSR), 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_FCC_LXT971 *//* ------------------------------------------------------------------------- *//* The Quality Semiconductor QS6612 is used on the RPX CLLF                  */#ifdef CONFIG_FCC_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){	volatile struct fcc_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_ADVERTISE, 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_BMCR), mii_parse_cr },		{ mk_mii_read(MII_ADVERTISE), 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_BMCR, 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_BMSR), mii_parse_sr },		{ mk_mii_read(MII_EXPANSION), 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 Davicom DM9131 is used on the HYMOD board			     */#ifdef CONFIG_FCC_DM9131/* register definitions */#define MII_DM9131_ACR		16	/* Aux. Config Register		*/#define MII_DM9131_ACSR		17	/* Aux. Config/Status Register	*/#define MII_DM9131_10TCSR	18	/* 10BaseT Config/Status Reg.	*/#define MII_DM9131_INTR		21	/* Interrupt Register		*/#define MII_DM9131_RECR		22	/* Receive Error Counter Reg.	*/#define MII_DM9131_DISCR	23	/* Disconnect Counter Register	*/static void mii_parse_dm9131_acsr(uint mii_reg, struct net_device *dev){	volatile struct fcc_enet_private *fep = dev->priv;	uint s = fep->phy_status;	s &= ~(PHY_STAT_SPMASK);	switch ((mii_reg >> 12) & 0xf) {	case 1: s |= PHY_STAT_10HDX;  break;	case 2: s |= PHY_STAT_10FDX;  break;	case 4: s |= PHY_STAT_100HDX; break;	case 8: s |= PHY_STAT_100FDX; break;	}	fep->phy_status = s;}static phy_info_t phy_info_dm9131 = {	0x00181b80,	"DM9131",	(const phy_cmd_t []) {  /* config */		/* parse cr and anar to get some info */		{ mk_mii_read(MII_BMCR), mii_parse_cr },		{ mk_mii_read(MII_ADVERTISE), mii_parse_anar },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* startup - enable interrupts */		{ mk_mii_write(MII_DM9131_INTR, 0x0002), NULL },		{ mk_mii_write(MII_BMCR, 0x1200), NULL }, /* autonegotiate */		{ mk_mii_end, }	},	(const phy_cmd_t []) { /* ack_int */		/* we need to read INTR, SR and ANER to acknowledge */		{ mk_mii_read(MII_DM9131_INTR), NULL },		{ mk_mii_read(MII_BMSR), mii_parse_sr },		{ mk_mii_read(MII_EXPANSION), NULL },		/* read acsr to get info */		{ mk_mii_read(MII_DM9131_ACSR), mii_parse_dm9131_acsr },		{ mk_mii_end, }	},	(const phy_cmd_t []) {  /* shutdown - disable interrupts */		{ mk_mii_write(MII_DM9131_INTR, 0x0f00), NULL },		{ mk_mii_end, }	},};#endif /* CONFIG_FEC_DM9131 */#ifdef CONFIG_FCC_DM9161/* ------------------------------------------------------------------------- *//* DM9161 Control register values */#define MIIM_DM9161_CR_STOP     0x0400#define MIIM_DM9161_CR_RSTAN    0x1200#define MIIM_DM9161_SCR         0x10#define MIIM_DM9161_SCR_INIT    0x0610/* DM9161 Specified Configuration and Status Register */#define MIIM_DM9161_SCSR        0x11#define MIIM_DM9161_SCSR_100F   0x8000#define MIIM_DM9161_SCSR_100H   0x4000#define MIIM_DM9161_SCSR_10F    0x2000#define MIIM_DM9161_SCSR_10H    0x1000/* DM9161 10BT register */#define MIIM_DM9161_10BTCSR 	0x12#define MIIM_DM9161_10BTCSR_INIT 0x7800/* DM9161 Interrupt Register */#define MIIM_DM9161_INTR        0x15#define MIIM_DM9161_INTR_PEND           0x8000#define MIIM_DM9161_INTR_DPLX_MASK      0x0800#define MIIM_DM9161_INTR_SPD_MASK       0x0400#define MIIM_DM9161_INTR_LINK_MASK      0x0200#define MIIM_DM9161_INTR_MASK           0x0100#define MIIM_DM9161_INTR_DPLX_CHANGE    0x0010#define MIIM_DM9161_INTR_SPD_CHANGE     0x0008#define MIIM_DM9161_INTR_LINK_CHANGE    0x0004#define MIIM_DM9161_INTR_INIT           0x0000#define MIIM_DM9161_INTR_STOP   \(MIIM_DM9161_INTR_DPLX_MASK | MIIM_DM9161_INTR_SPD_MASK \  | MIIM_DM9161_INTR_LINK_MASK | MIIM_DM9161_INTR_MASK)static void mii_parse_dm9161_sr(uint mii_reg, struct net_device * dev){	volatile struct fcc_enet_private *fep = dev->priv;	uint regstat,  timeout=0xffff;	while(!(mii_reg & 0x0020) && timeout--)	{		regstat=mk_mii_read(MII_BMSR);	        regstat |= fep->phy_addr <<23;	        mii_reg = mii_send_receive(fep->fip,regstat);	}	mii_parse_sr(mii_reg, dev);}static void mii_parse_dm9161_scsr(uint mii_reg, struct net_device * dev){	volatile struct fcc_enet_private *fep = dev->priv;	uint s = fep->phy_status;	s &= ~(PHY_STAT_SPMASK);	switch((mii_reg >>12) & 0xf) {		case 1:		{			s |= PHY_STAT_10HDX;			printk("10BaseT Half Duplex\n");			break;		}		case 2:		{			s |= PHY_STAT_10FDX;		        printk("10BaseT Full Duplex\n");			break;		}		case 4:	        {			s |= PHY_STAT_100HDX;		        printk("100BaseT Half Duplex\n");			break;		}		case 8:		{			s |= PHY_STAT_100FDX;			printk("100BaseT Full Duplex\n");			break;		}	}	fep->phy_status = s;}static void mii_dm9161_wait(uint mii_reg, struct net_device *dev){	int timeout = HZ;	/* Davicom takes a bit to come up after a reset,	 * so wait here for a bit */	schedule_timeout_uninterruptible(timeout);}static phy_info_t phy_info_dm9161 = {        0x00181b88,        "Davicom DM9161E",        (const phy_cmd_t[]) { /* config */                { mk_mii_write(MII_BMCR, MIIM_DM9161_CR_STOP), NULL},                /* Do not bypass the scrambler/descrambler */                { mk_mii_write(MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT), NULL},		/* Configure 10BTCSR register */		{ mk_mii_write(MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT),NULL},                /* Configure some basic stuff */                { mk_mii_write(MII_BMCR, 0x1000), NULL},		{ mk_mii_read(MII_BMCR), mii_parse_cr },		{ mk_mii_read(MII_ADVERTISE), mii_parse_anar },		{ mk_mii_end,}        },       (const phy_cmd_t[]) { /* startup */                /* Restart Auto Negotiation */                { mk_mii_write(MII_BMCR, MIIM_DM9161_CR_RSTAN), NULL},                /* Status is read once to clear old link state */                { mk_mii_read(MII_BMSR), mii_dm9161_wait},                /* Auto-negotiate */                { mk_mii_read(MII_BMSR), mii_parse_dm9161_sr},                /* Read the status */                { mk_mii_read(MIIM_DM9161_SCSR), mii_parse_dm9161_scsr},                /* Clear any pending interrupts */                { mk_mii_read(MIIM_DM9161_INTR), NULL},                /* Enable Interrupts */                { mk_mii_write(MIIM_DM9161_INTR, MIIM_DM9161_INTR_INIT), NULL},                { mk_mii_end,}        },       (const phy_cmd_t[]) { /* ack_int */                { mk_mii_read(MIIM_DM9161_INTR), NULL},#if 0		{ mk_mii_read(MII_BMSR), NULL},		{ mk_mii_read(MII_BMSR), mii_parse_dm9161_sr},		{ mk_mii_read(MIIM_DM9161_SCSR), mii_parse_dm9161_scsr},#endif                { mk_mii_end,}        },        (const phy_cmd_t[]) { /* shutdown */	        { mk_mii_read(MIIM_DM9161_INTR),NULL},                { mk_mii_write(MIIM_DM9161_INTR, MIIM_DM9161_INTR_STOP), NULL},	        { mk_mii_end,}	},};#endif /* CONFIG_FCC_DM9161 */static phy_info_t *phy_info[] = {#ifdef CONFIG_FCC_LXT970	&phy_info_lxt970,#endif /* CONFIG_FEC_LXT970 */#ifdef CONFIG_FCC_LXT971	&phy_info_lxt971,#endif /* CONFIG_FEC_LXT971 */#ifdef CONFIG_FCC_QS6612	&phy_info_qs6612,#endif /* CONFIG_FEC_QS6612 */#ifdef CONFIG_FCC_DM9131	&phy_info_dm9131,#endif /* CONFIG_FEC_DM9131 */#ifdef CONFIG_FCC_DM9161	&phy_info_dm9161,#endif /* CONFIG_FCC_DM9161 */#ifdef CONFIG_FCC_GENERIC_PHY	/* Generic PHY support.  This must be the last PHY in the table.	 * It will be used to support any PHY that doesn't match a previous	 * entry in the table.	 */	&phy_info_generic,#endif /* CONFIG_FCC_GENERIC_PHY */	NULL};static void mii_display_status(void *data){	struct net_device *dev = data;	volatile struct fcc_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");	}

⌨️ 快捷键说明

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