Intel 82550 Pro/100 Ethernet and Microcode
YongHyeon PYUN
pyunyh at gmail.com
Tue Mar 27 04:55:45 UTC 2012
On Mon, Mar 26, 2012 at 04:37:45PM +0200, Andreas Longwitz wrote:
> YongHyeon PYUN wrote:
> >
> > I've attached a patch which will show both compatibility and EEPROM
> > ID word and allowed loading microcode for 82550 family. Let me
> > know whether this patch works for you.
>
> Yes, the patch workes fine and I have for my LOM's (rev 0x0d):
>
> fxp0: <Intel 82550C Pro/100 Ethernet> port ....
> fxp0: Compatibility word : 0X0d13
> fxp0: EEPROM ID word : 0X5060
>
> and for two external cards (rev 0x0c) I see
>
> fxp1: <Intel 82550 Pro/100 Ethernet> port ...
> fxp1: Compatibility word : 0X040b
> fxp1: EEPROM ID word : 0X58a0
> fxp2: <Intel 82550 Pro/100 Ethernet> port ...
> fxp2: Compatibility word : 0X020b
> fxp2: EEPROM ID word : 0X50a0
>
Thanks a lot! Here is final version. The patch checks whether
the controller is i82550C with server extension. If driver see
server NIC like yours it would allow microcode loading.
I guess later 82550C controllers fixed the bug since mine has no
problems to handle fragmented UDP datagrams.
> > I vaguely guess there are
> > differences between LOM and non-LOM implementation(Mine is
> > stand-alone PCI NIC). I would be able to selectively allow
> > microcode loading after getting compatibility/EEPROM ID word.
>
> Thank you for investigating in this problem.
>
> Regards
>
> Andreas Longwitz
>
-------------- next part --------------
Index: sys/dev/fxp/if_fxpvar.h
===================================================================
--- sys/dev/fxp/if_fxpvar.h (revision 233418)
+++ sys/dev/fxp/if_fxpvar.h (working copy)
@@ -236,6 +236,7 @@
#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)
Index: sys/dev/fxp/if_fxp.c
===================================================================
--- sys/dev/fxp/if_fxp.c (revision 233418)
+++ sys/dev/fxp/if_fxp.c (working copy)
@@ -194,7 +194,7 @@
{ 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 @@
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_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 @@
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 @@
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 @@
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) \
More information about the freebsd-net
mailing list