Commit f63db4ef authored by Doug Berger's avatar Doug Berger Committed by David S. Miller

net: bcmgenet: Refactor bcmgenet_set_features()

In preparation for unconditionally enabling TX and RX checksum
offloads, refactor bcmgenet_set_features() a bit such that
__netdev_update_features() during register_netdev() can make sure
that features are correctly programmed during network device
registration.

Since we can now be called during register_netdev() with clocks
gated, we need to temporarily turn them on/off in order to have a
successful register programming.

We also move the CRC forward setting read into
bcmgenet_set_features() since priv->crc_fwd_en matters while
turning on RX checksum offload, that way we are guaranteed they
are in sync in case we ever add support for NETIF_F_RXFCS at some
point in the future.
Signed-off-by: default avatarDoug Berger <opendmb@gmail.com>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 81015539
...@@ -508,7 +508,7 @@ static int bcmgenet_set_link_ksettings(struct net_device *dev, ...@@ -508,7 +508,7 @@ static int bcmgenet_set_link_ksettings(struct net_device *dev,
return phy_ethtool_ksettings_set(dev->phydev, cmd); return phy_ethtool_ksettings_set(dev->phydev, cmd);
} }
static int bcmgenet_set_rx_csum(struct net_device *dev, static void bcmgenet_set_rx_csum(struct net_device *dev,
netdev_features_t wanted) netdev_features_t wanted)
{ {
struct bcmgenet_priv *priv = netdev_priv(dev); struct bcmgenet_priv *priv = netdev_priv(dev);
...@@ -535,11 +535,9 @@ static int bcmgenet_set_rx_csum(struct net_device *dev, ...@@ -535,11 +535,9 @@ static int bcmgenet_set_rx_csum(struct net_device *dev,
rbuf_chk_ctrl &= ~RBUF_SKIP_FCS; rbuf_chk_ctrl &= ~RBUF_SKIP_FCS;
bcmgenet_rbuf_writel(priv, rbuf_chk_ctrl, RBUF_CHK_CTRL); bcmgenet_rbuf_writel(priv, rbuf_chk_ctrl, RBUF_CHK_CTRL);
return 0;
} }
static int bcmgenet_set_tx_csum(struct net_device *dev, static void bcmgenet_set_tx_csum(struct net_device *dev,
netdev_features_t wanted) netdev_features_t wanted)
{ {
struct bcmgenet_priv *priv = netdev_priv(dev); struct bcmgenet_priv *priv = netdev_priv(dev);
...@@ -563,21 +561,27 @@ static int bcmgenet_set_tx_csum(struct net_device *dev, ...@@ -563,21 +561,27 @@ static int bcmgenet_set_tx_csum(struct net_device *dev,
bcmgenet_tbuf_ctrl_set(priv, tbuf_ctrl); bcmgenet_tbuf_ctrl_set(priv, tbuf_ctrl);
bcmgenet_rbuf_writel(priv, rbuf_ctrl, RBUF_CTRL); bcmgenet_rbuf_writel(priv, rbuf_ctrl, RBUF_CTRL);
return 0;
} }
static int bcmgenet_set_features(struct net_device *dev, static int bcmgenet_set_features(struct net_device *dev,
netdev_features_t features) netdev_features_t features)
{ {
netdev_features_t changed = features ^ dev->features; struct bcmgenet_priv *priv = netdev_priv(dev);
netdev_features_t wanted = dev->wanted_features; u32 reg;
int ret = 0; int ret;
ret = clk_prepare_enable(priv->clk);
if (ret)
return ret;
/* Make sure we reflect the value of CRC_CMD_FWD */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
priv->crc_fwd_en = !!(reg & CMD_CRC_FWD);
if (changed & NETIF_F_HW_CSUM) bcmgenet_set_tx_csum(dev, features);
ret = bcmgenet_set_tx_csum(dev, wanted); bcmgenet_set_rx_csum(dev, features);
if (changed & (NETIF_F_RXCSUM))
ret = bcmgenet_set_rx_csum(dev, wanted); clk_disable_unprepare(priv->clk);
return ret; return ret;
} }
...@@ -2880,10 +2884,6 @@ static int bcmgenet_open(struct net_device *dev) ...@@ -2880,10 +2884,6 @@ static int bcmgenet_open(struct net_device *dev)
init_umac(priv); init_umac(priv);
/* Make sure we reflect the value of CRC_CMD_FWD */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
priv->crc_fwd_en = !!(reg & CMD_CRC_FWD);
bcmgenet_set_hw_addr(priv, dev->dev_addr); bcmgenet_set_hw_addr(priv, dev->dev_addr);
if (priv->internal_phy) { if (priv->internal_phy) {
......
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