> From: Kan Liang <kan.li...@intel.com> > > This patch implements get_per_queue_coalesce for i40e driver. > For i40e driver, only rx and tx usecs has per queue value. So only these > two parameters are read from specific registers. For other interrupt > coalescing parameters, they are shared among queues. The values which > are stored in vsi will be return. > > Signed-off-by: Kan Liang <kan.li...@intel.com> > --- > drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 34 > ++++++++++++++++++++++++-- > 1 file changed, 32 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c > b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c > index 3f385ff..b41f0be 100644 > --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c > +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c > @@ -1843,11 +1843,16 @@ static int i40e_set_phys_id(struct net_device > *netdev, > * 125us (8000 interrupts per second) == ITR(62) > */ > > -static int i40e_get_coalesce(struct net_device *netdev, > - struct ethtool_coalesce *ec) > +static int __i40e_get_coalesce(struct net_device *netdev, > + struct ethtool_coalesce *ec, > + int queue) > { > struct i40e_netdev_priv *np = netdev_priv(netdev); > struct i40e_vsi *vsi = np->vsi; > + struct i40e_pf *pf = vsi->back; > + struct i40e_hw *hw = &pf->hw; > + struct i40e_q_vector *q_vector; > + u16 vector; > > ec->tx_max_coalesced_frames_irq = vsi->work_limit; > ec->rx_max_coalesced_frames_irq = vsi->work_limit; > @@ -1869,9 +1874,33 @@ static int i40e_get_coalesce(struct net_device > *netdev, > ec->rx_coalesce_usecs_high = vsi->int_rate_limit; > ec->tx_coalesce_usecs_high = vsi->int_rate_limit; > > + if (queue > 0) { > + if (queue >= vsi->num_q_vectors) { > + netif_info(pf, drv, netdev, "Invalid queue number\n"); > + return -EINVAL; > + } > + > + q_vector = vsi->q_vectors[queue];
The problem here is that there can be more queues than vectors and they're not spread round-robin style. For example, if the VSI was only given 4 vectors, but has 8 queues, there will be 2 queues per vector paired up such that V0 <= {Q0, Q1}, V1 <= {Q2, Q3} ... You'll need to check the requested queue number against vsi->num_queue_pairs for the max queue check, then look at vsi->tx_rings[queue].q_vector and/or vsi->rx_rings[queue].q_vector to find the actual q_vector for the requested queue. sln > + vector = vsi->base_vector + queue; > + > + ec->rx_coalesce_usecs = ITR_REG_TO_USEC(rd32(hw, > I40E_PFINT_ITRN(0, vector - 1))); > + ec->tx_coalesce_usecs = ITR_REG_TO_USEC(rd32(hw, > I40E_PFINT_ITRN(1, vector - 1))); > + } > return 0; > } > > +static int i40e_get_coalesce(struct net_device *netdev, > + struct ethtool_coalesce *ec) > +{ > + return __i40e_get_coalesce(netdev, ec, -1); > +} > + > +static int i40e_get_per_queue_coalesce(struct net_device *netdev, int > queue, > + struct ethtool_coalesce *ec) > +{ > + return __i40e_get_coalesce(netdev, ec, queue); > +} > + > static int i40e_set_coalesce(struct net_device *netdev, > struct ethtool_coalesce *ec) > { > @@ -2788,6 +2817,7 @@ static const struct ethtool_ops i40e_ethtool_ops = { > .get_ts_info = i40e_get_ts_info, > .get_priv_flags = i40e_get_priv_flags, > .set_priv_flags = i40e_set_priv_flags, > + .get_per_queue_coalesce = i40e_get_per_queue_coalesce, > }; > > void i40e_set_ethtool_ops(struct net_device *netdev) > -- > 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html