Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] m68knommu: FEC ethernet support for the ColdFire 5208

Add support for the new 5208 ColdFire (Matt Waddel / Mike Lavender)
Patch originally from Matt Waddel (from code originally written by
Mike Lavender).

I also re-ordered the init code to avoid interrupt lockups on
some platforms (at least the 5275, but others have reported it on
the 5235 as well).

Signed-off-by: Greg Ungerer <gerg@uclinux.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Greg Ungerer and committed by
Linus Torvalds
562d2f8c 7a77d918

+218 -22
+218 -22
drivers/net/fec.c
··· 18 18 * Much better multiple PHY support by Magnus Damm. 19 19 * Copyright (c) 2000 Ericsson Radio Systems AB. 20 20 * 21 - * Support for FEC controller of ColdFire/5270/5271/5272/5274/5275/5280/5282. 22 - * Copyright (c) 2001-2004 Greg Ungerer (gerg@snapgear.com) 21 + * Support for FEC controller of ColdFire processors. 22 + * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com) 23 23 * 24 24 * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) 25 25 * Copyright (c) 2004-2005 Macq Electronique SA. ··· 50 50 #include <asm/pgtable.h> 51 51 52 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 55 #include <asm/coldfire.h> 55 56 #include <asm/mcfsim.h> 56 57 #include "fec.h" ··· 78 77 (MCF_MBAR + 0x1800), 79 78 #elif defined(CONFIG_M523x) || defined(CONFIG_M528x) 80 79 (MCF_MBAR + 0x1000), 80 + #elif defined(CONFIG_M520x) 81 + (MCF_MBAR+0x30000), 81 82 #else 82 83 &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), 83 84 #endif ··· 142 139 #define TX_RING_SIZE 16 /* Must be power of two */ 143 140 #define TX_RING_MOD_MASK 15 /* for this to work */ 144 141 142 + #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) 143 + #error "FEC: descriptor ring size contants too large" 144 + #endif 145 + 145 146 /* Interrupt events/masks. 146 147 */ 147 148 #define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */ ··· 171 164 * size bits. Other FEC hardware does not, so we need to take that into 172 165 * account when setting it. 173 166 */ 174 - #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) 167 + #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ 168 + defined(CONFIG_M520x) 175 169 #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) 176 170 #else 177 171 #define OPT_FRAME_SIZE 0 ··· 1145 1137 }; 1146 1138 1147 1139 /* ------------------------------------------------------------------------- */ 1140 + /* register definitions for the DP83848 */ 1141 + 1142 + #define MII_DP8384X_PHYSTST 16 /* PHY Status Register */ 1143 + 1144 + static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev) 1145 + { 1146 + struct fec_enet_private *fep = dev->priv; 1147 + volatile uint *s = &(fep->phy_status); 1148 + 1149 + *s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC); 1150 + 1151 + /* Link up */ 1152 + if (mii_reg & 0x0001) { 1153 + fep->link = 1; 1154 + *s |= PHY_STAT_LINK; 1155 + } else 1156 + fep->link = 0; 1157 + /* Status of link */ 1158 + if (mii_reg & 0x0010) /* Autonegotioation complete */ 1159 + *s |= PHY_STAT_ANC; 1160 + if (mii_reg & 0x0002) { /* 10MBps? */ 1161 + if (mii_reg & 0x0004) /* Full Duplex? */ 1162 + *s |= PHY_STAT_10FDX; 1163 + else 1164 + *s |= PHY_STAT_10HDX; 1165 + } else { /* 100 Mbps? */ 1166 + if (mii_reg & 0x0004) /* Full Duplex? */ 1167 + *s |= PHY_STAT_100FDX; 1168 + else 1169 + *s |= PHY_STAT_100HDX; 1170 + } 1171 + if (mii_reg & 0x0008) 1172 + *s |= PHY_STAT_FAULT; 1173 + } 1174 + 1175 + static phy_info_t phy_info_dp83848= { 1176 + 0x020005c9, 1177 + "DP83848", 1178 + 1179 + (const phy_cmd_t []) { /* config */ 1180 + { mk_mii_read(MII_REG_CR), mii_parse_cr }, 1181 + { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, 1182 + { mk_mii_read(MII_DP8384X_PHYSTST), mii_parse_dp8384x_sr2 }, 1183 + { mk_mii_end, } 1184 + }, 1185 + (const phy_cmd_t []) { /* startup - enable interrupts */ 1186 + { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ 1187 + { mk_mii_read(MII_REG_SR), mii_parse_sr }, 1188 + { mk_mii_end, } 1189 + }, 1190 + (const phy_cmd_t []) { /* ack_int - never happens, no interrupt */ 1191 + { mk_mii_end, } 1192 + }, 1193 + (const phy_cmd_t []) { /* shutdown */ 1194 + { mk_mii_end, } 1195 + }, 1196 + }; 1197 + 1198 + /* ------------------------------------------------------------------------- */ 1148 1199 1149 1200 static phy_info_t const * const phy_info[] = { 1150 1201 &phy_info_lxt970, ··· 1211 1144 &phy_info_qs6612, 1212 1145 &phy_info_am79c874, 1213 1146 &phy_info_ks8721bl, 1147 + &phy_info_dp83848, 1214 1148 NULL 1215 1149 }; 1216 1150 ··· 1484 1416 /* 1485 1417 * Do not need to make region uncached on 5272. 1486 1418 */ 1419 + static void __inline__ fec_uncache(unsigned long addr) 1420 + { 1421 + } 1422 + 1423 + /* ------------------------------------------------------------------------- */ 1424 + 1425 + #elif defined(CONFIG_M520x) 1426 + 1427 + /* 1428 + * Code specific to Coldfire 520x 1429 + */ 1430 + static void __inline__ fec_request_intrs(struct net_device *dev) 1431 + { 1432 + struct fec_enet_private *fep; 1433 + int b; 1434 + static const struct idesc { 1435 + char *name; 1436 + unsigned short irq; 1437 + } *idp, id[] = { 1438 + { "fec(TXF)", 23 }, 1439 + { "fec(TXB)", 24 }, 1440 + { "fec(TXFIFO)", 25 }, 1441 + { "fec(TXCR)", 26 }, 1442 + { "fec(RXF)", 27 }, 1443 + { "fec(RXB)", 28 }, 1444 + { "fec(MII)", 29 }, 1445 + { "fec(LC)", 30 }, 1446 + { "fec(HBERR)", 31 }, 1447 + { "fec(GRA)", 32 }, 1448 + { "fec(EBERR)", 33 }, 1449 + { "fec(BABT)", 34 }, 1450 + { "fec(BABR)", 35 }, 1451 + { NULL }, 1452 + }; 1453 + 1454 + fep = netdev_priv(dev); 1455 + b = 64 + 13; 1456 + 1457 + /* Setup interrupt handlers. */ 1458 + for (idp = id; idp->name; idp++) { 1459 + if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) 1460 + printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq); 1461 + } 1462 + 1463 + /* Unmask interrupts at ColdFire interrupt controller */ 1464 + { 1465 + volatile unsigned char *icrp; 1466 + volatile unsigned long *imrp; 1467 + 1468 + icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 + 1469 + MCFINTC_ICR0); 1470 + for (b = 36; (b < 49); b++) 1471 + icrp[b] = 0x04; 1472 + imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + 1473 + MCFINTC_IMRH); 1474 + *imrp &= ~0x0001FFF0; 1475 + } 1476 + *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FEC) |= 0xf0; 1477 + *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C) |= 0x0f; 1478 + } 1479 + 1480 + static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) 1481 + { 1482 + volatile fec_t *fecp; 1483 + 1484 + fecp = fep->hwp; 1485 + fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04; 1486 + fecp->fec_x_cntrl = 0x00; 1487 + 1488 + /* 1489 + * Set MII speed to 2.5 MHz 1490 + * See 5282 manual section 17.5.4.7: MSCR 1491 + */ 1492 + fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; 1493 + fecp->fec_mii_speed = fep->phy_speed; 1494 + 1495 + fec_restart(dev, 0); 1496 + } 1497 + 1498 + static void __inline__ fec_get_mac(struct net_device *dev) 1499 + { 1500 + struct fec_enet_private *fep = netdev_priv(dev); 1501 + volatile fec_t *fecp; 1502 + unsigned char *iap, tmpaddr[ETH_ALEN]; 1503 + 1504 + fecp = fep->hwp; 1505 + 1506 + if (FEC_FLASHMAC) { 1507 + /* 1508 + * Get MAC address from FLASH. 1509 + * If it is all 1's or 0's, use the default. 1510 + */ 1511 + iap = FEC_FLASHMAC; 1512 + if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && 1513 + (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) 1514 + iap = fec_mac_default; 1515 + if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) && 1516 + (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) 1517 + iap = fec_mac_default; 1518 + } else { 1519 + *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; 1520 + *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); 1521 + iap = &tmpaddr[0]; 1522 + } 1523 + 1524 + memcpy(dev->dev_addr, iap, ETH_ALEN); 1525 + 1526 + /* Adjust MAC if using default MAC address */ 1527 + if (iap == fec_mac_default) 1528 + dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; 1529 + } 1530 + 1531 + static void __inline__ fec_enable_phy_intr(void) 1532 + { 1533 + } 1534 + 1535 + static void __inline__ fec_disable_phy_intr(void) 1536 + { 1537 + } 1538 + 1539 + static void __inline__ fec_phy_ack_intr(void) 1540 + { 1541 + } 1542 + 1543 + static void __inline__ fec_localhw_setup(void) 1544 + { 1545 + } 1546 + 1487 1547 static void __inline__ fec_uncache(unsigned long addr) 1488 1548 { 1489 1549 } ··· 2148 1952 if (index >= FEC_MAX_PORTS) 2149 1953 return -ENXIO; 2150 1954 1955 + /* Allocate memory for buffer descriptors. 1956 + */ 1957 + mem_addr = __get_free_page(GFP_KERNEL); 1958 + if (mem_addr == 0) { 1959 + printk("FEC: allocate descriptor memory failed?\n"); 1960 + return -ENOMEM; 1961 + } 1962 + 2151 1963 /* Create an Ethernet device instance. 2152 1964 */ 2153 1965 fecp = (volatile fec_t *) fec_hw[index]; ··· 2168 1964 fecp->fec_ecntrl = 1; 2169 1965 udelay(10); 2170 1966 2171 - /* Clear and enable interrupts */ 2172 - fecp->fec_ievent = 0xffc00000; 2173 - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | 2174 - FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); 2175 - fecp->fec_hash_table_high = 0; 2176 - fecp->fec_hash_table_low = 0; 2177 - fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; 2178 - fecp->fec_ecntrl = 2; 2179 - fecp->fec_r_des_active = 0x01000000; 2180 - 2181 1967 /* Set the Ethernet address. If using multiple Enets on the 8xx, 2182 1968 * this needs some work to get unique addresses. 2183 1969 * ··· 2176 1982 */ 2177 1983 fec_get_mac(dev); 2178 1984 2179 - /* Allocate memory for buffer descriptors. 2180 - */ 2181 - if (((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) > PAGE_SIZE) { 2182 - printk("FEC init error. Need more space.\n"); 2183 - printk("FEC initialization failed.\n"); 2184 - return 1; 2185 - } 2186 - mem_addr = __get_free_page(GFP_KERNEL); 2187 1985 cbd_base = (cbd_t *)mem_addr; 2188 1986 /* XXX: missing check for allocation failure */ 2189 1987 ··· 2252 2066 * the architecture. 2253 2067 */ 2254 2068 fec_request_intrs(dev); 2069 + 2070 + /* Clear and enable interrupts */ 2071 + fecp->fec_ievent = 0xffc00000; 2072 + fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | 2073 + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); 2074 + fecp->fec_hash_table_high = 0; 2075 + fecp->fec_hash_table_low = 0; 2076 + fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; 2077 + fecp->fec_ecntrl = 2; 2078 + fecp->fec_r_des_active = 0x01000000; 2255 2079 2256 2080 dev->base_addr = (unsigned long)fecp; 2257 2081