From patchwork Sat Jan 3 01:27:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ed Swierk X-Patchwork-Id: 425081 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 6D47B140081 for ; Sat, 3 Jan 2015 12:29:12 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752082AbbACB3B (ORCPT ); Fri, 2 Jan 2015 20:29:01 -0500 Received: from mail-pd0-f181.google.com ([209.85.192.181]:49171 "EHLO mail-pd0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752048AbbACB26 (ORCPT ); Fri, 2 Jan 2015 20:28:58 -0500 Received: by mail-pd0-f181.google.com with SMTP id v10so24476453pde.12 for ; Fri, 02 Jan 2015 17:28:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=Eq3dqcOUIreIavwzfCl7fYNqovdIQ1qoQetKqOVcmaM=; b=A2Mz/n3Zr5mF18gPCAkZkhjzJcv7Kh+f8TulouDKj1HxGeWzTS2HUHXHs9hhyzXLAv km+juZx5CXwpyju/UooDfsyj6D9paeWaUB2htB9U6Qo6keO4Xe5k5wx3UjNWNY55722a X8jjx3CJ74QUZ9K7vOKKZALM93a103Dm8WgyEYzvvBQqEQWICT6kWhrRnc6ZAK3Oy/n+ s1lWMnRU4O4M72AlhGSsipLpssyZP9khlY+jjX/LxRsdJJ4Pcf95nc2AwpHiutOeuM1R DlYxYk/30QR3VDCbitWLhOFFIuOzN198bNH4vjaKH66miO4C7foxnbcrCK1S8hGkwI3Y e7fA== X-Gm-Message-State: ALoCoQmB8JjVGLYqePWKtPc0cdZtG5mx6Qg2Dnxl0fOID3bornjFE3Gd1SB7LtI/yM8pmVqtB8OL X-Received: by 10.70.91.142 with SMTP id ce14mr128252254pdb.138.1420248527969; Fri, 02 Jan 2015 17:28:47 -0800 (PST) Received: from fido2.skyportsystems.com (gateway.skyportsystems.com. [74.93.0.69]) by mx.google.com with ESMTPSA id a13sm47698281pdm.44.2015.01.02.17.28.46 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 02 Jan 2015 17:28:47 -0800 (PST) From: Ed Swierk To: netdev@vger.kernel.org Cc: f.fainelli@gmail.com, linux-kernel@vger.kernel.org, Ed Swierk Subject: [PATCH] ethtool: Extend ethtool plugin module eeprom API to phylib Date: Fri, 2 Jan 2015 17:27:56 -0800 Message-Id: <1420248476-110859-1-git-send-email-eswierk@skyportsystems.com> X-Mailer: git-send-email 1.9.1 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch extends the ethtool plugin module eeprom API to support cards whose phy support is delegated to a separate driver. The handlers for ETHTOOL_GMODULEINFO and ETHTOOL_GMODULEEEPROM call the module_info and module_eeprom functions if the phy driver provides them; otherwise the handlers call the equivalent ethtool_ops functions provided by network drivers with built-in phy support. Signed-off-by: Ed Swierk --- include/linux/phy.h | 9 +++++++++ net/core/ethtool.c | 45 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/include/linux/phy.h b/include/linux/phy.h index 565188c..04e5f5c 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -472,6 +472,15 @@ struct phy_driver { /* See set_wol, but for checking whether Wake on LAN is enabled. */ void (*get_wol)(struct phy_device *dev, struct ethtool_wolinfo *wol); + /* Get the size and type of the eeprom contained within a plug-in + * module */ + int (*module_info)(struct phy_device *dev, + struct ethtool_modinfo *modinfo); + + /* Get the eeprom information from the plug-in module */ + int (*module_eeprom)(struct phy_device *dev, + struct ethtool_eeprom *ee, u8 *data); + struct device_driver driver; }; #define to_phy_driver(d) container_of(d, struct phy_driver, driver) diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 30071de..466526b 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1405,20 +1405,31 @@ static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr) return err; } +static int __ethtool_get_module_info(struct net_device *dev, + struct ethtool_modinfo *modinfo) +{ + const struct ethtool_ops *ops = dev->ethtool_ops; + struct phy_device *phydev = dev->phydev; + + if (phydev && phydev->drv && phydev->drv->module_info) + return phydev->drv->module_info(phydev, modinfo); + + if (ops->get_module_info) + return ops->get_module_info(dev, modinfo); + + return -EOPNOTSUPP; +} + static int ethtool_get_module_info(struct net_device *dev, void __user *useraddr) { int ret; struct ethtool_modinfo modinfo; - const struct ethtool_ops *ops = dev->ethtool_ops; - - if (!ops->get_module_info) - return -EOPNOTSUPP; if (copy_from_user(&modinfo, useraddr, sizeof(modinfo))) return -EFAULT; - ret = ops->get_module_info(dev, &modinfo); + ret = __ethtool_get_module_info(dev, &modinfo); if (ret) return ret; @@ -1428,21 +1439,33 @@ static int ethtool_get_module_info(struct net_device *dev, return 0; } +static int __ethtool_get_module_eeprom(struct net_device *dev, + struct ethtool_eeprom *ee, u8 *data) +{ + const struct ethtool_ops *ops = dev->ethtool_ops; + struct phy_device *phydev = dev->phydev; + + if (phydev && phydev->drv && phydev->drv->module_eeprom) + return phydev->drv->module_eeprom(phydev, ee, data); + + if (ops->get_module_eeprom) + return ops->get_module_eeprom(dev, ee, data); + + return -EOPNOTSUPP; +} + static int ethtool_get_module_eeprom(struct net_device *dev, void __user *useraddr) { int ret; struct ethtool_modinfo modinfo; - const struct ethtool_ops *ops = dev->ethtool_ops; - - if (!ops->get_module_info || !ops->get_module_eeprom) - return -EOPNOTSUPP; - ret = ops->get_module_info(dev, &modinfo); + ret = __ethtool_get_module_info(dev, &modinfo); if (ret) return ret; - return ethtool_get_any_eeprom(dev, useraddr, ops->get_module_eeprom, + return ethtool_get_any_eeprom(dev, useraddr, + __ethtool_get_module_eeprom, modinfo.eeprom_len); }