@@ -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
@@ -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);
}
}
@@ -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:
@@ -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)
@@ -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 */
@@ -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;