aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/fxp
diff options
context:
space:
mode:
authorPyun YongHyeon <yongari@FreeBSD.org>2012-03-28 01:08:55 +0000
committerPyun YongHyeon <yongari@FreeBSD.org>2012-03-28 01:08:55 +0000
commit1343a72fe2e47101186daabe801576f16b21b72c (patch)
tree1dde5053bb0eed91b17671d748d9c2cb1d604ef7 /sys/dev/fxp
parentf9be5550f7101c53efbdc68faf2444a4bcfd572e (diff)
downloadsrc-1343a72fe2e47101186daabe801576f16b21b72c.tar.gz
src-1343a72fe2e47101186daabe801576f16b21b72c.zip
Partially revert r223608 and selectively allow microcode loading
for 82550C. For 82550 controllers this change restores CPUSaver microcode loading. Due to silicon bug on 82550 and 82550C with server extension, these controllers seem to require CPUSaver microcode to receive fragmented UDP datagrams. However the microcode shouldn't be used on client featured 82550C as it locks up the controller. In addition, client featured 82550C does not have the silicon bug. Also clear temporary memory used for microcode loading since the same memory area is used for other commands. While I'm here use 82550C in probe message instead of generic 82550. Reported by: Andreas Longwitz <longwitz <> incore de> Tested by: Andreas Longwitz <longwitz <> incore de> MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=233585
Diffstat (limited to 'sys/dev/fxp')
-rw-r--r--sys/dev/fxp/if_fxp.c22
-rw-r--r--sys/dev/fxp/if_fxpvar.h1
2 files changed, 18 insertions, 5 deletions
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 74241e87df00..42ded6a8e9bc 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -194,7 +194,7 @@ static const struct fxp_ident const fxp_ident_table[] = {
{ 0x1229, 0x08, 0, "Intel 82559 Pro/100 Ethernet" },
{ 0x1229, 0x09, 0, "Intel 82559ER Pro/100 Ethernet" },
{ 0x1229, 0x0c, 0, "Intel 82550 Pro/100 Ethernet" },
- { 0x1229, 0x0d, 0, "Intel 82550 Pro/100 Ethernet" },
+ { 0x1229, 0x0d, 0, "Intel 82550C Pro/100 Ethernet" },
{ 0x1229, 0x0e, 0, "Intel 82550 Pro/100 Ethernet" },
{ 0x1229, 0x0f, 0, "Intel 82551 Pro/100 Ethernet" },
{ 0x1229, 0x10, 0, "Intel 82551 Pro/100 Ethernet" },
@@ -525,6 +525,18 @@ fxp_attach(device_t dev)
sc->flags |= FXP_FLAG_WOLCAP;
}
+ if (sc->revision == FXP_REV_82550_C) {
+ /*
+ * 82550C with server extension requires microcode to
+ * receive fragmented UDP datagrams. However if the
+ * microcode is used for client-only featured 82550C
+ * it locks up controller.
+ */
+ fxp_read_eeprom(sc, &data, 3, 1);
+ if ((data & 0x0400) == 0)
+ sc->flags |= FXP_FLAG_NO_UCODE;
+ }
+
/* Receiver lock-up workaround detection. */
if (sc->revision < FXP_REV_82558_A4) {
fxp_read_eeprom(sc, &data, 3, 1);
@@ -3014,10 +3026,8 @@ static uint32_t fxp_ucode_d101a[] = D101_A_RCVBUNDLE_UCODE;
static uint32_t fxp_ucode_d101b0[] = D101_B0_RCVBUNDLE_UCODE;
static uint32_t fxp_ucode_d101ma[] = D101M_B_RCVBUNDLE_UCODE;
static uint32_t fxp_ucode_d101s[] = D101S_RCVBUNDLE_UCODE;
-#ifdef notyet
static uint32_t fxp_ucode_d102[] = D102_B_RCVBUNDLE_UCODE;
static uint32_t fxp_ucode_d102c[] = D102_C_RCVBUNDLE_UCODE;
-#endif
static uint32_t fxp_ucode_d102e[] = D102_E_RCVBUNDLE_UCODE;
#define UCODE(x) x, sizeof(x)/sizeof(uint32_t)
@@ -3035,12 +3045,10 @@ static const struct ucode {
D101M_CPUSAVER_DWORD, D101M_CPUSAVER_BUNDLE_MAX_DWORD },
{ FXP_REV_82559S_A, UCODE(fxp_ucode_d101s),
D101S_CPUSAVER_DWORD, D101S_CPUSAVER_BUNDLE_MAX_DWORD },
-#ifdef notyet
{ FXP_REV_82550, UCODE(fxp_ucode_d102),
D102_B_CPUSAVER_DWORD, D102_B_CPUSAVER_BUNDLE_MAX_DWORD },
{ FXP_REV_82550_C, UCODE(fxp_ucode_d102c),
D102_C_CPUSAVER_DWORD, D102_C_CPUSAVER_BUNDLE_MAX_DWORD },
-#endif
{ FXP_REV_82551_F, UCODE(fxp_ucode_d102e),
D102_E_CPUSAVER_DWORD, D102_E_CPUSAVER_BUNDLE_MAX_DWORD },
{ FXP_REV_82551_10, UCODE(fxp_ucode_d102e),
@@ -3055,6 +3063,9 @@ fxp_load_ucode(struct fxp_softc *sc)
struct fxp_cb_ucode *cbp;
int i;
+ if (sc->flags & FXP_FLAG_NO_UCODE)
+ return;
+
for (uc = ucode_table; uc->ucode != NULL; uc++)
if (sc->revision == uc->revision)
break;
@@ -3087,6 +3098,7 @@ fxp_load_ucode(struct fxp_softc *sc)
sc->tunable_int_delay,
uc->bundle_max_offset == 0 ? 0 : sc->tunable_bundle_max);
sc->flags |= FXP_FLAG_UCODE;
+ bzero(cbp, FXP_TXCB_SZ);
}
#define FXP_SYSCTL_STAT_ADD(c, h, n, p, d) \
diff --git a/sys/dev/fxp/if_fxpvar.h b/sys/dev/fxp/if_fxpvar.h
index 5c2cf80b7285..02dd5f5bb72e 100644
--- a/sys/dev/fxp/if_fxpvar.h
+++ b/sys/dev/fxp/if_fxpvar.h
@@ -236,6 +236,7 @@ struct fxp_softc {
#define FXP_FLAG_WOLCAP 0x2000 /* WOL capability */
#define FXP_FLAG_WOL 0x4000 /* WOL active */
#define FXP_FLAG_RXBUG 0x8000 /* Rx lock-up bug */
+#define FXP_FLAG_NO_UCODE 0x10000 /* ucode is not applicable */
/* Macros to ease CSR access. */
#define CSR_READ_1(sc, reg) bus_read_1(sc->fxp_res[0], reg)