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

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
Loading
Loading
Loading
Loading
+19 −19
Original line number Diff line number Diff line
@@ -508,7 +508,7 @@ 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,
static void bcmgenet_set_rx_csum(struct net_device *dev,
				 netdev_features_t wanted)
{
	struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -535,11 +535,9 @@ 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,
static void bcmgenet_set_tx_csum(struct net_device *dev,
				 netdev_features_t wanted)
{
	struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -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) {