summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorgallatin <gallatin@FreeBSD.org>2006-11-22 16:33:40 +0000
committergallatin <gallatin@FreeBSD.org>2006-11-22 16:33:40 +0000
commitbcc8dcd383b99785d2df7ca26b8c621d166e6b82 (patch)
treee4b9b69422f4552decacbb22d913e16562d9fc0a /sys
parentec3e058a757e1f0ca8b0be0c5376387d7228e84f (diff)
downloadFreeBSD-src-bcc8dcd383b99785d2df7ca26b8c621d166e6b82.zip
FreeBSD-src-bcc8dcd383b99785d2df7ca26b8c621d166e6b82.tar.gz
Initialization bugfixes and enhancements:
- Fix bug preventing adoption of running firmware - Set PCIe max read request size to 4KB - Read PCIe link width from config space - Assume aligned completions from the southbridge ports of intel E5000 chips - Use aligned firmware when link width is x4 or less - Add hw.mxge.force_firmware tunable to allow user to force selection of aligned (or unaligned) firmware
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/mxge/if_mxge.c56
-rw-r--r--sys/dev/mxge/if_mxge_var.h1
2 files changed, 51 insertions, 6 deletions
diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c
index c4d3e6b..fb7dbae 100644
--- a/sys/dev/mxge/if_mxge.c
+++ b/sys/dev/mxge/if_mxge.c
@@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$");
/* tunable params */
static int mxge_nvidia_ecrc_enable = 1;
+static int mxge_force_firmware = 0;
static int mxge_max_intr_slots = 1024;
static int mxge_intr_coal_delay = 30;
static int mxge_deassert_wait = 1;
@@ -403,6 +404,29 @@ mxge_select_firmware(mxge_softc_t *sc)
device_t pdev;
uint16_t pvend, pdid;
+
+ if (mxge_force_firmware != 0) {
+ if (mxge_force_firmware == 1)
+ aligned = 1;
+ else
+ aligned = 0;
+ if (mxge_verbose)
+ device_printf(sc->dev,
+ "Assuming %s completions (forced)\n",
+ aligned ? "aligned" : "unaligned");
+ goto abort;
+ }
+
+ /* if the PCIe link width is 4 or less, we can use the aligned
+ firmware and skip any checks */
+ if (sc->link_width != 0 && sc->link_width <= 4) {
+ device_printf(sc->dev,
+ "PCIe x%d Link, expect reduced performance\n",
+ sc->link_width);
+ aligned = 1;
+ goto abort;
+ }
+
pdev = device_get_parent(device_get_parent(sc->dev));
if (pdev == NULL) {
device_printf(sc->dev, "could not find parent?\n");
@@ -428,8 +452,10 @@ mxge_select_firmware(mxge_softc_t *sc)
provided aligned completions */
if (/* HT2000 */ (pvend == 0x1166 && pdid == 0x0132) ||
/* PLX */ (pvend == 0x10b5 && pdid == 0x8532) ||
- /* Intel */ (pvend == 0x8086 &&
- /* E5000 */(pdid >= 0x25f7 && pdid <= 0x25fa))) {
+ /* Intel */ (pvend == 0x8086 &&
+ /* E5000 NorthBridge*/((pdid >= 0x25f7 && pdid <= 0x25fa) ||
+ /* E5000 SouthBridge*/ (pdid >= 0x3510 && pdid <= 0x351b)))) {
+ aligned = 1;
if (mxge_verbose)
device_printf(sc->dev,
"Assuming aligned completions "
@@ -722,7 +748,9 @@ mxge_load_firmware(mxge_softc_t *sc)
"performance consider loading optimized "
"firmware\n");
}
-
+ sc->fw_name = mxge_fw_unaligned;
+ sc->tx.boundary = 2048;
+ return 0;
}
/* clear confirmation addr */
confirm = (volatile uint32_t *)sc->cmd;
@@ -1093,6 +1121,10 @@ mxge_add_sysctls(mxge_softc_t *sc)
CTLFLAG_RD, &sc->product_code_string,
0, "product_code");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
+ "pcie_link_width",
+ CTLFLAG_RD, &sc->link_width,
+ 0, "tx_boundary");
+ SYSCTL_ADD_INT(ctx, children, OID_AUTO,
"tx_boundary",
CTLFLAG_RD, &sc->tx.boundary,
0, "tx_boundary");
@@ -2669,6 +2701,8 @@ mxge_fetch_tunables(mxge_softc_t *sc)
&mxge_intr_coal_delay);
TUNABLE_INT_FETCH("hw.mxge.nvidia_ecrc_enable",
&mxge_nvidia_ecrc_enable);
+ TUNABLE_INT_FETCH("hw.mxge.force_firmware",
+ &mxge_force_firmware);
TUNABLE_INT_FETCH("hw.mxge.deassert_wait",
&mxge_deassert_wait);
TUNABLE_INT_FETCH("hw.mxge.verbose",
@@ -2687,8 +2721,8 @@ mxge_attach(device_t dev)
mxge_softc_t *sc = device_get_softc(dev);
struct ifnet *ifp;
size_t bytes;
- int count, rid, err;
- uint16_t cmd;
+ int count, rid, err, reg;
+ uint16_t cmd, pectl, lnk;
sc->dev = dev;
mxge_fetch_tunables(sc);
@@ -2724,6 +2758,16 @@ mxge_attach(device_t dev)
MTX_NETWORK_LOCK, MTX_DEF);
sx_init(&sc->driver_lock, device_get_nameunit(dev));
+ /* find the PCIe link width and set max read request to 4KB*/
+ if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
+ lnk = pci_read_config(dev, reg + 0x12, 2);
+ sc->link_width = (lnk >> 4) & 0x3f;
+
+ pectl = pci_read_config(dev, reg + 0x8, 2);
+ pectl = (pectl & ~0x7000) | (5 << 12);
+ pci_write_config(dev, reg + 0x8, 2, pectl);
+ }
+
/* Enable DMA and Memory space access */
pci_enable_busmaster(dev);
cmd = pci_read_config(dev, PCIR_COMMAND, 2);
@@ -2802,7 +2846,7 @@ mxge_attach(device_t dev)
device_printf(dev, "could not alloc interrupt\n");
goto abort_with_rx_done;
}
- if (bootverbose)
+ if (mxge_verbose)
device_printf(dev, "using %s irq %ld\n",
sc->msi_enabled ? "MSI" : "INTx",
rman_get_start(sc->irq_res));
diff --git a/sys/dev/mxge/if_mxge_var.h b/sys/dev/mxge/if_mxge_var.h
index 2360424..f8c284f 100644
--- a/sys/dev/mxge/if_mxge_var.h
+++ b/sys/dev/mxge/if_mxge_var.h
@@ -156,6 +156,7 @@ typedef struct {
int write_dma;
int read_write_dma;
int fw_multicast_support;
+ int link_width;
char *mac_addr_string;
char product_code_string[64];
char serial_number_string[64];
OpenPOWER on IntegriCloud