diff options
Diffstat (limited to 'drivers/net/bfin_mac.c')
| -rw-r--r-- | drivers/net/bfin_mac.c | 145 |
1 files changed, 94 insertions, 51 deletions
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index f7233191162b..ce1e5e9d06f6 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Blackfin On-Chip MAC Driver | 2 | * Blackfin On-Chip MAC Driver |
| 3 | * | 3 | * |
| 4 | * Copyright 2004-2007 Analog Devices Inc. | 4 | * Copyright 2004-2010 Analog Devices Inc. |
| 5 | * | 5 | * |
| 6 | * Enter bugs at http://blackfin.uclinux.org/ | 6 | * Enter bugs at http://blackfin.uclinux.org/ |
| 7 | * | 7 | * |
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <linux/device.h> | 23 | #include <linux/device.h> |
| 24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
| 25 | #include <linux/mii.h> | 25 | #include <linux/mii.h> |
| 26 | #include <linux/phy.h> | ||
| 27 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
| 28 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
| 29 | #include <linux/ethtool.h> | 28 | #include <linux/ethtool.h> |
| @@ -76,12 +75,6 @@ static struct net_dma_desc_tx *current_tx_ptr; | |||
| 76 | static struct net_dma_desc_tx *tx_desc; | 75 | static struct net_dma_desc_tx *tx_desc; |
| 77 | static struct net_dma_desc_rx *rx_desc; | 76 | static struct net_dma_desc_rx *rx_desc; |
| 78 | 77 | ||
| 79 | #if defined(CONFIG_BFIN_MAC_RMII) | ||
| 80 | static u16 pin_req[] = P_RMII0; | ||
| 81 | #else | ||
| 82 | static u16 pin_req[] = P_MII0; | ||
| 83 | #endif | ||
| 84 | |||
| 85 | static void desc_list_free(void) | 78 | static void desc_list_free(void) |
| 86 | { | 79 | { |
| 87 | struct net_dma_desc_rx *r; | 80 | struct net_dma_desc_rx *r; |
| @@ -347,23 +340,23 @@ static void bfin_mac_adjust_link(struct net_device *dev) | |||
| 347 | } | 340 | } |
| 348 | 341 | ||
| 349 | if (phydev->speed != lp->old_speed) { | 342 | if (phydev->speed != lp->old_speed) { |
| 350 | #if defined(CONFIG_BFIN_MAC_RMII) | 343 | if (phydev->interface == PHY_INTERFACE_MODE_RMII) { |
| 351 | u32 opmode = bfin_read_EMAC_OPMODE(); | 344 | u32 opmode = bfin_read_EMAC_OPMODE(); |
| 352 | switch (phydev->speed) { | 345 | switch (phydev->speed) { |
| 353 | case 10: | 346 | case 10: |
| 354 | opmode |= RMII_10; | 347 | opmode |= RMII_10; |
| 355 | break; | 348 | break; |
| 356 | case 100: | 349 | case 100: |
| 357 | opmode &= ~(RMII_10); | 350 | opmode &= ~RMII_10; |
| 358 | break; | 351 | break; |
| 359 | default: | 352 | default: |
| 360 | printk(KERN_WARNING | 353 | printk(KERN_WARNING |
| 361 | "%s: Ack! Speed (%d) is not 10/100!\n", | 354 | "%s: Ack! Speed (%d) is not 10/100!\n", |
| 362 | DRV_NAME, phydev->speed); | 355 | DRV_NAME, phydev->speed); |
| 363 | break; | 356 | break; |
| 357 | } | ||
| 358 | bfin_write_EMAC_OPMODE(opmode); | ||
| 364 | } | 359 | } |
| 365 | bfin_write_EMAC_OPMODE(opmode); | ||
| 366 | #endif | ||
| 367 | 360 | ||
| 368 | new_state = 1; | 361 | new_state = 1; |
| 369 | lp->old_speed = phydev->speed; | 362 | lp->old_speed = phydev->speed; |
| @@ -392,7 +385,7 @@ static void bfin_mac_adjust_link(struct net_device *dev) | |||
| 392 | /* MDC = 2.5 MHz */ | 385 | /* MDC = 2.5 MHz */ |
| 393 | #define MDC_CLK 2500000 | 386 | #define MDC_CLK 2500000 |
| 394 | 387 | ||
| 395 | static int mii_probe(struct net_device *dev) | 388 | static int mii_probe(struct net_device *dev, int phy_mode) |
| 396 | { | 389 | { |
| 397 | struct bfin_mac_local *lp = netdev_priv(dev); | 390 | struct bfin_mac_local *lp = netdev_priv(dev); |
| 398 | struct phy_device *phydev = NULL; | 391 | struct phy_device *phydev = NULL; |
| @@ -411,8 +404,8 @@ static int mii_probe(struct net_device *dev) | |||
| 411 | sysctl = (sysctl & ~MDCDIV) | SET_MDCDIV(mdc_div); | 404 | sysctl = (sysctl & ~MDCDIV) | SET_MDCDIV(mdc_div); |
| 412 | bfin_write_EMAC_SYSCTL(sysctl); | 405 | bfin_write_EMAC_SYSCTL(sysctl); |
| 413 | 406 | ||
| 414 | /* search for connect PHY device */ | 407 | /* search for connected PHY device */ |
| 415 | for (i = 0; i < PHY_MAX_ADDR; i++) { | 408 | for (i = 0; i < PHY_MAX_ADDR; ++i) { |
| 416 | struct phy_device *const tmp_phydev = lp->mii_bus->phy_map[i]; | 409 | struct phy_device *const tmp_phydev = lp->mii_bus->phy_map[i]; |
| 417 | 410 | ||
| 418 | if (!tmp_phydev) | 411 | if (!tmp_phydev) |
| @@ -429,13 +422,14 @@ static int mii_probe(struct net_device *dev) | |||
| 429 | return -ENODEV; | 422 | return -ENODEV; |
| 430 | } | 423 | } |
| 431 | 424 | ||
| 432 | #if defined(CONFIG_BFIN_MAC_RMII) | 425 | if (phy_mode != PHY_INTERFACE_MODE_RMII && |
| 433 | phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link, | 426 | phy_mode != PHY_INTERFACE_MODE_MII) { |
| 434 | 0, PHY_INTERFACE_MODE_RMII); | 427 | printk(KERN_INFO "%s: Invalid phy interface mode\n", dev->name); |
| 435 | #else | 428 | return -EINVAL; |
| 429 | } | ||
| 430 | |||
| 436 | phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link, | 431 | phydev = phy_connect(dev, dev_name(&phydev->dev), &bfin_mac_adjust_link, |
| 437 | 0, PHY_INTERFACE_MODE_MII); | 432 | 0, phy_mode); |
| 438 | #endif | ||
| 439 | 433 | ||
| 440 | if (IS_ERR(phydev)) { | 434 | if (IS_ERR(phydev)) { |
| 441 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); | 435 | printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); |
| @@ -570,6 +564,8 @@ static const struct ethtool_ops bfin_mac_ethtool_ops = { | |||
| 570 | /**************************************************************************/ | 564 | /**************************************************************************/ |
| 571 | void setup_system_regs(struct net_device *dev) | 565 | void setup_system_regs(struct net_device *dev) |
| 572 | { | 566 | { |
| 567 | struct bfin_mac_local *lp = netdev_priv(dev); | ||
| 568 | int i; | ||
| 573 | unsigned short sysctl; | 569 | unsigned short sysctl; |
| 574 | 570 | ||
| 575 | /* | 571 | /* |
| @@ -577,6 +573,15 @@ void setup_system_regs(struct net_device *dev) | |||
| 577 | * Configure checksum support and rcve frame word alignment | 573 | * Configure checksum support and rcve frame word alignment |
| 578 | */ | 574 | */ |
| 579 | sysctl = bfin_read_EMAC_SYSCTL(); | 575 | sysctl = bfin_read_EMAC_SYSCTL(); |
| 576 | /* | ||
| 577 | * check if interrupt is requested for any PHY, | ||
| 578 | * enable PHY interrupt only if needed | ||
| 579 | */ | ||
| 580 | for (i = 0; i < PHY_MAX_ADDR; ++i) | ||
| 581 | if (lp->mii_bus->irq[i] != PHY_POLL) | ||
| 582 | break; | ||
| 583 | if (i < PHY_MAX_ADDR) | ||
| 584 | sysctl |= PHYIE; | ||
| 580 | sysctl |= RXDWA; | 585 | sysctl |= RXDWA; |
| 581 | #if defined(BFIN_MAC_CSUM_OFFLOAD) | 586 | #if defined(BFIN_MAC_CSUM_OFFLOAD) |
| 582 | sysctl |= RXCKS; | 587 | sysctl |= RXCKS; |
| @@ -1203,7 +1208,7 @@ static void bfin_mac_disable(void) | |||
| 1203 | /* | 1208 | /* |
| 1204 | * Enable Interrupts, Receive, and Transmit | 1209 | * Enable Interrupts, Receive, and Transmit |
| 1205 | */ | 1210 | */ |
| 1206 | static int bfin_mac_enable(void) | 1211 | static int bfin_mac_enable(struct phy_device *phydev) |
| 1207 | { | 1212 | { |
| 1208 | int ret; | 1213 | int ret; |
| 1209 | u32 opmode; | 1214 | u32 opmode; |
| @@ -1233,12 +1238,13 @@ static int bfin_mac_enable(void) | |||
| 1233 | opmode |= DRO | DC | PSF; | 1238 | opmode |= DRO | DC | PSF; |
| 1234 | opmode |= RE; | 1239 | opmode |= RE; |
| 1235 | 1240 | ||
| 1236 | #if defined(CONFIG_BFIN_MAC_RMII) | 1241 | if (phydev->interface == PHY_INTERFACE_MODE_RMII) { |
| 1237 | opmode |= RMII; /* For Now only 100MBit are supported */ | 1242 | opmode |= RMII; /* For Now only 100MBit are supported */ |
| 1238 | #if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) && CONFIG_BF_REV_0_2 | 1243 | #if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) && CONFIG_BF_REV_0_2 |
| 1239 | opmode |= TE; | 1244 | opmode |= TE; |
| 1240 | #endif | ||
| 1241 | #endif | 1245 | #endif |
| 1246 | } | ||
| 1247 | |||
| 1242 | /* Turn on the EMAC rx */ | 1248 | /* Turn on the EMAC rx */ |
| 1243 | bfin_write_EMAC_OPMODE(opmode); | 1249 | bfin_write_EMAC_OPMODE(opmode); |
| 1244 | 1250 | ||
| @@ -1270,7 +1276,7 @@ static void bfin_mac_timeout(struct net_device *dev) | |||
| 1270 | if (netif_queue_stopped(lp->ndev)) | 1276 | if (netif_queue_stopped(lp->ndev)) |
| 1271 | netif_wake_queue(lp->ndev); | 1277 | netif_wake_queue(lp->ndev); |
| 1272 | 1278 | ||
| 1273 | bfin_mac_enable(); | 1279 | bfin_mac_enable(lp->phydev); |
| 1274 | 1280 | ||
| 1275 | /* We can accept TX packets again */ | 1281 | /* We can accept TX packets again */ |
| 1276 | dev->trans_start = jiffies; /* prevent tx timeout */ | 1282 | dev->trans_start = jiffies; /* prevent tx timeout */ |
| @@ -1342,11 +1348,19 @@ static void bfin_mac_set_multicast_list(struct net_device *dev) | |||
| 1342 | 1348 | ||
| 1343 | static int bfin_mac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) | 1349 | static int bfin_mac_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) |
| 1344 | { | 1350 | { |
| 1351 | struct bfin_mac_local *lp = netdev_priv(netdev); | ||
| 1352 | |||
| 1353 | if (!netif_running(netdev)) | ||
| 1354 | return -EINVAL; | ||
| 1355 | |||
| 1345 | switch (cmd) { | 1356 | switch (cmd) { |
| 1346 | case SIOCSHWTSTAMP: | 1357 | case SIOCSHWTSTAMP: |
| 1347 | return bfin_mac_hwtstamp_ioctl(netdev, ifr, cmd); | 1358 | return bfin_mac_hwtstamp_ioctl(netdev, ifr, cmd); |
| 1348 | default: | 1359 | default: |
| 1349 | return -EOPNOTSUPP; | 1360 | if (lp->phydev) |
| 1361 | return phy_mii_ioctl(lp->phydev, ifr, cmd); | ||
| 1362 | else | ||
| 1363 | return -EOPNOTSUPP; | ||
| 1350 | } | 1364 | } |
| 1351 | } | 1365 | } |
| 1352 | 1366 | ||
| @@ -1394,7 +1408,7 @@ static int bfin_mac_open(struct net_device *dev) | |||
| 1394 | setup_mac_addr(dev->dev_addr); | 1408 | setup_mac_addr(dev->dev_addr); |
| 1395 | 1409 | ||
| 1396 | bfin_mac_disable(); | 1410 | bfin_mac_disable(); |
| 1397 | ret = bfin_mac_enable(); | 1411 | ret = bfin_mac_enable(lp->phydev); |
| 1398 | if (ret) | 1412 | if (ret) |
| 1399 | return ret; | 1413 | return ret; |
| 1400 | pr_debug("hardware init finished\n"); | 1414 | pr_debug("hardware init finished\n"); |
| @@ -1450,6 +1464,7 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) | |||
| 1450 | struct net_device *ndev; | 1464 | struct net_device *ndev; |
| 1451 | struct bfin_mac_local *lp; | 1465 | struct bfin_mac_local *lp; |
| 1452 | struct platform_device *pd; | 1466 | struct platform_device *pd; |
| 1467 | struct bfin_mii_bus_platform_data *mii_bus_data; | ||
| 1453 | int rc; | 1468 | int rc; |
| 1454 | 1469 | ||
| 1455 | ndev = alloc_etherdev(sizeof(struct bfin_mac_local)); | 1470 | ndev = alloc_etherdev(sizeof(struct bfin_mac_local)); |
| @@ -1501,11 +1516,12 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) | |||
| 1501 | if (!lp->mii_bus) { | 1516 | if (!lp->mii_bus) { |
| 1502 | dev_err(&pdev->dev, "Cannot get mii_bus!\n"); | 1517 | dev_err(&pdev->dev, "Cannot get mii_bus!\n"); |
| 1503 | rc = -ENODEV; | 1518 | rc = -ENODEV; |
| 1504 | goto out_err_mii_bus_probe; | 1519 | goto out_err_probe_mac; |
| 1505 | } | 1520 | } |
| 1506 | lp->mii_bus->priv = ndev; | 1521 | lp->mii_bus->priv = ndev; |
| 1522 | mii_bus_data = pd->dev.platform_data; | ||
| 1507 | 1523 | ||
| 1508 | rc = mii_probe(ndev); | 1524 | rc = mii_probe(ndev, mii_bus_data->phy_mode); |
| 1509 | if (rc) { | 1525 | if (rc) { |
| 1510 | dev_err(&pdev->dev, "MII Probe failed!\n"); | 1526 | dev_err(&pdev->dev, "MII Probe failed!\n"); |
| 1511 | goto out_err_mii_probe; | 1527 | goto out_err_mii_probe; |
| @@ -1552,8 +1568,6 @@ out_err_request_irq: | |||
| 1552 | out_err_mii_probe: | 1568 | out_err_mii_probe: |
| 1553 | mdiobus_unregister(lp->mii_bus); | 1569 | mdiobus_unregister(lp->mii_bus); |
| 1554 | mdiobus_free(lp->mii_bus); | 1570 | mdiobus_free(lp->mii_bus); |
| 1555 | out_err_mii_bus_probe: | ||
| 1556 | peripheral_free_list(pin_req); | ||
| 1557 | out_err_probe_mac: | 1571 | out_err_probe_mac: |
| 1558 | platform_set_drvdata(pdev, NULL); | 1572 | platform_set_drvdata(pdev, NULL); |
| 1559 | free_netdev(ndev); | 1573 | free_netdev(ndev); |
| @@ -1576,8 +1590,6 @@ static int __devexit bfin_mac_remove(struct platform_device *pdev) | |||
| 1576 | 1590 | ||
| 1577 | free_netdev(ndev); | 1591 | free_netdev(ndev); |
| 1578 | 1592 | ||
| 1579 | peripheral_free_list(pin_req); | ||
| 1580 | |||
| 1581 | return 0; | 1593 | return 0; |
| 1582 | } | 1594 | } |
| 1583 | 1595 | ||
| @@ -1623,12 +1635,21 @@ static int bfin_mac_resume(struct platform_device *pdev) | |||
| 1623 | static int __devinit bfin_mii_bus_probe(struct platform_device *pdev) | 1635 | static int __devinit bfin_mii_bus_probe(struct platform_device *pdev) |
| 1624 | { | 1636 | { |
| 1625 | struct mii_bus *miibus; | 1637 | struct mii_bus *miibus; |
| 1638 | struct bfin_mii_bus_platform_data *mii_bus_pd; | ||
| 1639 | const unsigned short *pin_req; | ||
| 1626 | int rc, i; | 1640 | int rc, i; |
| 1627 | 1641 | ||
| 1642 | mii_bus_pd = dev_get_platdata(&pdev->dev); | ||
| 1643 | if (!mii_bus_pd) { | ||
| 1644 | dev_err(&pdev->dev, "No peripherals in platform data!\n"); | ||
| 1645 | return -EINVAL; | ||
| 1646 | } | ||
| 1647 | |||
| 1628 | /* | 1648 | /* |
| 1629 | * We are setting up a network card, | 1649 | * We are setting up a network card, |
| 1630 | * so set the GPIO pins to Ethernet mode | 1650 | * so set the GPIO pins to Ethernet mode |
| 1631 | */ | 1651 | */ |
| 1652 | pin_req = mii_bus_pd->mac_peripherals; | ||
| 1632 | rc = peripheral_request_list(pin_req, DRV_NAME); | 1653 | rc = peripheral_request_list(pin_req, DRV_NAME); |
| 1633 | if (rc) { | 1654 | if (rc) { |
| 1634 | dev_err(&pdev->dev, "Requesting peripherals failed!\n"); | 1655 | dev_err(&pdev->dev, "Requesting peripherals failed!\n"); |
| @@ -1645,13 +1666,30 @@ static int __devinit bfin_mii_bus_probe(struct platform_device *pdev) | |||
| 1645 | 1666 | ||
| 1646 | miibus->parent = &pdev->dev; | 1667 | miibus->parent = &pdev->dev; |
| 1647 | miibus->name = "bfin_mii_bus"; | 1668 | miibus->name = "bfin_mii_bus"; |
| 1669 | miibus->phy_mask = mii_bus_pd->phy_mask; | ||
| 1670 | |||
| 1648 | snprintf(miibus->id, MII_BUS_ID_SIZE, "0"); | 1671 | snprintf(miibus->id, MII_BUS_ID_SIZE, "0"); |
| 1649 | miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); | 1672 | miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); |
| 1650 | if (miibus->irq == NULL) | 1673 | if (!miibus->irq) |
| 1651 | goto out_err_alloc; | 1674 | goto out_err_irq_alloc; |
| 1652 | for (i = 0; i < PHY_MAX_ADDR; ++i) | 1675 | |
| 1676 | for (i = rc; i < PHY_MAX_ADDR; ++i) | ||
| 1653 | miibus->irq[i] = PHY_POLL; | 1677 | miibus->irq[i] = PHY_POLL; |
| 1654 | 1678 | ||
| 1679 | rc = clamp(mii_bus_pd->phydev_number, 0, PHY_MAX_ADDR); | ||
| 1680 | if (rc != mii_bus_pd->phydev_number) | ||
| 1681 | dev_err(&pdev->dev, "Invalid number (%i) of phydevs\n", | ||
| 1682 | mii_bus_pd->phydev_number); | ||
| 1683 | for (i = 0; i < rc; ++i) { | ||
| 1684 | unsigned short phyaddr = mii_bus_pd->phydev_data[i].addr; | ||
| 1685 | if (phyaddr < PHY_MAX_ADDR) | ||
| 1686 | miibus->irq[phyaddr] = mii_bus_pd->phydev_data[i].irq; | ||
| 1687 | else | ||
| 1688 | dev_err(&pdev->dev, | ||
| 1689 | "Invalid PHY address %i for phydev %i\n", | ||
| 1690 | phyaddr, i); | ||
| 1691 | } | ||
| 1692 | |||
| 1655 | rc = mdiobus_register(miibus); | 1693 | rc = mdiobus_register(miibus); |
| 1656 | if (rc) { | 1694 | if (rc) { |
| 1657 | dev_err(&pdev->dev, "Cannot register MDIO bus!\n"); | 1695 | dev_err(&pdev->dev, "Cannot register MDIO bus!\n"); |
| @@ -1663,6 +1701,7 @@ static int __devinit bfin_mii_bus_probe(struct platform_device *pdev) | |||
| 1663 | 1701 | ||
| 1664 | out_err_mdiobus_register: | 1702 | out_err_mdiobus_register: |
| 1665 | kfree(miibus->irq); | 1703 | kfree(miibus->irq); |
| 1704 | out_err_irq_alloc: | ||
| 1666 | mdiobus_free(miibus); | 1705 | mdiobus_free(miibus); |
| 1667 | out_err_alloc: | 1706 | out_err_alloc: |
| 1668 | peripheral_free_list(pin_req); | 1707 | peripheral_free_list(pin_req); |
| @@ -1673,11 +1712,15 @@ out_err_alloc: | |||
| 1673 | static int __devexit bfin_mii_bus_remove(struct platform_device *pdev) | 1712 | static int __devexit bfin_mii_bus_remove(struct platform_device *pdev) |
| 1674 | { | 1713 | { |
| 1675 | struct mii_bus *miibus = platform_get_drvdata(pdev); | 1714 | struct mii_bus *miibus = platform_get_drvdata(pdev); |
| 1715 | struct bfin_mii_bus_platform_data *mii_bus_pd = | ||
| 1716 | dev_get_platdata(&pdev->dev); | ||
| 1717 | |||
| 1676 | platform_set_drvdata(pdev, NULL); | 1718 | platform_set_drvdata(pdev, NULL); |
| 1677 | mdiobus_unregister(miibus); | 1719 | mdiobus_unregister(miibus); |
| 1678 | kfree(miibus->irq); | 1720 | kfree(miibus->irq); |
| 1679 | mdiobus_free(miibus); | 1721 | mdiobus_free(miibus); |
| 1680 | peripheral_free_list(pin_req); | 1722 | peripheral_free_list(mii_bus_pd->mac_peripherals); |
| 1723 | |||
| 1681 | return 0; | 1724 | return 0; |
| 1682 | } | 1725 | } |
| 1683 | 1726 | ||
