@@ -1311,11 +1311,19 @@ static void bcm_sysport_netif_start(struct net_device *dev)
13111311 netif_tx_start_all_queues (dev );
13121312}
13131313
1314+ static void rbuf_init (struct bcm_sysport_priv * priv )
1315+ {
1316+ u32 reg ;
1317+
1318+ reg = rbuf_readl (priv , RBUF_CONTROL );
1319+ reg |= RBUF_4B_ALGN | RBUF_RSB_EN ;
1320+ rbuf_writel (priv , reg , RBUF_CONTROL );
1321+ }
1322+
13141323static int bcm_sysport_open (struct net_device * dev )
13151324{
13161325 struct bcm_sysport_priv * priv = netdev_priv (dev );
13171326 unsigned int i ;
1318- u32 reg ;
13191327 int ret ;
13201328
13211329 /* Reset UniMAC */
@@ -1332,9 +1340,7 @@ static int bcm_sysport_open(struct net_device *dev)
13321340 umac_enable_set (priv , CMD_RX_EN | CMD_TX_EN , 0 );
13331341
13341342 /* Enable RBUF 2bytes alignment and Receive Status Block */
1335- reg = rbuf_readl (priv , RBUF_CONTROL );
1336- reg |= RBUF_4B_ALGN | RBUF_RSB_EN ;
1337- rbuf_writel (priv , reg , RBUF_CONTROL );
1343+ rbuf_init (priv );
13381344
13391345 /* Set maximum frame length */
13401346 umac_writel (priv , UMAC_MAX_MTU_SIZE , UMAC_MAX_FRAME_LEN );
@@ -1640,6 +1646,155 @@ static int bcm_sysport_remove(struct platform_device *pdev)
16401646 return 0 ;
16411647}
16421648
1649+ #ifdef CONFIG_PM_SLEEP
1650+ static int bcm_sysport_suspend (struct device * d )
1651+ {
1652+ struct net_device * dev = dev_get_drvdata (d );
1653+ struct bcm_sysport_priv * priv = netdev_priv (dev );
1654+ unsigned int i ;
1655+ int ret ;
1656+ u32 reg ;
1657+
1658+ if (!netif_running (dev ))
1659+ return 0 ;
1660+
1661+ bcm_sysport_netif_stop (dev );
1662+
1663+ phy_suspend (priv -> phydev );
1664+
1665+ netif_device_detach (dev );
1666+
1667+ /* Disable UniMAC RX */
1668+ umac_enable_set (priv , CMD_RX_EN , 0 );
1669+
1670+ ret = rdma_enable_set (priv , 0 );
1671+ if (ret ) {
1672+ netdev_err (dev , "RDMA timeout!\n" );
1673+ return ret ;
1674+ }
1675+
1676+ /* Disable RXCHK if enabled */
1677+ if (priv -> rx_csum_en ) {
1678+ reg = rxchk_readl (priv , RXCHK_CONTROL );
1679+ reg &= ~RXCHK_EN ;
1680+ rxchk_writel (priv , reg , RXCHK_CONTROL );
1681+ }
1682+
1683+ /* Flush RX pipe */
1684+ topctrl_writel (priv , RX_FLUSH , RX_FLUSH_CNTL );
1685+
1686+ ret = tdma_enable_set (priv , 0 );
1687+ if (ret ) {
1688+ netdev_err (dev , "TDMA timeout!\n" );
1689+ return ret ;
1690+ }
1691+
1692+ /* Wait for a packet boundary */
1693+ usleep_range (2000 , 3000 );
1694+
1695+ umac_enable_set (priv , CMD_TX_EN , 0 );
1696+
1697+ topctrl_writel (priv , TX_FLUSH , TX_FLUSH_CNTL );
1698+
1699+ /* Free RX/TX rings SW structures */
1700+ for (i = 0 ; i < dev -> num_tx_queues ; i ++ )
1701+ bcm_sysport_fini_tx_ring (priv , i );
1702+ bcm_sysport_fini_rx_ring (priv );
1703+
1704+ return 0 ;
1705+ }
1706+
1707+ static int bcm_sysport_resume (struct device * d )
1708+ {
1709+ struct net_device * dev = dev_get_drvdata (d );
1710+ struct bcm_sysport_priv * priv = netdev_priv (dev );
1711+ unsigned int i ;
1712+ u32 reg ;
1713+ int ret ;
1714+
1715+ if (!netif_running (dev ))
1716+ return 0 ;
1717+
1718+ /* Initialize both hardware and software ring */
1719+ for (i = 0 ; i < dev -> num_tx_queues ; i ++ ) {
1720+ ret = bcm_sysport_init_tx_ring (priv , i );
1721+ if (ret ) {
1722+ netdev_err (dev , "failed to initialize TX ring %d\n" ,
1723+ i );
1724+ goto out_free_tx_rings ;
1725+ }
1726+ }
1727+
1728+ /* Initialize linked-list */
1729+ tdma_writel (priv , TDMA_LL_RAM_INIT_BUSY , TDMA_STATUS );
1730+
1731+ /* Initialize RX ring */
1732+ ret = bcm_sysport_init_rx_ring (priv );
1733+ if (ret ) {
1734+ netdev_err (dev , "failed to initialize RX ring\n" );
1735+ goto out_free_rx_ring ;
1736+ }
1737+
1738+ netif_device_attach (dev );
1739+
1740+ /* Enable RX interrupt and TX ring full interrupt */
1741+ intrl2_0_mask_clear (priv , INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL );
1742+
1743+ /* RX pipe enable */
1744+ topctrl_writel (priv , 0 , RX_FLUSH_CNTL );
1745+
1746+ ret = rdma_enable_set (priv , 1 );
1747+ if (ret ) {
1748+ netdev_err (dev , "failed to enable RDMA\n" );
1749+ goto out_free_rx_ring ;
1750+ }
1751+
1752+ /* Enable rxhck */
1753+ if (priv -> rx_csum_en ) {
1754+ reg = rxchk_readl (priv , RXCHK_CONTROL );
1755+ reg |= RXCHK_EN ;
1756+ rxchk_writel (priv , reg , RXCHK_CONTROL );
1757+ }
1758+
1759+ rbuf_init (priv );
1760+
1761+ /* Set maximum frame length */
1762+ umac_writel (priv , UMAC_MAX_MTU_SIZE , UMAC_MAX_FRAME_LEN );
1763+
1764+ /* Set MAC address */
1765+ umac_set_hw_addr (priv , dev -> dev_addr );
1766+
1767+ umac_enable_set (priv , CMD_RX_EN , 1 );
1768+
1769+ /* TX pipe enable */
1770+ topctrl_writel (priv , 0 , TX_FLUSH_CNTL );
1771+
1772+ umac_enable_set (priv , CMD_TX_EN , 1 );
1773+
1774+ ret = tdma_enable_set (priv , 1 );
1775+ if (ret ) {
1776+ netdev_err (dev , "TDMA timeout!\n" );
1777+ goto out_free_rx_ring ;
1778+ }
1779+
1780+ phy_resume (priv -> phydev );
1781+
1782+ bcm_sysport_netif_start (dev );
1783+
1784+ return 0 ;
1785+
1786+ out_free_rx_ring :
1787+ bcm_sysport_fini_rx_ring (priv );
1788+ out_free_tx_rings :
1789+ for (i = 0 ; i < dev -> num_tx_queues ; i ++ )
1790+ bcm_sysport_fini_tx_ring (priv , i );
1791+ return ret ;
1792+ }
1793+ #endif
1794+
1795+ static SIMPLE_DEV_PM_OPS (bcm_sysport_pm_ops ,
1796+ bcm_sysport_suspend , bcm_sysport_resume ) ;
1797+
16431798static const struct of_device_id bcm_sysport_of_match [] = {
16441799 { .compatible = "brcm,systemport-v1.00" },
16451800 { .compatible = "brcm,systemport" },
@@ -1653,6 +1808,7 @@ static struct platform_driver bcm_sysport_driver = {
16531808 .name = "brcm-systemport" ,
16541809 .owner = THIS_MODULE ,
16551810 .of_match_table = bcm_sysport_of_match ,
1811+ .pm = & bcm_sysport_pm_ops ,
16561812 },
16571813};
16581814module_platform_driver (bcm_sysport_driver );
0 commit comments