diff options
Diffstat (limited to 'drivers/net/ucc_geth.c')
-rw-r--r-- | drivers/net/ucc_geth.c | 582 |
1 files changed, 346 insertions, 236 deletions
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 8a7b8c7bd781..4469f2451a6f 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -209,9 +209,10 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, | |||
209 | { | 209 | { |
210 | struct sk_buff *skb = NULL; | 210 | struct sk_buff *skb = NULL; |
211 | 211 | ||
212 | skb = dev_alloc_skb(ugeth->ug_info->uf_info.max_rx_buf_length + | 212 | skb = __skb_dequeue(&ugeth->rx_recycle); |
213 | UCC_GETH_RX_DATA_BUF_ALIGNMENT); | 213 | if (!skb) |
214 | 214 | skb = dev_alloc_skb(ugeth->ug_info->uf_info.max_rx_buf_length + | |
215 | UCC_GETH_RX_DATA_BUF_ALIGNMENT); | ||
215 | if (skb == NULL) | 216 | if (skb == NULL) |
216 | return NULL; | 217 | return NULL; |
217 | 218 | ||
@@ -437,38 +438,6 @@ static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth, | |||
437 | QE_CR_PROTOCOL_ETHERNET, 0); | 438 | QE_CR_PROTOCOL_ETHERNET, 0); |
438 | } | 439 | } |
439 | 440 | ||
440 | #ifdef CONFIG_UGETH_MAGIC_PACKET | ||
441 | static void magic_packet_detection_enable(struct ucc_geth_private *ugeth) | ||
442 | { | ||
443 | struct ucc_fast_private *uccf; | ||
444 | struct ucc_geth __iomem *ug_regs; | ||
445 | |||
446 | uccf = ugeth->uccf; | ||
447 | ug_regs = ugeth->ug_regs; | ||
448 | |||
449 | /* Enable interrupts for magic packet detection */ | ||
450 | setbits32(uccf->p_uccm, UCC_GETH_UCCE_MPD); | ||
451 | |||
452 | /* Enable magic packet detection */ | ||
453 | setbits32(&ug_regs->maccfg2, MACCFG2_MPE); | ||
454 | } | ||
455 | |||
456 | static void magic_packet_detection_disable(struct ucc_geth_private *ugeth) | ||
457 | { | ||
458 | struct ucc_fast_private *uccf; | ||
459 | struct ucc_geth __iomem *ug_regs; | ||
460 | |||
461 | uccf = ugeth->uccf; | ||
462 | ug_regs = ugeth->ug_regs; | ||
463 | |||
464 | /* Disable interrupts for magic packet detection */ | ||
465 | clrbits32(uccf->p_uccm, UCC_GETH_UCCE_MPD); | ||
466 | |||
467 | /* Disable magic packet detection */ | ||
468 | clrbits32(&ug_regs->maccfg2, MACCFG2_MPE); | ||
469 | } | ||
470 | #endif /* MAGIC_PACKET */ | ||
471 | |||
472 | static inline int compare_addr(u8 **addr1, u8 **addr2) | 441 | static inline int compare_addr(u8 **addr1, u8 **addr2) |
473 | { | 442 | { |
474 | return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS); | 443 | return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS); |
@@ -1443,6 +1412,174 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth) | |||
1443 | return 0; | 1412 | return 0; |
1444 | } | 1413 | } |
1445 | 1414 | ||
1415 | static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) | ||
1416 | { | ||
1417 | struct ucc_fast_private *uccf; | ||
1418 | u32 cecr_subblock; | ||
1419 | u32 temp; | ||
1420 | int i = 10; | ||
1421 | |||
1422 | uccf = ugeth->uccf; | ||
1423 | |||
1424 | /* Mask GRACEFUL STOP TX interrupt bit and clear it */ | ||
1425 | clrbits32(uccf->p_uccm, UCC_GETH_UCCE_GRA); | ||
1426 | out_be32(uccf->p_ucce, UCC_GETH_UCCE_GRA); /* clear by writing 1 */ | ||
1427 | |||
1428 | /* Issue host command */ | ||
1429 | cecr_subblock = | ||
1430 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); | ||
1431 | qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock, | ||
1432 | QE_CR_PROTOCOL_ETHERNET, 0); | ||
1433 | |||
1434 | /* Wait for command to complete */ | ||
1435 | do { | ||
1436 | msleep(10); | ||
1437 | temp = in_be32(uccf->p_ucce); | ||
1438 | } while (!(temp & UCC_GETH_UCCE_GRA) && --i); | ||
1439 | |||
1440 | uccf->stopped_tx = 1; | ||
1441 | |||
1442 | return 0; | ||
1443 | } | ||
1444 | |||
1445 | static int ugeth_graceful_stop_rx(struct ucc_geth_private *ugeth) | ||
1446 | { | ||
1447 | struct ucc_fast_private *uccf; | ||
1448 | u32 cecr_subblock; | ||
1449 | u8 temp; | ||
1450 | int i = 10; | ||
1451 | |||
1452 | uccf = ugeth->uccf; | ||
1453 | |||
1454 | /* Clear acknowledge bit */ | ||
1455 | temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack); | ||
1456 | temp &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX; | ||
1457 | out_8(&ugeth->p_rx_glbl_pram->rxgstpack, temp); | ||
1458 | |||
1459 | /* Keep issuing command and checking acknowledge bit until | ||
1460 | it is asserted, according to spec */ | ||
1461 | do { | ||
1462 | /* Issue host command */ | ||
1463 | cecr_subblock = | ||
1464 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info. | ||
1465 | ucc_num); | ||
1466 | qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, | ||
1467 | QE_CR_PROTOCOL_ETHERNET, 0); | ||
1468 | msleep(10); | ||
1469 | temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack); | ||
1470 | } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX) && --i); | ||
1471 | |||
1472 | uccf->stopped_rx = 1; | ||
1473 | |||
1474 | return 0; | ||
1475 | } | ||
1476 | |||
1477 | static int ugeth_restart_tx(struct ucc_geth_private *ugeth) | ||
1478 | { | ||
1479 | struct ucc_fast_private *uccf; | ||
1480 | u32 cecr_subblock; | ||
1481 | |||
1482 | uccf = ugeth->uccf; | ||
1483 | |||
1484 | cecr_subblock = | ||
1485 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); | ||
1486 | qe_issue_cmd(QE_RESTART_TX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0); | ||
1487 | uccf->stopped_tx = 0; | ||
1488 | |||
1489 | return 0; | ||
1490 | } | ||
1491 | |||
1492 | static int ugeth_restart_rx(struct ucc_geth_private *ugeth) | ||
1493 | { | ||
1494 | struct ucc_fast_private *uccf; | ||
1495 | u32 cecr_subblock; | ||
1496 | |||
1497 | uccf = ugeth->uccf; | ||
1498 | |||
1499 | cecr_subblock = | ||
1500 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); | ||
1501 | qe_issue_cmd(QE_RESTART_RX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, | ||
1502 | 0); | ||
1503 | uccf->stopped_rx = 0; | ||
1504 | |||
1505 | return 0; | ||
1506 | } | ||
1507 | |||
1508 | static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode) | ||
1509 | { | ||
1510 | struct ucc_fast_private *uccf; | ||
1511 | int enabled_tx, enabled_rx; | ||
1512 | |||
1513 | uccf = ugeth->uccf; | ||
1514 | |||
1515 | /* check if the UCC number is in range. */ | ||
1516 | if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) { | ||
1517 | if (netif_msg_probe(ugeth)) | ||
1518 | ugeth_err("%s: ucc_num out of range.", __func__); | ||
1519 | return -EINVAL; | ||
1520 | } | ||
1521 | |||
1522 | enabled_tx = uccf->enabled_tx; | ||
1523 | enabled_rx = uccf->enabled_rx; | ||
1524 | |||
1525 | /* Get Tx and Rx going again, in case this channel was actively | ||
1526 | disabled. */ | ||
1527 | if ((mode & COMM_DIR_TX) && (!enabled_tx) && uccf->stopped_tx) | ||
1528 | ugeth_restart_tx(ugeth); | ||
1529 | if ((mode & COMM_DIR_RX) && (!enabled_rx) && uccf->stopped_rx) | ||
1530 | ugeth_restart_rx(ugeth); | ||
1531 | |||
1532 | ucc_fast_enable(uccf, mode); /* OK to do even if not disabled */ | ||
1533 | |||
1534 | return 0; | ||
1535 | |||
1536 | } | ||
1537 | |||
1538 | static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode) | ||
1539 | { | ||
1540 | struct ucc_fast_private *uccf; | ||
1541 | |||
1542 | uccf = ugeth->uccf; | ||
1543 | |||
1544 | /* check if the UCC number is in range. */ | ||
1545 | if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) { | ||
1546 | if (netif_msg_probe(ugeth)) | ||
1547 | ugeth_err("%s: ucc_num out of range.", __func__); | ||
1548 | return -EINVAL; | ||
1549 | } | ||
1550 | |||
1551 | /* Stop any transmissions */ | ||
1552 | if ((mode & COMM_DIR_TX) && uccf->enabled_tx && !uccf->stopped_tx) | ||
1553 | ugeth_graceful_stop_tx(ugeth); | ||
1554 | |||
1555 | /* Stop any receptions */ | ||
1556 | if ((mode & COMM_DIR_RX) && uccf->enabled_rx && !uccf->stopped_rx) | ||
1557 | ugeth_graceful_stop_rx(ugeth); | ||
1558 | |||
1559 | ucc_fast_disable(ugeth->uccf, mode); /* OK to do even if not enabled */ | ||
1560 | |||
1561 | return 0; | ||
1562 | } | ||
1563 | |||
1564 | static void ugeth_quiesce(struct ucc_geth_private *ugeth) | ||
1565 | { | ||
1566 | /* Wait for and prevent any further xmits. */ | ||
1567 | netif_tx_disable(ugeth->ndev); | ||
1568 | |||
1569 | /* Disable the interrupt to avoid NAPI rescheduling. */ | ||
1570 | disable_irq(ugeth->ug_info->uf_info.irq); | ||
1571 | |||
1572 | /* Stop NAPI, and possibly wait for its completion. */ | ||
1573 | napi_disable(&ugeth->napi); | ||
1574 | } | ||
1575 | |||
1576 | static void ugeth_activate(struct ucc_geth_private *ugeth) | ||
1577 | { | ||
1578 | napi_enable(&ugeth->napi); | ||
1579 | enable_irq(ugeth->ug_info->uf_info.irq); | ||
1580 | netif_tx_wake_all_queues(ugeth->ndev); | ||
1581 | } | ||
1582 | |||
1446 | /* Called every time the controller might need to be made | 1583 | /* Called every time the controller might need to be made |
1447 | * aware of new link state. The PHY code conveys this | 1584 | * aware of new link state. The PHY code conveys this |
1448 | * information through variables in the ugeth structure, and this | 1585 | * information through variables in the ugeth structure, and this |
@@ -1456,14 +1593,11 @@ static void adjust_link(struct net_device *dev) | |||
1456 | struct ucc_geth __iomem *ug_regs; | 1593 | struct ucc_geth __iomem *ug_regs; |
1457 | struct ucc_fast __iomem *uf_regs; | 1594 | struct ucc_fast __iomem *uf_regs; |
1458 | struct phy_device *phydev = ugeth->phydev; | 1595 | struct phy_device *phydev = ugeth->phydev; |
1459 | unsigned long flags; | ||
1460 | int new_state = 0; | 1596 | int new_state = 0; |
1461 | 1597 | ||
1462 | ug_regs = ugeth->ug_regs; | 1598 | ug_regs = ugeth->ug_regs; |
1463 | uf_regs = ugeth->uccf->uf_regs; | 1599 | uf_regs = ugeth->uccf->uf_regs; |
1464 | 1600 | ||
1465 | spin_lock_irqsave(&ugeth->lock, flags); | ||
1466 | |||
1467 | if (phydev->link) { | 1601 | if (phydev->link) { |
1468 | u32 tempval = in_be32(&ug_regs->maccfg2); | 1602 | u32 tempval = in_be32(&ug_regs->maccfg2); |
1469 | u32 upsmr = in_be32(&uf_regs->upsmr); | 1603 | u32 upsmr = in_be32(&uf_regs->upsmr); |
@@ -1514,9 +1648,21 @@ static void adjust_link(struct net_device *dev) | |||
1514 | ugeth->oldspeed = phydev->speed; | 1648 | ugeth->oldspeed = phydev->speed; |
1515 | } | 1649 | } |
1516 | 1650 | ||
1651 | /* | ||
1652 | * To change the MAC configuration we need to disable the | ||
1653 | * controller. To do so, we have to either grab ugeth->lock, | ||
1654 | * which is a bad idea since 'graceful stop' commands might | ||
1655 | * take quite a while, or we can quiesce driver's activity. | ||
1656 | */ | ||
1657 | ugeth_quiesce(ugeth); | ||
1658 | ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); | ||
1659 | |||
1517 | out_be32(&ug_regs->maccfg2, tempval); | 1660 | out_be32(&ug_regs->maccfg2, tempval); |
1518 | out_be32(&uf_regs->upsmr, upsmr); | 1661 | out_be32(&uf_regs->upsmr, upsmr); |
1519 | 1662 | ||
1663 | ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); | ||
1664 | ugeth_activate(ugeth); | ||
1665 | |||
1520 | if (!ugeth->oldlink) { | 1666 | if (!ugeth->oldlink) { |
1521 | new_state = 1; | 1667 | new_state = 1; |
1522 | ugeth->oldlink = 1; | 1668 | ugeth->oldlink = 1; |
@@ -1530,8 +1676,6 @@ static void adjust_link(struct net_device *dev) | |||
1530 | 1676 | ||
1531 | if (new_state && netif_msg_link(ugeth)) | 1677 | if (new_state && netif_msg_link(ugeth)) |
1532 | phy_print_status(phydev); | 1678 | phy_print_status(phydev); |
1533 | |||
1534 | spin_unlock_irqrestore(&ugeth->lock, flags); | ||
1535 | } | 1679 | } |
1536 | 1680 | ||
1537 | /* Initialize TBI PHY interface for communicating with the | 1681 | /* Initialize TBI PHY interface for communicating with the |
@@ -1618,157 +1762,6 @@ static int init_phy(struct net_device *dev) | |||
1618 | return 0; | 1762 | return 0; |
1619 | } | 1763 | } |
1620 | 1764 | ||
1621 | |||
1622 | |||
1623 | static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) | ||
1624 | { | ||
1625 | struct ucc_fast_private *uccf; | ||
1626 | u32 cecr_subblock; | ||
1627 | u32 temp; | ||
1628 | int i = 10; | ||
1629 | |||
1630 | uccf = ugeth->uccf; | ||
1631 | |||
1632 | /* Mask GRACEFUL STOP TX interrupt bit and clear it */ | ||
1633 | clrbits32(uccf->p_uccm, UCC_GETH_UCCE_GRA); | ||
1634 | out_be32(uccf->p_ucce, UCC_GETH_UCCE_GRA); /* clear by writing 1 */ | ||
1635 | |||
1636 | /* Issue host command */ | ||
1637 | cecr_subblock = | ||
1638 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); | ||
1639 | qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock, | ||
1640 | QE_CR_PROTOCOL_ETHERNET, 0); | ||
1641 | |||
1642 | /* Wait for command to complete */ | ||
1643 | do { | ||
1644 | msleep(10); | ||
1645 | temp = in_be32(uccf->p_ucce); | ||
1646 | } while (!(temp & UCC_GETH_UCCE_GRA) && --i); | ||
1647 | |||
1648 | uccf->stopped_tx = 1; | ||
1649 | |||
1650 | return 0; | ||
1651 | } | ||
1652 | |||
1653 | static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth) | ||
1654 | { | ||
1655 | struct ucc_fast_private *uccf; | ||
1656 | u32 cecr_subblock; | ||
1657 | u8 temp; | ||
1658 | int i = 10; | ||
1659 | |||
1660 | uccf = ugeth->uccf; | ||
1661 | |||
1662 | /* Clear acknowledge bit */ | ||
1663 | temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack); | ||
1664 | temp &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX; | ||
1665 | out_8(&ugeth->p_rx_glbl_pram->rxgstpack, temp); | ||
1666 | |||
1667 | /* Keep issuing command and checking acknowledge bit until | ||
1668 | it is asserted, according to spec */ | ||
1669 | do { | ||
1670 | /* Issue host command */ | ||
1671 | cecr_subblock = | ||
1672 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info. | ||
1673 | ucc_num); | ||
1674 | qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock, | ||
1675 | QE_CR_PROTOCOL_ETHERNET, 0); | ||
1676 | msleep(10); | ||
1677 | temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack); | ||
1678 | } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX) && --i); | ||
1679 | |||
1680 | uccf->stopped_rx = 1; | ||
1681 | |||
1682 | return 0; | ||
1683 | } | ||
1684 | |||
1685 | static int ugeth_restart_tx(struct ucc_geth_private *ugeth) | ||
1686 | { | ||
1687 | struct ucc_fast_private *uccf; | ||
1688 | u32 cecr_subblock; | ||
1689 | |||
1690 | uccf = ugeth->uccf; | ||
1691 | |||
1692 | cecr_subblock = | ||
1693 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); | ||
1694 | qe_issue_cmd(QE_RESTART_TX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0); | ||
1695 | uccf->stopped_tx = 0; | ||
1696 | |||
1697 | return 0; | ||
1698 | } | ||
1699 | |||
1700 | static int ugeth_restart_rx(struct ucc_geth_private *ugeth) | ||
1701 | { | ||
1702 | struct ucc_fast_private *uccf; | ||
1703 | u32 cecr_subblock; | ||
1704 | |||
1705 | uccf = ugeth->uccf; | ||
1706 | |||
1707 | cecr_subblock = | ||
1708 | ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num); | ||
1709 | qe_issue_cmd(QE_RESTART_RX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, | ||
1710 | 0); | ||
1711 | uccf->stopped_rx = 0; | ||
1712 | |||
1713 | return 0; | ||
1714 | } | ||
1715 | |||
1716 | static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode) | ||
1717 | { | ||
1718 | struct ucc_fast_private *uccf; | ||
1719 | int enabled_tx, enabled_rx; | ||
1720 | |||
1721 | uccf = ugeth->uccf; | ||
1722 | |||
1723 | /* check if the UCC number is in range. */ | ||
1724 | if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) { | ||
1725 | if (netif_msg_probe(ugeth)) | ||
1726 | ugeth_err("%s: ucc_num out of range.", __func__); | ||
1727 | return -EINVAL; | ||
1728 | } | ||
1729 | |||
1730 | enabled_tx = uccf->enabled_tx; | ||
1731 | enabled_rx = uccf->enabled_rx; | ||
1732 | |||
1733 | /* Get Tx and Rx going again, in case this channel was actively | ||
1734 | disabled. */ | ||
1735 | if ((mode & COMM_DIR_TX) && (!enabled_tx) && uccf->stopped_tx) | ||
1736 | ugeth_restart_tx(ugeth); | ||
1737 | if ((mode & COMM_DIR_RX) && (!enabled_rx) && uccf->stopped_rx) | ||
1738 | ugeth_restart_rx(ugeth); | ||
1739 | |||
1740 | ucc_fast_enable(uccf, mode); /* OK to do even if not disabled */ | ||
1741 | |||
1742 | return 0; | ||
1743 | |||
1744 | } | ||
1745 | |||
1746 | static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode) | ||
1747 | { | ||
1748 | struct ucc_fast_private *uccf; | ||
1749 | |||
1750 | uccf = ugeth->uccf; | ||
1751 | |||
1752 | /* check if the UCC number is in range. */ | ||
1753 | if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) { | ||
1754 | if (netif_msg_probe(ugeth)) | ||
1755 | ugeth_err("%s: ucc_num out of range.", __func__); | ||
1756 | return -EINVAL; | ||
1757 | } | ||
1758 | |||
1759 | /* Stop any transmissions */ | ||
1760 | if ((mode & COMM_DIR_TX) && uccf->enabled_tx && !uccf->stopped_tx) | ||
1761 | ugeth_graceful_stop_tx(ugeth); | ||
1762 | |||
1763 | /* Stop any receptions */ | ||
1764 | if ((mode & COMM_DIR_RX) && uccf->enabled_rx && !uccf->stopped_rx) | ||
1765 | ugeth_graceful_stop_rx(ugeth); | ||
1766 | |||
1767 | ucc_fast_disable(ugeth->uccf, mode); /* OK to do even if not enabled */ | ||
1768 | |||
1769 | return 0; | ||
1770 | } | ||
1771 | |||
1772 | static void ugeth_dump_regs(struct ucc_geth_private *ugeth) | 1765 | static void ugeth_dump_regs(struct ucc_geth_private *ugeth) |
1773 | { | 1766 | { |
1774 | #ifdef DEBUG | 1767 | #ifdef DEBUG |
@@ -1986,6 +1979,8 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth) | |||
1986 | iounmap(ugeth->ug_regs); | 1979 | iounmap(ugeth->ug_regs); |
1987 | ugeth->ug_regs = NULL; | 1980 | ugeth->ug_regs = NULL; |
1988 | } | 1981 | } |
1982 | |||
1983 | skb_queue_purge(&ugeth->rx_recycle); | ||
1989 | } | 1984 | } |
1990 | 1985 | ||
1991 | static void ucc_geth_set_multi(struct net_device *dev) | 1986 | static void ucc_geth_set_multi(struct net_device *dev) |
@@ -2202,6 +2197,8 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) | |||
2202 | return -ENOMEM; | 2197 | return -ENOMEM; |
2203 | } | 2198 | } |
2204 | 2199 | ||
2200 | skb_queue_head_init(&ugeth->rx_recycle); | ||
2201 | |||
2205 | return 0; | 2202 | return 0; |
2206 | } | 2203 | } |
2207 | 2204 | ||
@@ -3174,7 +3171,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3174 | #endif | 3171 | #endif |
3175 | spin_unlock_irqrestore(&ugeth->lock, flags); | 3172 | spin_unlock_irqrestore(&ugeth->lock, flags); |
3176 | 3173 | ||
3177 | return 0; | 3174 | return NETDEV_TX_OK; |
3178 | } | 3175 | } |
3179 | 3176 | ||
3180 | static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit) | 3177 | static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit) |
@@ -3209,8 +3206,10 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit | |||
3209 | if (netif_msg_rx_err(ugeth)) | 3206 | if (netif_msg_rx_err(ugeth)) |
3210 | ugeth_err("%s, %d: ERROR!!! skb - 0x%08x", | 3207 | ugeth_err("%s, %d: ERROR!!! skb - 0x%08x", |
3211 | __func__, __LINE__, (u32) skb); | 3208 | __func__, __LINE__, (u32) skb); |
3212 | if (skb) | 3209 | if (skb) { |
3213 | dev_kfree_skb_any(skb); | 3210 | skb->data = skb->head + NET_SKB_PAD; |
3211 | __skb_queue_head(&ugeth->rx_recycle, skb); | ||
3212 | } | ||
3214 | 3213 | ||
3215 | ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL; | 3214 | ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL; |
3216 | dev->stats.rx_dropped++; | 3215 | dev->stats.rx_dropped++; |
@@ -3268,6 +3267,8 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
3268 | 3267 | ||
3269 | /* Normal processing. */ | 3268 | /* Normal processing. */ |
3270 | while ((bd_status & T_R) == 0) { | 3269 | while ((bd_status & T_R) == 0) { |
3270 | struct sk_buff *skb; | ||
3271 | |||
3271 | /* BD contains already transmitted buffer. */ | 3272 | /* BD contains already transmitted buffer. */ |
3272 | /* Handle the transmitted buffer and release */ | 3273 | /* Handle the transmitted buffer and release */ |
3273 | /* the BD to be used with the current frame */ | 3274 | /* the BD to be used with the current frame */ |
@@ -3277,9 +3278,16 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) | |||
3277 | 3278 | ||
3278 | dev->stats.tx_packets++; | 3279 | dev->stats.tx_packets++; |
3279 | 3280 | ||
3280 | /* Free the sk buffer associated with this TxBD */ | 3281 | skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; |
3281 | dev_kfree_skb(ugeth-> | 3282 | |
3282 | tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]); | 3283 | if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN && |
3284 | skb_recycle_check(skb, | ||
3285 | ugeth->ug_info->uf_info.max_rx_buf_length + | ||
3286 | UCC_GETH_RX_DATA_BUF_ALIGNMENT)) | ||
3287 | __skb_queue_head(&ugeth->rx_recycle, skb); | ||
3288 | else | ||
3289 | dev_kfree_skb(skb); | ||
3290 | |||
3283 | ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL; | 3291 | ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL; |
3284 | ugeth->skb_dirtytx[txQ] = | 3292 | ugeth->skb_dirtytx[txQ] = |
3285 | (ugeth->skb_dirtytx[txQ] + | 3293 | (ugeth->skb_dirtytx[txQ] + |
@@ -3308,16 +3316,16 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget) | |||
3308 | 3316 | ||
3309 | ug_info = ugeth->ug_info; | 3317 | ug_info = ugeth->ug_info; |
3310 | 3318 | ||
3311 | howmany = 0; | ||
3312 | for (i = 0; i < ug_info->numQueuesRx; i++) | ||
3313 | howmany += ucc_geth_rx(ugeth, i, budget - howmany); | ||
3314 | |||
3315 | /* Tx event processing */ | 3319 | /* Tx event processing */ |
3316 | spin_lock(&ugeth->lock); | 3320 | spin_lock(&ugeth->lock); |
3317 | for (i = 0; i < ug_info->numQueuesTx; i++) | 3321 | for (i = 0; i < ug_info->numQueuesTx; i++) |
3318 | ucc_geth_tx(ugeth->ndev, i); | 3322 | ucc_geth_tx(ugeth->ndev, i); |
3319 | spin_unlock(&ugeth->lock); | 3323 | spin_unlock(&ugeth->lock); |
3320 | 3324 | ||
3325 | howmany = 0; | ||
3326 | for (i = 0; i < ug_info->numQueuesRx; i++) | ||
3327 | howmany += ucc_geth_rx(ugeth, i, budget - howmany); | ||
3328 | |||
3321 | if (howmany < budget) { | 3329 | if (howmany < budget) { |
3322 | napi_complete(napi); | 3330 | napi_complete(napi); |
3323 | setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS | UCCE_TX_EVENTS); | 3331 | setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS | UCCE_TX_EVENTS); |
@@ -3414,46 +3422,25 @@ static int ucc_geth_set_mac_addr(struct net_device *dev, void *p) | |||
3414 | return 0; | 3422 | return 0; |
3415 | } | 3423 | } |
3416 | 3424 | ||
3417 | /* Called when something needs to use the ethernet device */ | 3425 | static int ucc_geth_init_mac(struct ucc_geth_private *ugeth) |
3418 | /* Returns 0 for success. */ | ||
3419 | static int ucc_geth_open(struct net_device *dev) | ||
3420 | { | 3426 | { |
3421 | struct ucc_geth_private *ugeth = netdev_priv(dev); | 3427 | struct net_device *dev = ugeth->ndev; |
3422 | int err; | 3428 | int err; |
3423 | 3429 | ||
3424 | ugeth_vdbg("%s: IN", __func__); | ||
3425 | |||
3426 | /* Test station address */ | ||
3427 | if (dev->dev_addr[0] & ENET_GROUP_ADDR) { | ||
3428 | if (netif_msg_ifup(ugeth)) | ||
3429 | ugeth_err("%s: Multicast address used for station address" | ||
3430 | " - is this what you wanted?", __func__); | ||
3431 | return -EINVAL; | ||
3432 | } | ||
3433 | |||
3434 | err = init_phy(dev); | ||
3435 | if (err) { | ||
3436 | if (netif_msg_ifup(ugeth)) | ||
3437 | ugeth_err("%s: Cannot initialize PHY, aborting.", | ||
3438 | dev->name); | ||
3439 | return err; | ||
3440 | } | ||
3441 | |||
3442 | err = ucc_struct_init(ugeth); | 3430 | err = ucc_struct_init(ugeth); |
3443 | if (err) { | 3431 | if (err) { |
3444 | if (netif_msg_ifup(ugeth)) | 3432 | if (netif_msg_ifup(ugeth)) |
3445 | ugeth_err("%s: Cannot configure internal struct, aborting.", dev->name); | 3433 | ugeth_err("%s: Cannot configure internal struct, " |
3446 | goto out_err_stop; | 3434 | "aborting.", dev->name); |
3435 | goto err; | ||
3447 | } | 3436 | } |
3448 | 3437 | ||
3449 | napi_enable(&ugeth->napi); | ||
3450 | |||
3451 | err = ucc_geth_startup(ugeth); | 3438 | err = ucc_geth_startup(ugeth); |
3452 | if (err) { | 3439 | if (err) { |
3453 | if (netif_msg_ifup(ugeth)) | 3440 | if (netif_msg_ifup(ugeth)) |
3454 | ugeth_err("%s: Cannot configure net device, aborting.", | 3441 | ugeth_err("%s: Cannot configure net device, aborting.", |
3455 | dev->name); | 3442 | dev->name); |
3456 | goto out_err; | 3443 | goto err; |
3457 | } | 3444 | } |
3458 | 3445 | ||
3459 | err = adjust_enet_interface(ugeth); | 3446 | err = adjust_enet_interface(ugeth); |
@@ -3461,7 +3448,7 @@ static int ucc_geth_open(struct net_device *dev) | |||
3461 | if (netif_msg_ifup(ugeth)) | 3448 | if (netif_msg_ifup(ugeth)) |
3462 | ugeth_err("%s: Cannot configure net device, aborting.", | 3449 | ugeth_err("%s: Cannot configure net device, aborting.", |
3463 | dev->name); | 3450 | dev->name); |
3464 | goto out_err; | 3451 | goto err; |
3465 | } | 3452 | } |
3466 | 3453 | ||
3467 | /* Set MACSTNADDR1, MACSTNADDR2 */ | 3454 | /* Set MACSTNADDR1, MACSTNADDR2 */ |
@@ -3475,13 +3462,51 @@ static int ucc_geth_open(struct net_device *dev) | |||
3475 | &ugeth->ug_regs->macstnaddr1, | 3462 | &ugeth->ug_regs->macstnaddr1, |
3476 | &ugeth->ug_regs->macstnaddr2); | 3463 | &ugeth->ug_regs->macstnaddr2); |
3477 | 3464 | ||
3478 | phy_start(ugeth->phydev); | ||
3479 | |||
3480 | err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); | 3465 | err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); |
3481 | if (err) { | 3466 | if (err) { |
3482 | if (netif_msg_ifup(ugeth)) | 3467 | if (netif_msg_ifup(ugeth)) |
3483 | ugeth_err("%s: Cannot enable net device, aborting.", dev->name); | 3468 | ugeth_err("%s: Cannot enable net device, aborting.", dev->name); |
3484 | goto out_err; | 3469 | goto err; |
3470 | } | ||
3471 | |||
3472 | return 0; | ||
3473 | err: | ||
3474 | ucc_geth_stop(ugeth); | ||
3475 | return err; | ||
3476 | } | ||
3477 | |||
3478 | /* Called when something needs to use the ethernet device */ | ||
3479 | /* Returns 0 for success. */ | ||
3480 | static int ucc_geth_open(struct net_device *dev) | ||
3481 | { | ||
3482 | struct ucc_geth_private *ugeth = netdev_priv(dev); | ||
3483 | int err; | ||
3484 | |||
3485 | ugeth_vdbg("%s: IN", __func__); | ||
3486 | |||
3487 | /* Test station address */ | ||
3488 | if (dev->dev_addr[0] & ENET_GROUP_ADDR) { | ||
3489 | if (netif_msg_ifup(ugeth)) | ||
3490 | ugeth_err("%s: Multicast address used for station " | ||
3491 | "address - is this what you wanted?", | ||
3492 | __func__); | ||
3493 | return -EINVAL; | ||
3494 | } | ||
3495 | |||
3496 | err = init_phy(dev); | ||
3497 | if (err) { | ||
3498 | if (netif_msg_ifup(ugeth)) | ||
3499 | ugeth_err("%s: Cannot initialize PHY, aborting.", | ||
3500 | dev->name); | ||
3501 | return err; | ||
3502 | } | ||
3503 | |||
3504 | err = ucc_geth_init_mac(ugeth); | ||
3505 | if (err) { | ||
3506 | if (netif_msg_ifup(ugeth)) | ||
3507 | ugeth_err("%s: Cannot initialize MAC, aborting.", | ||
3508 | dev->name); | ||
3509 | goto err; | ||
3485 | } | 3510 | } |
3486 | 3511 | ||
3487 | err = request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler, | 3512 | err = request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler, |
@@ -3490,16 +3515,20 @@ static int ucc_geth_open(struct net_device *dev) | |||
3490 | if (netif_msg_ifup(ugeth)) | 3515 | if (netif_msg_ifup(ugeth)) |
3491 | ugeth_err("%s: Cannot get IRQ for net device, aborting.", | 3516 | ugeth_err("%s: Cannot get IRQ for net device, aborting.", |
3492 | dev->name); | 3517 | dev->name); |
3493 | goto out_err; | 3518 | goto err; |
3494 | } | 3519 | } |
3495 | 3520 | ||
3521 | phy_start(ugeth->phydev); | ||
3522 | napi_enable(&ugeth->napi); | ||
3496 | netif_start_queue(dev); | 3523 | netif_start_queue(dev); |
3497 | 3524 | ||
3525 | device_set_wakeup_capable(&dev->dev, | ||
3526 | qe_alive_during_sleep() || ugeth->phydev->irq); | ||
3527 | device_set_wakeup_enable(&dev->dev, ugeth->wol_en); | ||
3528 | |||
3498 | return err; | 3529 | return err; |
3499 | 3530 | ||
3500 | out_err: | 3531 | err: |
3501 | napi_disable(&ugeth->napi); | ||
3502 | out_err_stop: | ||
3503 | ucc_geth_stop(ugeth); | 3532 | ucc_geth_stop(ugeth); |
3504 | return err; | 3533 | return err; |
3505 | } | 3534 | } |
@@ -3561,6 +3590,85 @@ static void ucc_geth_timeout(struct net_device *dev) | |||
3561 | schedule_work(&ugeth->timeout_work); | 3590 | schedule_work(&ugeth->timeout_work); |
3562 | } | 3591 | } |
3563 | 3592 | ||
3593 | |||
3594 | #ifdef CONFIG_PM | ||
3595 | |||
3596 | static int ucc_geth_suspend(struct of_device *ofdev, pm_message_t state) | ||
3597 | { | ||
3598 | struct net_device *ndev = dev_get_drvdata(&ofdev->dev); | ||
3599 | struct ucc_geth_private *ugeth = netdev_priv(ndev); | ||
3600 | |||
3601 | if (!netif_running(ndev)) | ||
3602 | return 0; | ||
3603 | |||
3604 | napi_disable(&ugeth->napi); | ||
3605 | |||
3606 | /* | ||
3607 | * Disable the controller, otherwise we'll wakeup on any network | ||
3608 | * activity. | ||
3609 | */ | ||
3610 | ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); | ||
3611 | |||
3612 | if (ugeth->wol_en & WAKE_MAGIC) { | ||
3613 | setbits32(ugeth->uccf->p_uccm, UCC_GETH_UCCE_MPD); | ||
3614 | setbits32(&ugeth->ug_regs->maccfg2, MACCFG2_MPE); | ||
3615 | ucc_fast_enable(ugeth->uccf, COMM_DIR_RX_AND_TX); | ||
3616 | } else if (!(ugeth->wol_en & WAKE_PHY)) { | ||
3617 | phy_stop(ugeth->phydev); | ||
3618 | } | ||
3619 | |||
3620 | return 0; | ||
3621 | } | ||
3622 | |||
3623 | static int ucc_geth_resume(struct of_device *ofdev) | ||
3624 | { | ||
3625 | struct net_device *ndev = dev_get_drvdata(&ofdev->dev); | ||
3626 | struct ucc_geth_private *ugeth = netdev_priv(ndev); | ||
3627 | int err; | ||
3628 | |||
3629 | if (!netif_running(ndev)) | ||
3630 | return 0; | ||
3631 | |||
3632 | if (qe_alive_during_sleep()) { | ||
3633 | if (ugeth->wol_en & WAKE_MAGIC) { | ||
3634 | ucc_fast_disable(ugeth->uccf, COMM_DIR_RX_AND_TX); | ||
3635 | clrbits32(&ugeth->ug_regs->maccfg2, MACCFG2_MPE); | ||
3636 | clrbits32(ugeth->uccf->p_uccm, UCC_GETH_UCCE_MPD); | ||
3637 | } | ||
3638 | ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); | ||
3639 | } else { | ||
3640 | /* | ||
3641 | * Full reinitialization is required if QE shuts down | ||
3642 | * during sleep. | ||
3643 | */ | ||
3644 | ucc_geth_memclean(ugeth); | ||
3645 | |||
3646 | err = ucc_geth_init_mac(ugeth); | ||
3647 | if (err) { | ||
3648 | ugeth_err("%s: Cannot initialize MAC, aborting.", | ||
3649 | ndev->name); | ||
3650 | return err; | ||
3651 | } | ||
3652 | } | ||
3653 | |||
3654 | ugeth->oldlink = 0; | ||
3655 | ugeth->oldspeed = 0; | ||
3656 | ugeth->oldduplex = -1; | ||
3657 | |||
3658 | phy_stop(ugeth->phydev); | ||
3659 | phy_start(ugeth->phydev); | ||
3660 | |||
3661 | napi_enable(&ugeth->napi); | ||
3662 | netif_start_queue(ndev); | ||
3663 | |||
3664 | return 0; | ||
3665 | } | ||
3666 | |||
3667 | #else | ||
3668 | #define ucc_geth_suspend NULL | ||
3669 | #define ucc_geth_resume NULL | ||
3670 | #endif | ||
3671 | |||
3564 | static phy_interface_t to_phy_interface(const char *phy_connection_type) | 3672 | static phy_interface_t to_phy_interface(const char *phy_connection_type) |
3565 | { | 3673 | { |
3566 | if (strcasecmp(phy_connection_type, "mii") == 0) | 3674 | if (strcasecmp(phy_connection_type, "mii") == 0) |
@@ -3852,6 +3960,8 @@ static struct of_platform_driver ucc_geth_driver = { | |||
3852 | .match_table = ucc_geth_match, | 3960 | .match_table = ucc_geth_match, |
3853 | .probe = ucc_geth_probe, | 3961 | .probe = ucc_geth_probe, |
3854 | .remove = ucc_geth_remove, | 3962 | .remove = ucc_geth_remove, |
3963 | .suspend = ucc_geth_suspend, | ||
3964 | .resume = ucc_geth_resume, | ||
3855 | }; | 3965 | }; |
3856 | 3966 | ||
3857 | static int __init ucc_geth_init(void) | 3967 | static int __init ucc_geth_init(void) |