net: ethtool support to configure number of channels
authoramit salecha <amit.salecha@qlogic.com>
Thu, 7 Apr 2011 01:58:42 +0000 (01:58 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 13 Apr 2011 18:31:04 +0000 (11:31 -0700)
Ethtool support to configure RX, TX and other channels. combined field
in struct ethtool_channels to reflect set of channel (RX, TX or other).
Other channel can be link interrupts, SR-IOV coordination etc.

ETHTOOL_GCHANNELS will report max and current number of RX channels,
max and current number of TX channels, max and current number of other channel
or max and current number of combined channel.

Number of channel can be modify upto max number of channel through
ETHTOOL_SCHANNELS command.

Ben Hutchings:
o define 'combined' and 'other' types.  Most multiqueue drivers pair up RX and TX
  queues so that most channels combine RX and TX work.
o Please could you use a kernel-doc comment to describe the structure.

Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Reviewed-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/ethtool.h
net/core/ethtool.c

index 12cfbd0..ad22a68 100644 (file)
@@ -229,6 +229,34 @@ struct ethtool_ringparam {
        __u32   tx_pending;
 };
 
+/**
+ * struct ethtool_channels - configuring number of network channel
+ * @cmd: ETHTOOL_{G,S}CHANNELS
+ * @max_rx: Read only. Maximum number of receive channel the driver support.
+ * @max_tx: Read only. Maximum number of transmit channel the driver support.
+ * @max_other: Read only. Maximum number of other channel the driver support.
+ * @max_combined: Read only. Maximum number of combined channel the driver
+ *     support. Set of queues RX, TX or other.
+ * @rx_count: Valid values are in the range 1 to the max_rx.
+ * @tx_count: Valid values are in the range 1 to the max_tx.
+ * @other_count: Valid values are in the range 1 to the max_other.
+ * @combined_count: Valid values are in the range 1 to the max_combined.
+ *
+ * This can be used to configure RX, TX and other channels.
+ */
+
+struct ethtool_channels {
+       __u32   cmd;
+       __u32   max_rx;
+       __u32   max_tx;
+       __u32   max_other;
+       __u32   max_combined;
+       __u32   rx_count;
+       __u32   tx_count;
+       __u32   other_count;
+       __u32   combined_count;
+};
+
 /* for configuring link flow control parameters */
 struct ethtool_pauseparam {
        __u32   cmd;    /* ETHTOOL_{G,S}PAUSEPARAM */
@@ -818,6 +846,9 @@ bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported);
  *     Returns a negative error code or zero.
  * @set_rxfh_indir: Set the contents of the RX flow hash indirection table.
  *     Returns a negative error code or zero.
+ * @get_channels: Get number of channels.
+ * @set_channels: Set number of channels.  Returns a negative error code or
+ *     zero.
  *
  * All operations are optional (i.e. the function pointer may be set
  * to %NULL) and callers must take this into account.  Callers must
@@ -891,6 +922,9 @@ struct ethtool_ops {
                                  struct ethtool_rxfh_indir *);
        int     (*set_rxfh_indir)(struct net_device *,
                                  const struct ethtool_rxfh_indir *);
+       void    (*get_channels)(struct net_device *, struct ethtool_channels *);
+       int     (*set_channels)(struct net_device *, struct ethtool_channels *);
+
 };
 #endif /* __KERNEL__ */
 
@@ -959,6 +993,8 @@ struct ethtool_ops {
 
 #define ETHTOOL_GFEATURES      0x0000003a /* Get device offload settings */
 #define ETHTOOL_SFEATURES      0x0000003b /* Change device offload settings */
+#define ETHTOOL_GCHANNELS      0x0000003c /* Get no of channels */
+#define ETHTOOL_SCHANNELS      0x0000003d /* Set no of channels */
 
 /* compatibility with older code */
 #define SPARC_ETH_GSET         ETHTOOL_GSET
index 43ef09f..41dee2d 100644 (file)
@@ -1446,6 +1446,35 @@ static int ethtool_set_ringparam(struct net_device *dev, void __user *useraddr)
        return dev->ethtool_ops->set_ringparam(dev, &ringparam);
 }
 
+static noinline_for_stack int ethtool_get_channels(struct net_device *dev,
+                                                  void __user *useraddr)
+{
+       struct ethtool_channels channels = { .cmd = ETHTOOL_GCHANNELS };
+
+       if (!dev->ethtool_ops->get_channels)
+               return -EOPNOTSUPP;
+
+       dev->ethtool_ops->get_channels(dev, &channels);
+
+       if (copy_to_user(useraddr, &channels, sizeof(channels)))
+               return -EFAULT;
+       return 0;
+}
+
+static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
+                                                  void __user *useraddr)
+{
+       struct ethtool_channels channels;
+
+       if (!dev->ethtool_ops->set_channels)
+               return -EOPNOTSUPP;
+
+       if (copy_from_user(&channels, useraddr, sizeof(channels)))
+               return -EFAULT;
+
+       return dev->ethtool_ops->set_channels(dev, &channels);
+}
+
 static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr)
 {
        struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM };
@@ -2007,6 +2036,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
        case ETHTOOL_SGRO:
                rc = ethtool_set_one_feature(dev, useraddr, ethcmd);
                break;
+       case ETHTOOL_GCHANNELS:
+               rc = ethtool_get_channels(dev, useraddr);
+               break;
+       case ETHTOOL_SCHANNELS:
+               rc = ethtool_set_channels(dev, useraddr);
+               break;
        default:
                rc = -EOPNOTSUPP;
        }