aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBrice Goglin <brice@myri.com>2006-08-31 01:32:59 -0400
committerJeff Garzik <jeff@garzik.org>2006-09-06 11:06:46 -0400
commitce7f93680aa1d37171c654536ae0ce9745d86a24 (patch)
tree7c88e6ebafbcdf5c0a89feb82b572a5ea4e6d000 /drivers
parentb4d01327e4c05ab555a4cf38a33f4b4fa2f75e64 (diff)
[PATCH] myri10ge: improve firmware selection
Improve the firmware selection by adding 2 cases where we should use the optimized firmware: * when the actual PCIe link width is lower than 8x. * when the board is plugged to one of the new Intel PCIe chipsets that are known to provide aligned PCIe completions. The patch actually raises two concerns: * We might want to add a generic PCI function to get the PCIe link width since some other drivers (at least ipath) do the same. But we probably do not want to add a new function for every PCIe capability. I will probably look at it and discuss it on linux-pci in the future. * As requested during the submission, the PCI ids of chipsets that are known to provided aligned completion are defined in the myri10ge code. If we keep adding new ones, it might become better to move them to pciids.h. But, this sort of quirk to detect these chipsets are very specific to our NIC, I don't think it is worth moving it to the PCI core until somebody else really needs it. Signed-off-by: Brice Goglin <brice@myri.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/myri10ge/myri10ge.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index e2346e8a4d52..b19e2034d11f 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -2417,6 +2417,8 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
2417 */ 2417 */
2418 2418
2419#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE 0x0132 2419#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE 0x0132
2420#define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7
2421#define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
2420 2422
2421static void myri10ge_select_firmware(struct myri10ge_priv *mgp) 2423static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
2422{ 2424{
@@ -2426,15 +2428,34 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
2426 mgp->fw_name = myri10ge_fw_unaligned; 2428 mgp->fw_name = myri10ge_fw_unaligned;
2427 2429
2428 if (myri10ge_force_firmware == 0) { 2430 if (myri10ge_force_firmware == 0) {
2431 int link_width, exp_cap;
2432 u16 lnk;
2433
2434 exp_cap = pci_find_capability(mgp->pdev, PCI_CAP_ID_EXP);
2435 pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
2436 link_width = (lnk >> 4) & 0x3f;
2437
2429 myri10ge_enable_ecrc(mgp); 2438 myri10ge_enable_ecrc(mgp);
2430 2439
2431 /* Check to see if the upstream bridge is known to 2440 /* Check to see if Link is less than 8 or if the
2432 * provide aligned completions */ 2441 * upstream bridge is known to provide aligned
2433 if (bridge 2442 * completions */
2434 /* ServerWorks HT2000/HT1000 */ 2443 if (link_width < 8) {
2435 && bridge->vendor == PCI_VENDOR_ID_SERVERWORKS 2444 dev_info(&mgp->pdev->dev, "PCIE x%d Link\n",
2436 && bridge->device == 2445 link_width);
2437 PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE) { 2446 mgp->tx.boundary = 4096;
2447 mgp->fw_name = myri10ge_fw_aligned;
2448 } else if (bridge &&
2449 /* ServerWorks HT2000/HT1000 */
2450 ((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
2451 && bridge->device ==
2452 PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE)
2453 /* All Intel E5000 PCIE ports */
2454 || (bridge->vendor == PCI_VENDOR_ID_INTEL
2455 && bridge->device >=
2456 PCI_DEVICE_ID_INTEL_E5000_PCIE23
2457 && bridge->device <=
2458 PCI_DEVICE_ID_INTEL_E5000_PCIE47))) {
2438 dev_info(&mgp->pdev->dev, 2459 dev_info(&mgp->pdev->dev,
2439 "Assuming aligned completions (0x%x:0x%x)\n", 2460 "Assuming aligned completions (0x%x:0x%x)\n",
2440 bridge->vendor, bridge->device); 2461 bridge->vendor, bridge->device);