static int dpaa_set_pauseparam(struct net_device *net_dev, struct ethtool_pauseparam *epause) { struct mac_device *mac_dev; struct phy_device *phydev; bool rx_pause, tx_pause; struct dpaa_priv *priv; int err; priv = netdev_priv(net_dev); mac_dev = priv->mac_dev; phydev = net_dev->phydev; if (!phydev) { netdev_err(net_dev, "phy device not initialized\n"); return -ENODEV; } if (!phy_validate_pause(phydev, epause)) return -EINVAL; /* The MAC should know how to handle PAUSE frame autonegotiation before * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE * settings. */ mac_dev->autoneg_pause = !!epause->autoneg; mac_dev->rx_pause_req = !!epause->rx_pause; mac_dev->tx_pause_req = !!epause->tx_pause; /* Determine the sym/asym advertised PAUSE capabilities from the desired * rx/tx pause settings. */ phy_set_asym_pause(phydev, epause->rx_pause, epause->tx_pause); fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause); err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause); if (err < 0) netdev_err(net_dev, "set_mac_active_pause() = %d\n", err); return err; }
static int dpaa_set_pauseparam(struct net_device *net_dev, struct ethtool_pauseparam *epause) { struct mac_device *mac_dev; struct phy_device *phydev; bool rx_pause, tx_pause; struct dpaa_priv *priv; u32 newadv, oldadv; int err; priv = netdev_priv(net_dev); mac_dev = priv->mac_dev; phydev = net_dev->phydev; if (!phydev) { netdev_err(net_dev, "phy device not initialized\n"); return -ENODEV; } if (!(phydev->supported & SUPPORTED_Pause) || (!(phydev->supported & SUPPORTED_Asym_Pause) && (epause->rx_pause != epause->tx_pause))) return -EINVAL; /* The MAC should know how to handle PAUSE frame autonegotiation before * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE * settings. */ mac_dev->autoneg_pause = !!epause->autoneg; mac_dev->rx_pause_req = !!epause->rx_pause; mac_dev->tx_pause_req = !!epause->tx_pause; /* Determine the sym/asym advertised PAUSE capabilities from the desired * rx/tx pause settings. */ newadv = 0; if (epause->rx_pause) newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause; if (epause->tx_pause) newadv |= ADVERTISED_Asym_Pause; oldadv = phydev->advertising & (ADVERTISED_Pause | ADVERTISED_Asym_Pause); /* If there are differences between the old and the new advertised * values, restart PHY autonegotiation and advertise the new values. */ if (oldadv != newadv) { phydev->advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause); phydev->advertising |= newadv; if (phydev->autoneg) { err = phy_start_aneg(phydev); if (err < 0) netdev_err(net_dev, "phy_start_aneg() = %d\n", err); } } fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause); err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause); if (err < 0) netdev_err(net_dev, "set_mac_active_pause() = %d\n", err); return err; }