Re: [virtio-dev] [RFC PATCH V2] virtio_pci: Add SR-IOV support

2018-02-25 Thread Mark D Rustad
> On Feb 25, 2018, at 7:20 AM, Yan Vugenfirer  wrote:
> 
> Small mistake in the commit message. Red Hat (Qumranet) vendor ID is 1af4, 
> virtio-net device ID is 1041.
> Should be:
> PF: vendor: 1af4 device: 1041 subvendor: 8086 subdevice: 15fe
> VF: vendor: 1af4 device: 1041 subvendor: 8086 subdevice: 05fe

You are so right. I will fix it before I send the updated patch that provides 
the generic helper that Christoph suggested. Thanks for catching my mislabeling.

--
Mark Rustad, mrus...@gmail.com



signature.asc
Description: Message signed with OpenPGP


Re: [Intel-wired-lan] [PATCH] e1000e: prevent division by zero if TIMINCA is zero

2016-05-10 Thread Mark D Rustad

Jarod Wilson  wrote:


On Fri, May 06, 2016 at 11:43:17PM +, Rustad, Mark D wrote:

Denys Vlasenko  wrote:


Users report that under VMWare, er32(TIMINCA) returns zero.
This causes division by zero at init time as follows:

==>incvalue = er32(TIMINCA) & E1000_TIMINCA_INCVALUE_MASK;
   for (i = 0; i < E1000_MAX_82574_SYSTIM_REREADS; i++) {
   /* latch SYSTIMH on read of SYSTIML */
   systim_next = (cycle_t)er32(SYSTIML);
   systim_next |= (cycle_t)er32(SYSTIMH) << 32;

   time_delta = systim_next - systim;
   temp = time_delta;
>  rem = do_div(temp, incvalue);

This change makes kernel survive this, and users report that
NIC does work after this change.

Since on real hardware incvalue is never zero, this should not affect
real hardware use case.

...
I seem to recall that this was rejected before because it really is  
VMWare's

bug and, if they fix it, any existing VMs that use this will just work.
Changing the driver will only fix it for vms that install a new driver. I
don't object to doing it, it just seems like not the most effective  
place to

address the issue.


You could also have people who never update VMWare, for whom a kernel
work-around would be better. I think it'd be best to address it both at
the driver level and the emulated hardware level, to improve things for
the most possible users. Those who update neither hypervisor or
kernel/driver, well, they reap what they sow.


That is a sound argument for doing both. I would expect that there are more  
frozen VM images than host environments, but I can certainly imagine that  
some choose to freeze their host. Of course if everything is frozen there  
is no point at all. :-)


I am on an extended vacation, and don't work on e1000e anyway, so I will  
quit my kibitzing here.


--
Mark Rustad, mrus...@gmail.com


signature.asc
Description: Message signed with OpenPGP using GPGMail


[PATCH V4 1/2] pci: Add dev_flags bit to access VPD through function 0

2015-07-13 Thread Mark D Rustad
From: Mark Rustad mark.d.rus...@intel.com

Add a dev_flags bit, PCI_DEV_FLAGS_VPD_REF_F0, to access VPD through
function 0 to provide VPD access on other functions. This is for
hardware devices that provide copies of the same VPD capability
registers in multiple functions. Because the kernel expects that
each function has its own registers, both the locking and the state
tracking are affected by VPD accesses to different functions.

On such devices for example, if a VPD write is performed on function
0, *any* later attempt to read VPD from any other function of that
device will hang. This has to do with how the kernel tracks the
expected value of the F bit per function.

Concurrent accesses to different functions of the same device can
not only hang but also corrupt both read and write VPD data.

When hangs occur, typically the error message:

vpd r/w failed.  This is likely a firmware bug on this device.

will be seen.

Never set this bit on function 0 or there will be an infinite recursion.

Signed-off-by: Mark Rustad mark.d.rus...@intel.com
---
Changes in V2:
- Corrected spelling in log message
- Added checks to see that the referenced function 0 is reasonable
Changes in V3:
- Don't leak a device reference
- Check that function 0 has VPD
- Make a helper for the function 0 checks
- Do multifunction check in the quirk
Changes in V4:
- Provide a much more detailed explanation in the commit log
---
 drivers/pci/access.c |   61 +-
 include/linux/pci.h  |2 ++
 2 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index d9b64a175990..b965c12168b7 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -439,6 +439,56 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = {
.release = pci_vpd_pci22_release,
 };
 
