Re: [PATCH V12 6/7] net: sxgbe: add ethtool related functions support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2014-03-25 at 14:13 +0530, Vipul Pandya wrote:
> From: Vipul Pandya <vipul.pandya@xxxxxxxxxxx>
> 
> -- 

This ('-- ') is a signature separator.  Please don't put that at the top
of a message, as many mailers, including mine, will remove everything
below it from a reply.

[...]
> > [...]
> > > +static int sxgbe_get_coalesce(struct net_device *dev,
> > > +                             struct ethtool_coalesce *ec)
> > > +{
> > > +       struct sxgbe_priv_data *priv = netdev_priv(dev);
> > > +
> > > +       if (priv->use_riwt)
> > > +               ec->rx_coalesce_usecs =
> sxgbe_riwt2usec(priv->rx_riwt, priv);
> >
> > Also set:
> >
> >       ec->rx_max_coalesced_frames = !priv->use_riwt;
> >       ec->tx_coalesce_usecs = SXGBE_COAL_TX_TIMER;
> >       ec->tx_max_coalesced_frames = SXGBE_TX_FRAMES;
> Support for above additional parameters do not present in the hardware
> controller. So, they are not set.

See the definition of struct ethtool_coalesce, which says you have to
set at least one of each pair to be non-zero.

And if I read the code correctly:

- the driver can decide which TX descriptors will trigger an interrupt
on completion, and does so at intervals of SXGBE_TX_FRAMES
- the hardware does not have a timer for TX interrupt coalescing, but
the driver does have a timer to poll for TX completions

So you have effectively implemented TX interrupt coalescing, and should
describe it through the ethtool API.

> > > +       return 0;
> > > +}
> > > +
> > > +static int sxgbe_set_coalesce(struct net_device *dev,
> > > +                         struct ethtool_coalesce *ec)
> > > +{
> > > +   struct sxgbe_priv_data *priv = netdev_priv(dev);
> > > +   unsigned int rx_riwt;
> > > +
> > > +   rx_riwt = sxgbe_usec2riwt(ec->rx_coalesce_usecs, priv);
> > > +
> > > +   if ((rx_riwt > SXGBE_MAX_DMA_RIWT) || (rx_riwt <
> SXGBE_MIN_DMA_RIWT))
> > > +           return -EINVAL;
> > > +   else if (!priv->use_riwt)
> > > +           return -EOPNOTSUPP;
> >
> > Please check for attempts to change unsupported parameters:
> >
> >       if (ec->rx_max_coalesced_frames != !rx_riwt ||
> >           ec->tx_coalesce_usecs != SXGBE_COAL_TX_TIMER ||
> >           ec->tx_max_coalesced_frames != SXGBE_TX_FRAMES ||
> >           ec->use_adaptive_rx_coalesce ||
> >           ec->use_adaptive_tx_coalesce)
> >               return -EINVAL;
> There is only one supported parameter so I would rather check if the
> same is set
> or not as shown below:
> 
> if (!ec->rx_coalesce_usecs)
>         return -EINVAL;

All of those fields are parameters and you should not ignore them.

> > > +   priv->rx_riwt = rx_riwt;
> > > +   priv->hw->dma->rx_watchdog(priv->ioaddr, priv->rx_riwt);
> > > +
> > > +   return 0;
> > > +}
> > [...]
> > > +static int sxgbe_set_rss_hash_opt(struct sxgbe_priv_data *priv,
> > > +                             struct ethtool_rxnfc *cmd)
> > > +{
> > > +   u32 reg_val = 0;
> > > +
> > > +   /* RSS does not support anything other than hashing
> > > +    * to queues on src and dst IPs and ports
> > > +    */
> > > +   if (cmd->data & ~(RXH_IP_SRC | RXH_IP_DST |
> > > +                     RXH_L4_B_0_1 | RXH_L4_B_2_3))
> > > +           return -EINVAL;
> > > +
> > > +   switch (cmd->flow_type) {
> > > +   case TCP_V4_FLOW:
> > > +   case TCP_V6_FLOW:
> > > +           if (!(cmd->data & RXH_IP_SRC) ||
> > > +               !(cmd->data & RXH_IP_DST) ||
> > > +               !(cmd->data & RXH_L4_B_0_1) ||
> > > +               !(cmd->data & RXH_L4_B_2_3))
> > > +                   return -EINVAL;
> > > +           reg_val = SXGBE_CORE_RSS_CTL_TCP4TE;
> > > +           break;
> > > +   case UDP_V4_FLOW:
> > > +   case UDP_V6_FLOW:
> > > +           if (!(cmd->data & RXH_IP_SRC) ||
> > > +               !(cmd->data & RXH_IP_DST) ||
> > > +               !(cmd->data & RXH_L4_B_0_1) ||
> > > +               !(cmd->data & RXH_L4_B_2_3))
> > > +                   return -EINVAL;
> > > +           reg_val = SXGBE_CORE_RSS_CTL_UDP4TE;
> > > +           break;
> > > +   case SCTP_V4_FLOW:
> > > +   case AH_ESP_V4_FLOW:
> > > +   case AH_V4_FLOW:
> > > +   case ESP_V4_FLOW:
> > > +   case AH_ESP_V6_FLOW:
> > > +   case AH_V6_FLOW:
> > > +   case ESP_V6_FLOW:
> > > +   case SCTP_V6_FLOW:
> > > +   case IPV4_FLOW:
> > > +   case IPV6_FLOW:
> > > +           if (!(cmd->data & RXH_IP_SRC) ||
> > > +               !(cmd->data & RXH_IP_DST) ||
> > > +               (cmd->data & RXH_L4_B_0_1) ||
> > > +               (cmd->data & RXH_L4_B_2_3))
> > > +                   return -EINVAL;
> > > +           reg_val = SXGBE_CORE_RSS_CTL_IP2TE;
> > > +           break;
> > > +   default:
> > > +           return -EINVAL;
> > > +   }
> >
> > Unless I'm missing something, this only accepts the default values,
> so
> > it's not actually possible to change the configuration.  Why are you
> > implementing this operation at all?
> It is possible to change the configuration. There is a register write
> to the
> SXGBE_CORE_RSS_CTL_REG at the end of the function. I think you might
> have missed
> it.
[...]

I see, but I'm not sure I understand.  Does this mean that only one hash
function can be implemented at a time, i.e. do you have to choose:

(IP packets hashed by address
 OR
 TCP packets hashed by address+port
 OR
 UDP packets hashed by address+port)
AND
all other packets go to single queue

?

Because that's not what this operation is supposed to do at all.  It's
supposed to select *independently* for each flow type, how flows of that
type are hashed.  Most multiqueue controllers can do RX flow hashing
like this:

(TCP packets hashed by port+address OR by address)
AND
(UDP packets hashed by port+address OR by address)
AND
all other IP packets hashed by address
AND
all non-IP packets go to single queue

Then this operation would let you select between the alternative hash
functions for TCP and UDP, while not affecting other flow types.  (Some
hardware is more flexible, hence the large number of flow types
defined.)

Ben.

-- 
Ben Hutchings
Always try to do things in chronological order;
it's less confusing that way.

Attachment: signature.asc
Description: This is a digitally signed message part


[Index of Archives]     [Linux SoC Development]     [Linux Rockchip Development]     [Linux USB Development]     [Video for Linux]     [Linux Audio Users]     [Linux SCSI]     [Yosemite News]

  Powered by Linux