Patchwork [1/7] pci: Add PCI LRDT tag size and section size

login
register
mail settings
Submitter Matt Carlson
Date Feb. 25, 2010, 6:19 p.m.
Message ID <1267121962-6077-2-git-send-email-mcarlson@broadcom.com>
Download mbox | patch
Permalink /patch/46260/
State Changes Requested
Delegated to: David Miller
Headers show

Comments

Matt Carlson - Feb. 25, 2010, 6:19 p.m.
This patch adds a preprocessor constant to describe the PCI VPD large
resource data type tag size and an inline function to extract the large
resource section size from the large resource data type tag.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
 drivers/net/bnx2.c      |    9 ++++++---
 drivers/net/tg3.c       |   14 +++++++-------
 include/linux/pci-vpd.h |   26 ++++++++++++++++++++++++++
 3 files changed, 39 insertions(+), 10 deletions(-)
 create mode 100644 include/linux/pci-vpd.h
stephen hemminger - Feb. 25, 2010, 6:53 p.m.
On Thu, 25 Feb 2010 10:19:16 -0800
"Matt Carlson" <mcarlson@broadcom.com> wrote:

> +++ b/include/linux/pci-vpd.h
> @@ -0,0 +1,26 @@
> +/*
> + *	pci-vpd.h
> + *
> + *	PCI VPD defines and function prototypes
> + *
> + *	Copyright (C) 2010 Broadcom Corporation.
> + *
> + *	For more information, please consult the following manuals (look at
> + *	http://www.pcisig.com/ for how to get them):
> + *
> + *	PCI Local Bus Specification, Rev. 3.0 : Appendix I
> + */
> +
> +#ifndef LINUX_PCI_VPD_H
> +#define LINUX_PCI_VPD_H
> +
> +#include <linux/pci.h>
> +
> +#define PCI_VPD_LRDT_TAG_SIZE	3
> +
> +static inline u16 pci_vpd_lrdt_size(u8 *lrdt)
> +{
> +	return (u16)lrdt[1] + ((u16)lrdt[2] << 8);
> +}
> +
> +#endif /* LINUX_PCI_VPD_H */
> -- 

No need for new file for this, it should be part of existing pci.h
Also need kernel doc format comment to describe usage.
Shouldn't the function take the pci resource not just the register.

And finally, how common is this or is it just something unique to your hw.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Matt Carlson - Feb. 25, 2010, 7:11 p.m.
On Thu, Feb 25, 2010 at 10:53:45AM -0800, Stephen Hemminger wrote:
> On Thu, 25 Feb 2010 10:19:16 -0800
> "Matt Carlson" <mcarlson@broadcom.com> wrote:
> 
> > +++ b/include/linux/pci-vpd.h
> > @@ -0,0 +1,26 @@
> > +/*
> > + *	pci-vpd.h
> > + *
> > + *	PCI VPD defines and function prototypes
> > + *
> > + *	Copyright (C) 2010 Broadcom Corporation.
> > + *
> > + *	For more information, please consult the following manuals (look at
> > + *	http://www.pcisig.com/ for how to get them):
> > + *
> > + *	PCI Local Bus Specification, Rev. 3.0 : Appendix I
> > + */
> > +
> > +#ifndef LINUX_PCI_VPD_H
> > +#define LINUX_PCI_VPD_H
> > +
> > +#include <linux/pci.h>
> > +
> > +#define PCI_VPD_LRDT_TAG_SIZE	3
> > +
> > +static inline u16 pci_vpd_lrdt_size(u8 *lrdt)
> > +{
> > +	return (u16)lrdt[1] + ((u16)lrdt[2] << 8);
> > +}
> > +
> > +#endif /* LINUX_PCI_VPD_H */
> > -- 
> 
> No need for new file for this, it should be part of existing pci.h

O.K.  I'll make the change.

> Also need kernel doc format comment to describe usage.

O.K.

> Shouldn't the function take the pci resource not just the register.

The functions are designed to operate on a buffer of VPD data, not from
the hardware directly.

> And finally, how common is this or is it just something unique to your hw.

The VPD area is defined by the PCI specs, in the section noted in the
comment above.  The definitions and functions introduced in this patchset
should be usable by any driver.  I stopped short of modifying other
drivers, but I certainly could have.

However, there are two approaches taken as to how the VPD data is
extracted and used.  Drivers like tg3 and bnx2 load the VPD data into
a buffer and operate on that.  Other drivers like niu navigate the VPD
by loading a dword at a time.  This API would cover the former
implementation which I've only found to be used by the tg3 and bnx2
drivers so far.

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Ben Hutchings - Feb. 25, 2010, 7:36 p.m.
On Thu, 2010-02-25 at 11:11 -0800, Matt Carlson wrote:
> On Thu, Feb 25, 2010 at 10:53:45AM -0800, Stephen Hemminger wrote:
[...]
> > Shouldn't the function take the pci resource not just the register.
> 
> The functions are designed to operate on a buffer of VPD data, not from
> the hardware directly.
> 
> > And finally, how common is this or is it just something unique to your hw.
> 
> The VPD area is defined by the PCI specs, in the section noted in the
> comment above.  The definitions and functions introduced in this patchset
> should be usable by any driver.  I stopped short of modifying other
> drivers, but I certainly could have.
> 
> However, there are two approaches taken as to how the VPD data is
> extracted and used.  Drivers like tg3 and bnx2 load the VPD data into
> a buffer and operate on that.  Other drivers like niu navigate the VPD
> by loading a dword at a time.  This API would cover the former
> implementation which I've only found to be used by the tg3 and bnx2
> drivers so far.