+static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
+  void *arg)
+{
+   struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn));
+   ssize_t ret;
+
+   if (!tdev)
+   return -ENODEV;
+
+   ret = pci_read_vpd(tdev, pos, count, arg);
+   pci_dev_put(tdev);
+   return ret;
+}
+
+static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
+   const void *arg)
+{
+   struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn));
+   ssize_t ret;
+
+   if (!tdev)
+   return -ENODEV;
+
+   ret = pci_write_vpd(tdev, pos, count, arg);
+   pci_dev_put(tdev);
+   return ret;
+}
+
+static const struct pci_vpd_ops pci_vpd_f0_ops = {
+   .read = pci_vpd_f0_read,
+   .write = pci_vpd_f0_write,
+   .release = pci_vpd_pci22_release,
+};
+
+static int pci_vpd_f0_dev_check(struct pci_dev *dev)
+{
+   struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn));
+   int ret = 0;
+
+   if (!tdev)
+   return -ENODEV;
+   if (!tdev-vpd || !tdev-multifunction ||
+   dev-class != tdev-class || dev-vendor != tdev-vendor ||
+   dev-device != tdev-device)
+   ret = -ENODEV;
+
+   pci_dev_put(tdev);
+   return ret;
+}
+
 int pci_vpd_pci22_init(struct pci_dev *dev)
 {
struct pci_vpd_pci22 *vpd;
@@ -447,12 +497,21 @@ int pci_vpd_pci22_init(struct pci_dev *dev)
cap = pci_find_capability(dev, PCI_CAP_ID_VPD);
if (!cap)
return -ENODEV;
+   if (dev-dev_flags  PCI_DEV_FLAGS_VPD_REF_F0) {
+   int ret = pci_vpd_f0_dev_check(dev);
+
+   if (ret)
+   return ret;
+   }
vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC);
if (!vpd)
return -ENOMEM;
 
vpd-base.len = PCI_VPD_PCI22_SIZE;
-   vpd-base.ops = pci_vpd_pci22_ops;
+   if (dev-dev_flags  PCI_DEV_FLAGS_VPD_REF_F0)
+   vpd-base.ops = pci_vpd_f0_ops;
+   else
+   vpd-base.ops = pci_vpd_pci22_ops;
mutex_init(vpd-lock);
vpd-cap = cap;
vpd-busy = false;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 8a0321a8fb59..8edb125db13a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -180,6 +180,8 @@ enum pci_dev_flags {
PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1  6),
/* Do not use PM reset even if device advertises NoSoftRst- */
PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1  7),
+   /* Get VPD from function 0 VPD */
+   PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1  8),
 };
 
 enum pci_irq_reroute_variant {

--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V4 2/2] pci: Add VPD quirk for Intel Ethernet devices

2015-07-13 Thread Mark D Rustad
From: Mark Rustad mark.d.rus...@intel.com

This quirk sets the PCI_DEV_FLAGS_VPD_REF_F0 flag on all Intel
Ethernet device functions other than function 0.

Signed-off-by: Mark Rustad mark.d.rus...@intel.com
---
Changes in V3:
- Added a multifunction device check
---
 drivers/pci/quirks.c |9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index e9fd0e90fa3b..08c04e4f5ab2 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1894,6 +1894,15 @@ static void quirk_netmos(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,
 PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos);
 
+static void quirk_f0_vpd_link(struct pci_dev *dev)
+{
+   if (!dev-multifunction || !PCI_FUNC(dev-devfn))
+   return;
+   dev-dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0;
+}
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
+ PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link);
+
 static void quirk_e100_interrupt(struct pci_dev *dev)
 {
u16 command, pmcsr;

--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V4 0/2] pci: Provide a flag to access VPD through function 0

2015-07-13 Thread Mark D Rustad
Many multi-function devices provide shared registers in extended
config space for accessing VPD. The behavior of these registers
means that the state must be tracked and access locked correctly
for accesses not to hang or worse. One way to meet these needs is
to always perform the accesses through function 0, thereby using
the state tracking and mutex that already exists.

To provide this behavior, add a dev_flags bit to indicate that this
should be done. This bit can then be set for any non-zero function
that needs to redirect such VPD access to function 0. Do not set
this bit on the zero function or there will be an infinite recursion.

