From patchwork Thu Oct 7 14:23:35 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Narendra K X-Patchwork-Id: 238281 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o97ESOJO005371 for ; Thu, 7 Oct 2010 14:28:24 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753883Ab0JGO2X (ORCPT ); Thu, 7 Oct 2010 10:28:23 -0400 Received: from ausc60ps301.us.dell.com ([143.166.148.206]:61921 "EHLO ausc60ps301.us.dell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753787Ab0JGO2V convert rfc822-to-8bit (ORCPT ); Thu, 7 Oct 2010 10:28:21 -0400 X-Loopcount0: from 10.166.62.177 From: To: , , CC: , , , Date: Thu, 7 Oct 2010 07:23:35 -0700 Subject: [PATCH V2] Use firmware provided index to register a network interface Thread-Topic: [PATCH V2] Use firmware provided index to register a network interface Thread-Index: ActmK851iy+cIROmSnanendrfx2csQ== Message-ID: <20101007142319.GB2641@libnet-test.oslab.blr.amer.dell.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: user-agent: Mutt/1.5.20 (2009-12-10) acceptlanguage: en-US MIME-Version: 1.0 X-OriginalArrivalTime: 07 Oct 2010 14:28:14.0823 (UTC) FILETIME=[E09D6770:01CB662B] Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Thu, 07 Oct 2010 14:28:24 +0000 (UTC) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 3cdb4d8..73edbc0 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1529,6 +1529,12 @@ and is between 256 and 4096 characters. It is defined in the file This usage is only documented in each driver source file if at all. + no_netfwindex [NET] Do not use firmware index to derive ethN names + Names for onboard network interfaces are derived from + the firmware provided index for these devices. Using + this parameter would result in firmware index not being + used to derive ethN names. + nf_conntrack.acct= [NETFILTER] Enable connection tracking flow accounting 0 to disable accounting diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c index 90c0a72..8086268 100644 --- a/drivers/pci/pci-label.c +++ b/drivers/pci/pci-label.c @@ -55,6 +55,7 @@ find_smbios_instance_string(struct pci_dev *pdev, char *buf, "%s\n", dmi->name); } + pdev->firmware_index = donboard->instance; return strlen(dmi->name); } } diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index b5a7d9b..448ed9d 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -28,6 +28,7 @@ #include "pci.h" static int sysfs_initialized; /* = 0 */ +int pci_netdevs_with_fwindex; /* show configuration fields */ #define pci_config_attr(field, format_string) \ @@ -1167,6 +1168,10 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) pci_create_firmware_label_files(pdev); + if (pdev->firmware_index && (pdev->class >> 16) == + PCI_BASE_CLASS_NETWORK) + pci_netdevs_with_fwindex++; + return 0; err_vga_file: diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 46c36ff..4398dcf 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1080,6 +1080,8 @@ struct net_device { #define NETDEV_ALIGN 32 +extern int pci_netdevs_with_fwindex; + static inline struct netdev_queue *netdev_get_tx_queue(const struct net_device *dev, unsigned int index) diff --git a/include/linux/pci.h b/include/linux/pci.h index b1d1795..90113bb 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -243,6 +243,7 @@ struct pci_dev { unsigned short subsystem_vendor; unsigned short subsystem_device; unsigned int class; /* 3 bytes: (base,sub,prog-if) */ + unsigned int firmware_index; /* Firmware provided index */ u8 revision; /* PCI revision, low byte of class word */ u8 hdr_type; /* PCI header type (`multi' flag masked out) */ u8 pcie_cap; /* PCI-E capability offset */ diff --git a/net/core/dev.c b/net/core/dev.c index 1ae6543..f7982c4 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -853,9 +853,18 @@ int dev_valid_name(const char *name) } EXPORT_SYMBOL(dev_valid_name); +int netdev_use_fwindex = 1; + +static int __init netdev_use_fwindex_to_register(char *str) +{ + netdev_use_fwindex = 0; + return 0; +} +early_param("no_netfwindex", netdev_use_fwindex_to_register); + /** * __dev_alloc_name - allocate a name for a device - * @net: network namespace to allocate the device name in + * @dev: device * @name: name format string * @buf: scratch buffer and result name string * @@ -868,13 +877,15 @@ EXPORT_SYMBOL(dev_valid_name); * Returns the number of the unit assigned or a negative errno code. */ -static int __dev_alloc_name(struct net *net, const char *name, char *buf) +static int __dev_alloc_name(struct net_device *dev, const char *name, char *buf) { int i = 0; const char *p; const int max_netdevices = 8*PAGE_SIZE; unsigned long *inuse; struct net_device *d; + struct net *net; + struct pci_dev *pdev; p = strnchr(name, IFNAMSIZ-1, '%'); if (p) { @@ -886,15 +897,36 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) if (p[1] != 'd' || strchr(p + 2, '%')) return -EINVAL; + if (likely(netdev_use_fwindex)) { + pdev = to_pci_dev(dev->dev.parent); + if (pdev && pdev->firmware_index) { + snprintf(buf, IFNAMSIZ, name, + pdev->firmware_index - 1); + return pdev->firmware_index - 1; + } + } + /* Use one page as a bit array of possible slots */ inuse = (unsigned long *) get_zeroed_page(GFP_ATOMIC); if (!inuse) return -ENOMEM; + /* Reserve 0 to < pci_netdevs_with_fwindex for integrated + * ports with fwindex and allocate from pci_netdevs_with_fwindex + * onwards for add-in devices + */ + if (likely(netdev_use_fwindex)) { + for (i = 0; i < pci_netdevs_with_fwindex; i++) + set_bit(i, inuse); + } else + pci_netdevs_with_fwindex = 0; + + net = dev_net(dev); + for_each_netdev(net, d) { if (!sscanf(d->name, name, &i)) continue; - if (i < 0 || i >= max_netdevices) + if (i < pci_netdevs_with_fwindex || i >= max_netdevices) continue; /* avoid cases where sscanf is not exact inverse of printf */ @@ -936,12 +968,10 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf) int dev_alloc_name(struct net_device *dev, const char *name) { char buf[IFNAMSIZ]; - struct net *net; int ret; BUG_ON(!dev_net(dev)); - net = dev_net(dev); - ret = __dev_alloc_name(net, name, buf); + ret = __dev_alloc_name(dev, name, buf); if (ret >= 0) strlcpy(dev->name, buf, IFNAMSIZ); return ret;