return 0;
 }
 
+static void bcmgenet_get_pauseparam(struct net_device *dev,
+                                   struct ethtool_pauseparam *epause)
+{
+       struct bcmgenet_priv *priv;
+       u32 umac_cmd;
+
+       priv = netdev_priv(dev);
+
+       epause->autoneg = priv->autoneg_pause;
+
+       if (netif_carrier_ok(dev)) {
+               /* report active state when link is up */
+               umac_cmd = bcmgenet_umac_readl(priv, UMAC_CMD);
+               epause->tx_pause = !(umac_cmd & CMD_TX_PAUSE_IGNORE);
+               epause->rx_pause = !(umac_cmd & CMD_RX_PAUSE_IGNORE);
+       } else {
+               /* otherwise report stored settings */
+               epause->tx_pause = priv->tx_pause;
+               epause->rx_pause = priv->rx_pause;
+       }
+}
+
+static int bcmgenet_set_pauseparam(struct net_device *dev,
+                                  struct ethtool_pauseparam *epause)
+{
+       struct bcmgenet_priv *priv = netdev_priv(dev);
+
+       if (!dev->phydev)
+               return -ENODEV;
+
+       if (!phy_validate_pause(dev->phydev, epause))
+               return -EINVAL;
+
+       priv->autoneg_pause = !!epause->autoneg;
+       priv->tx_pause = !!epause->tx_pause;
+       priv->rx_pause = !!epause->rx_pause;
+
+       bcmgenet_phy_pause_set(dev, priv->rx_pause, priv->tx_pause);
+
+       return 0;
+}
+
 /* standard ethtool support functions. */
 enum bcmgenet_stat_type {
        BCMGENET_STAT_NETDEV = -1,
        .get_ts_info            = ethtool_op_get_ts_info,
        .get_rxnfc              = bcmgenet_get_rxnfc,
        .set_rxnfc              = bcmgenet_set_rxnfc,
+       .get_pauseparam         = bcmgenet_get_pauseparam,
+       .set_pauseparam         = bcmgenet_set_pauseparam,
 };
 
 /* Power down the unimac, based on mode. */
                goto err_irq1;
        }
 
+       bcmgenet_phy_pause_set(dev, priv->rx_pause, priv->tx_pause);
+
        bcmgenet_netif_start(dev);
 
        netif_tx_start_all_queues(dev);
 
        spin_lock_init(&priv->lock);
 
+       /* Set default pause parameters */
+       priv->autoneg_pause = 1;
+       priv->tx_pause = 1;
+       priv->rx_pause = 1;
+
        SET_NETDEV_DEV(dev, &pdev->dev);
        dev_set_drvdata(&pdev->dev, dev);
        dev->watchdog_timeo = 2 * HZ;
 
 
        /* other misc variables */
        struct bcmgenet_hw_params *hw_params;
+       unsigned autoneg_pause:1;
+       unsigned tx_pause:1;
+       unsigned rx_pause:1;
 
        /* MDIO bus variables */
        wait_queue_head_t wq;
 int bcmgenet_mii_config(struct net_device *dev, bool init);
 int bcmgenet_mii_probe(struct net_device *dev);
 void bcmgenet_mii_exit(struct net_device *dev);
+void bcmgenet_phy_pause_set(struct net_device *dev, bool rx, bool tx);
 void bcmgenet_phy_power_set(struct net_device *dev, bool enable);
 void bcmgenet_mii_setup(struct net_device *dev);
 
 
        cmd_bits <<= CMD_SPEED_SHIFT;
 
        /* duplex */
-       if (phydev->duplex != DUPLEX_FULL)
-               cmd_bits |= CMD_HD_EN;
+       if (phydev->duplex != DUPLEX_FULL) {
+               cmd_bits |= CMD_HD_EN |
+                       CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE;
+       } else {
+               /* pause capability defaults to Symmetric */
+               if (priv->autoneg_pause) {
+                       bool tx_pause = 0, rx_pause = 0;
+
+                       if (phydev->autoneg)
+                               phy_get_pause(phydev, &tx_pause, &rx_pause);
 
-       /* pause capability */
-       if (!phydev->pause)
-               cmd_bits |= CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE;
+                       if (!tx_pause)
+                               cmd_bits |= CMD_TX_PAUSE_IGNORE;
+                       if (!rx_pause)
+                               cmd_bits |= CMD_RX_PAUSE_IGNORE;
+               }
+
+               /* Manual override */
+               if (!priv->rx_pause)
+                       cmd_bits |= CMD_RX_PAUSE_IGNORE;
+               if (!priv->tx_pause)
+                       cmd_bits |= CMD_TX_PAUSE_IGNORE;
+       }
 
        /* Program UMAC and RGMII block based on established
         * link speed, duplex, and pause. The speed set in
        return 0;
 }
 
+void bcmgenet_phy_pause_set(struct net_device *dev, bool rx, bool tx)
+{
+       struct phy_device *phydev = dev->phydev;
+
+       linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising, rx);
+       linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising,
+                        rx | tx);
+       phy_start_aneg(phydev);
+
+       mutex_lock(&phydev->lock);
+       if (phydev->link)
+               bcmgenet_mac_config(dev);
+       mutex_unlock(&phydev->lock);
+}
+
 void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
                return ret;
        }
 
-       linkmode_copy(phydev->advertising, phydev->supported);
-
        /* The internal PHY has its link interrupts routed to the
         * Ethernet MAC ISRs. On GENETv5 there is a hardware issue
         * that prevents the signaling of link UP interrupts when