static int i40e_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec) { struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_q_vector *q_vector; struct i40e_vsi *vsi = np->vsi; struct i40e_pf *pf = vsi->back; struct i40e_hw *hw = &pf->hw; u16 vector; int i; if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq) vsi->work_limit = ec->tx_max_coalesced_frames_irq; switch (ec->rx_coalesce_usecs) { case 0: vsi->rx_itr_setting = 0; break; case 1: vsi->rx_itr_setting = (I40E_ITR_DYNAMIC | ITR_REG_TO_USEC(I40E_ITR_RX_DEF)); break; default: if ((ec->rx_coalesce_usecs < (I40E_MIN_ITR << 1)) || (ec->rx_coalesce_usecs > (I40E_MAX_ITR << 1))) return -EINVAL; vsi->rx_itr_setting = ec->rx_coalesce_usecs; break; } switch (ec->tx_coalesce_usecs) { case 0: vsi->tx_itr_setting = 0; break; case 1: vsi->tx_itr_setting = (I40E_ITR_DYNAMIC | ITR_REG_TO_USEC(I40E_ITR_TX_DEF)); break; default: if ((ec->tx_coalesce_usecs < (I40E_MIN_ITR << 1)) || (ec->tx_coalesce_usecs > (I40E_MAX_ITR << 1))) return -EINVAL; vsi->tx_itr_setting = ec->tx_coalesce_usecs; break; } vector = vsi->base_vector; for (i = 0; i < vsi->num_q_vectors; i++, vector++) { q_vector = vsi->q_vectors[i]; q_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting); wr32(hw, I40E_PFINT_ITRN(0, vector - 1), q_vector->rx.itr); q_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting); wr32(hw, I40E_PFINT_ITRN(1, vector - 1), q_vector->tx.itr); i40e_flush(hw); } return 0; }
/** * i40evf_set_coalesce - Set interrupt coalescing settings * @netdev: network interface device structure * @ec: ethtool coalesce structure * * Change current coalescing settings. **/ static int i40evf_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec) { struct i40evf_adapter *adapter = netdev_priv(netdev); struct i40e_hw *hw = &adapter->hw; struct i40e_vsi *vsi = &adapter->vsi; struct i40e_q_vector *q_vector; int i; if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq) vsi->work_limit = ec->tx_max_coalesced_frames_irq; if ((ec->rx_coalesce_usecs >= (I40E_MIN_ITR << 1)) && (ec->rx_coalesce_usecs <= (I40E_MAX_ITR << 1))) vsi->rx_itr_setting = ec->rx_coalesce_usecs; else return -EINVAL; if ((ec->tx_coalesce_usecs >= (I40E_MIN_ITR << 1)) && (ec->tx_coalesce_usecs <= (I40E_MAX_ITR << 1))) vsi->tx_itr_setting = ec->tx_coalesce_usecs; else if (ec->use_adaptive_tx_coalesce) vsi->tx_itr_setting = (I40E_ITR_DYNAMIC | ITR_REG_TO_USEC(I40E_ITR_RX_DEF)); else return -EINVAL; if (ec->use_adaptive_rx_coalesce) vsi->rx_itr_setting |= I40E_ITR_DYNAMIC; else vsi->rx_itr_setting &= ~I40E_ITR_DYNAMIC; if (ec->use_adaptive_tx_coalesce) vsi->tx_itr_setting |= I40E_ITR_DYNAMIC; else vsi->tx_itr_setting &= ~I40E_ITR_DYNAMIC; for (i = 0; i < adapter->num_msix_vectors - NONQ_VECS; i++) { q_vector = &adapter->q_vectors[i]; q_vector->rx.itr = ITR_TO_REG(vsi->rx_itr_setting); wr32(hw, I40E_VFINT_ITRN1(0, i), q_vector->rx.itr); q_vector->tx.itr = ITR_TO_REG(vsi->tx_itr_setting); wr32(hw, I40E_VFINT_ITRN1(1, i), q_vector->tx.itr); i40e_flush(hw); } return 0; }