diff mbox

Set PCIE maxpayload for card during hotplug insertion

Message ID 5B3AAEAF6B46EA4D955DF7AD46C2C48503989E7A@AUSX7MCPS303.AMER.DELL.COM (mailing list archive)
State Superseded, archived
Headers show

Commit Message

Jordan_Hargrave@Dell.com March 28, 2011, 7:52 a.m. UTC
None
diff mbox

Patch

diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c
index 80b461c..3b628c5 100644
--- a/drivers/pci/hotplug/pcihp_slot.c
+++ b/drivers/pci/hotplug/pcihp_slot.c
@@ -158,6 +158,46 @@  static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
 	 */
 }
 
+/* Program PCIE MaxPayload setting on device: ensure parent maxpayload 
+<= device */ static int pci_set_payload(struct pci_dev *dev) {
+	int pos, ppos;
+	u16 pctl, psz;
+	u16 dctl, dsz, dcap, dmax;
+	struct pci_dev *parent;
+
+	parent = dev->bus->self;
+	pos = pci_pcie_cap(dev);
+	if (!pos)
+		return 0;
+
+	/* Read Device MaxPayload capability and setting */
+	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &dctl);
+	pci_read_config_word(dev, pos + PCI_EXP_DEVCAP, &dcap);
+	dsz = (dctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5;
+	dmax = (dcap & PCI_EXP_DEVCAP_PAYLOAD);
+
+	/* Read Parent MaxPayload setting */
+	ppos = pci_pcie_cap(parent);
+	if (!ppos)
+		return 0;
+	pci_read_config_word(parent, ppos + PCI_EXP_DEVCTL, &pctl);
+	psz = (pctl &  PCI_EXP_DEVCTL_PAYLOAD) >> 5;
+
+	/* If parent payload > device max payload -> error
+	 * If parent payload > device payload -> set speed
+	 * If parent payload <= device payload -> do nothing
+	 */
+	if (psz > dmax)
+		return -1;
+	if (psz > dsz) {
+		dev_info(&dev->dev, "Setting MaxPayload to %d\n", 128 << psz);
+		dctl = (dctl & ~PCI_EXP_DEVCTL_PAYLOAD) + (psz << 5);
+		pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, dctl);
+	}
+	return 0;
+}
+
 void pci_configure_slot(struct pci_dev *dev)  {
 	struct pci_dev *cdev;
@@ -169,6 +209,10 @@  void pci_configure_slot(struct pci_dev *dev)
 			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))