net: bcmgenet: Refactor bcmgenet_set_features()
authorDoug Berger <opendmb@gmail.com>
Wed, 18 Dec 2019 00:51:11 +0000 (16:51 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 Dec 2019 02:11:10 +0000 (18:11 -0800)
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: Doug Berger <opendmb@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/genet/bcmgenet.c

index 13cbe58..811713e 100644 (file)
@@ -508,8 +508,8 @@ static int bcmgenet_set_link_ksettings(struct net_device *dev,
        return phy_ethtool_ksettings_set(dev->phydev, cmd);
 }
 
-static int bcmgenet_set_rx_csum(struct net_device *dev,
-                               netdev_features_t wanted)
+static void bcmgenet_set_rx_csum(struct net_device *dev,
+                                netdev_features_t wanted)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
        u32 rbuf_chk_ctrl;
@@ -535,12 +535,10 @@ static int bcmgenet_set_rx_csum(struct net_device *dev,
                rbuf_chk_ctrl &= ~RBUF_SKIP_FCS;
 
        bcmgenet_rbuf_writel(priv, rbuf_chk_ctrl, RBUF_CHK_CTRL);
-
-       return 0;
 }
 
-static int bcmgenet_set_tx_csum(struct net_device *dev,
-                               netdev_features_t wanted)
+static void bcmgenet_set_tx_csum(struct net_device *dev,
+                                netdev_features_t wanted)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
        bool desc_64b_en;
@@ -563,21 +561,27 @@ static int bcmgenet_set_tx_csum(struct net_device *dev,
 
        bcmgenet_tbuf_ctrl_set(priv, tbuf_ctrl);
        bcmgenet_rbuf_writel(priv, rbuf_ctrl, RBUF_CTRL);
-
-       return 0;
 }
 
 static int bcmgenet_set_features(struct net_device *dev,
                                 netdev_features_t features)
 {
-       netdev_features_t changed = features ^ dev->features;
-       netdev_features_t wanted = dev->wanted_features;
-       int ret = 0;
+       struct bcmgenet_priv *priv = netdev_priv(dev);
+       u32 reg;
+       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)
-               ret = bcmgenet_set_tx_csum(dev, wanted);
-       if (changed & (NETIF_F_RXCSUM))
-               ret = bcmgenet_set_rx_csum(dev, wanted);
+       bcmgenet_set_tx_csum(dev, features);
+       bcmgenet_set_rx_csum(dev, features);
+
+       clk_disable_unprepare(priv->clk);
 
        return ret;
 }
@@ -2880,10 +2884,6 @@ static int bcmgenet_open(struct net_device *dev)
 
        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);
 
        if (priv->internal_phy) {