diff options
author | Mugunthan V N <mugunthanvnm@ti.com> | 2014-09-08 13:24:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-08 19:00:30 -0400 |
commit | 1923d6e4186c9470a83d0179e86e1aea8cfcbe67 (patch) | |
tree | fb299adcec814c969778592edf0c1b09339eaec8 | |
parent | 119eccd5e7f6fcded9db6b7aa14f5f459d2a22ba (diff) |
drivers: net: cpsw: Add support for pause frames
CPSW supports both rx and tx pause frames for flow control.
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/ti/cpsw.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 03b409988566..76e73687d720 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
@@ -397,6 +397,8 @@ struct cpsw_priv { | |||
397 | struct cpdma_ctlr *dma; | 397 | struct cpdma_ctlr *dma; |
398 | struct cpdma_chan *txch, *rxch; | 398 | struct cpdma_chan *txch, *rxch; |
399 | struct cpsw_ale *ale; | 399 | struct cpsw_ale *ale; |
400 | bool rx_pause; | ||
401 | bool tx_pause; | ||
400 | /* snapshot of IRQ numbers */ | 402 | /* snapshot of IRQ numbers */ |
401 | u32 irqs_table[4]; | 403 | u32 irqs_table[4]; |
402 | u32 num_irqs; | 404 | u32 num_irqs; |
@@ -832,6 +834,12 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, | |||
832 | else if (phy->speed == 10) | 834 | else if (phy->speed == 10) |
833 | mac_control |= BIT(18); /* In Band mode */ | 835 | mac_control |= BIT(18); /* In Band mode */ |
834 | 836 | ||
837 | if (priv->rx_pause) | ||
838 | mac_control |= BIT(3); | ||
839 | |||
840 | if (priv->tx_pause) | ||
841 | mac_control |= BIT(4); | ||
842 | |||
835 | *link = true; | 843 | *link = true; |
836 | } else { | 844 | } else { |
837 | mac_control = 0; | 845 | mac_control = 0; |
@@ -1223,6 +1231,9 @@ static int cpsw_ndo_open(struct net_device *ndev) | |||
1223 | /* enable statistics collection only on all ports */ | 1231 | /* enable statistics collection only on all ports */ |
1224 | __raw_writel(0x7, &priv->regs->stat_port_en); | 1232 | __raw_writel(0x7, &priv->regs->stat_port_en); |
1225 | 1233 | ||
1234 | /* Enable internal fifo flow control */ | ||
1235 | writel(0x7, &priv->regs->flow_control); | ||
1236 | |||
1226 | if (WARN_ON(!priv->data.rx_descs)) | 1237 | if (WARN_ON(!priv->data.rx_descs)) |
1227 | priv->data.rx_descs = 128; | 1238 | priv->data.rx_descs = 128; |
1228 | 1239 | ||
@@ -1784,6 +1795,30 @@ static int cpsw_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) | |||
1784 | return -EOPNOTSUPP; | 1795 | return -EOPNOTSUPP; |
1785 | } | 1796 | } |
1786 | 1797 | ||
1798 | static void cpsw_get_pauseparam(struct net_device *ndev, | ||
1799 | struct ethtool_pauseparam *pause) | ||
1800 | { | ||
1801 | struct cpsw_priv *priv = netdev_priv(ndev); | ||
1802 | |||
1803 | pause->autoneg = AUTONEG_DISABLE; | ||
1804 | pause->rx_pause = priv->rx_pause ? true : false; | ||
1805 | pause->tx_pause = priv->tx_pause ? true : false; | ||
1806 | } | ||
1807 | |||
1808 | static int cpsw_set_pauseparam(struct net_device *ndev, | ||
1809 | struct ethtool_pauseparam *pause) | ||
1810 | { | ||
1811 | struct cpsw_priv *priv = netdev_priv(ndev); | ||
1812 | bool link; | ||
1813 | |||
1814 | priv->rx_pause = pause->rx_pause ? true : false; | ||
1815 | priv->tx_pause = pause->tx_pause ? true : false; | ||
1816 | |||
1817 | for_each_slave(priv, _cpsw_adjust_link, priv, &link); | ||
1818 | |||
1819 | return 0; | ||
1820 | } | ||
1821 | |||
1787 | static const struct ethtool_ops cpsw_ethtool_ops = { | 1822 | static const struct ethtool_ops cpsw_ethtool_ops = { |
1788 | .get_drvinfo = cpsw_get_drvinfo, | 1823 | .get_drvinfo = cpsw_get_drvinfo, |
1789 | .get_msglevel = cpsw_get_msglevel, | 1824 | .get_msglevel = cpsw_get_msglevel, |
@@ -1797,6 +1832,8 @@ static const struct ethtool_ops cpsw_ethtool_ops = { | |||
1797 | .get_sset_count = cpsw_get_sset_count, | 1832 | .get_sset_count = cpsw_get_sset_count, |
1798 | .get_strings = cpsw_get_strings, | 1833 | .get_strings = cpsw_get_strings, |
1799 | .get_ethtool_stats = cpsw_get_ethtool_stats, | 1834 | .get_ethtool_stats = cpsw_get_ethtool_stats, |
1835 | .get_pauseparam = cpsw_get_pauseparam, | ||
1836 | .set_pauseparam = cpsw_set_pauseparam, | ||
1800 | .get_wol = cpsw_get_wol, | 1837 | .get_wol = cpsw_get_wol, |
1801 | .set_wol = cpsw_set_wol, | 1838 | .set_wol = cpsw_set_wol, |
1802 | .get_regs_len = cpsw_get_regs_len, | 1839 | .get_regs_len = cpsw_get_regs_len, |