The second patch uses this new flag to invoke this behavior on all
multi-function Intel Ethernet devices.

Any hardware that shares VPD registers with multiple functions has
been suffering these problems forever. The hangs result in the log
message:

vpd r/w failed.  This is likely a firmware bug on this device.

Both read and write data corruption are also possible during
overlapping accesses in addition to hangs.

Signed-off-by: Mark Rustad mark.d.rus...@intel.com

---
Changes in V2:
- Corrected a spelling error in a log message
- Added checks to see that the referenced function 0 is reasonable
Changes in V3:
- Don't leak a device reference
- Check that function 0 has VPD
- Make a helper for the function 0 checks
- Moved a multifunction check to the quirk patch
Changes in V4:
- Provide a more extensive commit log for patch 1

---

Mark Rustad (2):
  pci: Add dev_flags bit to access VPD through function 0
  pci: Add VPD quirk for Intel Ethernet devices


 drivers/pci/access.c |   61 +-
 drivers/pci/quirks.c |9 +++
 include/linux/pci.h  |2 ++
 3 files changed, 71 insertions(+), 1 deletion(-)

-- 
Mark Rustad, Network Division, Intel Corporation
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V3 2/2] pci: Add VPD quirk for Intel Ethernet devices

2015-06-03 Thread Mark D Rustad
This quirk sets the PCI_DEV_FLAGS_VPD_REF_F0 flag on all Intel
Ethernet device functions other than function 0.

Signed-off-by: Mark Rustad mark.d.rus...@intel.com
---
Changes in V3:
- Added a multifunction device check
---
 drivers/pci/quirks.c |9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index c6dc1dfd25d5..1d6d848b66f9 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1903,6 +1903,15 @@ static void quirk_netmos(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,
 PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos);
 
+static void quirk_f0_vpd_link(struct pci_dev *dev)
+{
+   if (!dev-multifunction || !PCI_FUNC(dev-devfn))
+   return;
+   dev-dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0;
+}
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
+ PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link);
+
 static void quirk_e100_interrupt(struct pci_dev *dev)
 {
u16 command, pmcsr;

--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V3 1/2] pci: Add dev_flags bit to access VPD through function 0

2015-06-03 Thread Mark D Rustad
Add a dev_flags bit, PCI_DEV_FLAGS_VPD_REF_F0, to access VPD through
function 0 to provide VPD access on other functions. This solves
concurrent access problems on many devices without changing the
attributes exposed in sysfs. Never set this bit on function 0 or
there will be an infinite recursion.

Signed-off-by: Mark Rustad mark.d.rus...@intel.com
---
Changes in V2:
- Corrected spelling in log message
- Added checks to see that the referenced function 0 is reasonable
Changes in V3:
- Don't leak a device reference
- Check that function 0 has VPD
- Make a helper for the function 0 checks
- Do multifunction check in the quirk
---
 drivers/pci/access.c |   61 +-
 1 file changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index d9b64a175990..b965c12168b7 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -439,6 +439,56 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = {
.release = pci_vpd_pci22_release,
 };
 
+static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
+  void *arg)
+{
+   struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn));
+   ssize_t ret;
+
+   if (!tdev)
+   return -ENODEV;
+
+   ret = pci_read_vpd(tdev, pos, count, arg);
+   pci_dev_put(tdev);
+   return ret;
+}
+
+static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
+   const void *arg)
+{
+   struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn));
+   ssize_t ret;
+
+   if (!tdev)
+   return -ENODEV;
+
+   ret = pci_write_vpd(tdev, pos, count, arg);
+   pci_dev_put(tdev);
+   return ret;
+}
+
+static const struct pci_vpd_ops pci_vpd_f0_ops = {
+   .read = pci_vpd_f0_read,
+   .write = pci_vpd_f0_write,
+   .release = pci_vpd_pci22_release,
+};
+
+static int pci_vpd_f0_dev_check(struct pci_dev *dev)
+{
+   struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn));
+   int ret = 0;
+
+   if (!tdev)
+   return -ENODEV;
+   if (!tdev-vpd || !tdev-multifunction ||
+   dev-class != tdev-class || dev-vendor != tdev-vendor ||
+   dev-device != tdev-device)
+   ret = -ENODEV;
+
+   pci_dev_put(tdev);
+   return ret;
+}
+
 int pci_vpd_pci22_init(struct pci_dev *dev)
 {
struct pci_vpd_pci22 *vpd;
@@ -447,12 +497,21 @@ int pci_vpd_pci22_init(struct pci_dev *dev)
cap = pci_find_capability(dev, PCI_CAP_ID_VPD);
if (!cap)
return -ENODEV;
+   if (dev-dev_flags  PCI_DEV_FLAGS_VPD_REF_F0) {
+   int ret = pci_vpd_f0_dev_check(dev);
+
+   if (ret)
+   return ret;
+   }
vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC);
if (!vpd)
return -ENOMEM;
 
