aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel
diff options
context:
space:
mode:
authorJacob Keller <jacob.e.keller@intel.com>2013-04-09 03:20:09 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2013-04-18 00:51:06 -0400
commitb8e820015ec703b971e6a3e2354502ecdd905aee (patch)
tree281949bf7468e8fcea09ffa065b050adf9b30f28 /drivers/net/ethernet/intel
parentef1889d586a84ee17cf16fe48bfec03ace6eab2a (diff)
ixgbe: enable devices with internal switch to read pci parent
This patch modifies the driver to enable certain devices, which have an internal switch, to read data from the physical slot rather than reading data from the internal switch. The internal switch will always report the same PCI width and speed, which is not useful compared to knowing the width and speed of the slot the physical card is plugged into. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel')
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 54e7d0981039..3beac2300643 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -149,6 +149,52 @@ MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver");
149MODULE_LICENSE("GPL"); 149MODULE_LICENSE("GPL");
150MODULE_VERSION(DRV_VERSION); 150MODULE_VERSION(DRV_VERSION);
151 151
152static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_adapter *adapter,
153 u32 reg, u16 *value)
154{
155 int pos = 0;
156 struct pci_dev *parent_dev;
157 struct pci_bus *parent_bus;
158
159 parent_bus = adapter->pdev->bus->parent;
160 if (!parent_bus)
161 return -1;
162
163 parent_dev = parent_bus->self;
164 if (!parent_dev)
165 return -1;
166
167 pos = pci_find_capability(parent_dev, PCI_CAP_ID_EXP);
168 if (!pos)
169 return -1;
170
171 pci_read_config_word(parent_dev, pos + reg, value);
172 return 0;
173}
174
175static s32 ixgbe_get_parent_bus_info(struct ixgbe_adapter *adapter)
176{
177 struct ixgbe_hw *hw = &adapter->hw;
178 u16 link_status = 0;
179 int err;
180
181 hw->bus.type = ixgbe_bus_type_pci_express;
182
183 /* Get the negotiated link width and speed from PCI config space of the
184 * parent, as this device is behind a switch
185 */
186 err = ixgbe_read_pci_cfg_word_parent(adapter, 18, &link_status);
187
188 /* assume caller will handle error case */
189 if (err)
190 return err;
191
192 hw->bus.width = ixgbe_convert_bus_width(link_status);
193 hw->bus.speed = ixgbe_convert_bus_speed(link_status);
194
195 return 0;
196}
197
152static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter) 198static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
153{ 199{
154 if (!test_bit(__IXGBE_DOWN, &adapter->state) && 200 if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
@@ -7487,6 +7533,8 @@ skip_sriov:
7487 7533
7488 /* pick up the PCI bus settings for reporting later */ 7534 /* pick up the PCI bus settings for reporting later */
7489 hw->mac.ops.get_bus_info(hw); 7535 hw->mac.ops.get_bus_info(hw);
7536 if (hw->device_id == IXGBE_DEV_ID_82599_SFP_SF_QP)
7537 ixgbe_get_parent_bus_info(adapter);
7490 7538
7491 /* print bus type/speed/width info */ 7539 /* print bus type/speed/width info */
7492 e_dev_info("(PCI Express:%s:%s) %pM\n", 7540 e_dev_info("(PCI Express:%s:%s) %pM\n",