Commit c9e19ea4 authored by David S. Miller's avatar David S. Miller

Merge branch 'stmmac-rework-speed-selection'

Corentin Labbe says:

====================
net-next: stmmac: rework the speed selection

The current stmmac_adjust_link() part which handle speed have
some if (has_platform) code and my dwmac-sun8i will add more of them.

So we need to handle better speed selection.
Moreover the struct link member speed and port are hard to guess their
purpose. And their unique usage are to be combined for writing speed.

My first try was to create an adjust_link() in stmmac_ops but it duplicate some code

The current solution is to have direct value for 10/100/1000 and a mask for them.

The first 4 patchs fix some minor problem found in stmmac_adjust_link() and reported by Florian Fainelli in my previous serie.
The last patch is the real work.

This series is tested on cubieboard2 (dwmac1000) and opipc (dwmac-sun8i).

Changes since v3:
- Added the patch #4 "Convert old_link to bool" as suggested by Joe Perches
- Changed the speedmask

Changes since v2:
- Use true/false for new_state in patch #1
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 26d732ba ca84dfb9
...@@ -549,9 +549,11 @@ extern const struct stmmac_hwtimestamp stmmac_ptp; ...@@ -549,9 +549,11 @@ extern const struct stmmac_hwtimestamp stmmac_ptp;
extern const struct stmmac_mode_ops dwmac4_ring_mode_ops; extern const struct stmmac_mode_ops dwmac4_ring_mode_ops;
struct mac_link { struct mac_link {
int port; u32 speed_mask;
int duplex; u32 speed10;
int speed; u32 speed100;
u32 speed1000;
u32 duplex;
}; };
struct mii_regs { struct mii_regs {
......
...@@ -45,15 +45,17 @@ static void dwmac1000_core_init(struct mac_device_info *hw, int mtu) ...@@ -45,15 +45,17 @@ static void dwmac1000_core_init(struct mac_device_info *hw, int mtu)
if (hw->ps) { if (hw->ps) {
value |= GMAC_CONTROL_TE; value |= GMAC_CONTROL_TE;
if (hw->ps == SPEED_1000) { value &= ~hw->link.speed_mask;
value &= ~GMAC_CONTROL_PS; switch (hw->ps) {
} else { case SPEED_1000:
value |= GMAC_CONTROL_PS; value |= hw->link.speed1000;
break;
if (hw->ps == SPEED_10) case SPEED_100:
value &= ~GMAC_CONTROL_FES; value |= hw->link.speed100;
else break;
value |= GMAC_CONTROL_FES; case SPEED_10:
value |= hw->link.speed10;
break;
} }
} }
...@@ -531,9 +533,11 @@ struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins, ...@@ -531,9 +533,11 @@ struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
mac->mac = &dwmac1000_ops; mac->mac = &dwmac1000_ops;
mac->dma = &dwmac1000_dma_ops; mac->dma = &dwmac1000_dma_ops;
mac->link.port = GMAC_CONTROL_PS;
mac->link.duplex = GMAC_CONTROL_DM; mac->link.duplex = GMAC_CONTROL_DM;
mac->link.speed = GMAC_CONTROL_FES; mac->link.speed10 = GMAC_CONTROL_PS;
mac->link.speed100 = GMAC_CONTROL_PS | GMAC_CONTROL_FES;
mac->link.speed1000 = 0;
mac->link.speed_mask = GMAC_CONTROL_PS | GMAC_CONTROL_FES;
mac->mii.addr = GMAC_MII_ADDR; mac->mii.addr = GMAC_MII_ADDR;
mac->mii.data = GMAC_MII_DATA; mac->mii.data = GMAC_MII_DATA;
mac->mii.addr_shift = 11; mac->mii.addr_shift = 11;
......
...@@ -175,9 +175,11 @@ struct mac_device_info *dwmac100_setup(void __iomem *ioaddr, int *synopsys_id) ...@@ -175,9 +175,11 @@ struct mac_device_info *dwmac100_setup(void __iomem *ioaddr, int *synopsys_id)
mac->mac = &dwmac100_ops; mac->mac = &dwmac100_ops;
mac->dma = &dwmac100_dma_ops; mac->dma = &dwmac100_dma_ops;
mac->link.port = MAC_CONTROL_PS;
mac->link.duplex = MAC_CONTROL_F; mac->link.duplex = MAC_CONTROL_F;
mac->link.speed = 0; mac->link.speed10 = 0;
mac->link.speed100 = 0;
mac->link.speed1000 = 0;
mac->link.speed_mask = MAC_CONTROL_PS;
mac->mii.addr = MAC_MII_ADDR; mac->mii.addr = MAC_MII_ADDR;
mac->mii.data = MAC_MII_DATA; mac->mii.data = MAC_MII_DATA;
mac->mii.addr_shift = 11; mac->mii.addr_shift = 11;
......
...@@ -35,15 +35,17 @@ static void dwmac4_core_init(struct mac_device_info *hw, int mtu) ...@@ -35,15 +35,17 @@ static void dwmac4_core_init(struct mac_device_info *hw, int mtu)
if (hw->ps) { if (hw->ps) {
value |= GMAC_CONFIG_TE; value |= GMAC_CONFIG_TE;
if (hw->ps == SPEED_1000) { value &= hw->link.speed_mask;
value &= ~GMAC_CONFIG_PS; switch (hw->ps) {
} else { case SPEED_1000:
value |= GMAC_CONFIG_PS; value |= hw->link.speed1000;
break;
if (hw->ps == SPEED_10) case SPEED_100:
value &= ~GMAC_CONFIG_FES; value |= hw->link.speed100;
else break;
value |= GMAC_CONFIG_FES; case SPEED_10:
value |= hw->link.speed10;
break;
} }
} }
...@@ -747,9 +749,11 @@ struct mac_device_info *dwmac4_setup(void __iomem *ioaddr, int mcbins, ...@@ -747,9 +749,11 @@ struct mac_device_info *dwmac4_setup(void __iomem *ioaddr, int mcbins,
if (mac->multicast_filter_bins) if (mac->multicast_filter_bins)
mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins); mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
mac->link.port = GMAC_CONFIG_PS;
mac->link.duplex = GMAC_CONFIG_DM; mac->link.duplex = GMAC_CONFIG_DM;
mac->link.speed = GMAC_CONFIG_FES; mac->link.speed10 = GMAC_CONFIG_PS;
mac->link.speed100 = GMAC_CONFIG_FES | GMAC_CONFIG_PS;
mac->link.speed1000 = 0;
mac->link.speed_mask = GMAC_CONFIG_FES | GMAC_CONFIG_PS;
mac->mii.addr = GMAC_MDIO_ADDR; mac->mii.addr = GMAC_MDIO_ADDR;
mac->mii.data = GMAC_MDIO_DATA; mac->mii.data = GMAC_MDIO_DATA;
mac->mii.addr_shift = 21; mac->mii.addr_shift = 21;
......
...@@ -104,7 +104,7 @@ struct stmmac_priv { ...@@ -104,7 +104,7 @@ struct stmmac_priv {
/* TX Queue */ /* TX Queue */
struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES]; struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES];
int oldlink; bool oldlink;
int speed; int speed;
int oldduplex; int oldduplex;
unsigned int flow_ctrl; unsigned int flow_ctrl;
......
...@@ -775,7 +775,7 @@ static void stmmac_adjust_link(struct net_device *dev) ...@@ -775,7 +775,7 @@ static void stmmac_adjust_link(struct net_device *dev)
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phydev = dev->phydev; struct phy_device *phydev = dev->phydev;
unsigned long flags; unsigned long flags;
int new_state = 0; bool new_state = false;
if (!phydev) if (!phydev)
return; return;
...@@ -788,8 +788,8 @@ static void stmmac_adjust_link(struct net_device *dev) ...@@ -788,8 +788,8 @@ static void stmmac_adjust_link(struct net_device *dev)
/* Now we make sure that we can be in full duplex mode. /* Now we make sure that we can be in full duplex mode.
* If not, we operate in half-duplex mode. */ * If not, we operate in half-duplex mode. */
if (phydev->duplex != priv->oldduplex) { if (phydev->duplex != priv->oldduplex) {
new_state = 1; new_state = true;
if (!(phydev->duplex)) if (!phydev->duplex)
ctrl &= ~priv->hw->link.duplex; ctrl &= ~priv->hw->link.duplex;
else else
ctrl |= priv->hw->link.duplex; ctrl |= priv->hw->link.duplex;
...@@ -800,30 +800,17 @@ static void stmmac_adjust_link(struct net_device *dev) ...@@ -800,30 +800,17 @@ static void stmmac_adjust_link(struct net_device *dev)
stmmac_mac_flow_ctrl(priv, phydev->duplex); stmmac_mac_flow_ctrl(priv, phydev->duplex);
if (phydev->speed != priv->speed) { if (phydev->speed != priv->speed) {
new_state = 1; new_state = true;
ctrl &= ~priv->hw->link.speed_mask;
switch (phydev->speed) { switch (phydev->speed) {
case 1000: case SPEED_1000:
if (priv->plat->has_gmac || ctrl |= priv->hw->link.speed1000;
priv->plat->has_gmac4)
ctrl &= ~priv->hw->link.port;
break; break;
case 100: case SPEED_100:
if (priv->plat->has_gmac || ctrl |= priv->hw->link.speed100;
priv->plat->has_gmac4) {
ctrl |= priv->hw->link.port;
ctrl |= priv->hw->link.speed;
} else {
ctrl &= ~priv->hw->link.port;
}
break; break;
case 10: case SPEED_10:
if (priv->plat->has_gmac || ctrl |= priv->hw->link.speed10;
priv->plat->has_gmac4) {
ctrl |= priv->hw->link.port;
ctrl &= ~(priv->hw->link.speed);
} else {
ctrl &= ~priv->hw->link.port;
}
break; break;
default: default:
netif_warn(priv, link, priv->dev, netif_warn(priv, link, priv->dev,
...@@ -839,12 +826,12 @@ static void stmmac_adjust_link(struct net_device *dev) ...@@ -839,12 +826,12 @@ static void stmmac_adjust_link(struct net_device *dev)
writel(ctrl, priv->ioaddr + MAC_CTRL_REG); writel(ctrl, priv->ioaddr + MAC_CTRL_REG);
if (!priv->oldlink) { if (!priv->oldlink) {
new_state = 1; new_state = true;
priv->oldlink = 1; priv->oldlink = true;
} }
} else if (priv->oldlink) { } else if (priv->oldlink) {
new_state = 1; new_state = true;
priv->oldlink = 0; priv->oldlink = false;
priv->speed = SPEED_UNKNOWN; priv->speed = SPEED_UNKNOWN;
priv->oldduplex = DUPLEX_UNKNOWN; priv->oldduplex = DUPLEX_UNKNOWN;
} }
...@@ -907,7 +894,7 @@ static int stmmac_init_phy(struct net_device *dev) ...@@ -907,7 +894,7 @@ static int stmmac_init_phy(struct net_device *dev)
char bus_id[MII_BUS_ID_SIZE]; char bus_id[MII_BUS_ID_SIZE];
int interface = priv->plat->interface; int interface = priv->plat->interface;
int max_speed = priv->plat->max_speed; int max_speed = priv->plat->max_speed;
priv->oldlink = 0; priv->oldlink = false;
priv->speed = SPEED_UNKNOWN; priv->speed = SPEED_UNKNOWN;
priv->oldduplex = DUPLEX_UNKNOWN; priv->oldduplex = DUPLEX_UNKNOWN;
...@@ -4291,7 +4278,7 @@ int stmmac_suspend(struct device *dev) ...@@ -4291,7 +4278,7 @@ int stmmac_suspend(struct device *dev)
} }
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
priv->oldlink = 0; priv->oldlink = false;
priv->speed = SPEED_UNKNOWN; priv->speed = SPEED_UNKNOWN;
priv->oldduplex = DUPLEX_UNKNOWN; priv->oldduplex = DUPLEX_UNKNOWN;
return 0; return 0;
......
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