?? fec.c
字號(hào):
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)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -