Commit 29feff39 authored by Joao Pinto's avatar Joao Pinto Committed by David S. Miller

net: stmmac: flow_ctrl functions adapted to mtl

This patch adapts flow_ctrl function to prepare it for multiple queues.
Signed-off-by: default avatarJoao Pinto <jpinto@synopsys.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d43042f4
...@@ -476,7 +476,7 @@ struct stmmac_ops { ...@@ -476,7 +476,7 @@ struct stmmac_ops {
void (*set_filter)(struct mac_device_info *hw, struct net_device *dev); void (*set_filter)(struct mac_device_info *hw, struct net_device *dev);
/* Flow control setting */ /* Flow control setting */
void (*flow_ctrl)(struct mac_device_info *hw, unsigned int duplex, void (*flow_ctrl)(struct mac_device_info *hw, unsigned int duplex,
unsigned int fc, unsigned int pause_time); unsigned int fc, unsigned int pause_time, u32 tx_cnt);
/* Set power management mode (e.g. magic frame) */ /* Set power management mode (e.g. magic frame) */
void (*pmt)(struct mac_device_info *hw, unsigned long mode); void (*pmt)(struct mac_device_info *hw, unsigned long mode);
/* Set/Get Unicast MAC addresses */ /* Set/Get Unicast MAC addresses */
......
...@@ -216,7 +216,8 @@ static void dwmac1000_set_filter(struct mac_device_info *hw, ...@@ -216,7 +216,8 @@ static void dwmac1000_set_filter(struct mac_device_info *hw,
static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
unsigned int fc, unsigned int pause_time) unsigned int fc, unsigned int pause_time,
u32 tx_cnt)
{ {
void __iomem *ioaddr = hw->pcsr; void __iomem *ioaddr = hw->pcsr;
/* Set flow such that DZPQ in Mac Register 6 is 0, /* Set flow such that DZPQ in Mac Register 6 is 0,
......
...@@ -131,7 +131,8 @@ static void dwmac100_set_filter(struct mac_device_info *hw, ...@@ -131,7 +131,8 @@ static void dwmac100_set_filter(struct mac_device_info *hw,
} }
static void dwmac100_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, static void dwmac100_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
unsigned int fc, unsigned int pause_time) unsigned int fc, unsigned int pause_time,
u32 tx_cnt)
{ {
void __iomem *ioaddr = hw->pcsr; void __iomem *ioaddr = hw->pcsr;
unsigned int flow = MAC_FLOW_CTRL_ENABLE; unsigned int flow = MAC_FLOW_CTRL_ENABLE;
......
...@@ -336,11 +336,12 @@ static void dwmac4_set_filter(struct mac_device_info *hw, ...@@ -336,11 +336,12 @@ static void dwmac4_set_filter(struct mac_device_info *hw,
} }
static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
unsigned int fc, unsigned int pause_time) unsigned int fc, unsigned int pause_time,
u32 tx_cnt)
{ {
void __iomem *ioaddr = hw->pcsr; void __iomem *ioaddr = hw->pcsr;
u32 channel = STMMAC_CHAN0; /* FIXME */
unsigned int flow = 0; unsigned int flow = 0;
u32 queue = 0;
pr_debug("GMAC Flow-Control:\n"); pr_debug("GMAC Flow-Control:\n");
if (fc & FLOW_RX) { if (fc & FLOW_RX) {
...@@ -350,13 +351,18 @@ static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, ...@@ -350,13 +351,18 @@ static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
} }
if (fc & FLOW_TX) { if (fc & FLOW_TX) {
pr_debug("\tTransmit Flow-Control ON\n"); pr_debug("\tTransmit Flow-Control ON\n");
flow |= GMAC_TX_FLOW_CTRL_TFE;
writel(flow, ioaddr + GMAC_QX_TX_FLOW_CTRL(channel));
if (duplex) { if (duplex)
pr_debug("\tduplex mode: PAUSE %d\n", pause_time); pr_debug("\tduplex mode: PAUSE %d\n", pause_time);
flow |= (pause_time << GMAC_TX_FLOW_CTRL_PT_SHIFT);
writel(flow, ioaddr + GMAC_QX_TX_FLOW_CTRL(channel)); for (queue = 0; queue < tx_cnt; queue++) {
flow |= GMAC_TX_FLOW_CTRL_TFE;
if (duplex)
flow |=
(pause_time << GMAC_TX_FLOW_CTRL_PT_SHIFT);
writel(flow, ioaddr + GMAC_QX_TX_FLOW_CTRL(queue));
} }
} }
} }
......
...@@ -481,6 +481,7 @@ stmmac_set_pauseparam(struct net_device *netdev, ...@@ -481,6 +481,7 @@ stmmac_set_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause) struct ethtool_pauseparam *pause)
{ {
struct stmmac_priv *priv = netdev_priv(netdev); struct stmmac_priv *priv = netdev_priv(netdev);
u32 tx_cnt = priv->plat->tx_queues_to_use;
struct phy_device *phy = netdev->phydev; struct phy_device *phy = netdev->phydev;
int new_pause = FLOW_OFF; int new_pause = FLOW_OFF;
...@@ -511,7 +512,7 @@ stmmac_set_pauseparam(struct net_device *netdev, ...@@ -511,7 +512,7 @@ stmmac_set_pauseparam(struct net_device *netdev,
} }
priv->hw->mac->flow_ctrl(priv->hw, phy->duplex, priv->flow_ctrl, priv->hw->mac->flow_ctrl(priv->hw, phy->duplex, priv->flow_ctrl,
priv->pause); priv->pause, tx_cnt);
return 0; return 0;
} }
......
...@@ -672,6 +672,19 @@ static void stmmac_release_ptp(struct stmmac_priv *priv) ...@@ -672,6 +672,19 @@ static void stmmac_release_ptp(struct stmmac_priv *priv)
stmmac_ptp_unregister(priv); stmmac_ptp_unregister(priv);
} }
/**
* stmmac_mac_flow_ctrl - Configure flow control in all queues
* @priv: driver private structure
* Description: It is used for configuring the flow control in all queues
*/
static void stmmac_mac_flow_ctrl(struct stmmac_priv *priv, u32 duplex)
{
u32 tx_cnt = priv->plat->tx_queues_to_use;
priv->hw->mac->flow_ctrl(priv->hw, duplex, priv->flow_ctrl,
priv->pause, tx_cnt);
}
/** /**
* stmmac_adjust_link - adjusts the link parameters * stmmac_adjust_link - adjusts the link parameters
* @dev: net device structure * @dev: net device structure
...@@ -687,7 +700,6 @@ static void stmmac_adjust_link(struct net_device *dev) ...@@ -687,7 +700,6 @@ static void stmmac_adjust_link(struct net_device *dev)
struct phy_device *phydev = dev->phydev; struct phy_device *phydev = dev->phydev;
unsigned long flags; unsigned long flags;
int new_state = 0; int new_state = 0;
unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
if (!phydev) if (!phydev)
return; return;
...@@ -709,8 +721,7 @@ static void stmmac_adjust_link(struct net_device *dev) ...@@ -709,8 +721,7 @@ static void stmmac_adjust_link(struct net_device *dev)
} }
/* Flow Control operation */ /* Flow Control operation */
if (phydev->pause) if (phydev->pause)
priv->hw->mac->flow_ctrl(priv->hw, phydev->duplex, stmmac_mac_flow_ctrl(priv, phydev->duplex);
fc, pause_time);
if (phydev->speed != priv->speed) { if (phydev->speed != priv->speed) {
new_state = 1; new_state = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment