From owner-freebsd-hackers Mon Mar 27 19:42:45 2000 Delivered-To: freebsd-hackers@freebsd.org Received: from implode.root.com (root.com [209.102.106.178]) by hub.freebsd.org (Postfix) with ESMTP id BA93E37B71F for ; Mon, 27 Mar 2000 19:42:40 -0800 (PST) (envelope-from dg@implode.root.com) Received: from implode.root.com (localhost [127.0.0.1]) by implode.root.com (8.8.8/8.8.5) with ESMTP id TAA17969; Mon, 27 Mar 2000 19:36:02 -0800 (PST) Message-Id: <200003280336.TAA17969@implode.root.com> To: Milon Papezik Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: Onboard Intel NIC In-reply-to: Your message of "Mon, 27 Mar 2000 23:07:00 +0200." <38DFCD74.620123EC@oskarmobil.cz> From: David Greenman Reply-To: dg@root.com Date: Mon, 27 Mar 2000 19:36:01 -0800 Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG >At the moment I have a spare machine >and the NIC available for testing. > >Please let me know if you are interested >in my offer to test your patches to 4.0 driver? Thanks, Milon. I've attached patches which I believe will fix the problem as seen with the Compaq cards/motherboards, SuperMicro motherboards, and certain newer Pro/100+ cards. Please test and let me know if they work for you. I've tested this with (Compaq and Pro/100+) cards that some FreeBSD users shipped to me a few months ago when the problem was first noticed, and the driver now works fine with those. The algorithm for sizing the SEEPROM was taken from the NetBSD version of the driver. Thanks for your patience. -DG David Greenman Co-founder/Principal Architect, The FreeBSD Project - http://www.freebsd.org Creator of high-performance Internet servers - http://www.terasolutions.com Pave the road of life with opportunities. Index: if_fxp.c =================================================================== RCS file: /home/ncvs/src/sys/pci/if_fxp.c,v retrieving revision 1.77 diff -c -r1.77 if_fxp.c *** if_fxp.c 1999/09/30 19:03:12 1.77 --- if_fxp.c 2000/03/28 02:58:41 *************** *** 232,237 **** --- 232,238 ---- static int fxp_add_rfabuf __P((struct fxp_softc *, struct mbuf *)); static int fxp_mdi_read __P((struct fxp_softc *, int, int)); static void fxp_mdi_write __P((struct fxp_softc *, int, int, int)); + static void fxp_autosize_eeprom __P((struct fxp_softc *)); static void fxp_read_eeprom __P((struct fxp_softc *, u_int16_t *, int, int)); static int fxp_attach_common __P((struct fxp_softc *, u_int8_t *)); *************** *** 748,753 **** --- 749,759 ---- } /* + * Find out how large of an SEEPROM we have. + */ + fxp_autosize_eeprom(sc); + + /* * Get info about the primary PHY */ fxp_read_eeprom(sc, (u_int16_t *)&data, 6, 1); *************** *** 802,807 **** --- 808,883 ---- } /* + * From NetBSD: + * + * Figure out EEPROM size. + * + * 559's can have either 64-word or 256-word EEPROMs, the 558 + * datasheet only talks about 64-word EEPROMs, and the 557 datasheet + * talks about the existance of 16 to 256 word EEPROMs. + * + * The only known sizes are 64 and 256, where the 256 version is used + * by CardBus cards to store CIS information. + * + * The address is shifted in msb-to-lsb, and after the last + * address-bit the EEPROM is supposed to output a `dummy zero' bit, + * after which follows the actual data. We try to detect this zero, by + * probing the data-out bit in the EEPROM control register just after + * having shifted in a bit. If the bit is zero, we assume we've + * shifted enough address bits. The data-out should be tri-state, + * before this, which should translate to a logical one. + * + * Other ways to do this would be to try to read a register with known + * contents with a varying number of address bits, but no such + * register seem to be available. The high bits of register 10 are 01 + * on the 558 and 559, but apparently not on the 557. + * + * The Linux driver computes a checksum on the EEPROM data, but the + * value of this checksum is not very well documented. + */ + static void + fxp_autosize_eeprom(sc) + struct fxp_softc *sc; + { + u_int16_t reg; + int x; + + CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); + /* + * Shift in read opcode. + */ + for (x = 3; x > 0; x--) { + if (FXP_EEPROM_OPC_READ & (1 << (x - 1))) { + reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI; + } else { + reg = FXP_EEPROM_EECS; + } + CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg); + CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, + reg | FXP_EEPROM_EESK); + DELAY(1); + CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg); + DELAY(1); + } + /* + * Shift in address. + * Wait for the dummy zero following a correct address shift. + */ + for (x = 1; x <= 8; x++) { + CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); + CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, + FXP_EEPROM_EECS | FXP_EEPROM_EESK); + DELAY(1); + if ((CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO) == 0) + break; + CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS); + DELAY(1); + } + CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0); + DELAY(1); + sc->eeprom_size = x; + } + /* * Read from the serial EEPROM. Basically, you manually shift in * the read opcode (one bit at a time) and then shift in the address, * and then you shift out the data (all of this one bit at a time). *************** *** 839,845 **** /* * Shift in address. */ ! for (x = 6; x > 0; x--) { if ((i + offset) & (1 << (x - 1))) { reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI; } else { --- 915,921 ---- /* * Shift in address. */ ! for (x = sc->eeprom_size; x > 0; x--) { if ((i + offset) & (1 << (x - 1))) { reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI; } else { Index: if_fxpvar.h =================================================================== RCS file: /home/ncvs/src/sys/pci/if_fxpvar.h,v retrieving revision 1.9 diff -c -r1.9 if_fxpvar.h *** if_fxpvar.h 1999/09/30 19:03:12 1.9 --- if_fxpvar.h 2000/03/28 02:56:29 *************** *** 67,72 **** --- 67,73 ---- int phy_primary_addr; /* address of primary PHY */ int phy_primary_device; /* device type of primary PHY */ int phy_10Mbps_only; /* PHY is 10Mbps-only device */ + int eeprom_size; /* size of serial EEPROM */ }; /* Macros to ease CSR access. */ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message