.. | .. |
---|
75 | 75 | |
---|
76 | 76 | #define DRIVER_NAME "fec" |
---|
77 | 77 | |
---|
78 | | -#define FEC_ENET_GET_QUQUE(_x) ((_x == 0) ? 1 : ((_x == 1) ? 2 : 0)) |
---|
| 78 | +static const u16 fec_enet_vlan_pri_to_queue[8] = {0, 0, 1, 1, 1, 2, 2, 2}; |
---|
79 | 79 | |
---|
80 | 80 | /* Pause frame feild and FIFO threshold */ |
---|
81 | 81 | #define FEC_ENET_FCE (1 << 5) |
---|
.. | .. |
---|
88 | 88 | |
---|
89 | 89 | struct fec_devinfo { |
---|
90 | 90 | u32 quirks; |
---|
91 | | - u8 stop_gpr_reg; |
---|
92 | | - u8 stop_gpr_bit; |
---|
93 | 91 | }; |
---|
94 | 92 | |
---|
95 | 93 | static const struct fec_devinfo fec_imx25_info = { |
---|
.. | .. |
---|
104 | 102 | static const struct fec_devinfo fec_imx28_info = { |
---|
105 | 103 | .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME | |
---|
106 | 104 | FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC | |
---|
107 | | - FEC_QUIRK_HAS_FRREG, |
---|
| 105 | + FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII, |
---|
108 | 106 | }; |
---|
109 | 107 | |
---|
110 | 108 | static const struct fec_devinfo fec_imx6q_info = { |
---|
111 | 109 | .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | |
---|
112 | 110 | FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM | |
---|
113 | 111 | FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 | |
---|
114 | | - FEC_QUIRK_HAS_RACC, |
---|
115 | | - .stop_gpr_reg = 0x34, |
---|
116 | | - .stop_gpr_bit = 27, |
---|
| 112 | + FEC_QUIRK_HAS_RACC | FEC_QUIRK_CLEAR_SETUP_MII, |
---|
117 | 113 | }; |
---|
118 | 114 | |
---|
119 | 115 | static const struct fec_devinfo fec_mvf600_info = { |
---|
.. | .. |
---|
125 | 121 | FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM | |
---|
126 | 122 | FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB | |
---|
127 | 123 | FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE | |
---|
128 | | - FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE, |
---|
| 124 | + FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE | |
---|
| 125 | + FEC_QUIRK_CLEAR_SETUP_MII, |
---|
129 | 126 | }; |
---|
130 | 127 | |
---|
131 | 128 | static const struct fec_devinfo fec_imx6ul_info = { |
---|
.. | .. |
---|
133 | 130 | FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM | |
---|
134 | 131 | FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR007885 | |
---|
135 | 132 | FEC_QUIRK_BUG_CAPTURE | FEC_QUIRK_HAS_RACC | |
---|
136 | | - FEC_QUIRK_HAS_COALESCE, |
---|
| 133 | + FEC_QUIRK_HAS_COALESCE | FEC_QUIRK_CLEAR_SETUP_MII, |
---|
137 | 134 | }; |
---|
138 | 135 | |
---|
139 | 136 | static struct platform_device_id fec_devtype[] = { |
---|
.. | .. |
---|
246 | 243 | |
---|
247 | 244 | /* FEC MII MMFR bits definition */ |
---|
248 | 245 | #define FEC_MMFR_ST (1 << 30) |
---|
| 246 | +#define FEC_MMFR_ST_C45 (0) |
---|
249 | 247 | #define FEC_MMFR_OP_READ (2 << 28) |
---|
| 248 | +#define FEC_MMFR_OP_READ_C45 (3 << 28) |
---|
250 | 249 | #define FEC_MMFR_OP_WRITE (1 << 28) |
---|
| 250 | +#define FEC_MMFR_OP_ADDR_WRITE (0) |
---|
251 | 251 | #define FEC_MMFR_PA(v) ((v & 0x1f) << 23) |
---|
252 | 252 | #define FEC_MMFR_RA(v) ((v & 0x1f) << 18) |
---|
253 | 253 | #define FEC_MMFR_TA (2 << 16) |
---|
.. | .. |
---|
403 | 403 | status = fec16_to_cpu(bdp->cbd_sc); |
---|
404 | 404 | status &= ~BD_ENET_TX_STATS; |
---|
405 | 405 | status |= (BD_ENET_TX_TC | BD_ENET_TX_READY); |
---|
406 | | - frag_len = skb_shinfo(skb)->frags[frag].size; |
---|
| 406 | + frag_len = skb_frag_size(&skb_shinfo(skb)->frags[frag]); |
---|
407 | 407 | |
---|
408 | 408 | /* Handle the last BD specially */ |
---|
409 | 409 | if (frag == nr_frags - 1) { |
---|
.. | .. |
---|
425 | 425 | ebdp->cbd_esc = cpu_to_fec32(estatus); |
---|
426 | 426 | } |
---|
427 | 427 | |
---|
428 | | - bufaddr = page_address(this_frag->page.p) + this_frag->page_offset; |
---|
| 428 | + bufaddr = skb_frag_address(this_frag); |
---|
429 | 429 | |
---|
430 | 430 | index = fec_enet_get_bd_index(bdp, &txq->bd); |
---|
431 | 431 | if (((unsigned long) bufaddr) & fep->tx_align || |
---|
.. | .. |
---|
623 | 623 | dev_kfree_skb_any(skb); |
---|
624 | 624 | if (net_ratelimit()) |
---|
625 | 625 | netdev_err(ndev, "Tx DMA memory map failed\n"); |
---|
626 | | - return NETDEV_TX_BUSY; |
---|
| 626 | + return NETDEV_TX_OK; |
---|
627 | 627 | } |
---|
628 | 628 | |
---|
629 | 629 | bdp->cbd_datlen = cpu_to_fec16(size); |
---|
.. | .. |
---|
685 | 685 | dev_kfree_skb_any(skb); |
---|
686 | 686 | if (net_ratelimit()) |
---|
687 | 687 | netdev_err(ndev, "Tx DMA memory map failed\n"); |
---|
688 | | - return NETDEV_TX_BUSY; |
---|
| 688 | + return NETDEV_TX_OK; |
---|
689 | 689 | } |
---|
690 | 690 | } |
---|
691 | 691 | |
---|
.. | .. |
---|
711 | 711 | struct net_device *ndev) |
---|
712 | 712 | { |
---|
713 | 713 | struct fec_enet_private *fep = netdev_priv(ndev); |
---|
714 | | - int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); |
---|
715 | | - int total_len, data_left; |
---|
| 714 | + int hdr_len, total_len, data_left; |
---|
716 | 715 | struct bufdesc *bdp = txq->bd.cur; |
---|
717 | 716 | struct tso_t tso; |
---|
718 | 717 | unsigned int index = 0; |
---|
.. | .. |
---|
732 | 731 | } |
---|
733 | 732 | |
---|
734 | 733 | /* Initialize the TSO handler, and prepare the first payload */ |
---|
735 | | - tso_start(skb, &tso); |
---|
| 734 | + hdr_len = tso_start(skb, &tso); |
---|
736 | 735 | |
---|
737 | 736 | total_len = skb->len - hdr_len; |
---|
738 | 737 | while (total_len > 0) { |
---|
.. | .. |
---|
973 | 972 | writel((__force u32)cpu_to_be32(temp_mac[1]), |
---|
974 | 973 | fep->hwp + FEC_ADDR_HIGH); |
---|
975 | 974 | |
---|
976 | | - /* Clear any outstanding interrupt. */ |
---|
977 | | - writel(0xffffffff, fep->hwp + FEC_IEVENT); |
---|
| 975 | + /* Clear any outstanding interrupt, except MDIO. */ |
---|
| 976 | + writel((0xffffffff & ~FEC_ENET_MII), fep->hwp + FEC_IEVENT); |
---|
978 | 977 | |
---|
979 | 978 | fec_enet_bd_init(ndev); |
---|
980 | 979 | |
---|
.. | .. |
---|
1120 | 1119 | if (fep->link) |
---|
1121 | 1120 | writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); |
---|
1122 | 1121 | else |
---|
1123 | | - writel(FEC_ENET_MII, fep->hwp + FEC_IMASK); |
---|
| 1122 | + writel(0, fep->hwp + FEC_IMASK); |
---|
1124 | 1123 | |
---|
1125 | 1124 | /* Init the interrupt coalescing */ |
---|
1126 | 1125 | fec_enet_itr_coal_init(ndev); |
---|
.. | .. |
---|
1191 | 1190 | |
---|
1192 | 1191 | |
---|
1193 | 1192 | static void |
---|
1194 | | -fec_timeout(struct net_device *ndev) |
---|
| 1193 | +fec_timeout(struct net_device *ndev, unsigned int txqueue) |
---|
1195 | 1194 | { |
---|
1196 | 1195 | struct fec_enet_private *fep = netdev_priv(ndev); |
---|
1197 | 1196 | |
---|
.. | .. |
---|
1249 | 1248 | |
---|
1250 | 1249 | fep = netdev_priv(ndev); |
---|
1251 | 1250 | |
---|
1252 | | - queue_id = FEC_ENET_GET_QUQUE(queue_id); |
---|
1253 | | - |
---|
1254 | 1251 | txq = fep->tx_queue[queue_id]; |
---|
1255 | 1252 | /* get next bdp of dirty_tx */ |
---|
1256 | 1253 | nq = netdev_get_tx_queue(ndev, queue_id); |
---|
.. | .. |
---|
1299 | 1296 | ndev->stats.tx_bytes += skb->len; |
---|
1300 | 1297 | } |
---|
1301 | 1298 | |
---|
1302 | | - if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS) && |
---|
1303 | | - fep->bufdesc_ex) { |
---|
| 1299 | + /* NOTE: SKBTX_IN_PROGRESS being set does not imply it's we who |
---|
| 1300 | + * are to time stamp the packet, so we still need to check time |
---|
| 1301 | + * stamping enabled flag. |
---|
| 1302 | + */ |
---|
| 1303 | + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS && |
---|
| 1304 | + fep->hwts_tx_en) && |
---|
| 1305 | + fep->bufdesc_ex) { |
---|
1304 | 1306 | struct skb_shared_hwtstamps shhwtstamps; |
---|
1305 | 1307 | struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp; |
---|
1306 | 1308 | |
---|
.. | .. |
---|
1341 | 1343 | writel(0, txq->bd.reg_desc_active); |
---|
1342 | 1344 | } |
---|
1343 | 1345 | |
---|
1344 | | -static void |
---|
1345 | | -fec_enet_tx(struct net_device *ndev) |
---|
| 1346 | +static void fec_enet_tx(struct net_device *ndev) |
---|
1346 | 1347 | { |
---|
1347 | 1348 | struct fec_enet_private *fep = netdev_priv(ndev); |
---|
1348 | | - u16 queue_id; |
---|
1349 | | - /* First process class A queue, then Class B and Best Effort queue */ |
---|
1350 | | - for_each_set_bit(queue_id, &fep->work_tx, FEC_ENET_MAX_TX_QS) { |
---|
1351 | | - clear_bit(queue_id, &fep->work_tx); |
---|
1352 | | - fec_enet_tx_queue(ndev, queue_id); |
---|
1353 | | - } |
---|
1354 | | - return; |
---|
| 1349 | + int i; |
---|
| 1350 | + |
---|
| 1351 | + /* Make sure that AVB queues are processed first. */ |
---|
| 1352 | + for (i = fep->num_tx_queues - 1; i >= 0; i--) |
---|
| 1353 | + fec_enet_tx_queue(ndev, i); |
---|
1355 | 1354 | } |
---|
1356 | 1355 | |
---|
1357 | 1356 | static int |
---|
.. | .. |
---|
1427 | 1426 | #ifdef CONFIG_M532x |
---|
1428 | 1427 | flush_cache_all(); |
---|
1429 | 1428 | #endif |
---|
1430 | | - queue_id = FEC_ENET_GET_QUQUE(queue_id); |
---|
1431 | 1429 | rxq = fep->rx_queue[queue_id]; |
---|
1432 | 1430 | |
---|
1433 | 1431 | /* First, grab all of the stats for the incoming packet. |
---|
.. | .. |
---|
1551 | 1549 | htons(ETH_P_8021Q), |
---|
1552 | 1550 | vlan_tag); |
---|
1553 | 1551 | |
---|
| 1552 | + skb_record_rx_queue(skb, queue_id); |
---|
1554 | 1553 | napi_gro_receive(&fep->napi, skb); |
---|
1555 | 1554 | |
---|
1556 | 1555 | if (is_copybreak) { |
---|
.. | .. |
---|
1596 | 1595 | return pkt_received; |
---|
1597 | 1596 | } |
---|
1598 | 1597 | |
---|
1599 | | -static int |
---|
1600 | | -fec_enet_rx(struct net_device *ndev, int budget) |
---|
| 1598 | +static int fec_enet_rx(struct net_device *ndev, int budget) |
---|
1601 | 1599 | { |
---|
1602 | | - int pkt_received = 0; |
---|
1603 | | - u16 queue_id; |
---|
1604 | 1600 | struct fec_enet_private *fep = netdev_priv(ndev); |
---|
| 1601 | + int i, done = 0; |
---|
1605 | 1602 | |
---|
1606 | | - for_each_set_bit(queue_id, &fep->work_rx, FEC_ENET_MAX_RX_QS) { |
---|
1607 | | - int ret; |
---|
| 1603 | + /* Make sure that AVB queues are processed first. */ |
---|
| 1604 | + for (i = fep->num_rx_queues - 1; i >= 0; i--) |
---|
| 1605 | + done += fec_enet_rx_queue(ndev, budget - done, i); |
---|
1608 | 1606 | |
---|
1609 | | - ret = fec_enet_rx_queue(ndev, |
---|
1610 | | - budget - pkt_received, queue_id); |
---|
1611 | | - |
---|
1612 | | - if (ret < budget - pkt_received) |
---|
1613 | | - clear_bit(queue_id, &fep->work_rx); |
---|
1614 | | - |
---|
1615 | | - pkt_received += ret; |
---|
1616 | | - } |
---|
1617 | | - return pkt_received; |
---|
| 1607 | + return done; |
---|
1618 | 1608 | } |
---|
1619 | 1609 | |
---|
1620 | | -static bool |
---|
1621 | | -fec_enet_collect_events(struct fec_enet_private *fep, uint int_events) |
---|
| 1610 | +static bool fec_enet_collect_events(struct fec_enet_private *fep) |
---|
1622 | 1611 | { |
---|
1623 | | - if (int_events == 0) |
---|
1624 | | - return false; |
---|
| 1612 | + uint int_events; |
---|
1625 | 1613 | |
---|
1626 | | - if (int_events & FEC_ENET_RXF_0) |
---|
1627 | | - fep->work_rx |= (1 << 2); |
---|
1628 | | - if (int_events & FEC_ENET_RXF_1) |
---|
1629 | | - fep->work_rx |= (1 << 0); |
---|
1630 | | - if (int_events & FEC_ENET_RXF_2) |
---|
1631 | | - fep->work_rx |= (1 << 1); |
---|
| 1614 | + int_events = readl(fep->hwp + FEC_IEVENT); |
---|
1632 | 1615 | |
---|
1633 | | - if (int_events & FEC_ENET_TXF_0) |
---|
1634 | | - fep->work_tx |= (1 << 2); |
---|
1635 | | - if (int_events & FEC_ENET_TXF_1) |
---|
1636 | | - fep->work_tx |= (1 << 0); |
---|
1637 | | - if (int_events & FEC_ENET_TXF_2) |
---|
1638 | | - fep->work_tx |= (1 << 1); |
---|
| 1616 | + /* Don't clear MDIO events, we poll for those */ |
---|
| 1617 | + int_events &= ~FEC_ENET_MII; |
---|
1639 | 1618 | |
---|
1640 | | - return true; |
---|
| 1619 | + writel(int_events, fep->hwp + FEC_IEVENT); |
---|
| 1620 | + |
---|
| 1621 | + return int_events != 0; |
---|
1641 | 1622 | } |
---|
1642 | 1623 | |
---|
1643 | 1624 | static irqreturn_t |
---|
.. | .. |
---|
1645 | 1626 | { |
---|
1646 | 1627 | struct net_device *ndev = dev_id; |
---|
1647 | 1628 | struct fec_enet_private *fep = netdev_priv(ndev); |
---|
1648 | | - uint int_events; |
---|
1649 | 1629 | irqreturn_t ret = IRQ_NONE; |
---|
1650 | 1630 | |
---|
1651 | | - int_events = readl(fep->hwp + FEC_IEVENT); |
---|
1652 | | - writel(int_events, fep->hwp + FEC_IEVENT); |
---|
1653 | | - fec_enet_collect_events(fep, int_events); |
---|
1654 | | - |
---|
1655 | | - if ((fep->work_tx || fep->work_rx) && fep->link) { |
---|
| 1631 | + if (fec_enet_collect_events(fep) && fep->link) { |
---|
1656 | 1632 | ret = IRQ_HANDLED; |
---|
1657 | 1633 | |
---|
1658 | 1634 | if (napi_schedule_prep(&fep->napi)) { |
---|
1659 | | - /* Disable the NAPI interrupts */ |
---|
1660 | | - writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK); |
---|
| 1635 | + /* Disable interrupts */ |
---|
| 1636 | + writel(0, fep->hwp + FEC_IMASK); |
---|
1661 | 1637 | __napi_schedule(&fep->napi); |
---|
1662 | 1638 | } |
---|
1663 | 1639 | } |
---|
1664 | 1640 | |
---|
1665 | | - if (int_events & FEC_ENET_MII) { |
---|
1666 | | - ret = IRQ_HANDLED; |
---|
1667 | | - complete(&fep->mdio_done); |
---|
1668 | | - } |
---|
1669 | 1641 | return ret; |
---|
1670 | 1642 | } |
---|
1671 | 1643 | |
---|
.. | .. |
---|
1673 | 1645 | { |
---|
1674 | 1646 | struct net_device *ndev = napi->dev; |
---|
1675 | 1647 | struct fec_enet_private *fep = netdev_priv(ndev); |
---|
1676 | | - int pkts; |
---|
| 1648 | + int done = 0; |
---|
1677 | 1649 | |
---|
1678 | | - pkts = fec_enet_rx(ndev, budget); |
---|
| 1650 | + do { |
---|
| 1651 | + done += fec_enet_rx(ndev, budget - done); |
---|
| 1652 | + fec_enet_tx(ndev); |
---|
| 1653 | + } while ((done < budget) && fec_enet_collect_events(fep)); |
---|
1679 | 1654 | |
---|
1680 | | - fec_enet_tx(ndev); |
---|
1681 | | - |
---|
1682 | | - if (pkts < budget) { |
---|
1683 | | - napi_complete_done(napi, pkts); |
---|
| 1655 | + if (done < budget) { |
---|
| 1656 | + napi_complete_done(napi, done); |
---|
1684 | 1657 | writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); |
---|
1685 | 1658 | } |
---|
1686 | | - return pkts; |
---|
| 1659 | + |
---|
| 1660 | + return done; |
---|
1687 | 1661 | } |
---|
1688 | 1662 | |
---|
1689 | 1663 | /* ------------------------------------------------------------------------- */ |
---|
.. | .. |
---|
1708 | 1682 | struct device_node *np = fep->pdev->dev.of_node; |
---|
1709 | 1683 | if (np) { |
---|
1710 | 1684 | const char *mac = of_get_mac_address(np); |
---|
1711 | | - if (mac) |
---|
| 1685 | + if (!IS_ERR(mac)) |
---|
1712 | 1686 | iap = (unsigned char *) mac; |
---|
1713 | 1687 | } |
---|
1714 | 1688 | } |
---|
.. | .. |
---|
1767 | 1741 | struct phy_device *phy_dev = ndev->phydev; |
---|
1768 | 1742 | int status_change = 0; |
---|
1769 | 1743 | |
---|
1770 | | - /* Prevent a state halted on mii error */ |
---|
1771 | | - if (fep->mii_timeout && phy_dev->state == PHY_HALTED) { |
---|
1772 | | - phy_dev->state = PHY_RESUMING; |
---|
1773 | | - return; |
---|
1774 | | - } |
---|
1775 | | - |
---|
1776 | 1744 | /* |
---|
1777 | 1745 | * If the netdev is down, or is going down, we're not interested |
---|
1778 | 1746 | * in link state events, so just mark our idea of the link as down |
---|
.. | .. |
---|
1821 | 1789 | phy_print_status(phy_dev); |
---|
1822 | 1790 | } |
---|
1823 | 1791 | |
---|
| 1792 | +static int fec_enet_mdio_wait(struct fec_enet_private *fep) |
---|
| 1793 | +{ |
---|
| 1794 | + uint ievent; |
---|
| 1795 | + int ret; |
---|
| 1796 | + |
---|
| 1797 | + ret = readl_poll_timeout_atomic(fep->hwp + FEC_IEVENT, ievent, |
---|
| 1798 | + ievent & FEC_ENET_MII, 2, 30000); |
---|
| 1799 | + |
---|
| 1800 | + if (!ret) |
---|
| 1801 | + writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT); |
---|
| 1802 | + |
---|
| 1803 | + return ret; |
---|
| 1804 | +} |
---|
| 1805 | + |
---|
1824 | 1806 | static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) |
---|
1825 | 1807 | { |
---|
1826 | 1808 | struct fec_enet_private *fep = bus->priv; |
---|
1827 | 1809 | struct device *dev = &fep->pdev->dev; |
---|
1828 | | - unsigned long time_left; |
---|
1829 | | - int ret = 0; |
---|
| 1810 | + int ret = 0, frame_start, frame_addr, frame_op; |
---|
| 1811 | + bool is_c45 = !!(regnum & MII_ADDR_C45); |
---|
1830 | 1812 | |
---|
1831 | | - ret = pm_runtime_get_sync(dev); |
---|
| 1813 | + ret = pm_runtime_resume_and_get(dev); |
---|
1832 | 1814 | if (ret < 0) |
---|
1833 | 1815 | return ret; |
---|
1834 | 1816 | |
---|
1835 | | - fep->mii_timeout = 0; |
---|
1836 | | - reinit_completion(&fep->mdio_done); |
---|
| 1817 | + if (is_c45) { |
---|
| 1818 | + frame_start = FEC_MMFR_ST_C45; |
---|
| 1819 | + |
---|
| 1820 | + /* write address */ |
---|
| 1821 | + frame_addr = (regnum >> 16); |
---|
| 1822 | + writel(frame_start | FEC_MMFR_OP_ADDR_WRITE | |
---|
| 1823 | + FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(frame_addr) | |
---|
| 1824 | + FEC_MMFR_TA | (regnum & 0xFFFF), |
---|
| 1825 | + fep->hwp + FEC_MII_DATA); |
---|
| 1826 | + |
---|
| 1827 | + /* wait for end of transfer */ |
---|
| 1828 | + ret = fec_enet_mdio_wait(fep); |
---|
| 1829 | + if (ret) { |
---|
| 1830 | + netdev_err(fep->netdev, "MDIO address write timeout\n"); |
---|
| 1831 | + goto out; |
---|
| 1832 | + } |
---|
| 1833 | + |
---|
| 1834 | + frame_op = FEC_MMFR_OP_READ_C45; |
---|
| 1835 | + |
---|
| 1836 | + } else { |
---|
| 1837 | + /* C22 read */ |
---|
| 1838 | + frame_op = FEC_MMFR_OP_READ; |
---|
| 1839 | + frame_start = FEC_MMFR_ST; |
---|
| 1840 | + frame_addr = regnum; |
---|
| 1841 | + } |
---|
1837 | 1842 | |
---|
1838 | 1843 | /* start a read op */ |
---|
1839 | | - writel(FEC_MMFR_ST | FEC_MMFR_OP_READ | |
---|
1840 | | - FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(regnum) | |
---|
| 1844 | + writel(frame_start | frame_op | |
---|
| 1845 | + FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(frame_addr) | |
---|
1841 | 1846 | FEC_MMFR_TA, fep->hwp + FEC_MII_DATA); |
---|
1842 | 1847 | |
---|
1843 | 1848 | /* wait for end of transfer */ |
---|
1844 | | - time_left = wait_for_completion_timeout(&fep->mdio_done, |
---|
1845 | | - usecs_to_jiffies(FEC_MII_TIMEOUT)); |
---|
1846 | | - if (time_left == 0) { |
---|
1847 | | - fep->mii_timeout = 1; |
---|
| 1849 | + ret = fec_enet_mdio_wait(fep); |
---|
| 1850 | + if (ret) { |
---|
1848 | 1851 | netdev_err(fep->netdev, "MDIO read timeout\n"); |
---|
1849 | | - ret = -ETIMEDOUT; |
---|
1850 | 1852 | goto out; |
---|
1851 | 1853 | } |
---|
1852 | 1854 | |
---|
.. | .. |
---|
1864 | 1866 | { |
---|
1865 | 1867 | struct fec_enet_private *fep = bus->priv; |
---|
1866 | 1868 | struct device *dev = &fep->pdev->dev; |
---|
1867 | | - unsigned long time_left; |
---|
1868 | | - int ret; |
---|
| 1869 | + int ret, frame_start, frame_addr; |
---|
| 1870 | + bool is_c45 = !!(regnum & MII_ADDR_C45); |
---|
1869 | 1871 | |
---|
1870 | | - ret = pm_runtime_get_sync(dev); |
---|
| 1872 | + ret = pm_runtime_resume_and_get(dev); |
---|
1871 | 1873 | if (ret < 0) |
---|
1872 | 1874 | return ret; |
---|
1873 | | - else |
---|
1874 | | - ret = 0; |
---|
1875 | 1875 | |
---|
1876 | | - fep->mii_timeout = 0; |
---|
1877 | | - reinit_completion(&fep->mdio_done); |
---|
| 1876 | + if (is_c45) { |
---|
| 1877 | + frame_start = FEC_MMFR_ST_C45; |
---|
| 1878 | + |
---|
| 1879 | + /* write address */ |
---|
| 1880 | + frame_addr = (regnum >> 16); |
---|
| 1881 | + writel(frame_start | FEC_MMFR_OP_ADDR_WRITE | |
---|
| 1882 | + FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(frame_addr) | |
---|
| 1883 | + FEC_MMFR_TA | (regnum & 0xFFFF), |
---|
| 1884 | + fep->hwp + FEC_MII_DATA); |
---|
| 1885 | + |
---|
| 1886 | + /* wait for end of transfer */ |
---|
| 1887 | + ret = fec_enet_mdio_wait(fep); |
---|
| 1888 | + if (ret) { |
---|
| 1889 | + netdev_err(fep->netdev, "MDIO address write timeout\n"); |
---|
| 1890 | + goto out; |
---|
| 1891 | + } |
---|
| 1892 | + } else { |
---|
| 1893 | + /* C22 write */ |
---|
| 1894 | + frame_start = FEC_MMFR_ST; |
---|
| 1895 | + frame_addr = regnum; |
---|
| 1896 | + } |
---|
1878 | 1897 | |
---|
1879 | 1898 | /* start a write op */ |
---|
1880 | | - writel(FEC_MMFR_ST | FEC_MMFR_OP_WRITE | |
---|
1881 | | - FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(regnum) | |
---|
| 1899 | + writel(frame_start | FEC_MMFR_OP_WRITE | |
---|
| 1900 | + FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(frame_addr) | |
---|
1882 | 1901 | FEC_MMFR_TA | FEC_MMFR_DATA(value), |
---|
1883 | 1902 | fep->hwp + FEC_MII_DATA); |
---|
1884 | 1903 | |
---|
1885 | 1904 | /* wait for end of transfer */ |
---|
1886 | | - time_left = wait_for_completion_timeout(&fep->mdio_done, |
---|
1887 | | - usecs_to_jiffies(FEC_MII_TIMEOUT)); |
---|
1888 | | - if (time_left == 0) { |
---|
1889 | | - fep->mii_timeout = 1; |
---|
| 1905 | + ret = fec_enet_mdio_wait(fep); |
---|
| 1906 | + if (ret) |
---|
1890 | 1907 | netdev_err(fep->netdev, "MDIO write timeout\n"); |
---|
1891 | | - ret = -ETIMEDOUT; |
---|
1892 | | - } |
---|
1893 | 1908 | |
---|
| 1909 | +out: |
---|
1894 | 1910 | pm_runtime_mark_last_busy(dev); |
---|
1895 | 1911 | pm_runtime_put_autosuspend(dev); |
---|
1896 | 1912 | |
---|
.. | .. |
---|
1959 | 1975 | return 0; |
---|
1960 | 1976 | |
---|
1961 | 1977 | failed_clk_ref: |
---|
1962 | | - if (fep->clk_ref) |
---|
1963 | | - clk_disable_unprepare(fep->clk_ref); |
---|
| 1978 | + if (fep->clk_ptp) { |
---|
| 1979 | + mutex_lock(&fep->ptp_clk_mutex); |
---|
| 1980 | + clk_disable_unprepare(fep->clk_ptp); |
---|
| 1981 | + fep->ptp_clk_on = false; |
---|
| 1982 | + mutex_unlock(&fep->ptp_clk_mutex); |
---|
| 1983 | + } |
---|
1964 | 1984 | failed_clk_ptp: |
---|
1965 | | - if (fep->clk_enet_out) |
---|
1966 | | - clk_disable_unprepare(fep->clk_enet_out); |
---|
| 1985 | + clk_disable_unprepare(fep->clk_enet_out); |
---|
1967 | 1986 | |
---|
1968 | 1987 | return ret; |
---|
1969 | 1988 | } |
---|
.. | .. |
---|
2015 | 2034 | |
---|
2016 | 2035 | /* mask with MAC supported features */ |
---|
2017 | 2036 | if (fep->quirks & FEC_QUIRK_HAS_GBIT) { |
---|
2018 | | - phy_dev->supported &= PHY_GBIT_FEATURES; |
---|
2019 | | - phy_dev->supported &= ~SUPPORTED_1000baseT_Half; |
---|
| 2037 | + phy_set_max_speed(phy_dev, 1000); |
---|
| 2038 | + phy_remove_link_mode(phy_dev, |
---|
| 2039 | + ETHTOOL_LINK_MODE_1000baseT_Half_BIT); |
---|
2020 | 2040 | #if !defined(CONFIG_M5272) |
---|
2021 | | - phy_dev->supported |= SUPPORTED_Pause; |
---|
| 2041 | + phy_support_sym_pause(phy_dev); |
---|
2022 | 2042 | #endif |
---|
2023 | 2043 | } |
---|
2024 | 2044 | else |
---|
2025 | | - phy_dev->supported &= PHY_BASIC_FEATURES; |
---|
2026 | | - |
---|
2027 | | - phy_dev->advertising = phy_dev->supported; |
---|
| 2045 | + phy_set_max_speed(phy_dev, 100); |
---|
2028 | 2046 | |
---|
2029 | 2047 | fep->link = 0; |
---|
2030 | 2048 | fep->full_duplex = 0; |
---|
.. | .. |
---|
2039 | 2057 | static struct mii_bus *fec0_mii_bus; |
---|
2040 | 2058 | struct net_device *ndev = platform_get_drvdata(pdev); |
---|
2041 | 2059 | struct fec_enet_private *fep = netdev_priv(ndev); |
---|
| 2060 | + bool suppress_preamble = false; |
---|
2042 | 2061 | struct device_node *node; |
---|
2043 | 2062 | int err = -ENXIO; |
---|
2044 | 2063 | u32 mii_speed, holdtime; |
---|
| 2064 | + u32 bus_freq; |
---|
2045 | 2065 | |
---|
2046 | 2066 | /* |
---|
2047 | 2067 | * The i.MX28 dual fec interfaces are not equal. |
---|
.. | .. |
---|
2069 | 2089 | return -ENOENT; |
---|
2070 | 2090 | } |
---|
2071 | 2091 | |
---|
2072 | | - fep->mii_timeout = 0; |
---|
| 2092 | + bus_freq = 2500000; /* 2.5MHz by default */ |
---|
| 2093 | + node = of_get_child_by_name(pdev->dev.of_node, "mdio"); |
---|
| 2094 | + if (node) { |
---|
| 2095 | + of_property_read_u32(node, "clock-frequency", &bus_freq); |
---|
| 2096 | + suppress_preamble = of_property_read_bool(node, |
---|
| 2097 | + "suppress-preamble"); |
---|
| 2098 | + } |
---|
2073 | 2099 | |
---|
2074 | 2100 | /* |
---|
2075 | | - * Set MII speed to 2.5 MHz (= clk_get_rate() / 2 * phy_speed) |
---|
| 2101 | + * Set MII speed (= clk_get_rate() / 2 * phy_speed) |
---|
2076 | 2102 | * |
---|
2077 | 2103 | * The formula for FEC MDC is 'ref_freq / (MII_SPEED x 2)' while |
---|
2078 | 2104 | * for ENET-MAC is 'ref_freq / ((MII_SPEED + 1) x 2)'. The i.MX28 |
---|
2079 | 2105 | * Reference Manual has an error on this, and gets fixed on i.MX6Q |
---|
2080 | 2106 | * document. |
---|
2081 | 2107 | */ |
---|
2082 | | - mii_speed = DIV_ROUND_UP(clk_get_rate(fep->clk_ipg), 5000000); |
---|
| 2108 | + mii_speed = DIV_ROUND_UP(clk_get_rate(fep->clk_ipg), bus_freq * 2); |
---|
2083 | 2109 | if (fep->quirks & FEC_QUIRK_ENET_MAC) |
---|
2084 | 2110 | mii_speed--; |
---|
2085 | 2111 | if (mii_speed > 63) { |
---|
.. | .. |
---|
2106 | 2132 | |
---|
2107 | 2133 | fep->phy_speed = mii_speed << 1 | holdtime << 8; |
---|
2108 | 2134 | |
---|
| 2135 | + if (suppress_preamble) |
---|
| 2136 | + fep->phy_speed |= BIT(7); |
---|
| 2137 | + |
---|
| 2138 | + if (fep->quirks & FEC_QUIRK_CLEAR_SETUP_MII) { |
---|
| 2139 | + /* Clear MMFR to avoid to generate MII event by writing MSCR. |
---|
| 2140 | + * MII event generation condition: |
---|
| 2141 | + * - writing MSCR: |
---|
| 2142 | + * - mmfr[31:0]_not_zero & mscr[7:0]_is_zero & |
---|
| 2143 | + * mscr_reg_data_in[7:0] != 0 |
---|
| 2144 | + * - writing MMFR: |
---|
| 2145 | + * - mscr[7:0]_not_zero |
---|
| 2146 | + */ |
---|
| 2147 | + writel(0, fep->hwp + FEC_MII_DATA); |
---|
| 2148 | + } |
---|
| 2149 | + |
---|
2109 | 2150 | writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); |
---|
| 2151 | + |
---|
| 2152 | + /* Clear any pending transaction complete indication */ |
---|
| 2153 | + writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT); |
---|
2110 | 2154 | |
---|
2111 | 2155 | fep->mii_bus = mdiobus_alloc(); |
---|
2112 | 2156 | if (fep->mii_bus == NULL) { |
---|
.. | .. |
---|
2122 | 2166 | fep->mii_bus->priv = fep; |
---|
2123 | 2167 | fep->mii_bus->parent = &pdev->dev; |
---|
2124 | 2168 | |
---|
2125 | | - node = of_get_child_by_name(pdev->dev.of_node, "mdio"); |
---|
2126 | 2169 | err = of_mdiobus_register(fep->mii_bus, node); |
---|
2127 | | - if (node) |
---|
2128 | | - of_node_put(node); |
---|
2129 | 2170 | if (err) |
---|
2130 | 2171 | goto err_out_free_mdiobus; |
---|
| 2172 | + of_node_put(node); |
---|
2131 | 2173 | |
---|
2132 | 2174 | mii_cnt++; |
---|
2133 | 2175 | |
---|
.. | .. |
---|
2140 | 2182 | err_out_free_mdiobus: |
---|
2141 | 2183 | mdiobus_free(fep->mii_bus); |
---|
2142 | 2184 | err_out: |
---|
| 2185 | + of_node_put(node); |
---|
2143 | 2186 | return err; |
---|
2144 | 2187 | } |
---|
2145 | 2188 | |
---|
.. | .. |
---|
2158 | 2201 | |
---|
2159 | 2202 | strlcpy(info->driver, fep->pdev->dev.driver->name, |
---|
2160 | 2203 | sizeof(info->driver)); |
---|
2161 | | - strlcpy(info->version, "Revision: 1.0", sizeof(info->version)); |
---|
2162 | 2204 | strlcpy(info->bus_info, dev_name(&ndev->dev), sizeof(info->bus_info)); |
---|
2163 | 2205 | } |
---|
2164 | 2206 | |
---|
.. | .. |
---|
2179 | 2221 | #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ |
---|
2180 | 2222 | defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \ |
---|
2181 | 2223 | defined(CONFIG_ARM64) || defined(CONFIG_COMPILE_TEST) |
---|
| 2224 | +static __u32 fec_enet_register_version = 2; |
---|
2182 | 2225 | static u32 fec_enet_register_offset[] = { |
---|
2183 | 2226 | FEC_IEVENT, FEC_IMASK, FEC_R_DES_ACTIVE_0, FEC_X_DES_ACTIVE_0, |
---|
2184 | 2227 | FEC_ECNTRL, FEC_MII_DATA, FEC_MII_SPEED, FEC_MIB_CTRLSTAT, FEC_R_CNTRL, |
---|
.. | .. |
---|
2208 | 2251 | IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR, |
---|
2209 | 2252 | IEEE_R_FDXFC, IEEE_R_OCTETS_OK |
---|
2210 | 2253 | }; |
---|
| 2254 | +/* for i.MX6ul */ |
---|
| 2255 | +static u32 fec_enet_register_offset_6ul[] = { |
---|
| 2256 | + FEC_IEVENT, FEC_IMASK, FEC_R_DES_ACTIVE_0, FEC_X_DES_ACTIVE_0, |
---|
| 2257 | + FEC_ECNTRL, FEC_MII_DATA, FEC_MII_SPEED, FEC_MIB_CTRLSTAT, FEC_R_CNTRL, |
---|
| 2258 | + FEC_X_CNTRL, FEC_ADDR_LOW, FEC_ADDR_HIGH, FEC_OPD, FEC_TXIC0, FEC_RXIC0, |
---|
| 2259 | + FEC_HASH_TABLE_HIGH, FEC_HASH_TABLE_LOW, FEC_GRP_HASH_TABLE_HIGH, |
---|
| 2260 | + FEC_GRP_HASH_TABLE_LOW, FEC_X_WMRK, FEC_R_DES_START_0, |
---|
| 2261 | + FEC_X_DES_START_0, FEC_R_BUFF_SIZE_0, FEC_R_FIFO_RSFL, FEC_R_FIFO_RSEM, |
---|
| 2262 | + FEC_R_FIFO_RAEM, FEC_R_FIFO_RAFL, FEC_RACC, |
---|
| 2263 | + RMON_T_DROP, RMON_T_PACKETS, RMON_T_BC_PKT, RMON_T_MC_PKT, |
---|
| 2264 | + RMON_T_CRC_ALIGN, RMON_T_UNDERSIZE, RMON_T_OVERSIZE, RMON_T_FRAG, |
---|
| 2265 | + RMON_T_JAB, RMON_T_COL, RMON_T_P64, RMON_T_P65TO127, RMON_T_P128TO255, |
---|
| 2266 | + RMON_T_P256TO511, RMON_T_P512TO1023, RMON_T_P1024TO2047, |
---|
| 2267 | + RMON_T_P_GTE2048, RMON_T_OCTETS, |
---|
| 2268 | + IEEE_T_DROP, IEEE_T_FRAME_OK, IEEE_T_1COL, IEEE_T_MCOL, IEEE_T_DEF, |
---|
| 2269 | + IEEE_T_LCOL, IEEE_T_EXCOL, IEEE_T_MACERR, IEEE_T_CSERR, IEEE_T_SQE, |
---|
| 2270 | + IEEE_T_FDXFC, IEEE_T_OCTETS_OK, |
---|
| 2271 | + RMON_R_PACKETS, RMON_R_BC_PKT, RMON_R_MC_PKT, RMON_R_CRC_ALIGN, |
---|
| 2272 | + RMON_R_UNDERSIZE, RMON_R_OVERSIZE, RMON_R_FRAG, RMON_R_JAB, |
---|
| 2273 | + RMON_R_RESVD_O, RMON_R_P64, RMON_R_P65TO127, RMON_R_P128TO255, |
---|
| 2274 | + RMON_R_P256TO511, RMON_R_P512TO1023, RMON_R_P1024TO2047, |
---|
| 2275 | + RMON_R_P_GTE2048, RMON_R_OCTETS, |
---|
| 2276 | + IEEE_R_DROP, IEEE_R_FRAME_OK, IEEE_R_CRC, IEEE_R_ALIGN, IEEE_R_MACERR, |
---|
| 2277 | + IEEE_R_FDXFC, IEEE_R_OCTETS_OK |
---|
| 2278 | +}; |
---|
2211 | 2279 | #else |
---|
| 2280 | +static __u32 fec_enet_register_version = 1; |
---|
2212 | 2281 | static u32 fec_enet_register_offset[] = { |
---|
2213 | 2282 | FEC_ECNTRL, FEC_IEVENT, FEC_IMASK, FEC_IVEC, FEC_R_DES_ACTIVE_0, |
---|
2214 | 2283 | FEC_R_DES_ACTIVE_1, FEC_R_DES_ACTIVE_2, FEC_X_DES_ACTIVE_0, |
---|
.. | .. |
---|
2227 | 2296 | { |
---|
2228 | 2297 | struct fec_enet_private *fep = netdev_priv(ndev); |
---|
2229 | 2298 | u32 __iomem *theregs = (u32 __iomem *)fep->hwp; |
---|
| 2299 | + struct device *dev = &fep->pdev->dev; |
---|
2230 | 2300 | u32 *buf = (u32 *)regbuf; |
---|
2231 | 2301 | u32 i, off; |
---|
| 2302 | + int ret; |
---|
| 2303 | +#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ |
---|
| 2304 | + defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \ |
---|
| 2305 | + defined(CONFIG_ARM64) || defined(CONFIG_COMPILE_TEST) |
---|
| 2306 | + u32 *reg_list; |
---|
| 2307 | + u32 reg_cnt; |
---|
| 2308 | + |
---|
| 2309 | + if (!of_machine_is_compatible("fsl,imx6ul")) { |
---|
| 2310 | + reg_list = fec_enet_register_offset; |
---|
| 2311 | + reg_cnt = ARRAY_SIZE(fec_enet_register_offset); |
---|
| 2312 | + } else { |
---|
| 2313 | + reg_list = fec_enet_register_offset_6ul; |
---|
| 2314 | + reg_cnt = ARRAY_SIZE(fec_enet_register_offset_6ul); |
---|
| 2315 | + } |
---|
| 2316 | +#else |
---|
| 2317 | + /* coldfire */ |
---|
| 2318 | + static u32 *reg_list = fec_enet_register_offset; |
---|
| 2319 | + static const u32 reg_cnt = ARRAY_SIZE(fec_enet_register_offset); |
---|
| 2320 | +#endif |
---|
| 2321 | + ret = pm_runtime_resume_and_get(dev); |
---|
| 2322 | + if (ret < 0) |
---|
| 2323 | + return; |
---|
| 2324 | + |
---|
| 2325 | + regs->version = fec_enet_register_version; |
---|
2232 | 2326 | |
---|
2233 | 2327 | memset(buf, 0, regs->len); |
---|
2234 | 2328 | |
---|
2235 | | - for (i = 0; i < ARRAY_SIZE(fec_enet_register_offset); i++) { |
---|
2236 | | - off = fec_enet_register_offset[i]; |
---|
| 2329 | + for (i = 0; i < reg_cnt; i++) { |
---|
| 2330 | + off = reg_list[i]; |
---|
2237 | 2331 | |
---|
2238 | 2332 | if ((off == FEC_R_BOUND || off == FEC_R_FSTART) && |
---|
2239 | 2333 | !(fep->quirks & FEC_QUIRK_HAS_FRREG)) |
---|
.. | .. |
---|
2242 | 2336 | off >>= 2; |
---|
2243 | 2337 | buf[off] = readl(&theregs[off]); |
---|
2244 | 2338 | } |
---|
| 2339 | + |
---|
| 2340 | + pm_runtime_mark_last_busy(dev); |
---|
| 2341 | + pm_runtime_put_autosuspend(dev); |
---|
2245 | 2342 | } |
---|
2246 | 2343 | |
---|
2247 | 2344 | static int fec_enet_get_ts_info(struct net_device *ndev, |
---|
.. | .. |
---|
2305 | 2402 | fep->pause_flag |= pause->rx_pause ? FEC_PAUSE_FLAG_ENABLE : 0; |
---|
2306 | 2403 | fep->pause_flag |= pause->autoneg ? FEC_PAUSE_FLAG_AUTONEG : 0; |
---|
2307 | 2404 | |
---|
2308 | | - if (pause->rx_pause || pause->autoneg) { |
---|
2309 | | - ndev->phydev->supported |= ADVERTISED_Pause; |
---|
2310 | | - ndev->phydev->advertising |= ADVERTISED_Pause; |
---|
2311 | | - } else { |
---|
2312 | | - ndev->phydev->supported &= ~ADVERTISED_Pause; |
---|
2313 | | - ndev->phydev->advertising &= ~ADVERTISED_Pause; |
---|
2314 | | - } |
---|
| 2405 | + phy_set_sym_pause(ndev->phydev, pause->rx_pause, pause->tx_pause, |
---|
| 2406 | + pause->autoneg); |
---|
2315 | 2407 | |
---|
2316 | 2408 | if (pause->autoneg) { |
---|
2317 | 2409 | if (netif_running(ndev)) |
---|
.. | .. |
---|
2535 | 2627 | fec_enet_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *ec) |
---|
2536 | 2628 | { |
---|
2537 | 2629 | struct fec_enet_private *fep = netdev_priv(ndev); |
---|
| 2630 | + struct device *dev = &fep->pdev->dev; |
---|
2538 | 2631 | unsigned int cycle; |
---|
2539 | 2632 | |
---|
2540 | 2633 | if (!(fep->quirks & FEC_QUIRK_HAS_COALESCE)) |
---|
2541 | 2634 | return -EOPNOTSUPP; |
---|
2542 | 2635 | |
---|
2543 | 2636 | if (ec->rx_max_coalesced_frames > 255) { |
---|
2544 | | - pr_err("Rx coalesced frames exceed hardware limitation\n"); |
---|
| 2637 | + dev_err(dev, "Rx coalesced frames exceed hardware limitation\n"); |
---|
2545 | 2638 | return -EINVAL; |
---|
2546 | 2639 | } |
---|
2547 | 2640 | |
---|
2548 | 2641 | if (ec->tx_max_coalesced_frames > 255) { |
---|
2549 | | - pr_err("Tx coalesced frame exceed hardware limitation\n"); |
---|
| 2642 | + dev_err(dev, "Tx coalesced frame exceed hardware limitation\n"); |
---|
2550 | 2643 | return -EINVAL; |
---|
2551 | 2644 | } |
---|
2552 | 2645 | |
---|
2553 | 2646 | cycle = fec_enet_us_to_itr_clock(ndev, ec->rx_coalesce_usecs); |
---|
2554 | 2647 | if (cycle > 0xFFFF) { |
---|
2555 | | - pr_err("Rx coalesced usec exceed hardware limitation\n"); |
---|
| 2648 | + dev_err(dev, "Rx coalesced usec exceed hardware limitation\n"); |
---|
2556 | 2649 | return -EINVAL; |
---|
2557 | 2650 | } |
---|
2558 | 2651 | |
---|
2559 | 2652 | cycle = fec_enet_us_to_itr_clock(ndev, ec->tx_coalesce_usecs); |
---|
2560 | 2653 | if (cycle > 0xFFFF) { |
---|
2561 | | - pr_err("Tx coalesced usec exceed hardware limitation\n"); |
---|
| 2654 | + dev_err(dev, "Tx coalesced usec exceed hardware limitation\n"); |
---|
2562 | 2655 | return -EINVAL; |
---|
2563 | 2656 | } |
---|
2564 | 2657 | |
---|
.. | .. |
---|
2663 | 2756 | } |
---|
2664 | 2757 | |
---|
2665 | 2758 | static const struct ethtool_ops fec_enet_ethtool_ops = { |
---|
| 2759 | + .supported_coalesce_params = ETHTOOL_COALESCE_USECS | |
---|
| 2760 | + ETHTOOL_COALESCE_MAX_FRAMES, |
---|
2666 | 2761 | .get_drvinfo = fec_enet_get_drvinfo, |
---|
2667 | 2762 | .get_regs_len = fec_enet_get_regs_len, |
---|
2668 | 2763 | .get_regs = fec_enet_get_regs, |
---|
.. | .. |
---|
2698 | 2793 | return -ENODEV; |
---|
2699 | 2794 | |
---|
2700 | 2795 | if (fep->bufdesc_ex) { |
---|
2701 | | - if (cmd == SIOCSHWTSTAMP) |
---|
2702 | | - return fec_ptp_set(ndev, rq); |
---|
2703 | | - if (cmd == SIOCGHWTSTAMP) |
---|
2704 | | - return fec_ptp_get(ndev, rq); |
---|
| 2796 | + bool use_fec_hwts = !phy_has_hwtstamp(phydev); |
---|
| 2797 | + |
---|
| 2798 | + if (cmd == SIOCSHWTSTAMP) { |
---|
| 2799 | + if (use_fec_hwts) |
---|
| 2800 | + return fec_ptp_set(ndev, rq); |
---|
| 2801 | + fec_ptp_disable_hwts(ndev); |
---|
| 2802 | + } else if (cmd == SIOCGHWTSTAMP) { |
---|
| 2803 | + if (use_fec_hwts) |
---|
| 2804 | + return fec_ptp_get(ndev, rq); |
---|
| 2805 | + } |
---|
2705 | 2806 | } |
---|
2706 | 2807 | |
---|
2707 | 2808 | return phy_mii_ioctl(phydev, rq, cmd); |
---|
.. | .. |
---|
2736 | 2837 | |
---|
2737 | 2838 | for (q = 0; q < fep->num_tx_queues; q++) { |
---|
2738 | 2839 | txq = fep->tx_queue[q]; |
---|
2739 | | - bdp = txq->bd.base; |
---|
2740 | 2840 | for (i = 0; i < txq->bd.ring_size; i++) { |
---|
2741 | 2841 | kfree(txq->tx_bounce[i]); |
---|
2742 | 2842 | txq->tx_bounce[i] = NULL; |
---|
.. | .. |
---|
2919 | 3019 | int ret; |
---|
2920 | 3020 | bool reset_again; |
---|
2921 | 3021 | |
---|
2922 | | - ret = pm_runtime_get_sync(&fep->pdev->dev); |
---|
| 3022 | + ret = pm_runtime_resume_and_get(&fep->pdev->dev); |
---|
2923 | 3023 | if (ret < 0) |
---|
2924 | 3024 | return ret; |
---|
2925 | 3025 | |
---|
.. | .. |
---|
3166 | 3266 | return 0; |
---|
3167 | 3267 | } |
---|
3168 | 3268 | |
---|
| 3269 | +static u16 fec_enet_get_raw_vlan_tci(struct sk_buff *skb) |
---|
| 3270 | +{ |
---|
| 3271 | + struct vlan_ethhdr *vhdr; |
---|
| 3272 | + unsigned short vlan_TCI = 0; |
---|
| 3273 | + |
---|
| 3274 | + if (skb->protocol == htons(ETH_P_ALL)) { |
---|
| 3275 | + vhdr = (struct vlan_ethhdr *)(skb->data); |
---|
| 3276 | + vlan_TCI = ntohs(vhdr->h_vlan_TCI); |
---|
| 3277 | + } |
---|
| 3278 | + |
---|
| 3279 | + return vlan_TCI; |
---|
| 3280 | +} |
---|
| 3281 | + |
---|
| 3282 | +static u16 fec_enet_select_queue(struct net_device *ndev, struct sk_buff *skb, |
---|
| 3283 | + struct net_device *sb_dev) |
---|
| 3284 | +{ |
---|
| 3285 | + struct fec_enet_private *fep = netdev_priv(ndev); |
---|
| 3286 | + u16 vlan_tag; |
---|
| 3287 | + |
---|
| 3288 | + if (!(fep->quirks & FEC_QUIRK_HAS_AVB)) |
---|
| 3289 | + return netdev_pick_tx(ndev, skb, NULL); |
---|
| 3290 | + |
---|
| 3291 | + vlan_tag = fec_enet_get_raw_vlan_tci(skb); |
---|
| 3292 | + if (!vlan_tag) |
---|
| 3293 | + return vlan_tag; |
---|
| 3294 | + |
---|
| 3295 | + return fec_enet_vlan_pri_to_queue[vlan_tag >> 13]; |
---|
| 3296 | +} |
---|
| 3297 | + |
---|
3169 | 3298 | static const struct net_device_ops fec_netdev_ops = { |
---|
3170 | 3299 | .ndo_open = fec_enet_open, |
---|
3171 | 3300 | .ndo_stop = fec_enet_close, |
---|
3172 | 3301 | .ndo_start_xmit = fec_enet_start_xmit, |
---|
| 3302 | + .ndo_select_queue = fec_enet_select_queue, |
---|
3173 | 3303 | .ndo_set_rx_mode = set_multicast_list, |
---|
3174 | 3304 | .ndo_validate_addr = eth_validate_addr, |
---|
3175 | 3305 | .ndo_tx_timeout = fec_timeout, |
---|
.. | .. |
---|
3234 | 3364 | ret = -ENOMEM; |
---|
3235 | 3365 | goto free_queue_mem; |
---|
3236 | 3366 | } |
---|
3237 | | - |
---|
3238 | | - memset(cbd_base, 0, bd_size); |
---|
3239 | 3367 | |
---|
3240 | 3368 | /* Get the Ethernet address */ |
---|
3241 | 3369 | fec_get_mac(ndev); |
---|
.. | .. |
---|
3429 | 3557 | } |
---|
3430 | 3558 | |
---|
3431 | 3559 | static int fec_enet_init_stop_mode(struct fec_enet_private *fep, |
---|
3432 | | - struct fec_devinfo *dev_info, |
---|
3433 | 3560 | struct device_node *np) |
---|
3434 | 3561 | { |
---|
3435 | 3562 | struct device_node *gpr_np; |
---|
| 3563 | + u32 out_val[3]; |
---|
3436 | 3564 | int ret = 0; |
---|
3437 | 3565 | |
---|
3438 | | - if (!dev_info) |
---|
3439 | | - return 0; |
---|
3440 | | - |
---|
3441 | | - gpr_np = of_parse_phandle(np, "gpr", 0); |
---|
| 3566 | + gpr_np = of_parse_phandle(np, "fsl,stop-mode", 0); |
---|
3442 | 3567 | if (!gpr_np) |
---|
3443 | 3568 | return 0; |
---|
| 3569 | + |
---|
| 3570 | + ret = of_property_read_u32_array(np, "fsl,stop-mode", out_val, |
---|
| 3571 | + ARRAY_SIZE(out_val)); |
---|
| 3572 | + if (ret) { |
---|
| 3573 | + dev_dbg(&fep->pdev->dev, "no stop mode property\n"); |
---|
| 3574 | + goto out; |
---|
| 3575 | + } |
---|
3444 | 3576 | |
---|
3445 | 3577 | fep->stop_gpr.gpr = syscon_node_to_regmap(gpr_np); |
---|
3446 | 3578 | if (IS_ERR(fep->stop_gpr.gpr)) { |
---|
.. | .. |
---|
3450 | 3582 | goto out; |
---|
3451 | 3583 | } |
---|
3452 | 3584 | |
---|
3453 | | - fep->stop_gpr.reg = dev_info->stop_gpr_reg; |
---|
3454 | | - fep->stop_gpr.bit = dev_info->stop_gpr_bit; |
---|
| 3585 | + fep->stop_gpr.reg = out_val[1]; |
---|
| 3586 | + fep->stop_gpr.bit = out_val[2]; |
---|
3455 | 3587 | |
---|
3456 | 3588 | out: |
---|
3457 | 3589 | of_node_put(gpr_np); |
---|
.. | .. |
---|
3464 | 3596 | { |
---|
3465 | 3597 | struct fec_enet_private *fep; |
---|
3466 | 3598 | struct fec_platform_data *pdata; |
---|
| 3599 | + phy_interface_t interface; |
---|
3467 | 3600 | struct net_device *ndev; |
---|
3468 | 3601 | int i, irq, ret = 0; |
---|
3469 | | - struct resource *r; |
---|
3470 | 3602 | const struct of_device_id *of_id; |
---|
3471 | 3603 | static int dev_id; |
---|
3472 | 3604 | struct device_node *np = pdev->dev.of_node, *phy_node; |
---|
.. | .. |
---|
3509 | 3641 | /* Select default pin state */ |
---|
3510 | 3642 | pinctrl_pm_select_default_state(&pdev->dev); |
---|
3511 | 3643 | |
---|
3512 | | - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
3513 | | - fep->hwp = devm_ioremap_resource(&pdev->dev, r); |
---|
| 3644 | + fep->hwp = devm_platform_ioremap_resource(pdev, 0); |
---|
3514 | 3645 | if (IS_ERR(fep->hwp)) { |
---|
3515 | 3646 | ret = PTR_ERR(fep->hwp); |
---|
3516 | 3647 | goto failed_ioremap; |
---|
.. | .. |
---|
3529 | 3660 | if (of_get_property(np, "fsl,magic-packet", NULL)) |
---|
3530 | 3661 | fep->wol_flag |= FEC_WOL_HAS_MAGIC_PACKET; |
---|
3531 | 3662 | |
---|
3532 | | - ret = fec_enet_init_stop_mode(fep, dev_info, np); |
---|
| 3663 | + ret = fec_enet_init_stop_mode(fep, np); |
---|
3533 | 3664 | if (ret) |
---|
3534 | 3665 | goto failed_stop_mode; |
---|
3535 | 3666 | |
---|
.. | .. |
---|
3545 | 3676 | } |
---|
3546 | 3677 | fep->phy_node = phy_node; |
---|
3547 | 3678 | |
---|
3548 | | - ret = of_get_phy_mode(pdev->dev.of_node); |
---|
3549 | | - if (ret < 0) { |
---|
| 3679 | + ret = of_get_phy_mode(pdev->dev.of_node, &interface); |
---|
| 3680 | + if (ret) { |
---|
3550 | 3681 | pdata = dev_get_platdata(&pdev->dev); |
---|
3551 | 3682 | if (pdata) |
---|
3552 | 3683 | fep->phy_interface = pdata->phy; |
---|
3553 | 3684 | else |
---|
3554 | 3685 | fep->phy_interface = PHY_INTERFACE_MODE_MII; |
---|
3555 | 3686 | } else { |
---|
3556 | | - fep->phy_interface = ret; |
---|
| 3687 | + fep->phy_interface = interface; |
---|
3557 | 3688 | } |
---|
3558 | 3689 | |
---|
3559 | 3690 | fep->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
---|
.. | .. |
---|
3601 | 3732 | if (ret) |
---|
3602 | 3733 | goto failed_clk_ahb; |
---|
3603 | 3734 | |
---|
3604 | | - fep->reg_phy = devm_regulator_get(&pdev->dev, "phy"); |
---|
| 3735 | + fep->reg_phy = devm_regulator_get_optional(&pdev->dev, "phy"); |
---|
3605 | 3736 | if (!IS_ERR(fep->reg_phy)) { |
---|
3606 | 3737 | ret = regulator_enable(fep->reg_phy); |
---|
3607 | 3738 | if (ret) { |
---|
3608 | 3739 | dev_err(&pdev->dev, |
---|
3609 | 3740 | "Failed to enable phy regulator: %d\n", ret); |
---|
3610 | | - clk_disable_unprepare(fep->clk_ipg); |
---|
3611 | 3741 | goto failed_regulator; |
---|
3612 | 3742 | } |
---|
3613 | 3743 | } else { |
---|
.. | .. |
---|
3638 | 3768 | |
---|
3639 | 3769 | for (i = 0; i < irq_cnt; i++) { |
---|
3640 | 3770 | snprintf(irq_name, sizeof(irq_name), "int%d", i); |
---|
3641 | | - irq = platform_get_irq_byname(pdev, irq_name); |
---|
| 3771 | + irq = platform_get_irq_byname_optional(pdev, irq_name); |
---|
3642 | 3772 | if (irq < 0) |
---|
3643 | 3773 | irq = platform_get_irq(pdev, i); |
---|
3644 | 3774 | if (irq < 0) { |
---|
.. | .. |
---|
3653 | 3783 | fep->irq[i] = irq; |
---|
3654 | 3784 | } |
---|
3655 | 3785 | |
---|
3656 | | - init_completion(&fep->mdio_done); |
---|
3657 | 3786 | ret = fec_enet_mii_init(pdev); |
---|
3658 | 3787 | if (ret) |
---|
3659 | 3788 | goto failed_mii_init; |
---|
.. | .. |
---|
3662 | 3791 | netif_carrier_off(ndev); |
---|
3663 | 3792 | fec_enet_clk_enable(ndev, false); |
---|
3664 | 3793 | pinctrl_pm_select_sleep_state(&pdev->dev); |
---|
| 3794 | + |
---|
| 3795 | + ndev->max_mtu = PKT_MAXBUF_SIZE - ETH_HLEN - ETH_FCS_LEN; |
---|
3665 | 3796 | |
---|
3666 | 3797 | ret = register_netdev(ndev); |
---|
3667 | 3798 | if (ret) |
---|
.. | .. |
---|
3721 | 3852 | |
---|
3722 | 3853 | ret = pm_runtime_get_sync(&pdev->dev); |
---|
3723 | 3854 | if (ret < 0) |
---|
3724 | | - return ret; |
---|
| 3855 | + dev_err(&pdev->dev, |
---|
| 3856 | + "Failed to resume device in remove callback (%pe)\n", |
---|
| 3857 | + ERR_PTR(ret)); |
---|
3725 | 3858 | |
---|
3726 | 3859 | cancel_work_sync(&fep->tx_timeout_work); |
---|
3727 | 3860 | fec_ptp_stop(pdev); |
---|
.. | .. |
---|
3734 | 3867 | of_phy_deregister_fixed_link(np); |
---|
3735 | 3868 | of_node_put(fep->phy_node); |
---|
3736 | 3869 | |
---|
3737 | | - clk_disable_unprepare(fep->clk_ahb); |
---|
3738 | | - clk_disable_unprepare(fep->clk_ipg); |
---|
| 3870 | + /* After pm_runtime_get_sync() failed, the clks are still off, so skip |
---|
| 3871 | + * disabling them again. |
---|
| 3872 | + */ |
---|
| 3873 | + if (ret >= 0) { |
---|
| 3874 | + clk_disable_unprepare(fep->clk_ahb); |
---|
| 3875 | + clk_disable_unprepare(fep->clk_ipg); |
---|
| 3876 | + } |
---|
3739 | 3877 | pm_runtime_put_noidle(&pdev->dev); |
---|
3740 | 3878 | pm_runtime_disable(&pdev->dev); |
---|
3741 | 3879 | |
---|
.. | .. |
---|
3864 | 4002 | .name = DRIVER_NAME, |
---|
3865 | 4003 | .pm = &fec_pm_ops, |
---|
3866 | 4004 | .of_match_table = fec_dt_ids, |
---|
| 4005 | + .suppress_bind_attrs = true, |
---|
3867 | 4006 | }, |
---|
3868 | 4007 | .id_table = fec_devtype, |
---|
3869 | 4008 | .probe = fec_probe, |
---|