Commit 10b476c5 authored by Florian Fainelli's avatar Florian Fainelli Committed by David S. Miller

net: systemport: Refactor bcm_sysport_set_features()

In preparation for unconditionally enabling TX and RX checksum offloads,
refactor bcm_sysport_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
bcm_sysport_set_features() since priv->crc_fwd 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 avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 460b3601
...@@ -126,8 +126,8 @@ static inline void tdma_port_write_desc_addr(struct bcm_sysport_priv *priv, ...@@ -126,8 +126,8 @@ static inline void tdma_port_write_desc_addr(struct bcm_sysport_priv *priv,
} }
/* Ethtool operations */ /* Ethtool operations */
static int bcm_sysport_set_rx_csum(struct net_device *dev, static void bcm_sysport_set_rx_csum(struct net_device *dev,
netdev_features_t wanted) netdev_features_t wanted)
{ {
struct bcm_sysport_priv *priv = netdev_priv(dev); struct bcm_sysport_priv *priv = netdev_priv(dev);
u32 reg; u32 reg;
...@@ -157,12 +157,10 @@ static int bcm_sysport_set_rx_csum(struct net_device *dev, ...@@ -157,12 +157,10 @@ static int bcm_sysport_set_rx_csum(struct net_device *dev,
reg &= ~RXCHK_BRCM_TAG_EN; reg &= ~RXCHK_BRCM_TAG_EN;
rxchk_writel(priv, reg, RXCHK_CONTROL); rxchk_writel(priv, reg, RXCHK_CONTROL);
return 0;
} }
static int bcm_sysport_set_tx_csum(struct net_device *dev, static void bcm_sysport_set_tx_csum(struct net_device *dev,
netdev_features_t wanted) netdev_features_t wanted)
{ {
struct bcm_sysport_priv *priv = netdev_priv(dev); struct bcm_sysport_priv *priv = netdev_priv(dev);
u32 reg; u32 reg;
...@@ -177,23 +175,24 @@ static int bcm_sysport_set_tx_csum(struct net_device *dev, ...@@ -177,23 +175,24 @@ static int bcm_sysport_set_tx_csum(struct net_device *dev,
else else
reg &= ~tdma_control_bit(priv, TSB_EN); reg &= ~tdma_control_bit(priv, TSB_EN);
tdma_writel(priv, reg, TDMA_CONTROL); tdma_writel(priv, reg, TDMA_CONTROL);
return 0;
} }
static int bcm_sysport_set_features(struct net_device *dev, static int bcm_sysport_set_features(struct net_device *dev,
netdev_features_t features) netdev_features_t features)
{ {
netdev_features_t changed = features ^ dev->features; struct bcm_sysport_priv *priv = netdev_priv(dev);
netdev_features_t wanted = dev->wanted_features;
int ret = 0; /* Read CRC forward */
if (!priv->is_lite)
priv->crc_fwd = !!(umac_readl(priv, UMAC_CMD) & CMD_CRC_FWD);
else
priv->crc_fwd = !((gib_readl(priv, GIB_CONTROL) &
GIB_FCS_STRIP) >> GIB_FCS_STRIP_SHIFT);
if (changed & NETIF_F_RXCSUM) bcm_sysport_set_rx_csum(dev, features);
ret = bcm_sysport_set_rx_csum(dev, wanted); bcm_sysport_set_tx_csum(dev, features);
if (changed & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))
ret = bcm_sysport_set_tx_csum(dev, wanted);
return ret; return 0;
} }
/* Hardware counters must be kept in sync because the order/offset /* Hardware counters must be kept in sync because the order/offset
...@@ -1976,13 +1975,6 @@ static int bcm_sysport_open(struct net_device *dev) ...@@ -1976,13 +1975,6 @@ static int bcm_sysport_open(struct net_device *dev)
/* Set MAC address */ /* Set MAC address */
umac_set_hw_addr(priv, dev->dev_addr); umac_set_hw_addr(priv, dev->dev_addr);
/* Read CRC forward */
if (!priv->is_lite)
priv->crc_fwd = !!(umac_readl(priv, UMAC_CMD) & CMD_CRC_FWD);
else
priv->crc_fwd = !((gib_readl(priv, GIB_CONTROL) &
GIB_FCS_STRIP) >> GIB_FCS_STRIP_SHIFT);
phydev = of_phy_connect(dev, priv->phy_dn, bcm_sysport_adj_link, phydev = of_phy_connect(dev, priv->phy_dn, bcm_sysport_adj_link,
0, priv->phy_interface); 0, priv->phy_interface);
if (!phydev) { if (!phydev) {
......
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