vpd-base.len = PCI_VPD_PCI22_SIZE;
-   vpd-base.ops = pci_vpd_pci22_ops;
+   if (dev-dev_flags  PCI_DEV_FLAGS_VPD_REF_F0)
+   vpd-base.ops = pci_vpd_f0_ops;
+   else
+   vpd-base.ops = pci_vpd_pci22_ops;
mutex_init(vpd-lock);
vpd-cap = cap;
vpd-busy = false;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 353db8dc4c6e..194df6d635e6 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -180,6 +180,8 @@ enum pci_dev_flags {
PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1  6),
/* Do not use PM reset even if device advertises NoSoftRst- */
PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1  7),
+   /* Get VPD from function 0 VPD */
+   PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1  8),
 };
 
 enum pci_irq_reroute_variant {

--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V3 0/2] pci: Provide a flag to access VPD through function 0

2015-06-03 Thread Mark D Rustad
Many multi-function devices provide shared registers in extended
config space for accessing VPD. The behavior of these registers
means that the state must be tracked and access locked correctly
for accesses not to hang or worse. One way to meet these needs is
to always perform the accesses through function 0, thereby using
the state tracking and mutex that already exists.

To provide this behavior, add a dev_flags bit to indicate that this
should be done. This bit can then be set for any non-zero function
that needs to redirect such VPD access to function 0. Do not set
this bit on the zero function or there will be an infinite recursion.

The second patch uses this new flag to invoke this behavior on all
multi-function Intel Ethernet devices.

Signed-off-by: Mark Rustad mark.d.rus...@intel.com

---
Changes in V2:
- Corrected a spelling error in a log message
- Added checks to see that the referenced function 0 is reasonable
Changes in V3:
- Don't leak a device reference
- Check that function 0 has VPD
- Make a helper for the function 0 checks
- Moved a multifunction check to the quirk patch

---

Mark D Rustad (2):
  pci: Add dev_flags bit to access VPD through function 0
  pci: Add VPD quirk for Intel Ethernet devices


 drivers/pci/access.c |   61 +-
 drivers/pci/quirks.c |9 +++
 2 files changed, 69 insertions(+), 1 deletion(-)

-- 
Mark Rustad, Network Division, Intel Corporation
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[PATCH V2 2/2] pci: Add VPD quirk for Intel Ethernet devices

2015-06-02 Thread Mark D Rustad
This quirk sets the PCI_DEV_FLAGS_VPD_REF_F0 flag on all Intel
Ethernet device functions other than function 0.

Signed-off-by: Mark Rustad mark.d.rus...@intel.com
---
 drivers/pci/quirks.c |9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index c6dc1dfd25d5..9ddf6a533f4f 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1903,6 +1903,15 @@ static void quirk_netmos(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,
 PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos);
 
+static void quirk_f0_vpd_link(struct pci_dev *dev)
+{
+   if (!PCI_FUNC(dev-devfn))
+   return;
+   dev-dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0;
+}
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
+ PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link);
+
 static void quirk_e100_interrupt(struct pci_dev *dev)
 {
u16 command, pmcsr;

--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 0/2] pci: Provide a flag to access VPD through function 0

2015-06-02 Thread Mark D Rustad
Many multi-function devices provide shared registers in extended
config space for accessing VPD. The behavior of these registers
means that the state must be tracked and access locked correctly
for accesses not to hang or worse. One way to meet these needs is
to always perform the accesses through function 0, thereby using
the state tracking and mutex that already exists.

To provide this behavior, add a dev_flags bit to indicate that this
should be done. This bit can then be set for any non-zero function
that needs to redirect such VPD access to function 0. Do not set
this bit on the zero function or there will be an infinite recursion.