VPD *access* can be done generically through pci_read_vpd() and
pci_write_vpd(), which use struct pci_vpd_ops.  Currently the only
implementation of pci_vpd_ops is for standard PCI 2.2 VPD.  Other
implementations could be provided for PCI 2.1 VPD or non-standard access
methods.

VPD *parsing* is currently left to user-space (lspci etc.) and to a few
drivers that need it for some reason.

I notice that bnx2 and tg3 are not using pci_read_vpd().  Presumably
this is an optimisation?

Ben.
Matt Carlson - Feb. 25, 2010, 7:48 p.m.
On Thu, Feb 25, 2010 at 11:36:01AM -0800, Ben Hutchings wrote:
> On Thu, 2010-02-25 at 11:11 -0800, Matt Carlson wrote:
> > On Thu, Feb 25, 2010 at 10:53:45AM -0800, Stephen Hemminger wrote:
> [...]
> > > Shouldn't the function take the pci resource not just the register.
> > 
> > The functions are designed to operate on a buffer of VPD data, not from
> > the hardware directly.
> > 
> > > And finally, how common is this or is it just something unique to your hw.
> > 
> > The VPD area is defined by the PCI specs, in the section noted in the
> > comment above.  The definitions and functions introduced in this patchset
> > should be usable by any driver.  I stopped short of modifying other
> > drivers, but I certainly could have.
> > 
> > However, there are two approaches taken as to how the VPD data is
> > extracted and used.  Drivers like tg3 and bnx2 load the VPD data into
> > a buffer and operate on that.  Other drivers like niu navigate the VPD
> > by loading a dword at a time.  This API would cover the former
> > implementation which I've only found to be used by the tg3 and bnx2
> > drivers so far.
> 
> VPD *access* can be done generically through pci_read_vpd() and
> pci_write_vpd(), which use struct pci_vpd_ops.  Currently the only
> implementation of pci_vpd_ops is for standard PCI 2.2 VPD.  Other
> implementations could be provided for PCI 2.1 VPD or non-standard access
> methods.
> 
> VPD *parsing* is currently left to user-space (lspci etc.) and to a few
> drivers that need it for some reason.
> 
> I notice that bnx2 and tg3 are not using pci_read_vpd().  Presumably
> this is an optimisation?

The tg3 driver does use pci_read_vpd() for those cases where
(magic != TG3_EEPROM_MAGIC).  But yes, it is an optimization.

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

Patch

diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 65df1de..9f5b0fc 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -21,6 +21,7 @@ 
 #include <linux/vmalloc.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/pci-vpd.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -7763,15 +7764,17 @@  bnx2_read_vpd_fw_ver(struct bnx2 *bp)
 		unsigned int block_end;
 
 		if (val == 0x82 || val == 0x91) {
-			i = (i + 3 + (data[i + 1] + (data[i + 2] << 8)));
+			i += PCI_VPD_LRDT_TAG_SIZE +
+			     pci_vpd_lrdt_size(&data[i]);
 			continue;
 		}
 
 		if (val != 0x90)
 			goto vpd_done;
 
-		block_end = (i + 3 + (data[i + 1] + (data[i + 2] << 8)));
-		i += 3;
+		block_end = (i + PCI_VPD_LRDT_TAG_SIZE +
+			    pci_vpd_lrdt_size(&data[i]));
+		i += PCI_VPD_LRDT_TAG_SIZE;
 
 		if (block_end > BNX2_VPD_LEN)
 			goto vpd_done;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 7f82b02..6cab97f 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -27,6 +27,7 @@ 
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
+#include <linux/pci-vpd.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
@@ -12483,19 +12484,18 @@  static void __devinit tg3_read_partno(struct tg3 *tp)
 		unsigned int block_end;
 
 		if (val == 0x82 || val == 0x91) {
-			i = (i + 3 +
-			     (vpd_data[i + 1] +
-			      (vpd_data[i + 2] << 8)));
+			i += PCI_VPD_LRDT_TAG_SIZE +
+			     pci_vpd_lrdt_size(&vpd_data[i]);
 			continue;
 		}
 
 		if (val != 0x90)
 			goto out_not_found;
 
-		block_end = (i + 3 +
-			     (vpd_data[i + 1] +
-			      (vpd_data[i + 2] << 8)));
-		i += 3;
+		block_end = i + PCI_VPD_LRDT_TAG_SIZE +
+			    pci_vpd_lrdt_size(&vpd_data[i]);
+
+		i += PCI_VPD_LRDT_TAG_SIZE;
 
 		if (block_end > TG3_NVM_VPD_LEN)
 			goto out_not_found;
diff --git a/include/linux/pci-vpd.h b/include/linux/pci-vpd.h
new file mode 100644
index 0000000..c077369
--- /dev/null
+++ b/include/linux/pci-vpd.h
@@ -0,0 +1,26 @@ 
+/*
+ *	pci-vpd.h
+ *
+ *	PCI VPD defines and function prototypes
+ *
+ *	Copyright (C) 2010 Broadcom Corporation.
+ *
+ *	For more information, please consult the following manuals (look at
+ *	http://www.pcisig.com/ for how to get them):
+ *
+ *	PCI Local Bus Specification, Rev. 3.0 : Appendix I
+ */
+
+#ifndef LINUX_PCI_VPD_H
+#define LINUX_PCI_VPD_H
+
+#include <linux/pci.h>
+
+#define PCI_VPD_LRDT_TAG_SIZE	3
+
+static inline u16 pci_vpd_lrdt_size(u8 *lrdt)
+{
+	return (u16)lrdt[1] + ((u16)lrdt[2] << 8);
+}
+
+#endif /* LINUX_PCI_VPD_H */