From owner-svn-src-stable@FreeBSD.ORG Wed Apr 11 07:08:42 2012 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7196C106566C; Wed, 11 Apr 2012 07:08:42 +0000 (UTC) (envelope-from yongari@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 512F68FC19; Wed, 11 Apr 2012 07:08:42 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q3B78gxO059784; Wed, 11 Apr 2012 07:08:42 GMT (envelope-from yongari@svn.freebsd.org) Received: (from yongari@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q3B78gAj059780; Wed, 11 Apr 2012 07:08:42 GMT (envelope-from yongari@svn.freebsd.org) Message-Id: <201204110708.q3B78gAj059780@svn.freebsd.org> From: Pyun YongHyeon Date: Wed, 11 Apr 2012 07:08:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r234123 - in stable/9/sys: dev/fxp i386/conf kern X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Apr 2012 07:08:42 -0000 Author: yongari Date: Wed Apr 11 07:08:41 2012 New Revision: 234123 URL: http://svn.freebsd.org/changeset/base/234123 Log: MFC r233585-233587: r233585: 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 incore de> Tested by: Andreas Longwitz incore de> r233586: Load entire EEPROM contents in device attach time and verify whether the checksum of EEPROM is valid or not. Because driver heavily relies on EEPROM information when it selectively enables features/workarounds, it would be helpful to know whether driver sees valid EEPROM. While I'm here remove all other EEPROM accesses since the entire EEPROM is loaded at device attach time. r233587: Remove unnecessary #if as the software workaround for PCI protocol violation should be activated unless the system is cold-booted after updating EEPROM. The PCI protocol violation happens only when established link is 10Mbps so the workaround should be updated whenever link state change is detected. Previously the workaround was activated only when user checks current media status with ifconfig(8). Modified: stable/9/sys/dev/fxp/if_fxp.c stable/9/sys/dev/fxp/if_fxpreg.h stable/9/sys/dev/fxp/if_fxpvar.h Directory Properties: stable/9/sys/ (props changed) stable/9/sys/amd64/include/xen/ (props changed) stable/9/sys/boot/ (props changed) stable/9/sys/boot/i386/efi/ (props changed) stable/9/sys/boot/ia64/efi/ (props changed) stable/9/sys/boot/ia64/ski/ (props changed) stable/9/sys/boot/powerpc/boot1.chrp/ (props changed) stable/9/sys/boot/powerpc/ofw/ (props changed) stable/9/sys/cddl/contrib/opensolaris/ (props changed) stable/9/sys/conf/ (props changed) stable/9/sys/contrib/dev/acpica/ (props changed) stable/9/sys/contrib/octeon-sdk/ (props changed) stable/9/sys/contrib/pf/ (props changed) stable/9/sys/contrib/x86emu/ (props changed) stable/9/sys/fs/ (props changed) stable/9/sys/fs/ntfs/ (props changed) stable/9/sys/i386/conf/XENHVM (props changed) stable/9/sys/kern/subr_witness.c (props changed) Modified: stable/9/sys/dev/fxp/if_fxp.c ============================================================================== --- stable/9/sys/dev/fxp/if_fxp.c Wed Apr 11 06:35:13 2012 (r234122) +++ stable/9/sys/dev/fxp/if_fxp.c Wed Apr 11 07:08:41 2012 (r234123) @@ -194,7 +194,7 @@ static const struct fxp_ident const fxp_ { 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" }, @@ -248,6 +248,7 @@ static uint16_t fxp_eeprom_getword(stru static void fxp_eeprom_putword(struct fxp_softc *sc, int offset, uint16_t data); static void fxp_autosize_eeprom(struct fxp_softc *sc); +static void fxp_load_eeprom(struct fxp_softc *sc); static void fxp_read_eeprom(struct fxp_softc *sc, u_short *data, int offset, int words); static void fxp_write_eeprom(struct fxp_softc *sc, u_short *data, @@ -426,7 +427,7 @@ fxp_attach(device_t dev) struct fxp_rx *rxp; struct ifnet *ifp; uint32_t val; - uint16_t data, myea[ETHER_ADDR_LEN / 2]; + uint16_t data; u_char eaddr[ETHER_ADDR_LEN]; int error, flags, i, pmc, prefer_iomap; @@ -498,6 +499,7 @@ fxp_attach(device_t dev) * Find out how large of an SEEPROM we have. */ fxp_autosize_eeprom(sc); + fxp_load_eeprom(sc); /* * Find out the chip revision; lump all 82557 revs together. @@ -507,7 +509,7 @@ fxp_attach(device_t dev) /* Assume ICH controllers are 82559. */ sc->revision = FXP_REV_82559_A0; } else { - fxp_read_eeprom(sc, &data, 5, 1); + data = sc->eeprom[FXP_EEPROM_MAP_CNTR]; if ((data >> 8) == 1) sc->revision = FXP_REV_82557; else @@ -519,15 +521,27 @@ fxp_attach(device_t dev) */ if (sc->revision >= FXP_REV_82558_A4 && sc->revision != FXP_REV_82559S_A) { - fxp_read_eeprom(sc, &data, 10, 1); + data = sc->eeprom[FXP_EEPROM_MAP_ID]; if ((data & 0x20) != 0 && pci_find_cap(sc->dev, PCIY_PMG, &pmc) == 0) 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. + */ + data = sc->eeprom[FXP_EEPROM_MAP_COMPAT]; + 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); + data = sc->eeprom[FXP_EEPROM_MAP_COMPAT]; if ((data & 0x03) != 0x03) { sc->flags |= FXP_FLAG_RXBUG; device_printf(dev, "Enabling Rx lock-up workaround\n"); @@ -537,7 +551,7 @@ fxp_attach(device_t dev) /* * Determine whether we must use the 503 serial interface. */ - fxp_read_eeprom(sc, &data, 6, 1); + data = sc->eeprom[FXP_EEPROM_MAP_PRI_PHY]; if (sc->revision == FXP_REV_82557 && (data & FXP_PHY_DEVICE_MASK) != 0 && (data & FXP_PHY_SERIAL_ONLY)) sc->flags |= FXP_FLAG_SERIAL_MEDIA; @@ -557,7 +571,7 @@ fxp_attach(device_t dev) */ if ((sc->ident->ich >= 2 && sc->ident->ich <= 3) || (sc->ident->ich == 0 && sc->revision >= FXP_REV_82559_A0)) { - fxp_read_eeprom(sc, &data, 10, 1); + data = sc->eeprom[FXP_EEPROM_MAP_ID]; if (data & 0x02) { /* STB enable */ uint16_t cksum; int i; @@ -565,27 +579,24 @@ fxp_attach(device_t dev) device_printf(dev, "Disabling dynamic standby mode in EEPROM\n"); data &= ~0x02; - fxp_write_eeprom(sc, &data, 10, 1); + sc->eeprom[FXP_EEPROM_MAP_ID] = data; + fxp_write_eeprom(sc, &data, FXP_EEPROM_MAP_ID, 1); device_printf(dev, "New EEPROM ID: 0x%x\n", data); cksum = 0; - for (i = 0; i < (1 << sc->eeprom_size) - 1; i++) { - fxp_read_eeprom(sc, &data, i, 1); - cksum += data; - } + for (i = 0; i < (1 << sc->eeprom_size) - 1; i++) + cksum += sc->eeprom[i]; i = (1 << sc->eeprom_size) - 1; cksum = 0xBABA - cksum; - fxp_read_eeprom(sc, &data, i, 1); fxp_write_eeprom(sc, &cksum, i, 1); device_printf(dev, "EEPROM checksum @ 0x%x: 0x%x -> 0x%x\n", - i, data, cksum); -#if 1 + i, sc->eeprom[i], cksum); + sc->eeprom[i] = cksum; /* * If the user elects to continue, try the software * workaround, as it is better than nothing. */ sc->flags |= FXP_FLAG_CU_RESUME_BUG; -#endif } } @@ -779,21 +790,20 @@ fxp_attach(device_t dev) /* * Read MAC address. */ - fxp_read_eeprom(sc, myea, 0, 3); - eaddr[0] = myea[0] & 0xff; - eaddr[1] = myea[0] >> 8; - eaddr[2] = myea[1] & 0xff; - eaddr[3] = myea[1] >> 8; - eaddr[4] = myea[2] & 0xff; - eaddr[5] = myea[2] >> 8; + eaddr[0] = sc->eeprom[FXP_EEPROM_MAP_IA0] & 0xff; + eaddr[1] = sc->eeprom[FXP_EEPROM_MAP_IA0] >> 8; + eaddr[2] = sc->eeprom[FXP_EEPROM_MAP_IA1] & 0xff; + eaddr[3] = sc->eeprom[FXP_EEPROM_MAP_IA1] >> 8; + eaddr[4] = sc->eeprom[FXP_EEPROM_MAP_IA2] & 0xff; + eaddr[5] = sc->eeprom[FXP_EEPROM_MAP_IA2] >> 8; if (bootverbose) { device_printf(dev, "PCI IDs: %04x %04x %04x %04x %04x\n", pci_get_vendor(dev), pci_get_device(dev), pci_get_subvendor(dev), pci_get_subdevice(dev), pci_get_revid(dev)); - fxp_read_eeprom(sc, &data, 10, 1); device_printf(dev, "Dynamic Standby mode is %s\n", - data & 0x02 ? "enabled" : "disabled"); + sc->eeprom[FXP_EEPROM_MAP_ID] & 0x02 ? "enabled" : + "disabled"); } /* @@ -1289,6 +1299,23 @@ fxp_write_eeprom(struct fxp_softc *sc, u fxp_eeprom_putword(sc, offset + i, data[i]); } +static void +fxp_load_eeprom(struct fxp_softc *sc) +{ + int i; + uint16_t cksum; + + fxp_read_eeprom(sc, sc->eeprom, 0, 1 << sc->eeprom_size); + cksum = 0; + for (i = 0; i < (1 << sc->eeprom_size) - 1; i++) + cksum += sc->eeprom[i]; + cksum = 0xBABA - cksum; + if (cksum != sc->eeprom[(1 << sc->eeprom_size) - 1]) + device_printf(sc->dev, + "EEPROM checksum mismatch! (0x%04x -> 0x%04x)\n", + cksum, sc->eeprom[(1 << sc->eeprom_size) - 1]); +} + /* * Grab the softc lock and call the real fxp_start_body() routine */ @@ -2582,12 +2609,6 @@ fxp_ifmedia_sts(struct ifnet *ifp, struc mii_pollstat(mii); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; - - if (IFM_SUBTYPE(ifmr->ifm_active) == IFM_10_T && - sc->flags & FXP_FLAG_CU_RESUME_BUG) - sc->cu_resume_bug = 1; - else - sc->cu_resume_bug = 0; FXP_UNLOCK(sc); } @@ -2780,6 +2801,11 @@ fxp_miibus_statchg(device_t dev) (IFM_AVALID | IFM_ACTIVE)) return; + if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T && + sc->flags & FXP_FLAG_CU_RESUME_BUG) + sc->cu_resume_bug = 1; + else + sc->cu_resume_bug = 0; /* * Call fxp_init_body in order to adjust the flow control settings. * Note that the 82557 doesn't support hardware flow control. @@ -3014,10 +3040,8 @@ static uint32_t fxp_ucode_d101a[] = D101 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 +3059,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 +3077,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 +3112,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) \ Modified: stable/9/sys/dev/fxp/if_fxpreg.h ============================================================================== --- stable/9/sys/dev/fxp/if_fxpreg.h Wed Apr 11 06:35:13 2012 (r234122) +++ stable/9/sys/dev/fxp/if_fxpreg.h Wed Apr 11 07:08:41 2012 (r234123) @@ -448,6 +448,24 @@ struct fxp_stats { #define FXP_EEPROM_OPC_READ 0x6 /* + * EEPROM map + */ +#define FXP_EEPROM_MAP_IA0 0x00 /* Station address */ +#define FXP_EEPROM_MAP_IA1 0x01 +#define FXP_EEPROM_MAP_IA2 0x02 +#define FXP_EEPROM_MAP_COMPAT 0x03 /* Compatibility */ +#define FXP_EEPROM_MAP_CNTR 0x05 /* Controller/connector type */ +#define FXP_EEPROM_MAP_PRI_PHY 0x06 /* Primary PHY record */ +#define FXP_EEPROM_MAP_SEC_PHY 0x07 /* Secondary PHY record */ +#define FXP_EEPROM_MAP_PWA0 0x08 /* Printed wire assembly num. */ +#define FXP_EEPROM_MAP_PWA1 0x09 /* Printed wire assembly num. */ +#define FXP_EEPROM_MAP_ID 0x0A /* EEPROM ID */ +#define FXP_EEPROM_MAP_SUBSYS 0x0B /* Subsystem ID */ +#define FXP_EEPROM_MAP_SUBVEN 0x0C /* Subsystem vendor ID */ +#define FXP_EEPROM_MAP_CKSUM64 0x3F /* 64-word EEPROM checksum */ +#define FXP_EEPROM_MAP_CKSUM256 0xFF /* 256-word EEPROM checksum */ + +/* * Management Data Interface opcodes */ #define FXP_MDI_WRITE 0x1 Modified: stable/9/sys/dev/fxp/if_fxpvar.h ============================================================================== --- stable/9/sys/dev/fxp/if_fxpvar.h Wed Apr 11 06:35:13 2012 (r234122) +++ stable/9/sys/dev/fxp/if_fxpvar.h Wed Apr 11 07:08:41 2012 (r234123) @@ -219,6 +219,7 @@ struct fxp_softc { int if_flags; uint8_t rfa_size; uint32_t tx_cmd; + uint16_t eeprom[256]; }; #define FXP_FLAG_MWI_ENABLE 0x0001 /* MWI enable */ @@ -236,6 +237,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)