static int pch_gbe_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) { struct pch_gbe_adapter *adapter = netdev_priv(netdev); struct pch_gbe_hw *hw = &adapter->hw; int ret = 0; hw->mac.fc_autoneg = pause->autoneg; if ((pause->rx_pause) && (pause->tx_pause)) hw->mac.fc = PCH_GBE_FC_FULL; else if ((pause->rx_pause) && (!pause->tx_pause)) hw->mac.fc = PCH_GBE_FC_RX_PAUSE; else if ((!pause->rx_pause) && (pause->tx_pause)) hw->mac.fc = PCH_GBE_FC_TX_PAUSE; else if ((!pause->rx_pause) && (!pause->tx_pause)) hw->mac.fc = PCH_GBE_FC_NONE; if (hw->mac.fc_autoneg == AUTONEG_ENABLE) { if ((netif_running(adapter->netdev))) { pch_gbe_down(adapter); ret = pch_gbe_up(adapter); } else { pch_gbe_reset(adapter); } } else { ret = pch_gbe_mac_force_mac_fc(hw); } return ret; }
/** * pch_gbe_set_settings - Set device-specific settings * @netdev: Network interface device structure * @ecmd: Ethtool command * Returns * 0: Successful. * Negative value: Failed. */ static int pch_gbe_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct pch_gbe_adapter *adapter = netdev_priv(netdev); struct pch_gbe_hw *hw = &adapter->hw; int ret; pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET); if (ecmd->speed == USHRT_MAX) { ecmd->speed = SPEED_1000; ecmd->duplex = DUPLEX_FULL; } ret = mii_ethtool_sset(&adapter->mii, ecmd); if (ret) { pr_err("Error: mii_ethtool_sset\n"); return ret; } hw->mac.link_speed = ecmd->speed; hw->mac.link_duplex = ecmd->duplex; hw->phy.autoneg_advertised = ecmd->advertising; hw->mac.autoneg = ecmd->autoneg; pch_gbe_hal_phy_sw_reset(hw); /* reset the link */ if (netif_running(adapter->netdev)) { pch_gbe_down(adapter); ret = pch_gbe_up(adapter); } else { pch_gbe_reset(adapter); } return ret; }
static int pch_gbe_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) { struct pch_gbe_adapter *adapter = netdev_priv(netdev); struct pch_gbe_tx_ring *txdr, *tx_old; struct pch_gbe_rx_ring *rxdr, *rx_old; int tx_ring_size, rx_ring_size; int err = 0; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; tx_ring_size = (int)sizeof(struct pch_gbe_tx_ring); rx_ring_size = (int)sizeof(struct pch_gbe_rx_ring); if ((netif_running(adapter->netdev))) pch_gbe_down(adapter); tx_old = adapter->tx_ring; rx_old = adapter->rx_ring; txdr = kzalloc(tx_ring_size, GFP_KERNEL); if (!txdr) { err = -ENOMEM; goto err_alloc_tx; } rxdr = kzalloc(rx_ring_size, GFP_KERNEL); if (!rxdr) { err = -ENOMEM; goto err_alloc_rx; } adapter->tx_ring = txdr; adapter->rx_ring = rxdr; rxdr->count = clamp_val(ring->rx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD); rxdr->count = roundup(rxdr->count, PCH_GBE_RX_DESC_MULTIPLE); txdr->count = clamp_val(ring->tx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD); txdr->count = roundup(txdr->count, PCH_GBE_TX_DESC_MULTIPLE); if ((netif_running(adapter->netdev))) { /* */ err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring); if (err) goto err_setup_rx; err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring); if (err) goto err_setup_tx; /* */ #ifdef RINGFREE adapter->rx_ring = rx_old; adapter->tx_ring = tx_old; pch_gbe_free_rx_resources(adapter, adapter->rx_ring); pch_gbe_free_tx_resources(adapter, adapter->tx_ring); kfree(tx_old); kfree(rx_old); adapter->rx_ring = rxdr; adapter->tx_ring = txdr; #else pch_gbe_free_rx_resources(adapter, rx_old); pch_gbe_free_tx_resources(adapter, tx_old); kfree(tx_old); kfree(rx_old); adapter->rx_ring = rxdr; adapter->tx_ring = txdr; #endif err = pch_gbe_up(adapter); } return err; err_setup_tx: pch_gbe_free_rx_resources(adapter, adapter->rx_ring); err_setup_rx: adapter->rx_ring = rx_old; adapter->tx_ring = tx_old; kfree(rxdr); err_alloc_rx: kfree(txdr); err_alloc_tx: if (netif_running(adapter->netdev)) pch_gbe_up(adapter); return err; }