From patchwork Fri Oct 14 20:54:01 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Carlson X-Patchwork-Id: 119916 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 51A38B70B2 for ; Sat, 15 Oct 2011 07:54:10 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933409Ab1JNUyE (ORCPT ); Fri, 14 Oct 2011 16:54:04 -0400 Received: from mms2.broadcom.com ([216.31.210.18]:2608 "EHLO mms2.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932460Ab1JNUyC (ORCPT ); Fri, 14 Oct 2011 16:54:02 -0400 Received: from [10.9.200.131] by mms2.broadcom.com with ESMTP (Broadcom SMTP Relay (Email Firewall v6.3.2)); Fri, 14 Oct 2011 14:00:37 -0700 X-Server-Uuid: D3C04415-6FA8-4F2C-93C1-920E106A2031 Received: from mail-irva-13.broadcom.com (10.11.16.103) by IRVEXCHHUB01.corp.ad.broadcom.com (10.9.200.131) with Microsoft SMTP Server id 8.2.247.2; Fri, 14 Oct 2011 13:53:53 -0700 Received: from mcarlson (mcarlson [10.12.148.101]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id D49AEBC396; Fri, 14 Oct 2011 13:53:53 -0700 (PDT) From: "Matt Carlson" To: davem@davemloft.net cc: netdev@vger.kernel.org, mcarlson@broadcom.com, bhutchings@solarflare.com Subject: [PATCH RFC 1/2] ethtool: Add extended flow control query facility Date: Fri, 14 Oct 2011 13:54:01 -0700 Message-ID: <1318625642-9668-2-git-send-email-mcarlson@broadcom.com> X-Mailer: git-send-email 1.7.3.4 MIME-Version: 1.0 X-WSS-ID: 62867D7F5IS18795762-01-01 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch creates a new ethtool_pauseparamext structure that elaborates on the older struct ethtool_pauseparam structure. The new structure adds two new fields that represent the current flow control status. Signed-off-by: Matt Carlson --- include/linux/ethtool.h | 14 ++++++++++- net/core/ethtool.c | 59 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 45f00b6..cd60d74 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -284,6 +284,15 @@ struct ethtool_pauseparam { __u32 tx_pause; }; +/* for configuring link flow control parameters */ +struct ethtool_pauseparamext { + struct ethtool_pauseparam cfg; + + __u32 rx_pause_status; + __u32 tx_pause_status; + __u32 reserved[2]; +}; + #define ETH_GSTRING_LEN 32 enum ethtool_stringset { ETH_SS_TEST = 0, @@ -956,7 +965,8 @@ struct ethtool_ops { int (*get_dump_data)(struct net_device *, struct ethtool_dump *, void *); int (*set_dump)(struct net_device *, struct ethtool_dump *); - + void (*get_pauseparamext)(struct net_device *, + struct ethtool_pauseparamext*); }; #endif /* __KERNEL__ */ @@ -1030,6 +1040,8 @@ struct ethtool_ops { #define ETHTOOL_SET_DUMP 0x0000003e /* Set dump settings */ #define ETHTOOL_GET_DUMP_FLAG 0x0000003f /* Get dump settings */ #define ETHTOOL_GET_DUMP_DATA 0x00000040 /* Get dump data */ +#define ETHTOOL_GPAUSEPARAMEXT 0x00000041 /* Get pause parameters v2 */ +#define ETHTOOL_SPAUSEPARAMEXT 0x00000042 /* Set pause parameters v2 */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET diff --git a/net/core/ethtool.c b/net/core/ethtool.c index f444817..1c0f58c 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1206,15 +1206,21 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev, static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr) { - struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM }; + struct ethtool_pauseparamext pauseparam = { + { .cmd = ETHTOOL_GPAUSEPARAM } + }; - if (!dev->ethtool_ops->get_pauseparam) + if (dev->ethtool_ops->get_pauseparam) + dev->ethtool_ops->get_pauseparam(dev, &pauseparam.cfg); + else if (dev->ethtool_ops->get_pauseparamext) + dev->ethtool_ops->get_pauseparamext(dev, &pauseparam); + else return -EOPNOTSUPP; - dev->ethtool_ops->get_pauseparam(dev, &pauseparam); - - if (copy_to_user(useraddr, &pauseparam, sizeof(pauseparam))) + if (copy_to_user(useraddr, &pauseparam, + sizeof(struct ethtool_pauseparam))) return -EFAULT; + return 0; } @@ -1231,6 +1237,42 @@ static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr) return dev->ethtool_ops->set_pauseparam(dev, &pauseparam); } +static int ethtool_get_pauseparamext(struct net_device *dev, + void __user *useraddr) +{ + struct ethtool_pauseparamext pauseparam = { + { .cmd = ETHTOOL_GPAUSEPARAMEXT } + }; + + if (dev->ethtool_ops->get_pauseparamext) { + dev->ethtool_ops->get_pauseparamext(dev, &pauseparam); + } else { + if (!dev->ethtool_ops->get_pauseparam) + return -EOPNOTSUPP; + + dev->ethtool_ops->get_pauseparam(dev, &pauseparam.cfg); + } + + if (copy_to_user(useraddr, &pauseparam, sizeof(pauseparam))) + return -EFAULT; + + return 0; +} + +static int ethtool_set_pauseparamext(struct net_device *dev, + void __user *useraddr) +{ + struct ethtool_pauseparamext pauseparam; + + if (!dev->ethtool_ops->set_pauseparam) + return -EOPNOTSUPP; + + if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam))) + return -EFAULT; + + return dev->ethtool_ops->set_pauseparam(dev, &pauseparam.cfg); +} + static int __ethtool_set_sg(struct net_device *dev, u32 data) { int err; @@ -1667,6 +1709,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GCOALESCE: case ETHTOOL_GRINGPARAM: case ETHTOOL_GPAUSEPARAM: + case ETHTOOL_GPAUSEPARAMEXT: case ETHTOOL_GRXCSUM: case ETHTOOL_GTXCSUM: case ETHTOOL_GSG: @@ -1754,6 +1797,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_SPAUSEPARAM: rc = ethtool_set_pauseparam(dev, useraddr); break; + case ETHTOOL_GPAUSEPARAMEXT: + rc = ethtool_get_pauseparamext(dev, useraddr); + break; + case ETHTOOL_SPAUSEPARAMEXT: + rc = ethtool_set_pauseparamext(dev, useraddr); + break; case ETHTOOL_TEST: rc = ethtool_self_test(dev, useraddr); break;