The second patch uses this new flag to invoke this behavior on all
multi-function Intel Ethernet devices.

Signed-off-by: Mark Rustad mark.d.rus...@intel.com

---
Changes in V2:
- Corrected a spelling error in a log message
- Added checks to see that the referenced function 0 is reasonable

---

Mark D Rustad (2):
  pci: Add dev_flags bit to access VPD through function 0
  pci: Add VPD quirk for Intel Ethernet devices


 drivers/pci/access.c |   48 +++-
 drivers/pci/quirks.c |9 +
 2 files changed, 56 insertions(+), 1 deletion(-)

-- 
Mark Rustad, Network Division, Intel Corporation
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 1/2] pci: Add dev_flags bit to access VPD through function 0

2015-06-02 Thread Mark D Rustad
Add a dev_flags bit, PCI_DEV_FLAGS_VPD_REF_F0, to access VPD through
function 0 to provide VPD access on other functions. This solves
concurrent access problems on many devices without changing the
attributes exposed in sysfs. Never set this bit on function 0 or
there will be an infinite recursion.

Signed-off-by: Mark Rustad mark.d.rus...@intel.com
---
Changes in V2:
- Corrected spelling in log message
- Added checks to see that the referenced function 0 is reasonable
---
 drivers/pci/access.c |   48 +++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index d9b64a175990..74634d4868a2 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -439,6 +439,40 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = {
.release = pci_vpd_pci22_release,
 };
 
+static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
+  void *arg)
+{
+   struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn));
+   ssize_t ret;
+
+   if (!tdev)
+   return -ENODEV;
+
+   ret = pci_read_vpd(tdev, pos, count, arg);
+   pci_dev_put(tdev);
+   return ret;
+}
+
+static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
+   const void *arg)
+{
+   struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn));
+   ssize_t ret;
+
+   if (!tdev)
+   return -ENODEV;
+
+   ret = pci_write_vpd(tdev, pos, count, arg);
+   pci_dev_put(tdev);
+   return ret;
+}
+
+static const struct pci_vpd_ops pci_vpd_f0_ops = {
+   .read = pci_vpd_f0_read,
+   .write = pci_vpd_f0_write,
+   .release = pci_vpd_pci22_release,
+};
+
 int pci_vpd_pci22_init(struct pci_dev *dev)
 {
struct pci_vpd_pci22 *vpd;
@@ -447,12 +481,24 @@ int pci_vpd_pci22_init(struct pci_dev *dev)
cap = pci_find_capability(dev, PCI_CAP_ID_VPD);
if (!cap)
return -ENODEV;
+   if (dev-dev_flags  PCI_DEV_FLAGS_VPD_REF_F0) {
+   struct pci_dev *tdev;
+
+   tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn));
+   if (!tdev || !dev-multifunction || !tdev-multifunction ||
+   dev-class != tdev-class || dev-vendor != tdev-vendor ||
+   dev-device != tdev-device)
+   return -ENODEV;
+   }
vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC);
if (!vpd)
return -ENOMEM;
 
vpd-base.len = PCI_VPD_PCI22_SIZE;
-   vpd-base.ops = pci_vpd_pci22_ops;
+   if (dev-dev_flags  PCI_DEV_FLAGS_VPD_REF_F0)
+   vpd-base.ops = pci_vpd_f0_ops;
+   else
+   vpd-base.ops = pci_vpd_pci22_ops;
mutex_init(vpd-lock);
vpd-cap = cap;
vpd-busy = false;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 353db8dc4c6e..194df6d635e6 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -180,6 +180,8 @@ enum pci_dev_flags {
PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1  6),
/* Do not use PM reset even if device advertises NoSoftRst- */
PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1  7),
+   /* Get VPD from function 0 VPD */
+   PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1  8),
 };
 
 enum pci_irq_reroute_variant {

--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] pci: Add VPD quirk for Intel Ethernet devices

2015-06-02 Thread Mark D Rustad
This quirk sets the PCI_DEV_FLAGS_VPD_REF_F0 flag on all Intel
Ethernet device functions other than function 0.

Signed-off-by: Mark Rustad mark.d.rus...@intel.com
---
 drivers/pci/quirks.c |9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index c6dc1dfd25d5..9ddf6a533f4f 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1903,6 +1903,15 @@ static void quirk_netmos(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,
 PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos);
 
