aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ucc_geth.c
diff options
context:
space:
mode:
authorKim Phillips <kim.phillips@freescale.com>2007-04-13 02:26:03 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-28 11:01:04 -0400
commit728de4c927a3544b6d3da331b634035d4c75ca17 (patch)
tree5f05e0b318de9c1d517bd7bbca5964249c7cc885 /drivers/net/ucc_geth.c
parenta999589ccaae16472531e0616f23826ad097aa40 (diff)
ucc_geth: migrate ucc_geth to phylib
migrate ucc_geth to use the common phylib code. There are several side effects from doing this: o deprecate 'interface' property specification present in some old device tree source files in favour of a split 'max-speed' and 'interface-type' description to appropriately match definitions in include/linux/phy.h. Note that 'interface' property is still honoured if max-speed or interface-type are not present (backward compatible). o compile-time CONFIG_UGETH_HAS_GIGA is eliminated in favour of probe time speed derivation logic. o adjust_link streamlined to only operate on maccfg2 and upsmr.r10m, instead of reapplying static initial values related to the interface-type. o Addition of UEC MDIO of_platform driver requires platform code add 'mdio' type to id list prior to calling of_platform_bus_probe (separate patch). o ucc_struct_init introduced to reduce ucc_geth_startup complexity. Signed-off-by: Li Yang <leoli@freescale.com> Signed-off-by: Kim Phillips <kim.phillips@freescale.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r--drivers/net/ucc_geth.c814
1 files changed, 271 insertions, 543 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 639e1e6913bf..d93cfde663e9 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -29,6 +29,7 @@
29#include <linux/fsl_devices.h> 29#include <linux/fsl_devices.h>
30#include <linux/ethtool.h> 30#include <linux/ethtool.h>
31#include <linux/mii.h> 31#include <linux/mii.h>
32#include <linux/phy.h>
32#include <linux/workqueue.h> 33#include <linux/workqueue.h>
33 34
34#include <asm/of_platform.h> 35#include <asm/of_platform.h>
@@ -41,7 +42,7 @@
41#include <asm/ucc_fast.h> 42#include <asm/ucc_fast.h>
42 43
43#include "ucc_geth.h" 44#include "ucc_geth.h"
44#include "ucc_geth_phy.h" 45#include "ucc_geth_mii.h"
45 46
46#undef DEBUG 47#undef DEBUG
47 48
@@ -73,22 +74,13 @@ static struct ucc_geth_info ugeth_primary_info = {
73 .bd_mem_part = MEM_PART_SYSTEM, 74 .bd_mem_part = MEM_PART_SYSTEM,
74 .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES, 75 .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES,
75 .max_rx_buf_length = 1536, 76 .max_rx_buf_length = 1536,
76/* FIXME: should be changed in run time for 1G and 100M */ 77 /* adjusted at startup if max-speed 1000 */
77#ifdef CONFIG_UGETH_HAS_GIGA
78 .urfs = UCC_GETH_URFS_GIGA_INIT,
79 .urfet = UCC_GETH_URFET_GIGA_INIT,
80 .urfset = UCC_GETH_URFSET_GIGA_INIT,
81 .utfs = UCC_GETH_UTFS_GIGA_INIT,
82 .utfet = UCC_GETH_UTFET_GIGA_INIT,
83 .utftt = UCC_GETH_UTFTT_GIGA_INIT,
84#else
85 .urfs = UCC_GETH_URFS_INIT, 78 .urfs = UCC_GETH_URFS_INIT,
86 .urfet = UCC_GETH_URFET_INIT, 79 .urfet = UCC_GETH_URFET_INIT,
87 .urfset = UCC_GETH_URFSET_INIT, 80 .urfset = UCC_GETH_URFSET_INIT,
88 .utfs = UCC_GETH_UTFS_INIT, 81 .utfs = UCC_GETH_UTFS_INIT,
89 .utfet = UCC_GETH_UTFET_INIT, 82 .utfet = UCC_GETH_UTFET_INIT,
90 .utftt = UCC_GETH_UTFTT_INIT, 83 .utftt = UCC_GETH_UTFTT_INIT,
91#endif
92 .ufpt = 256, 84 .ufpt = 256,
93 .mode = UCC_FAST_PROTOCOL_MODE_ETHERNET, 85 .mode = UCC_FAST_PROTOCOL_MODE_ETHERNET,
94 .ttx_trx = UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL, 86 .ttx_trx = UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL,
@@ -217,70 +209,6 @@ static struct list_head *dequeue(struct list_head *lh)
217 } 209 }
218} 210}
219 211
220static int get_interface_details(enum enet_interface enet_interface,
221 enum enet_speed *speed,
222 int *r10m,
223 int *rmm,
224 int *rpm,
225 int *tbi, int *limited_to_full_duplex)
226{
227 /* Analyze enet_interface according to Interface Mode
228 Configuration table */
229 switch (enet_interface) {
230 case ENET_10_MII:
231 *speed = ENET_SPEED_10BT;
232 break;
233 case ENET_10_RMII:
234 *speed = ENET_SPEED_10BT;
235 *r10m = 1;
236 *rmm = 1;
237 break;
238 case ENET_10_RGMII:
239 *speed = ENET_SPEED_10BT;
240 *rpm = 1;
241 *r10m = 1;
242 *limited_to_full_duplex = 1;
243 break;
244 case ENET_100_MII:
245 *speed = ENET_SPEED_100BT;
246 break;
247 case ENET_100_RMII:
248 *speed = ENET_SPEED_100BT;
249 *rmm = 1;
250 break;
251 case ENET_100_RGMII:
252 *speed = ENET_SPEED_100BT;
253 *rpm = 1;
254 *limited_to_full_duplex = 1;
255 break;
256 case ENET_1000_GMII:
257 *speed = ENET_SPEED_1000BT;
258 *limited_to_full_duplex = 1;
259 break;
260 case ENET_1000_RGMII:
261 *speed = ENET_SPEED_1000BT;
262 *rpm = 1;
263 *limited_to_full_duplex = 1;
264 break;
265 case ENET_1000_TBI:
266 *speed = ENET_SPEED_1000BT;
267 *tbi = 1;
268 *limited_to_full_duplex = 1;
269 break;
270 case ENET_1000_RTBI:
271 *speed = ENET_SPEED_1000BT;
272 *rpm = 1;
273 *tbi = 1;
274 *limited_to_full_duplex = 1;
275 break;
276 default:
277 return -EINVAL;
278 break;
279 }
280
281 return 0;
282}
283
284static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd) 212static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd)
285{ 213{
286 struct sk_buff *skb = NULL; 214 struct sk_buff *skb = NULL;
@@ -758,24 +686,6 @@ static void dump_regs(struct ucc_geth_private *ugeth)
758 ugeth_info("hafdup : addr - 0x%08x, val - 0x%08x", 686 ugeth_info("hafdup : addr - 0x%08x, val - 0x%08x",
759 (u32) & ugeth->ug_regs->hafdup, 687 (u32) & ugeth->ug_regs->hafdup,
760 in_be32(&ugeth->ug_regs->hafdup)); 688 in_be32(&ugeth->ug_regs->hafdup));
761 ugeth_info("miimcfg : addr - 0x%08x, val - 0x%08x",
762 (u32) & ugeth->ug_regs->miimng.miimcfg,
763 in_be32(&ugeth->ug_regs->miimng.miimcfg));
764 ugeth_info("miimcom : addr - 0x%08x, val - 0x%08x",
765 (u32) & ugeth->ug_regs->miimng.miimcom,
766 in_be32(&ugeth->ug_regs->miimng.miimcom));
767 ugeth_info("miimadd : addr - 0x%08x, val - 0x%08x",
768 (u32) & ugeth->ug_regs->miimng.miimadd,
769 in_be32(&ugeth->ug_regs->miimng.miimadd));
770 ugeth_info("miimcon : addr - 0x%08x, val - 0x%08x",
771 (u32) & ugeth->ug_regs->miimng.miimcon,
772 in_be32(&ugeth->ug_regs->miimng.miimcon));
773 ugeth_info("miimstat : addr - 0x%08x, val - 0x%08x",
774 (u32) & ugeth->ug_regs->miimng.miimstat,
775 in_be32(&ugeth->ug_regs->miimng.miimstat));
776 ugeth_info("miimmind : addr - 0x%08x, val - 0x%08x",
777 (u32) & ugeth->ug_regs->miimng.miimind,
778 in_be32(&ugeth->ug_regs->miimng.miimind));
779 ugeth_info("ifctl : addr - 0x%08x, val - 0x%08x", 689 ugeth_info("ifctl : addr - 0x%08x, val - 0x%08x",
780 (u32) & ugeth->ug_regs->ifctl, 690 (u32) & ugeth->ug_regs->ifctl,
781 in_be32(&ugeth->ug_regs->ifctl)); 691 in_be32(&ugeth->ug_regs->ifctl));
@@ -1425,27 +1335,6 @@ static int init_mac_station_addr_regs(u8 address_byte_0,
1425 return 0; 1335 return 0;
1426} 1336}
1427 1337
1428static int init_mac_duplex_mode(int full_duplex,
1429 int limited_to_full_duplex,
1430 volatile u32 *maccfg2_register)
1431{
1432 u32 value = 0;
1433
1434 /* some interfaces must work in full duplex mode */
1435 if ((full_duplex == 0) && (limited_to_full_duplex == 1))
1436 return -EINVAL;
1437
1438 value = in_be32(maccfg2_register);
1439
1440 if (full_duplex)
1441 value |= MACCFG2_FDX;
1442 else
1443 value &= ~MACCFG2_FDX;
1444
1445 out_be32(maccfg2_register, value);
1446 return 0;
1447}
1448
1449static int init_check_frame_length_mode(int length_check, 1338static int init_check_frame_length_mode(int length_check,
1450 volatile u32 *maccfg2_register) 1339 volatile u32 *maccfg2_register)
1451{ 1340{
@@ -1477,40 +1366,6 @@ static int init_preamble_length(u8 preamble_length,
1477 return 0; 1366 return 0;
1478} 1367}
1479 1368
1480static int init_mii_management_configuration(int reset_mgmt,
1481 int preamble_supress,
1482 volatile u32 *miimcfg_register,
1483 volatile u32 *miimind_register)
1484{
1485 unsigned int timeout = PHY_INIT_TIMEOUT;
1486 u32 value = 0;
1487
1488 value = in_be32(miimcfg_register);
1489 if (reset_mgmt) {
1490 value |= MIIMCFG_RESET_MANAGEMENT;
1491 out_be32(miimcfg_register, value);
1492 }
1493
1494 value = 0;
1495
1496 if (preamble_supress)
1497 value |= MIIMCFG_NO_PREAMBLE;
1498
1499 value |= UCC_GETH_MIIMCFG_MNGMNT_CLC_DIV_INIT;
1500 out_be32(miimcfg_register, value);
1501
1502 /* Wait until the bus is free */
1503 while ((in_be32(miimind_register) & MIIMIND_BUSY) && timeout--)
1504 cpu_relax();
1505
1506 if (timeout <= 0) {
1507 ugeth_err("%s: The MII Bus is stuck!", __FUNCTION__);
1508 return -ETIMEDOUT;
1509 }
1510
1511 return 0;
1512}
1513
1514static int init_rx_parameters(int reject_broadcast, 1369static int init_rx_parameters(int reject_broadcast,
1515 int receive_short_frames, 1370 int receive_short_frames,
1516 int promiscuous, volatile u32 *upsmr_register) 1371 int promiscuous, volatile u32 *upsmr_register)
@@ -1570,10 +1425,8 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
1570 struct ucc_geth_info *ug_info; 1425 struct ucc_geth_info *ug_info;
1571 struct ucc_geth *ug_regs; 1426 struct ucc_geth *ug_regs;
1572 struct ucc_fast *uf_regs; 1427 struct ucc_fast *uf_regs;
1573 enum enet_speed speed; 1428 int ret_val;
1574 int ret_val, rpm = 0, tbi = 0, r10m = 0, rmm = 1429 u32 upsmr, maccfg2, tbiBaseAddress;
1575 0, limited_to_full_duplex = 0;
1576 u32 upsmr, maccfg2, utbipar, tbiBaseAddress;
1577 u16 value; 1430 u16 value;
1578 1431
1579 ugeth_vdbg("%s: IN", __FUNCTION__); 1432 ugeth_vdbg("%s: IN", __FUNCTION__);
@@ -1582,24 +1435,13 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
1582 ug_regs = ugeth->ug_regs; 1435 ug_regs = ugeth->ug_regs;
1583 uf_regs = ugeth->uccf->uf_regs; 1436 uf_regs = ugeth->uccf->uf_regs;
1584 1437
1585 /* Analyze enet_interface according to Interface Mode Configuration
1586 table */
1587 ret_val =
1588 get_interface_details(ug_info->enet_interface, &speed, &r10m, &rmm,
1589 &rpm, &tbi, &limited_to_full_duplex);
1590 if (ret_val != 0) {
1591 ugeth_err
1592 ("%s: half duplex not supported in requested configuration.",
1593 __FUNCTION__);
1594 return ret_val;
1595 }
1596
1597 /* Set MACCFG2 */ 1438 /* Set MACCFG2 */
1598 maccfg2 = in_be32(&ug_regs->maccfg2); 1439 maccfg2 = in_be32(&ug_regs->maccfg2);
1599 maccfg2 &= ~MACCFG2_INTERFACE_MODE_MASK; 1440 maccfg2 &= ~MACCFG2_INTERFACE_MODE_MASK;
1600 if ((speed == ENET_SPEED_10BT) || (speed == ENET_SPEED_100BT)) 1441 if ((ugeth->max_speed == SPEED_10) ||
1442 (ugeth->max_speed == SPEED_100))
1601 maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE; 1443 maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
1602 else if (speed == ENET_SPEED_1000BT) 1444 else if (ugeth->max_speed == SPEED_1000)
1603 maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE; 1445 maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
1604 maccfg2 |= ug_info->padAndCrc; 1446 maccfg2 |= ug_info->padAndCrc;
1605 out_be32(&ug_regs->maccfg2, maccfg2); 1447 out_be32(&ug_regs->maccfg2, maccfg2);
@@ -1607,54 +1449,39 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
1607 /* Set UPSMR */ 1449 /* Set UPSMR */
1608 upsmr = in_be32(&uf_regs->upsmr); 1450 upsmr = in_be32(&uf_regs->upsmr);
1609 upsmr &= ~(UPSMR_RPM | UPSMR_R10M | UPSMR_TBIM | UPSMR_RMM); 1451 upsmr &= ~(UPSMR_RPM | UPSMR_R10M | UPSMR_TBIM | UPSMR_RMM);
1610 if (rpm) 1452 if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) ||
1453 (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) ||
1454 (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
1455 (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
1611 upsmr |= UPSMR_RPM; 1456 upsmr |= UPSMR_RPM;
1612 if (r10m) 1457 switch (ugeth->max_speed) {
1613 upsmr |= UPSMR_R10M; 1458 case SPEED_10:
1614 if (tbi) 1459 upsmr |= UPSMR_R10M;
1460 /* FALLTHROUGH */
1461 case SPEED_100:
1462 if (ugeth->phy_interface != PHY_INTERFACE_MODE_RTBI)
1463 upsmr |= UPSMR_RMM;
1464 }
1465 }
1466 if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) ||
1467 (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
1615 upsmr |= UPSMR_TBIM; 1468 upsmr |= UPSMR_TBIM;
1616 if (rmm) 1469 }
1617 upsmr |= UPSMR_RMM;
1618 out_be32(&uf_regs->upsmr, upsmr); 1470 out_be32(&uf_regs->upsmr, upsmr);
1619 1471
1620 /* Set UTBIPAR */
1621 utbipar = in_be32(&ug_regs->utbipar);
1622 utbipar &= ~UTBIPAR_PHY_ADDRESS_MASK;
1623 if (tbi)
1624 utbipar |=
1625 (ug_info->phy_address +
1626 ugeth->ug_info->uf_info.
1627 ucc_num) << UTBIPAR_PHY_ADDRESS_SHIFT;
1628 else
1629 utbipar |=
1630 (0x10 +
1631 ugeth->ug_info->uf_info.
1632 ucc_num) << UTBIPAR_PHY_ADDRESS_SHIFT;
1633 out_be32(&ug_regs->utbipar, utbipar);
1634
1635 /* Disable autonegotiation in tbi mode, because by default it 1472 /* Disable autonegotiation in tbi mode, because by default it
1636 comes up in autonegotiation mode. */ 1473 comes up in autonegotiation mode. */
1637 /* Note that this depends on proper setting in utbipar register. */ 1474 /* Note that this depends on proper setting in utbipar register. */
1638 if (tbi) { 1475 if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) ||
1476 (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
1639 tbiBaseAddress = in_be32(&ug_regs->utbipar); 1477 tbiBaseAddress = in_be32(&ug_regs->utbipar);
1640 tbiBaseAddress &= UTBIPAR_PHY_ADDRESS_MASK; 1478 tbiBaseAddress &= UTBIPAR_PHY_ADDRESS_MASK;
1641 tbiBaseAddress >>= UTBIPAR_PHY_ADDRESS_SHIFT; 1479 tbiBaseAddress >>= UTBIPAR_PHY_ADDRESS_SHIFT;
1642 value = 1480 value = ugeth->phydev->bus->read(ugeth->phydev->bus,
1643 ugeth->mii_info->mdio_read(ugeth->dev, (u8) tbiBaseAddress, 1481 (u8) tbiBaseAddress, ENET_TBI_MII_CR);
1644 ENET_TBI_MII_CR);
1645 value &= ~0x1000; /* Turn off autonegotiation */ 1482 value &= ~0x1000; /* Turn off autonegotiation */
1646 ugeth->mii_info->mdio_write(ugeth->dev, (u8) tbiBaseAddress, 1483 ugeth->phydev->bus->write(ugeth->phydev->bus,
1647 ENET_TBI_MII_CR, value); 1484 (u8) tbiBaseAddress, ENET_TBI_MII_CR, value);
1648 }
1649
1650 ret_val = init_mac_duplex_mode(1,
1651 limited_to_full_duplex,
1652 &ug_regs->maccfg2);
1653 if (ret_val != 0) {
1654 ugeth_err
1655 ("%s: half duplex not supported in requested configuration.",
1656 __FUNCTION__);
1657 return ret_val;
1658 } 1485 }
1659 1486
1660 init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2); 1487 init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2);
@@ -1676,76 +1503,88 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
1676 * function converts those variables into the appropriate 1503 * function converts those variables into the appropriate
1677 * register values, and can bring down the device if needed. 1504 * register values, and can bring down the device if needed.
1678 */ 1505 */
1506
1679static void adjust_link(struct net_device *dev) 1507static void adjust_link(struct net_device *dev)
1680{ 1508{
1681 struct ucc_geth_private *ugeth = netdev_priv(dev); 1509 struct ucc_geth_private *ugeth = netdev_priv(dev);
1682 struct ucc_geth *ug_regs; 1510 struct ucc_geth *ug_regs;
1683 u32 tempval; 1511 struct ucc_fast *uf_regs;
1684 struct ugeth_mii_info *mii_info = ugeth->mii_info; 1512 struct phy_device *phydev = ugeth->phydev;
1513 unsigned long flags;
1514 int new_state = 0;
1685 1515
1686 ug_regs = ugeth->ug_regs; 1516 ug_regs = ugeth->ug_regs;
1517 uf_regs = ugeth->uccf->uf_regs;
1687 1518
1688 if (mii_info->link) { 1519 spin_lock_irqsave(&ugeth->lock, flags);
1520
1521 if (phydev->link) {
1522 u32 tempval = in_be32(&ug_regs->maccfg2);
1523 u32 upsmr = in_be32(&uf_regs->upsmr);
1689 /* Now we make sure that we can be in full duplex mode. 1524 /* Now we make sure that we can be in full duplex mode.
1690 * If not, we operate in half-duplex mode. */ 1525 * If not, we operate in half-duplex mode. */
1691 if (mii_info->duplex != ugeth->oldduplex) { 1526 if (phydev->duplex != ugeth->oldduplex) {
1692 if (!(mii_info->duplex)) { 1527 new_state = 1;
1693 tempval = in_be32(&ug_regs->maccfg2); 1528 if (!(phydev->duplex))
1694 tempval &= ~(MACCFG2_FDX); 1529 tempval &= ~(MACCFG2_FDX);
1695 out_be32(&ug_regs->maccfg2, tempval); 1530 else
1696
1697 ugeth_info("%s: Half Duplex", dev->name);
1698 } else {
1699 tempval = in_be32(&ug_regs->maccfg2);
1700 tempval |= MACCFG2_FDX; 1531 tempval |= MACCFG2_FDX;
1701 out_be32(&ug_regs->maccfg2, tempval); 1532 ugeth->oldduplex = phydev->duplex;
1702
1703 ugeth_info("%s: Full Duplex", dev->name);
1704 }
1705
1706 ugeth->oldduplex = mii_info->duplex;
1707 } 1533 }
1708 1534
1709 if (mii_info->speed != ugeth->oldspeed) { 1535 if (phydev->speed != ugeth->oldspeed) {
1710 switch (mii_info->speed) { 1536 new_state = 1;
1711 case 1000: 1537 switch (phydev->speed) {
1712 ugeth->ug_info->enet_interface = ENET_1000_RGMII; 1538 case SPEED_1000:
1713 break; 1539 tempval = ((tempval &
1714 case 100: 1540 ~(MACCFG2_INTERFACE_MODE_MASK)) |
1715 ugeth->ug_info->enet_interface = ENET_100_RGMII; 1541 MACCFG2_INTERFACE_MODE_BYTE);
1716 break; 1542 break;
1717 case 10: 1543 case SPEED_100:
1718 ugeth->ug_info->enet_interface = ENET_10_RGMII; 1544 case SPEED_10:
1545 tempval = ((tempval &
1546 ~(MACCFG2_INTERFACE_MODE_MASK)) |
1547 MACCFG2_INTERFACE_MODE_NIBBLE);
1548 /* if reduced mode, re-set UPSMR.R10M */
1549 if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) ||
1550 (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) ||
1551 (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
1552 (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
1553 if (phydev->speed == SPEED_10)
1554 upsmr |= UPSMR_R10M;
1555 else
1556 upsmr &= ~(UPSMR_R10M);
1557 }
1719 break; 1558 break;
1720 default: 1559 default:
1721 ugeth_warn 1560 if (netif_msg_link(ugeth))
1722 ("%s: Ack! Speed (%d) is not 10/100/1000!", 1561 ugeth_warn(
1723 dev->name, mii_info->speed); 1562 "%s: Ack! Speed (%d) is not 10/100/1000!",
1563 dev->name, phydev->speed);
1724 break; 1564 break;
1725 } 1565 }
1726 adjust_enet_interface(ugeth); 1566 ugeth->oldspeed = phydev->speed;
1727
1728 ugeth_info("%s: Speed %dBT", dev->name,
1729 mii_info->speed);
1730
1731 ugeth->oldspeed = mii_info->speed;
1732 } 1567 }
1733 1568
1569 out_be32(&ug_regs->maccfg2, tempval);
1570 out_be32(&uf_regs->upsmr, upsmr);
1571
1734 if (!ugeth->oldlink) { 1572 if (!ugeth->oldlink) {
1735 ugeth_info("%s: Link is up", dev->name); 1573 new_state = 1;
1736 ugeth->oldlink = 1; 1574 ugeth->oldlink = 1;
1737 netif_carrier_on(dev);
1738 netif_schedule(dev); 1575 netif_schedule(dev);
1739 } 1576 }
1740 } else { 1577 } else if (ugeth->oldlink) {
1741 if (ugeth->oldlink) { 1578 new_state = 1;
1742 ugeth_info("%s: Link is down", dev->name);
1743 ugeth->oldlink = 0; 1579 ugeth->oldlink = 0;
1744 ugeth->oldspeed = 0; 1580 ugeth->oldspeed = 0;
1745 ugeth->oldduplex = -1; 1581 ugeth->oldduplex = -1;
1746 netif_carrier_off(dev);
1747 }
1748 } 1582 }
1583
1584 if (new_state && netif_msg_link(ugeth))
1585 phy_print_status(phydev);
1586
1587 spin_unlock_irqrestore(&ugeth->lock, flags);
1749} 1588}
1750 1589
1751/* Configure the PHY for dev. 1590/* Configure the PHY for dev.
@@ -1753,94 +1592,40 @@ static void adjust_link(struct net_device *dev)
1753 */ 1592 */
1754static int init_phy(struct net_device *dev) 1593static int init_phy(struct net_device *dev)
1755{ 1594{
1756 struct ucc_geth_private *ugeth = netdev_priv(dev); 1595 struct ucc_geth_private *priv = netdev_priv(dev);
1757 struct phy_info *curphy; 1596 struct phy_device *phydev;
1758 struct ucc_mii_mng *mii_regs; 1597 char phy_id[BUS_ID_SIZE];
1759 struct ugeth_mii_info *mii_info;
1760 int err;
1761 1598
1762 mii_regs = &ugeth->ug_regs->miimng; 1599 priv->oldlink = 0;
1600 priv->oldspeed = 0;
1601 priv->oldduplex = -1;
1763 1602
1764 ugeth->oldlink = 0; 1603 snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, priv->ug_info->mdio_bus,
1765 ugeth->oldspeed = 0; 1604 priv->ug_info->phy_address);
1766 ugeth->oldduplex = -1;
1767 1605
1768 mii_info = kmalloc(sizeof(struct ugeth_mii_info), GFP_KERNEL); 1606 phydev = phy_connect(dev, phy_id, &adjust_link, 0, priv->phy_interface);
1769 1607
1770 if (NULL == mii_info) { 1608 if (IS_ERR(phydev)) {
1771 ugeth_err("%s: Could not allocate mii_info", dev->name); 1609 printk("%s: Could not attach to PHY\n", dev->name);
1772 return -ENOMEM; 1610 return PTR_ERR(phydev);
1773 } 1611 }
1774 1612
1775 mii_info->mii_regs = mii_regs; 1613 phydev->supported &= (ADVERTISED_10baseT_Half |
1776 mii_info->speed = SPEED_1000;
1777 mii_info->duplex = DUPLEX_FULL;
1778 mii_info->pause = 0;
1779 mii_info->link = 0;
1780
1781 mii_info->advertising = (ADVERTISED_10baseT_Half |
1782 ADVERTISED_10baseT_Full | 1614 ADVERTISED_10baseT_Full |
1783 ADVERTISED_100baseT_Half | 1615 ADVERTISED_100baseT_Half |
1784 ADVERTISED_100baseT_Full | 1616 ADVERTISED_100baseT_Full);
1785 ADVERTISED_1000baseT_Full);
1786 mii_info->autoneg = 1;
1787
1788 mii_info->mii_id = ugeth->ug_info->phy_address;
1789
1790 mii_info->dev = dev;
1791 1617
1792 mii_info->mdio_read = &read_phy_reg; 1618 if (priv->max_speed == SPEED_1000)
1793 mii_info->mdio_write = &write_phy_reg; 1619 phydev->supported |= ADVERTISED_1000baseT_Full;
1794 1620
1795 spin_lock_init(&mii_info->mdio_lock); 1621 phydev->advertising = phydev->supported;
1796 1622
1797 ugeth->mii_info = mii_info; 1623 priv->phydev = phydev;
1798
1799 spin_lock_irq(&ugeth->lock);
1800
1801 /* Set this UCC to be the master of the MII managment */
1802 ucc_set_qe_mux_mii_mng(ugeth->ug_info->uf_info.ucc_num);
1803
1804 if (init_mii_management_configuration(1,
1805 ugeth->ug_info->
1806 miiPreambleSupress,
1807 &mii_regs->miimcfg,
1808 &mii_regs->miimind)) {
1809 ugeth_err("%s: The MII Bus is stuck!", dev->name);
1810 err = -1;
1811 goto bus_fail;
1812 }
1813
1814 spin_unlock_irq(&ugeth->lock);
1815
1816 /* get info for this PHY */
1817 curphy = get_phy_info(ugeth->mii_info);
1818
1819 if (curphy == NULL) {
1820 ugeth_err("%s: No PHY found", dev->name);
1821 err = -1;
1822 goto no_phy;
1823 }
1824
1825 mii_info->phyinfo = curphy;
1826
1827 /* Run the commands which initialize the PHY */
1828 if (curphy->init) {
1829 err = curphy->init(ugeth->mii_info);
1830 if (err)
1831 goto phy_init_fail;
1832 }
1833 1624
1834 return 0; 1625 return 0;
1835
1836 phy_init_fail:
1837 no_phy:
1838 bus_fail:
1839 kfree(mii_info);
1840
1841 return err;
1842} 1626}
1843 1627
1628
1844#ifdef CONFIG_UGETH_TX_ON_DEMOND 1629#ifdef CONFIG_UGETH_TX_ON_DEMOND
1845static int ugeth_transmit_on_demand(struct ucc_geth_private *ugeth) 1630static int ugeth_transmit_on_demand(struct ucc_geth_private *ugeth)
1846{ 1631{
@@ -2487,6 +2272,7 @@ static void ucc_geth_set_multi(struct net_device *dev)
2487static void ucc_geth_stop(struct ucc_geth_private *ugeth) 2272static void ucc_geth_stop(struct ucc_geth_private *ugeth)
2488{ 2273{
2489 struct ucc_geth *ug_regs = ugeth->ug_regs; 2274 struct ucc_geth *ug_regs = ugeth->ug_regs;
2275 struct phy_device *phydev = ugeth->phydev;
2490 u32 tempval; 2276 u32 tempval;
2491 2277
2492 ugeth_vdbg("%s: IN", __FUNCTION__); 2278 ugeth_vdbg("%s: IN", __FUNCTION__);
@@ -2495,8 +2281,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
2495 ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); 2281 ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
2496 2282
2497 /* Tell the kernel the link is down */ 2283 /* Tell the kernel the link is down */
2498 ugeth->mii_info->link = 0; 2284 phy_stop(phydev);
2499 adjust_link(ugeth->dev);
2500 2285
2501 /* Mask all interrupts */ 2286 /* Mask all interrupts */
2502 out_be32(ugeth->uccf->p_ucce, 0x00000000); 2287 out_be32(ugeth->uccf->p_ucce, 0x00000000);
@@ -2509,46 +2294,16 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
2509 tempval &= ~(MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX); 2294 tempval &= ~(MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
2510 out_be32(&ug_regs->maccfg1, tempval); 2295 out_be32(&ug_regs->maccfg1, tempval);
2511 2296
2512 if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) {
2513 /* Clear any pending interrupts */
2514 mii_clear_phy_interrupt(ugeth->mii_info);
2515
2516 /* Disable PHY Interrupts */
2517 mii_configure_phy_interrupt(ugeth->mii_info,
2518 MII_INTERRUPT_DISABLED);
2519 }
2520
2521 free_irq(ugeth->ug_info->uf_info.irq, ugeth->dev); 2297 free_irq(ugeth->ug_info->uf_info.irq, ugeth->dev);
2522 2298
2523 if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) {
2524 free_irq(ugeth->ug_info->phy_interrupt, ugeth->dev);
2525 } else {
2526 del_timer_sync(&ugeth->phy_info_timer);
2527 }
2528
2529 ucc_geth_memclean(ugeth); 2299 ucc_geth_memclean(ugeth);
2530} 2300}
2531 2301
2532static int ucc_geth_startup(struct ucc_geth_private *ugeth) 2302static int ucc_struct_init(struct ucc_geth_private *ugeth)
2533{ 2303{
2534 struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
2535 struct ucc_geth_init_pram *p_init_enet_pram;
2536 struct ucc_fast_private *uccf;
2537 struct ucc_geth_info *ug_info; 2304 struct ucc_geth_info *ug_info;
2538 struct ucc_fast_info *uf_info; 2305 struct ucc_fast_info *uf_info;
2539 struct ucc_fast *uf_regs; 2306 int i;
2540 struct ucc_geth *ug_regs;
2541 int ret_val = -EINVAL;
2542 u32 remoder = UCC_GETH_REMODER_INIT;
2543 u32 init_enet_pram_offset, cecr_subblock, command, maccfg1;
2544 u32 ifstat, i, j, size, l2qt, l3qt, length;
2545 u16 temoder = UCC_GETH_TEMODER_INIT;
2546 u16 test;
2547 u8 function_code = 0;
2548 u8 *bd, *endOfRing;
2549 u8 numThreadsRxNumerical, numThreadsTxNumerical;
2550
2551 ugeth_vdbg("%s: IN", __FUNCTION__);
2552 2307
2553 ug_info = ugeth->ug_info; 2308 ug_info = ugeth->ug_info;
2554 uf_info = &ug_info->uf_info; 2309 uf_info = &ug_info->uf_info;
@@ -2647,12 +2402,42 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
2647 for (i = 0; i < ug_info->numQueuesTx; i++) 2402 for (i = 0; i < ug_info->numQueuesTx; i++)
2648 uf_info->uccm_mask |= (UCCE_TXBF_SINGLE_MASK << i); 2403 uf_info->uccm_mask |= (UCCE_TXBF_SINGLE_MASK << i);
2649 /* Initialize the general fast UCC block. */ 2404 /* Initialize the general fast UCC block. */
2650 if (ucc_fast_init(uf_info, &uccf)) { 2405 if (ucc_fast_init(uf_info, &ugeth->uccf)) {
2651 ugeth_err("%s: Failed to init uccf.", __FUNCTION__); 2406 ugeth_err("%s: Failed to init uccf.", __FUNCTION__);
2652 ucc_geth_memclean(ugeth); 2407 ucc_geth_memclean(ugeth);
2653 return -ENOMEM; 2408 return -ENOMEM;
2654 } 2409 }
2655 ugeth->uccf = uccf; 2410
2411 ugeth->ug_regs = (struct ucc_geth *) ioremap(uf_info->regs, sizeof(struct ucc_geth));
2412
2413 return 0;
2414}
2415
2416static int ucc_geth_startup(struct ucc_geth_private *ugeth)
2417{
2418 struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
2419 struct ucc_geth_init_pram *p_init_enet_pram;
2420 struct ucc_fast_private *uccf;
2421 struct ucc_geth_info *ug_info;
2422 struct ucc_fast_info *uf_info;
2423 struct ucc_fast *uf_regs;
2424 struct ucc_geth *ug_regs;
2425 int ret_val = -EINVAL;
2426 u32 remoder = UCC_GETH_REMODER_INIT;
2427 u32 init_enet_pram_offset, cecr_subblock, command, maccfg1;
2428 u32 ifstat, i, j, size, l2qt, l3qt, length;
2429 u16 temoder = UCC_GETH_TEMODER_INIT;
2430 u16 test;
2431 u8 function_code = 0;
2432 u8 *bd, *endOfRing;
2433 u8 numThreadsRxNumerical, numThreadsTxNumerical;
2434
2435 ugeth_vdbg("%s: IN", __FUNCTION__);
2436 uccf = ugeth->uccf;
2437 ug_info = ugeth->ug_info;
2438 uf_info = &ug_info->uf_info;
2439 uf_regs = uccf->uf_regs;
2440 ug_regs = ugeth->ug_regs;
2656 2441
2657 switch (ug_info->numThreadsRx) { 2442 switch (ug_info->numThreadsRx) {
2658 case UCC_GETH_NUM_OF_THREADS_1: 2443 case UCC_GETH_NUM_OF_THREADS_1:
@@ -2711,10 +2496,6 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
2711 || (ug_info->vlanOperationNonTagged != 2496 || (ug_info->vlanOperationNonTagged !=
2712 UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP); 2497 UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP);
2713 2498
2714 uf_regs = uccf->uf_regs;
2715 ug_regs = (struct ucc_geth *) (uccf->uf_regs);
2716 ugeth->ug_regs = ug_regs;
2717
2718 init_default_reg_vals(&uf_regs->upsmr, 2499 init_default_reg_vals(&uf_regs->upsmr,
2719 &ug_regs->maccfg1, &ug_regs->maccfg2); 2500 &ug_regs->maccfg1, &ug_regs->maccfg2);
2720 2501
@@ -3841,128 +3622,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
3841 return IRQ_HANDLED; 3622 return IRQ_HANDLED;
3842} 3623}
3843 3624
3844static irqreturn_t phy_interrupt(int irq, void *dev_id)
3845{
3846 struct net_device *dev = (struct net_device *)dev_id;
3847 struct ucc_geth_private *ugeth = netdev_priv(dev);
3848
3849 ugeth_vdbg("%s: IN", __FUNCTION__);
3850
3851 /* Clear the interrupt */
3852 mii_clear_phy_interrupt(ugeth->mii_info);
3853
3854 /* Disable PHY interrupts */
3855 mii_configure_phy_interrupt(ugeth->mii_info, MII_INTERRUPT_DISABLED);
3856
3857 /* Schedule the phy change */
3858 schedule_work(&ugeth->tq);
3859
3860 return IRQ_HANDLED;
3861}
3862
3863/* Scheduled by the phy_interrupt/timer to handle PHY changes */
3864static void ugeth_phy_change(struct work_struct *work)
3865{
3866 struct ucc_geth_private *ugeth =
3867 container_of(work, struct ucc_geth_private, tq);
3868 struct net_device *dev = ugeth->dev;
3869 struct ucc_geth *ug_regs;
3870 int result = 0;
3871
3872 ugeth_vdbg("%s: IN", __FUNCTION__);
3873
3874 ug_regs = ugeth->ug_regs;
3875
3876 /* Delay to give the PHY a chance to change the
3877 * register state */
3878 msleep(1);
3879
3880 /* Update the link, speed, duplex */
3881 result = ugeth->mii_info->phyinfo->read_status(ugeth->mii_info);
3882
3883 /* Adjust the known status as long as the link
3884 * isn't still coming up */
3885 if ((0 == result) || (ugeth->mii_info->link == 0))
3886 adjust_link(dev);
3887
3888 /* Reenable interrupts, if needed */
3889 if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR)
3890 mii_configure_phy_interrupt(ugeth->mii_info,
3891 MII_INTERRUPT_ENABLED);
3892}
3893
3894/* Called every so often on systems that don't interrupt
3895 * the core for PHY changes */
3896static void ugeth_phy_timer(unsigned long data)
3897{
3898 struct net_device *dev = (struct net_device *)data;
3899 struct ucc_geth_private *ugeth = netdev_priv(dev);
3900
3901 schedule_work(&ugeth->tq);
3902
3903 mod_timer(&ugeth->phy_info_timer, jiffies + PHY_CHANGE_TIME * HZ);
3904}
3905
3906/* Keep trying aneg for some time
3907 * If, after GFAR_AN_TIMEOUT seconds, it has not
3908 * finished, we switch to forced.
3909 * Either way, once the process has completed, we either
3910 * request the interrupt, or switch the timer over to
3911 * using ugeth_phy_timer to check status */
3912static void ugeth_phy_startup_timer(unsigned long data)
3913{
3914 struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data;
3915 struct ucc_geth_private *ugeth = netdev_priv(mii_info->dev);
3916 static int secondary = UGETH_AN_TIMEOUT;
3917 int result;
3918
3919 /* Configure the Auto-negotiation */
3920 result = mii_info->phyinfo->config_aneg(mii_info);
3921
3922 /* If autonegotiation failed to start, and
3923 * we haven't timed out, reset the timer, and return */
3924 if (result && secondary--) {
3925 mod_timer(&ugeth->phy_info_timer, jiffies + HZ);
3926 return;
3927 } else if (result) {
3928 /* Couldn't start autonegotiation.
3929 * Try switching to forced */
3930 mii_info->autoneg = 0;
3931 result = mii_info->phyinfo->config_aneg(mii_info);
3932
3933 /* Forcing failed! Give up */
3934 if (result) {
3935 ugeth_err("%s: Forcing failed!", mii_info->dev->name);
3936 return;
3937 }
3938 }
3939
3940 /* Kill the timer so it can be restarted */
3941 del_timer_sync(&ugeth->phy_info_timer);
3942
3943 /* Grab the PHY interrupt, if necessary/possible */
3944 if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) {
3945 if (request_irq(ugeth->ug_info->phy_interrupt,
3946 phy_interrupt, IRQF_SHARED,
3947 "phy_interrupt", mii_info->dev) < 0) {
3948 ugeth_err("%s: Can't get IRQ %d (PHY)",
3949 mii_info->dev->name,
3950 ugeth->ug_info->phy_interrupt);
3951 } else {
3952 mii_configure_phy_interrupt(ugeth->mii_info,
3953 MII_INTERRUPT_ENABLED);
3954 return;
3955 }
3956 }
3957
3958 /* Start the timer again, this time in order to
3959 * handle a change in status */
3960 init_timer(&ugeth->phy_info_timer);
3961 ugeth->phy_info_timer.function = &ugeth_phy_timer;
3962 ugeth->phy_info_timer.data = (unsigned long)mii_info->dev;
3963 mod_timer(&ugeth->phy_info_timer, jiffies + PHY_CHANGE_TIME * HZ);
3964}
3965
3966/* Called when something needs to use the ethernet device */ 3625/* Called when something needs to use the ethernet device */
3967/* Returns 0 for success. */ 3626/* Returns 0 for success. */
3968static int ucc_geth_open(struct net_device *dev) 3627static int ucc_geth_open(struct net_device *dev)
@@ -3979,6 +3638,12 @@ static int ucc_geth_open(struct net_device *dev)
3979 return -EINVAL; 3638 return -EINVAL;
3980 } 3639 }
3981 3640
3641 err = ucc_struct_init(ugeth);
3642 if (err) {
3643 ugeth_err("%s: Cannot configure internal struct, aborting.", dev->name);
3644 return err;
3645 }
3646
3982 err = ucc_geth_startup(ugeth); 3647 err = ucc_geth_startup(ugeth);
3983 if (err) { 3648 if (err) {
3984 ugeth_err("%s: Cannot configure net device, aborting.", 3649 ugeth_err("%s: Cannot configure net device, aborting.",
@@ -4006,9 +3671,12 @@ static int ucc_geth_open(struct net_device *dev)
4006 3671
4007 err = init_phy(dev); 3672 err = init_phy(dev);
4008 if (err) { 3673 if (err) {
4009 ugeth_err("%s: Cannot initialzie PHY, aborting.", dev->name); 3674 ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name);
4010 return err; 3675 return err;
4011 } 3676 }
3677
3678 phy_start(ugeth->phydev);
3679
4012#ifndef CONFIG_UGETH_NAPI 3680#ifndef CONFIG_UGETH_NAPI
4013 err = 3681 err =
4014 request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler, 0, 3682 request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler, 0,
@@ -4021,14 +3689,6 @@ static int ucc_geth_open(struct net_device *dev)
4021 } 3689 }
4022#endif /* CONFIG_UGETH_NAPI */ 3690#endif /* CONFIG_UGETH_NAPI */
4023 3691
4024 /* Set up the PHY change work queue */
4025 INIT_WORK(&ugeth->tq, ugeth_phy_change);
4026
4027 init_timer(&ugeth->phy_info_timer);
4028 ugeth->phy_info_timer.function = &ugeth_phy_startup_timer;
4029 ugeth->phy_info_timer.data = (unsigned long)ugeth->mii_info;
4030 mod_timer(&ugeth->phy_info_timer, jiffies + HZ);
4031
4032 err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); 3692 err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
4033 if (err) { 3693 if (err) {
4034 ugeth_err("%s: Cannot enable net device, aborting.", dev->name); 3694 ugeth_err("%s: Cannot enable net device, aborting.", dev->name);
@@ -4050,11 +3710,8 @@ static int ucc_geth_close(struct net_device *dev)
4050 3710
4051 ucc_geth_stop(ugeth); 3711 ucc_geth_stop(ugeth);
4052 3712
4053 /* Shutdown the PHY */ 3713 phy_disconnect(ugeth->phydev);
4054 if (ugeth->mii_info->phyinfo->close) 3714 ugeth->phydev = NULL;
4055 ugeth->mii_info->phyinfo->close(ugeth->mii_info);
4056
4057 kfree(ugeth->mii_info);
4058 3715
4059 netif_stop_queue(dev); 3716 netif_stop_queue(dev);
4060 3717
@@ -4063,20 +3720,53 @@ static int ucc_geth_close(struct net_device *dev)
4063 3720
4064const struct ethtool_ops ucc_geth_ethtool_ops = { }; 3721const struct ethtool_ops ucc_geth_ethtool_ops = { };
4065 3722
3723static phy_interface_t to_phy_interface(const char *interface_type)
3724{
3725 if (strcasecmp(interface_type, "mii") == 0)
3726 return PHY_INTERFACE_MODE_MII;
3727 if (strcasecmp(interface_type, "gmii") == 0)
3728 return PHY_INTERFACE_MODE_GMII;
3729 if (strcasecmp(interface_type, "tbi") == 0)
3730 return PHY_INTERFACE_MODE_TBI;
3731 if (strcasecmp(interface_type, "rmii") == 0)
3732 return PHY_INTERFACE_MODE_RMII;
3733 if (strcasecmp(interface_type, "rgmii") == 0)
3734 return PHY_INTERFACE_MODE_RGMII;
3735 if (strcasecmp(interface_type, "rgmii-id") == 0)
3736 return PHY_INTERFACE_MODE_RGMII_ID;
3737 if (strcasecmp(interface_type, "rtbi") == 0)
3738 return PHY_INTERFACE_MODE_RTBI;
3739
3740 return PHY_INTERFACE_MODE_MII;
3741}
3742
4066static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match) 3743static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match)
4067{ 3744{
4068 struct device *device = &ofdev->dev; 3745 struct device *device = &ofdev->dev;
4069 struct device_node *np = ofdev->node; 3746 struct device_node *np = ofdev->node;
3747 struct device_node *mdio;
4070 struct net_device *dev = NULL; 3748 struct net_device *dev = NULL;
4071 struct ucc_geth_private *ugeth = NULL; 3749 struct ucc_geth_private *ugeth = NULL;
4072 struct ucc_geth_info *ug_info; 3750 struct ucc_geth_info *ug_info;
4073 struct resource res; 3751 struct resource res;
4074 struct device_node *phy; 3752 struct device_node *phy;
4075 int err, ucc_num, phy_interface; 3753 int err, ucc_num, max_speed = 0;
4076 static int mii_mng_configured = 0;
4077 const phandle *ph; 3754 const phandle *ph;
4078 const unsigned int *prop; 3755 const unsigned int *prop;
4079 const void *mac_addr; 3756 const void *mac_addr;
3757 phy_interface_t phy_interface;
3758 static const int enet_to_speed[] = {
3759 SPEED_10, SPEED_10, SPEED_10,
3760 SPEED_100, SPEED_100, SPEED_100,
3761 SPEED_1000, SPEED_1000, SPEED_1000, SPEED_1000,
3762 };
3763 static const phy_interface_t enet_to_phy_interface[] = {
3764 PHY_INTERFACE_MODE_MII, PHY_INTERFACE_MODE_RMII,
3765 PHY_INTERFACE_MODE_RGMII, PHY_INTERFACE_MODE_MII,
3766 PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII,
3767 PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_RGMII,
3768 PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI,
3769 };
4080 3770
4081 ugeth_vdbg("%s: IN", __FUNCTION__); 3771 ugeth_vdbg("%s: IN", __FUNCTION__);
4082 3772
@@ -4087,6 +3777,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
4087 3777
4088 ug_info = &ugeth_info[ucc_num]; 3778 ug_info = &ugeth_info[ucc_num];
4089 ug_info->uf_info.ucc_num = ucc_num; 3779 ug_info->uf_info.ucc_num = ucc_num;
3780
4090 prop = get_property(np, "rx-clock", NULL); 3781 prop = get_property(np, "rx-clock", NULL);
4091 ug_info->uf_info.rx_clock = *prop; 3782 ug_info->uf_info.rx_clock = *prop;
4092 prop = get_property(np, "tx-clock", NULL); 3783 prop = get_property(np, "tx-clock", NULL);
@@ -4104,13 +3795,72 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
4104 if (phy == NULL) 3795 if (phy == NULL)
4105 return -ENODEV; 3796 return -ENODEV;
4106 3797
3798 /* set the PHY address */
4107 prop = get_property(phy, "reg", NULL); 3799 prop = get_property(phy, "reg", NULL);
3800 if (prop == NULL)
3801 return -1;
4108 ug_info->phy_address = *prop; 3802 ug_info->phy_address = *prop;
4109 prop = get_property(phy, "interface", NULL); 3803
4110 ug_info->enet_interface = *prop; 3804 /* get the phy interface type, or default to MII */
4111 ug_info->phy_interrupt = irq_of_parse_and_map(phy, 0); 3805 prop = get_property(np, "interface-type", NULL);
4112 ug_info->board_flags = (ug_info->phy_interrupt == NO_IRQ)? 3806 if (!prop) {
4113 0:FSL_UGETH_BRD_HAS_PHY_INTR; 3807 /* handle interface property present in old trees */
3808 prop = get_property(phy, "interface", NULL);
3809 if (prop != NULL)
3810 phy_interface = enet_to_phy_interface[*prop];
3811 else
3812 phy_interface = PHY_INTERFACE_MODE_MII;
3813 } else {
3814 phy_interface = to_phy_interface((const char *)prop);
3815 }
3816
3817 /* get speed, or derive from interface */
3818 prop = get_property(np, "max-speed", NULL);
3819 if (!prop) {
3820 /* handle interface property present in old trees */
3821 prop = get_property(phy, "interface", NULL);
3822 if (prop != NULL)
3823 max_speed = enet_to_speed[*prop];
3824 } else {
3825 max_speed = *prop;
3826 }
3827 if (!max_speed) {
3828 switch (phy_interface) {
3829 case PHY_INTERFACE_MODE_GMII:
3830 case PHY_INTERFACE_MODE_RGMII:
3831 case PHY_INTERFACE_MODE_RGMII_ID:
3832 case PHY_INTERFACE_MODE_TBI:
3833 case PHY_INTERFACE_MODE_RTBI:
3834 max_speed = SPEED_1000;
3835 break;
3836 default:
3837 max_speed = SPEED_100;
3838 break;
3839 }
3840 }
3841
3842 if (max_speed == SPEED_1000) {
3843 ug_info->uf_info.urfs = UCC_GETH_URFS_GIGA_INIT;
3844 ug_info->uf_info.urfet = UCC_GETH_URFET_GIGA_INIT;
3845 ug_info->uf_info.urfset = UCC_GETH_URFSET_GIGA_INIT;
3846 ug_info->uf_info.utfs = UCC_GETH_UTFS_GIGA_INIT;
3847 ug_info->uf_info.utfet = UCC_GETH_UTFET_GIGA_INIT;
3848 ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT;
3849 }
3850
3851 /* Set the bus id */
3852 mdio = of_get_parent(phy);
3853
3854 if (mdio == NULL)
3855 return -1;
3856
3857 err = of_address_to_resource(mdio, 0, &res);
3858 of_node_put(mdio);
3859
3860 if (err)
3861 return -1;
3862
3863 ug_info->mdio_bus = res.start;
4114 3864
4115 printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n", 3865 printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n",
4116 ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs, 3866 ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs,
@@ -4122,43 +3872,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
4122 return -ENODEV; 3872 return -ENODEV;
4123 } 3873 }
4124 3874
4125 /* FIXME: Work around for early chip rev. */
4126 /* There's a bug in initial chip rev(s) in the RGMII ac */
4127 /* timing. */
4128 /* The following compensates by writing to the reserved */
4129 /* QE Port Output Hold Registers (CPOH1?). */
4130 prop = get_property(phy, "interface", NULL);
4131 phy_interface = *prop;
4132 if ((phy_interface == ENET_1000_RGMII) ||
4133 (phy_interface == ENET_100_RGMII) ||
4134 (phy_interface == ENET_10_RGMII)) {
4135 struct device_node *soc;
4136 phys_addr_t immrbase = -1;
4137 u32 *tmp_reg;
4138 u32 tmp_val;
4139
4140 soc = of_find_node_by_type(NULL, "soc");
4141 if (soc) {
4142 unsigned int size;
4143 const void *prop = get_property(soc, "reg", &size);
4144 immrbase = of_translate_address(soc, prop);
4145 of_node_put(soc);
4146 };
4147
4148 tmp_reg = (u32 *) ioremap(immrbase + 0x14A8, 0x4);
4149 tmp_val = in_be32(tmp_reg);
4150 if (ucc_num == 1)
4151 out_be32(tmp_reg, tmp_val | 0x00003000);
4152 else if (ucc_num == 2)
4153 out_be32(tmp_reg, tmp_val | 0x0c000000);
4154 iounmap(tmp_reg);
4155 }
4156
4157 if (!mii_mng_configured) {
4158 ucc_set_qe_mux_mii_mng(ucc_num);
4159 mii_mng_configured = 1;
4160 }
4161
4162 /* Create an ethernet device instance */ 3875 /* Create an ethernet device instance */
4163 dev = alloc_etherdev(sizeof(*ugeth)); 3876 dev = alloc_etherdev(sizeof(*ugeth));
4164 3877
@@ -4192,6 +3905,10 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
4192 dev->set_multicast_list = ucc_geth_set_multi; 3905 dev->set_multicast_list = ucc_geth_set_multi;
4193 dev->ethtool_ops = &ucc_geth_ethtool_ops; 3906 dev->ethtool_ops = &ucc_geth_ethtool_ops;
4194 3907
3908 ugeth->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
3909 ugeth->phy_interface = phy_interface;
3910 ugeth->max_speed = max_speed;
3911
4195 err = register_netdev(dev); 3912 err = register_netdev(dev);
4196 if (err) { 3913 if (err) {
4197 ugeth_err("%s: Cannot register net device, aborting.", 3914 ugeth_err("%s: Cannot register net device, aborting.",
@@ -4200,13 +3917,13 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
4200 return err; 3917 return err;
4201 } 3918 }
4202 3919
4203 ugeth->ug_info = ug_info;
4204 ugeth->dev = dev;
4205
4206 mac_addr = of_get_mac_address(np); 3920 mac_addr = of_get_mac_address(np);
4207 if (mac_addr) 3921 if (mac_addr)
4208 memcpy(dev->dev_addr, mac_addr, 6); 3922 memcpy(dev->dev_addr, mac_addr, 6);
4209 3923
3924 ugeth->ug_info = ug_info;
3925 ugeth->dev = dev;
3926
4210 return 0; 3927 return 0;
4211} 3928}
4212 3929
@@ -4242,19 +3959,30 @@ static struct of_platform_driver ucc_geth_driver = {
4242 3959
4243static int __init ucc_geth_init(void) 3960static int __init ucc_geth_init(void)
4244{ 3961{
4245 int i; 3962 int i, ret;
3963
3964 ret = uec_mdio_init();
3965
3966 if (ret)
3967 return ret;
4246 3968
4247 printk(KERN_INFO "ucc_geth: " DRV_DESC "\n"); 3969 printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
4248 for (i = 0; i < 8; i++) 3970 for (i = 0; i < 8; i++)
4249 memcpy(&(ugeth_info[i]), &ugeth_primary_info, 3971 memcpy(&(ugeth_info[i]), &ugeth_primary_info,
4250 sizeof(ugeth_primary_info)); 3972 sizeof(ugeth_primary_info));
4251 3973
4252 return of_register_platform_driver(&ucc_geth_driver); 3974 ret = of_register_platform_driver(&ucc_geth_driver);
3975
3976 if (ret)
3977 uec_mdio_exit();
3978
3979 return ret;
4253} 3980}
4254 3981
4255static void __exit ucc_geth_exit(void) 3982static void __exit ucc_geth_exit(void)
4256{ 3983{
4257 of_unregister_platform_driver(&ucc_geth_driver); 3984 of_unregister_platform_driver(&ucc_geth_driver);
3985 uec_mdio_exit();
4258} 3986}
4259 3987
4260module_init(ucc_geth_init); 3988module_init(ucc_geth_init);