From patchwork Sun Feb 13 11:11:46 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TWljaGHFgiBNaXJvc8WCYXc=?= X-Patchwork-Id: 82982 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 B4482B7122 for ; Sun, 13 Feb 2011 22:12:09 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754235Ab1BMLMB (ORCPT ); Sun, 13 Feb 2011 06:12:01 -0500 Received: from rere.qmqm.pl ([89.167.52.164]:50513 "EHLO rere.qmqm.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754158Ab1BMLLt (ORCPT ); Sun, 13 Feb 2011 06:11:49 -0500 Received: by rere.qmqm.pl (Postfix, from userid 1000) id 1D13C13A62; Sun, 13 Feb 2011 12:11:46 +0100 (CET) Message-Id: In-Reply-To: References: From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Subject: [PATCH v5 RESEND 7/9] net: use ndo_fix_features for ethtool_ops->set_flags MIME-Version: 1.0 To: netdev@vger.kernel.org Cc: Ben Hutchings , David Miller Date: Sun, 13 Feb 2011 12:11:46 +0100 (CET) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Signed-off-by: Michał Mirosław --- net/core/ethtool.c | 31 +++++++++++++++++++++++++++++-- 1 files changed, 29 insertions(+), 2 deletions(-) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 6599997..65b3d50 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -427,6 +427,34 @@ static int ethtool_set_one_feature(struct net_device *dev, } } +static int __ethtool_set_flags(struct net_device *dev, u32 data) +{ + u32 changed; + + if (data & ~flags_dup_features) + return -EINVAL; + + /* legacy set_flags() op */ + if (dev->ethtool_ops->set_flags) { + if (unlikely(dev->hw_features & flags_dup_features)) + netdev_warn(dev, + "driver BUG: mixed hw_features and set_flags()\n"); + return dev->ethtool_ops->set_flags(dev, data); + } + + /* allow changing only bits set in hw_features */ + changed = (data ^ dev->wanted_features) & flags_dup_features; + if (changed & ~dev->hw_features) + return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP; + + dev->wanted_features = + (dev->wanted_features & ~changed) | data; + + netdev_update_features(dev); + + return 0; +} + static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) { struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; @@ -1768,8 +1796,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) ethtool_op_get_flags)); break; case ETHTOOL_SFLAGS: - rc = ethtool_set_value(dev, useraddr, - dev->ethtool_ops->set_flags); + rc = ethtool_set_value(dev, useraddr, __ethtool_set_flags); break; case ETHTOOL_GPFLAGS: rc = ethtool_get_value(dev, useraddr, ethcmd,