+static void quirk_f0_vpd_link(struct pci_dev *dev)
+{
+   if (!PCI_FUNC(dev-devfn))
+   return;
+   dev-dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0;
+}
+DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
+ PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link);
+
 static void quirk_e100_interrupt(struct pci_dev *dev)
 {
u16 command, pmcsr;

--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] pci: Add dev_flags bit to access VPD through function 0

2015-06-02 Thread Mark D Rustad
Add a dev_flags bit, PCI_DEV_FLAGS_VPD_REF_F0, to access VPD through
function 0 to provide VPD access on other functions. This solves
concurrent access problems on many devices without changing the
attributes exposed in sysfs. Never set this bit on funciton 0 or
there will be an infinite recursion.

Signed-off-by: Mark Rustad mark.d.rus...@intel.com
---
 drivers/pci/access.c |   39 ++-
 include/linux/pci.h  |2 ++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index d9b64a175990..e435c087c354 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -439,6 +439,40 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = {
.release = pci_vpd_pci22_release,
 };
 
+static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
+  void *arg)
+{
+   struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn));
+   ssize_t ret;
+
+   if (!tdev)
+   return -ENODEV;
+
+   ret = pci_read_vpd(tdev, pos, count, arg);
+   pci_dev_put(tdev);
+   return ret;
+}
+
+static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
+   const void *arg)
+{
+   struct pci_dev *tdev = pci_get_slot(dev-bus, PCI_SLOT(dev-devfn));
+   ssize_t ret;
+
+   if (!tdev)
+   return -ENODEV;
+
+   ret = pci_write_vpd(tdev, pos, count, arg);
+   pci_dev_put(tdev);
+   return ret;
+}
+
+static const struct pci_vpd_ops pci_vpd_f0_ops = {
+   .read = pci_vpd_f0_read,
+   .write = pci_vpd_f0_write,
+   .release = pci_vpd_pci22_release,
+};
+
 int pci_vpd_pci22_init(struct pci_dev *dev)
 {
struct pci_vpd_pci22 *vpd;
@@ -452,7 +486,10 @@ int pci_vpd_pci22_init(struct pci_dev *dev)
return -ENOMEM;
 
vpd-base.len = PCI_VPD_PCI22_SIZE;
-   vpd-base.ops = pci_vpd_pci22_ops;
+   if (dev-dev_flags  PCI_DEV_FLAGS_VPD_REF_F0)
+   vpd-base.ops = pci_vpd_f0_ops;
+   else
+   vpd-base.ops = pci_vpd_pci22_ops;
mutex_init(vpd-lock);
vpd-cap = cap;
vpd-busy = false;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 353db8dc4c6e..194df6d635e6 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -180,6 +180,8 @@ enum pci_dev_flags {
PCI_DEV_FLAGS_NO_BUS_RESET = (__force pci_dev_flags_t) (1  6),
/* Do not use PM reset even if device advertises NoSoftRst- */
PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1  7),
+   /* Get VPD from function 0 VPD */
+   PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1  8),
 };
 
 enum pci_irq_reroute_variant {

--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/2] pci: Provide a flag to access VPD through function 0

2015-06-02 Thread Mark D Rustad
Many multi-function devices provide shared registers in extended
config space for accessing VPD. The behavior of these registers
means that the state must be tracked and access locked correctly
for accesses not to hang or worse. One way to meet these needs is
to always perform the accesses through function 0, thereby using
the state tracking and mutex that already exists.

To provide this behavior, add a dev_flags bit to indicate that this
should be done. This bit can then be set for any non-zero function
that needs to redirect such VPD access to function 0. Do not set
this bit on the zero function or there will be an infinite recursion.

The second patch uses this new flag to invoke this behavior on all
multi-function Intel Ethernet devices.

Signed-off-by: Mark Rustad mark.d.rus...@intel.com

---

Mark D Rustad (2):
  pci: Add dev_flags bit to access VPD through function 0
  pci: Add VPD quirk for Intel Ethernet devices


 drivers/pci/access.c |   39 ++-
 drivers/pci/quirks.c |9 +
 include/linux/pci.h  |2 ++
 3 files changed, 49 insertions(+), 1 deletion(-)

-- 
Mark Rustad, Network Division, Intel Corporation
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html