diff options
| -rw-r--r-- | drivers/net/fec.c | 198 |
1 files changed, 179 insertions, 19 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 16fc12fe933c..0ba9f77603f6 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c | |||
| @@ -51,7 +51,7 @@ | |||
| 51 | 51 | ||
| 52 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ | 52 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ |
| 53 | defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ | 53 | defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ |
| 54 | defined(CONFIG_M520x) | 54 | defined(CONFIG_M520x) || defined(CONFIG_M532x) |
| 55 | #include <asm/coldfire.h> | 55 | #include <asm/coldfire.h> |
| 56 | #include <asm/mcfsim.h> | 56 | #include <asm/mcfsim.h> |
| 57 | #include "fec.h" | 57 | #include "fec.h" |
| @@ -80,6 +80,8 @@ static unsigned int fec_hw[] = { | |||
| 80 | (MCF_MBAR + 0x1000), | 80 | (MCF_MBAR + 0x1000), |
| 81 | #elif defined(CONFIG_M520x) | 81 | #elif defined(CONFIG_M520x) |
| 82 | (MCF_MBAR+0x30000), | 82 | (MCF_MBAR+0x30000), |
| 83 | #elif defined(CONFIG_M532x) | ||
| 84 | (MCF_MBAR+0xfc030000), | ||
| 83 | #else | 85 | #else |
| 84 | &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), | 86 | &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), |
| 85 | #endif | 87 | #endif |
| @@ -143,7 +145,7 @@ typedef struct { | |||
| 143 | #define TX_RING_MOD_MASK 15 /* for this to work */ | 145 | #define TX_RING_MOD_MASK 15 /* for this to work */ |
| 144 | 146 | ||
| 145 | #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) | 147 | #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) |
| 146 | #error "FEC: descriptor ring size contants too large" | 148 | #error "FEC: descriptor ring size constants too large" |
| 147 | #endif | 149 | #endif |
| 148 | 150 | ||
| 149 | /* Interrupt events/masks. | 151 | /* Interrupt events/masks. |
| @@ -167,12 +169,12 @@ typedef struct { | |||
| 167 | 169 | ||
| 168 | 170 | ||
| 169 | /* | 171 | /* |
| 170 | * The 5270/5271/5280/5282 RX control register also contains maximum frame | 172 | * The 5270/5271/5280/5282/532x RX control register also contains maximum frame |
| 171 | * size bits. Other FEC hardware does not, so we need to take that into | 173 | * size bits. Other FEC hardware does not, so we need to take that into |
| 172 | * account when setting it. | 174 | * account when setting it. |
| 173 | */ | 175 | */ |
| 174 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ | 176 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ |
| 175 | defined(CONFIG_M520x) | 177 | defined(CONFIG_M520x) || defined(CONFIG_M532x) |
| 176 | #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) | 178 | #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) |
| 177 | #else | 179 | #else |
| 178 | #define OPT_FRAME_SIZE 0 | 180 | #define OPT_FRAME_SIZE 0 |
| @@ -1216,7 +1218,7 @@ static phy_info_t const * const phy_info[] = { | |||
| 1216 | }; | 1218 | }; |
| 1217 | 1219 | ||
| 1218 | /* ------------------------------------------------------------------------- */ | 1220 | /* ------------------------------------------------------------------------- */ |
| 1219 | 1221 | #if !defined(CONFIG_M532x) | |
| 1220 | #ifdef CONFIG_RPXCLASSIC | 1222 | #ifdef CONFIG_RPXCLASSIC |
| 1221 | static void | 1223 | static void |
| 1222 | mii_link_interrupt(void *dev_id); | 1224 | mii_link_interrupt(void *dev_id); |
| @@ -1224,6 +1226,7 @@ mii_link_interrupt(void *dev_id); | |||
| 1224 | static irqreturn_t | 1226 | static irqreturn_t |
| 1225 | mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs); | 1227 | mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs); |
| 1226 | #endif | 1228 | #endif |
| 1229 | #endif | ||
| 1227 | 1230 | ||
| 1228 | #if defined(CONFIG_M5272) | 1231 | #if defined(CONFIG_M5272) |
| 1229 | 1232 | ||
| @@ -1618,6 +1621,159 @@ static void __inline__ fec_uncache(unsigned long addr) | |||
| 1618 | 1621 | ||
| 1619 | /* ------------------------------------------------------------------------- */ | 1622 | /* ------------------------------------------------------------------------- */ |
| 1620 | 1623 | ||
| 1624 | #elif defined(CONFIG_M532x) | ||
| 1625 | /* | ||
| 1626 | * Code specific for M532x | ||
| 1627 | */ | ||
| 1628 | static void __inline__ fec_request_intrs(struct net_device *dev) | ||
| 1629 | { | ||
| 1630 | struct fec_enet_private *fep; | ||
| 1631 | int b; | ||
| 1632 | static const struct idesc { | ||
| 1633 | char *name; | ||
| 1634 | unsigned short irq; | ||
| 1635 | } *idp, id[] = { | ||
| 1636 | { "fec(TXF)", 36 }, | ||
| 1637 | { "fec(TXB)", 37 }, | ||
| 1638 | { "fec(TXFIFO)", 38 }, | ||
| 1639 | { "fec(TXCR)", 39 }, | ||
| 1640 | { "fec(RXF)", 40 }, | ||
| 1641 | { "fec(RXB)", 41 }, | ||
| 1642 | { "fec(MII)", 42 }, | ||
| 1643 | { "fec(LC)", 43 }, | ||
| 1644 | { "fec(HBERR)", 44 }, | ||
| 1645 | { "fec(GRA)", 45 }, | ||
| 1646 | { "fec(EBERR)", 46 }, | ||
| 1647 | { "fec(BABT)", 47 }, | ||
| 1648 | { "fec(BABR)", 48 }, | ||
| 1649 | { NULL }, | ||
| 1650 | }; | ||
| 1651 | |||
| 1652 | fep = netdev_priv(dev); | ||
| 1653 | b = (fep->index) ? 128 : 64; | ||
| 1654 | |||
| 1655 | /* Setup interrupt handlers. */ | ||
| 1656 | for (idp = id; idp->name; idp++) { | ||
| 1657 | if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) | ||
| 1658 | printk("FEC: Could not allocate %s IRQ(%d)!\n", | ||
| 1659 | idp->name, b+idp->irq); | ||
| 1660 | } | ||
| 1661 | |||
| 1662 | /* Unmask interrupts */ | ||
| 1663 | MCF_INTC0_ICR36 = 0x2; | ||
| 1664 | MCF_INTC0_ICR37 = 0x2; | ||
| 1665 | MCF_INTC0_ICR38 = 0x2; | ||
| 1666 | MCF_INTC0_ICR39 = 0x2; | ||
| 1667 | MCF_INTC0_ICR40 = 0x2; | ||
| 1668 | MCF_INTC0_ICR41 = 0x2; | ||
| 1669 | MCF_INTC0_ICR42 = 0x2; | ||
| 1670 | MCF_INTC0_ICR43 = 0x2; | ||
| 1671 | MCF_INTC0_ICR44 = 0x2; | ||
| 1672 | MCF_INTC0_ICR45 = 0x2; | ||
| 1673 | MCF_INTC0_ICR46 = 0x2; | ||
| 1674 | MCF_INTC0_ICR47 = 0x2; | ||
| 1675 | MCF_INTC0_ICR48 = 0x2; | ||
| 1676 | |||
| 1677 | MCF_INTC0_IMRH &= ~( | ||
| 1678 | MCF_INTC_IMRH_INT_MASK36 | | ||
| 1679 | MCF_INTC_IMRH_INT_MASK37 | | ||
| 1680 | MCF_INTC_IMRH_INT_MASK38 | | ||
| 1681 | MCF_INTC_IMRH_INT_MASK39 | | ||
| 1682 | MCF_INTC_IMRH_INT_MASK40 | | ||
| 1683 | MCF_INTC_IMRH_INT_MASK41 | | ||
| 1684 | MCF_INTC_IMRH_INT_MASK42 | | ||
| 1685 | MCF_INTC_IMRH_INT_MASK43 | | ||
| 1686 | MCF_INTC_IMRH_INT_MASK44 | | ||
| 1687 | MCF_INTC_IMRH_INT_MASK45 | | ||
| 1688 | MCF_INTC_IMRH_INT_MASK46 | | ||
| 1689 | MCF_INTC_IMRH_INT_MASK47 | | ||
| 1690 | MCF_INTC_IMRH_INT_MASK48 ); | ||
| 1691 | |||
| 1692 | /* Set up gpio outputs for MII lines */ | ||
| 1693 | MCF_GPIO_PAR_FECI2C |= (0 | | ||
| 1694 | MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC | | ||
| 1695 | MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO); | ||
| 1696 | MCF_GPIO_PAR_FEC = (0 | | ||
| 1697 | MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | | ||
| 1698 | MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC); | ||
| 1699 | } | ||
| 1700 | |||
| 1701 | static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) | ||
| 1702 | { | ||
| 1703 | volatile fec_t *fecp; | ||
| 1704 | |||
| 1705 | fecp = fep->hwp; | ||
| 1706 | fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04; | ||
| 1707 | fecp->fec_x_cntrl = 0x00; | ||
| 1708 | |||
| 1709 | /* | ||
| 1710 | * Set MII speed to 2.5 MHz | ||
| 1711 | */ | ||
| 1712 | fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; | ||
| 1713 | fecp->fec_mii_speed = fep->phy_speed; | ||
| 1714 | |||
| 1715 | fec_restart(dev, 0); | ||
| 1716 | } | ||
| 1717 | |||
| 1718 | static void __inline__ fec_get_mac(struct net_device *dev) | ||
| 1719 | { | ||
| 1720 | struct fec_enet_private *fep = netdev_priv(dev); | ||
| 1721 | volatile fec_t *fecp; | ||
| 1722 | unsigned char *iap, tmpaddr[ETH_ALEN]; | ||
| 1723 | |||
| 1724 | fecp = fep->hwp; | ||
| 1725 | |||
| 1726 | if (FEC_FLASHMAC) { | ||
| 1727 | /* | ||
| 1728 | * Get MAC address from FLASH. | ||
| 1729 | * If it is all 1's or 0's, use the default. | ||
| 1730 | */ | ||
| 1731 | iap = FEC_FLASHMAC; | ||
| 1732 | if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && | ||
| 1733 | (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) | ||
| 1734 | iap = fec_mac_default; | ||
| 1735 | if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) && | ||
| 1736 | (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) | ||
| 1737 | iap = fec_mac_default; | ||
| 1738 | } else { | ||
| 1739 | *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; | ||
| 1740 | *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); | ||
| 1741 | iap = &tmpaddr[0]; | ||
| 1742 | } | ||
| 1743 | |||
| 1744 | memcpy(dev->dev_addr, iap, ETH_ALEN); | ||
| 1745 | |||
| 1746 | /* Adjust MAC if using default MAC address */ | ||
| 1747 | if (iap == fec_mac_default) | ||
| 1748 | dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; | ||
| 1749 | } | ||
| 1750 | |||
| 1751 | static void __inline__ fec_enable_phy_intr(void) | ||
| 1752 | { | ||
| 1753 | } | ||
| 1754 | |||
| 1755 | static void __inline__ fec_disable_phy_intr(void) | ||
| 1756 | { | ||
| 1757 | } | ||
| 1758 | |||
| 1759 | static void __inline__ fec_phy_ack_intr(void) | ||
| 1760 | { | ||
| 1761 | } | ||
| 1762 | |||
| 1763 | static void __inline__ fec_localhw_setup(void) | ||
| 1764 | { | ||
| 1765 | } | ||
| 1766 | |||
| 1767 | /* | ||
| 1768 | * Do not need to make region uncached on 532x. | ||
| 1769 | */ | ||
| 1770 | static void __inline__ fec_uncache(unsigned long addr) | ||
| 1771 | { | ||
| 1772 | } | ||
| 1773 | |||
| 1774 | /* ------------------------------------------------------------------------- */ | ||
| 1775 | |||
| 1776 | |||
| 1621 | #else | 1777 | #else |
| 1622 | 1778 | ||
| 1623 | /* | 1779 | /* |
| @@ -1985,9 +2141,12 @@ fec_enet_open(struct net_device *dev) | |||
| 1985 | mii_do_cmd(dev, fep->phy->config); | 2141 | mii_do_cmd(dev, fep->phy->config); |
| 1986 | mii_do_cmd(dev, phy_cmd_config); /* display configuration */ | 2142 | mii_do_cmd(dev, phy_cmd_config); /* display configuration */ |
| 1987 | 2143 | ||
| 1988 | /* FIXME: use netif_carrier_{on,off} ; this polls | 2144 | /* Poll until the PHY tells us its configuration |
| 1989 | * until link is up which is wrong... could be | 2145 | * (not link state). |
| 1990 | * 30 seconds or more we are trapped in here. -jgarzik | 2146 | * Request is initiated by mii_do_cmd above, but answer |
| 2147 | * comes by interrupt. | ||
| 2148 | * This should take about 25 usec per register at 2.5 MHz, | ||
| 2149 | * and we read approximately 5 registers. | ||
| 1991 | */ | 2150 | */ |
| 1992 | while(!fep->sequence_done) | 2151 | while(!fep->sequence_done) |
| 1993 | schedule(); | 2152 | schedule(); |
| @@ -2253,15 +2412,11 @@ int __init fec_enet_init(struct net_device *dev) | |||
| 2253 | */ | 2412 | */ |
| 2254 | fec_request_intrs(dev); | 2413 | fec_request_intrs(dev); |
| 2255 | 2414 | ||
| 2256 | /* Clear and enable interrupts */ | ||
| 2257 | fecp->fec_ievent = 0xffc00000; | ||
| 2258 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | ||
| 2259 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
| 2260 | fecp->fec_hash_table_high = 0; | 2415 | fecp->fec_hash_table_high = 0; |
| 2261 | fecp->fec_hash_table_low = 0; | 2416 | fecp->fec_hash_table_low = 0; |
| 2262 | fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; | 2417 | fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; |
| 2263 | fecp->fec_ecntrl = 2; | 2418 | fecp->fec_ecntrl = 2; |
| 2264 | fecp->fec_r_des_active = 0x01000000; | 2419 | fecp->fec_r_des_active = 0; |
| 2265 | 2420 | ||
| 2266 | dev->base_addr = (unsigned long)fecp; | 2421 | dev->base_addr = (unsigned long)fecp; |
| 2267 | 2422 | ||
| @@ -2281,6 +2436,11 @@ int __init fec_enet_init(struct net_device *dev) | |||
| 2281 | /* setup MII interface */ | 2436 | /* setup MII interface */ |
| 2282 | fec_set_mii(dev, fep); | 2437 | fec_set_mii(dev, fep); |
| 2283 | 2438 | ||
| 2439 | /* Clear and enable interrupts */ | ||
| 2440 | fecp->fec_ievent = 0xffc00000; | ||
| 2441 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | ||
| 2442 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
| 2443 | |||
| 2284 | /* Queue up command to detect the PHY and initialize the | 2444 | /* Queue up command to detect the PHY and initialize the |
| 2285 | * remainder of the interface. | 2445 | * remainder of the interface. |
| 2286 | */ | 2446 | */ |
| @@ -2312,11 +2472,6 @@ fec_restart(struct net_device *dev, int duplex) | |||
| 2312 | fecp->fec_ecntrl = 1; | 2472 | fecp->fec_ecntrl = 1; |
| 2313 | udelay(10); | 2473 | udelay(10); |
| 2314 | 2474 | ||
| 2315 | /* Enable interrupts we wish to service. | ||
| 2316 | */ | ||
| 2317 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | ||
| 2318 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
| 2319 | |||
| 2320 | /* Clear any outstanding interrupt. | 2475 | /* Clear any outstanding interrupt. |
| 2321 | */ | 2476 | */ |
| 2322 | fecp->fec_ievent = 0xffc00000; | 2477 | fecp->fec_ievent = 0xffc00000; |
| @@ -2408,7 +2563,12 @@ fec_restart(struct net_device *dev, int duplex) | |||
| 2408 | /* And last, enable the transmit and receive processing. | 2563 | /* And last, enable the transmit and receive processing. |
| 2409 | */ | 2564 | */ |
| 2410 | fecp->fec_ecntrl = 2; | 2565 | fecp->fec_ecntrl = 2; |
| 2411 | fecp->fec_r_des_active = 0x01000000; | 2566 | fecp->fec_r_des_active = 0; |
| 2567 | |||
| 2568 | /* Enable interrupts we wish to service. | ||
| 2569 | */ | ||
| 2570 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | ||
| 2571 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
| 2412 | } | 2572 | } |
| 2413 | 2573 | ||
| 2414 | static void | 2574 | static void |
