aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/fec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/fec.c')
-rw-r--r--drivers/net/fec.c240
1 files changed, 218 insertions, 22 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 85504fb900da..bd6983d1afba 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -18,8 +18,8 @@
18 * Much better multiple PHY support by Magnus Damm. 18 * Much better multiple PHY support by Magnus Damm.
19 * Copyright (c) 2000 Ericsson Radio Systems AB. 19 * Copyright (c) 2000 Ericsson Radio Systems AB.
20 * 20 *
21 * Support for FEC controller of ColdFire/5270/5271/5272/5274/5275/5280/5282. 21 * Support for FEC controller of ColdFire processors.
22 * Copyright (c) 2001-2004 Greg Ungerer (gerg@snapgear.com) 22 * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com)
23 * 23 *
24 * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) 24 * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
25 * Copyright (c) 2004-2005 Macq Electronique SA. 25 * Copyright (c) 2004-2005 Macq Electronique SA.
@@ -50,7 +50,8 @@
50#include <asm/pgtable.h> 50#include <asm/pgtable.h>
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#include <asm/coldfire.h> 55#include <asm/coldfire.h>
55#include <asm/mcfsim.h> 56#include <asm/mcfsim.h>
56#include "fec.h" 57#include "fec.h"
@@ -77,6 +78,8 @@ static unsigned int fec_hw[] = {
77 (MCF_MBAR + 0x1800), 78 (MCF_MBAR + 0x1800),
78#elif defined(CONFIG_M523x) || defined(CONFIG_M528x) 79#elif defined(CONFIG_M523x) || defined(CONFIG_M528x)
79 (MCF_MBAR + 0x1000), 80 (MCF_MBAR + 0x1000),
81#elif defined(CONFIG_M520x)
82 (MCF_MBAR+0x30000),
80#else 83#else
81 &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), 84 &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
82#endif 85#endif
@@ -139,6 +142,10 @@ typedef struct {
139#define TX_RING_SIZE 16 /* Must be power of two */ 142#define TX_RING_SIZE 16 /* Must be power of two */
140#define TX_RING_MOD_MASK 15 /* for this to work */ 143#define TX_RING_MOD_MASK 15 /* for this to work */
141 144
145#if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE)
146#error "FEC: descriptor ring size contants too large"
147#endif
148
142/* Interrupt events/masks. 149/* Interrupt events/masks.
143*/ 150*/
144#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */ 151#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
@@ -164,7 +171,8 @@ typedef struct {
164 * size bits. Other FEC hardware does not, so we need to take that into 171 * size bits. Other FEC hardware does not, so we need to take that into
165 * account when setting it. 172 * account when setting it.
166 */ 173 */
167#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) 174#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
175 defined(CONFIG_M520x)
168#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) 176#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
169#else 177#else
170#define OPT_FRAME_SIZE 0 178#define OPT_FRAME_SIZE 0
@@ -1137,6 +1145,65 @@ static phy_info_t const phy_info_ks8721bl = {
1137}; 1145};
1138 1146
1139/* ------------------------------------------------------------------------- */ 1147/* ------------------------------------------------------------------------- */
1148/* register definitions for the DP83848 */
1149
1150#define MII_DP8384X_PHYSTST 16 /* PHY Status Register */
1151
1152static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev)
1153{
1154 struct fec_enet_private *fep = dev->priv;
1155 volatile uint *s = &(fep->phy_status);
1156
1157 *s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
1158
1159 /* Link up */
1160 if (mii_reg & 0x0001) {
1161 fep->link = 1;
1162 *s |= PHY_STAT_LINK;
1163 } else
1164 fep->link = 0;
1165 /* Status of link */
1166 if (mii_reg & 0x0010) /* Autonegotioation complete */
1167 *s |= PHY_STAT_ANC;
1168 if (mii_reg & 0x0002) { /* 10MBps? */
1169 if (mii_reg & 0x0004) /* Full Duplex? */
1170 *s |= PHY_STAT_10FDX;
1171 else
1172 *s |= PHY_STAT_10HDX;
1173 } else { /* 100 Mbps? */
1174 if (mii_reg & 0x0004) /* Full Duplex? */
1175 *s |= PHY_STAT_100FDX;
1176 else
1177 *s |= PHY_STAT_100HDX;
1178 }
1179 if (mii_reg & 0x0008)
1180 *s |= PHY_STAT_FAULT;
1181}
1182
1183static phy_info_t phy_info_dp83848= {
1184 0x020005c9,
1185 "DP83848",
1186
1187 (const phy_cmd_t []) { /* config */
1188 { mk_mii_read(MII_REG_CR), mii_parse_cr },
1189 { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
1190 { mk_mii_read(MII_DP8384X_PHYSTST), mii_parse_dp8384x_sr2 },
1191 { mk_mii_end, }
1192 },
1193 (const phy_cmd_t []) { /* startup - enable interrupts */
1194 { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
1195 { mk_mii_read(MII_REG_SR), mii_parse_sr },
1196 { mk_mii_end, }
1197 },
1198 (const phy_cmd_t []) { /* ack_int - never happens, no interrupt */
1199 { mk_mii_end, }
1200 },
1201 (const phy_cmd_t []) { /* shutdown */
1202 { mk_mii_end, }
1203 },
1204};
1205
1206/* ------------------------------------------------------------------------- */
1140 1207
1141static phy_info_t const * const phy_info[] = { 1208static phy_info_t const * const phy_info[] = {
1142 &phy_info_lxt970, 1209 &phy_info_lxt970,
@@ -1144,6 +1211,7 @@ static phy_info_t const * const phy_info[] = {
1144 &phy_info_qs6612, 1211 &phy_info_qs6612,
1145 &phy_info_am79c874, 1212 &phy_info_am79c874,
1146 &phy_info_ks8721bl, 1213 &phy_info_ks8721bl,
1214 &phy_info_dp83848,
1147 NULL 1215 NULL
1148}; 1216};
1149 1217
@@ -1422,6 +1490,134 @@ static void __inline__ fec_uncache(unsigned long addr)
1422 1490
1423/* ------------------------------------------------------------------------- */ 1491/* ------------------------------------------------------------------------- */
1424 1492
1493#elif defined(CONFIG_M520x)
1494
1495/*
1496 * Code specific to Coldfire 520x
1497 */
1498static void __inline__ fec_request_intrs(struct net_device *dev)
1499{
1500 struct fec_enet_private *fep;
1501 int b;
1502 static const struct idesc {
1503 char *name;
1504 unsigned short irq;
1505 } *idp, id[] = {
1506 { "fec(TXF)", 23 },
1507 { "fec(TXB)", 24 },
1508 { "fec(TXFIFO)", 25 },
1509 { "fec(TXCR)", 26 },
1510 { "fec(RXF)", 27 },
1511 { "fec(RXB)", 28 },
1512 { "fec(MII)", 29 },
1513 { "fec(LC)", 30 },
1514 { "fec(HBERR)", 31 },
1515 { "fec(GRA)", 32 },
1516 { "fec(EBERR)", 33 },
1517 { "fec(BABT)", 34 },
1518 { "fec(BABR)", 35 },
1519 { NULL },
1520 };
1521
1522 fep = netdev_priv(dev);
1523 b = 64 + 13;
1524
1525 /* Setup interrupt handlers. */
1526 for (idp = id; idp->name; idp++) {
1527 if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0)
1528 printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
1529 }
1530
1531 /* Unmask interrupts at ColdFire interrupt controller */
1532 {
1533 volatile unsigned char *icrp;
1534 volatile unsigned long *imrp;
1535
1536 icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
1537 MCFINTC_ICR0);
1538 for (b = 36; (b < 49); b++)
1539 icrp[b] = 0x04;
1540 imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 +
1541 MCFINTC_IMRH);
1542 *imrp &= ~0x0001FFF0;
1543 }
1544 *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FEC) |= 0xf0;
1545 *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C) |= 0x0f;
1546}
1547
1548static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
1549{
1550 volatile fec_t *fecp;
1551
1552 fecp = fep->hwp;
1553 fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
1554 fecp->fec_x_cntrl = 0x00;
1555
1556 /*
1557 * Set MII speed to 2.5 MHz
1558 * See 5282 manual section 17.5.4.7: MSCR
1559 */
1560 fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
1561 fecp->fec_mii_speed = fep->phy_speed;
1562
1563 fec_restart(dev, 0);
1564}
1565
1566static void __inline__ fec_get_mac(struct net_device *dev)
1567{
1568 struct fec_enet_private *fep = netdev_priv(dev);
1569 volatile fec_t *fecp;
1570 unsigned char *iap, tmpaddr[ETH_ALEN];
1571
1572 fecp = fep->hwp;
1573
1574 if (FEC_FLASHMAC) {
1575 /*
1576 * Get MAC address from FLASH.
1577 * If it is all 1's or 0's, use the default.
1578 */
1579 iap = FEC_FLASHMAC;
1580 if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
1581 (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
1582 iap = fec_mac_default;
1583 if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
1584 (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
1585 iap = fec_mac_default;
1586 } else {
1587 *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
1588 *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
1589 iap = &tmpaddr[0];
1590 }
1591
1592 memcpy(dev->dev_addr, iap, ETH_ALEN);
1593
1594 /* Adjust MAC if using default MAC address */
1595 if (iap == fec_mac_default)
1596 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
1597}
1598
1599static void __inline__ fec_enable_phy_intr(void)
1600{
1601}
1602
1603static void __inline__ fec_disable_phy_intr(void)
1604{
1605}
1606
1607static void __inline__ fec_phy_ack_intr(void)
1608{
1609}
1610
1611static void __inline__ fec_localhw_setup(void)
1612{
1613}
1614
1615static void __inline__ fec_uncache(unsigned long addr)
1616{
1617}
1618
1619/* ------------------------------------------------------------------------- */
1620
1425#else 1621#else
1426 1622
1427/* 1623/*
@@ -1952,6 +2148,14 @@ int __init fec_enet_init(struct net_device *dev)
1952 if (index >= FEC_MAX_PORTS) 2148 if (index >= FEC_MAX_PORTS)
1953 return -ENXIO; 2149 return -ENXIO;
1954 2150
2151 /* Allocate memory for buffer descriptors.
2152 */
2153 mem_addr = __get_free_page(GFP_KERNEL);
2154 if (mem_addr == 0) {
2155 printk("FEC: allocate descriptor memory failed?\n");
2156 return -ENOMEM;
2157 }
2158
1955 /* Create an Ethernet device instance. 2159 /* Create an Ethernet device instance.
1956 */ 2160 */
1957 fecp = (volatile fec_t *) fec_hw[index]; 2161 fecp = (volatile fec_t *) fec_hw[index];
@@ -1964,16 +2168,6 @@ int __init fec_enet_init(struct net_device *dev)
1964 fecp->fec_ecntrl = 1; 2168 fecp->fec_ecntrl = 1;
1965 udelay(10); 2169 udelay(10);
1966 2170
1967 /* Clear and enable interrupts */
1968 fecp->fec_ievent = 0xffc00000;
1969 fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
1970 FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
1971 fecp->fec_hash_table_high = 0;
1972 fecp->fec_hash_table_low = 0;
1973 fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
1974 fecp->fec_ecntrl = 2;
1975 fecp->fec_r_des_active = 0x01000000;
1976
1977 /* Set the Ethernet address. If using multiple Enets on the 8xx, 2171 /* Set the Ethernet address. If using multiple Enets on the 8xx,
1978 * this needs some work to get unique addresses. 2172 * this needs some work to get unique addresses.
1979 * 2173 *
@@ -1982,14 +2176,6 @@ int __init fec_enet_init(struct net_device *dev)
1982 */ 2176 */
1983 fec_get_mac(dev); 2177 fec_get_mac(dev);
1984 2178
1985 /* Allocate memory for buffer descriptors.
1986 */
1987 if (((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) > PAGE_SIZE) {
1988 printk("FEC init error. Need more space.\n");
1989 printk("FEC initialization failed.\n");
1990 return 1;
1991 }
1992 mem_addr = __get_free_page(GFP_KERNEL);
1993 cbd_base = (cbd_t *)mem_addr; 2179 cbd_base = (cbd_t *)mem_addr;
1994 /* XXX: missing check for allocation failure */ 2180 /* XXX: missing check for allocation failure */
1995 2181
@@ -2067,6 +2253,16 @@ int __init fec_enet_init(struct net_device *dev)
2067 */ 2253 */
2068 fec_request_intrs(dev); 2254 fec_request_intrs(dev);
2069 2255
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;
2261 fecp->fec_hash_table_low = 0;
2262 fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
2263 fecp->fec_ecntrl = 2;
2264 fecp->fec_r_des_active = 0x01000000;
2265
2070 dev->base_addr = (unsigned long)fecp; 2266 dev->base_addr = (unsigned long)fecp;
2071 2267
2072 /* The FEC Ethernet specific entries in the device structure. */ 2268 /* The FEC Ethernet specific entries in the device structure. */