From owner-freebsd-net@FreeBSD.ORG Fri Oct 14 19:15:21 2005 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 6BB5016A41F for ; Fri, 14 Oct 2005 19:15:21 +0000 (GMT) (envelope-from ambrisko@ambrisko.com) Received: from mail.ambrisko.com (mail.ambrisko.com [64.174.51.43]) by mx1.FreeBSD.org (Postfix) with ESMTP id DDEF743D55 for ; Fri, 14 Oct 2005 19:15:20 +0000 (GMT) (envelope-from ambrisko@ambrisko.com) Received: from server2.ambrisko.com (HELO www.ambrisko.com) ([192.168.1.2]) by mail.ambrisko.com with ESMTP; 14 Oct 2005 12:15:21 -0700 Received: from ambrisko.com (localhost [127.0.0.1]) by www.ambrisko.com (8.12.11/8.12.9) with ESMTP id j9EJFJee059155 for ; Fri, 14 Oct 2005 12:15:19 -0700 (PDT) (envelope-from ambrisko@ambrisko.com) Received: (from ambrisko@localhost) by ambrisko.com (8.12.11/8.12.11/Submit) id j9EJFJ8T059154 for freebsd-net@freebsd.org; Fri, 14 Oct 2005 12:15:19 -0700 (PDT) (envelope-from ambrisko) From: Doug Ambrisko Message-Id: <200510141915.j9EJFJ8T059154@ambrisko.com> To: freebsd-net@freebsd.org Date: Fri, 14 Oct 2005 12:15:19 -0700 (PDT) X-Mailer: ELM [version 2.4ME+ PL94b (25)] MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII Subject: bge BCM5721/BCM5750 fixes to work with IPMI X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Oct 2005 19:15:21 -0000 Here are some first pass patches to make the bge driver not break IPMI. This was tested on a Dell PE850: bge0: mem 0xfe6f0000-0xfe6fffff irq 16 at device 0.0 on pci4 miibus1: on bge0 brgphy0: on miibus1 brgphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseTX, 1000baseTX-FDX, auto It shouldn't break other bge cards and it might work with other Broadcom IPMI capable chips (they seem to have different usages). Please let me know how this goes. I gleaned this info. from the Linux drivers. YMMV. Doug A. Index: if_bge.c =================================================================== RCS file: /usr/local/cvsroot/freebsd/src/sys/dev/bge/if_bge.c,v retrieving revision 1.94 diff -u -p -r1.94 if_bge.c --- if_bge.c 4 Sep 2005 06:35:59 -0000 1.94 +++ if_bge.c 14 Oct 2005 19:11:11 -0000 @@ -264,6 +264,11 @@ static int bge_miibus_readreg (device_t, static int bge_miibus_writereg (device_t, int, int, int); static void bge_miibus_statchg (device_t); +#define BGE_RESET_START 1 +#define BGE_RESET_STOP 2 +static void bge_sig_post_reset(struct bge_softc *, int); +static void bge_sig_legacy(struct bge_softc *, int); +static void bge_sig_pre_reset(struct bge_softc *, int); static void bge_reset (struct bge_softc *); static device_method_t bge_methods[] = { @@ -1187,6 +1192,78 @@ bge_setmulti(sc) return; } +static void +bge_sig_pre_reset(sc, type) + struct bge_softc *sc; + int type; +{ + bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER); + + if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) { + switch (type) { + case BGE_RESET_START: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */ + break; + case BGE_RESET_STOP: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */ + break; + } + } +} + +static void +bge_sig_post_reset(sc, type) + struct bge_softc *sc; + int type; +{ + if (sc->bge_asf_mode & ASF_NEW_HANDSHAKE) { + switch (type) { + case BGE_RESET_START: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000001); + /* START DONE */ + break; + case BGE_RESET_STOP: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x80000002); + break; + } + } +} + +static void +bge_sig_legacy(sc, type) + struct bge_softc *sc; + int type; +{ + if (sc->bge_asf_mode) { + switch (type) { + case BGE_RESET_START: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x1); /* START */ + break; + case BGE_RESET_STOP: + bge_writemem_ind(sc, BGE_SDI_STATUS, 0x2); /* UNLOAD */ + break; + } + } +} + +void bge_stop_fw(struct bge_softc *); +void +bge_stop_fw(sc) + struct bge_softc *sc; +{ + int i; + + if (sc->bge_asf_mode) { + bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM_FW, BGE_FW_PAUSE); + + for (i = 0; i < 100; i++ ) { + if (!(CSR_READ_4(sc, BGE_CPU_EVENT) & (1 << 14))) + break; + DELAY(10); + } + } +} + /* * Do endian, PCI and DMA initialization. Also check the on-board ROM * self-test results. @@ -1284,10 +1361,13 @@ bge_chipinit(sc) /* * Set up general mode register. */ + CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_MODECTL_WORDSWAP_NONFRAME| BGE_MODECTL_BYTESWAP_DATA|BGE_MODECTL_WORDSWAP_DATA| BGE_MODECTL_MAC_ATTN_INTR|BGE_MODECTL_HOST_SEND_BDS| BGE_MODECTL_TX_NO_PHDR_CSUM|BGE_MODECTL_RX_NO_PHDR_CSUM); + BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); + /* * Disable memory write invalidate. Apparently it is not supported @@ -2326,8 +2406,28 @@ bge_attach(dev) } } + sc->bge_asf_mode = 0; + if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_SIG) + == BGE_MAGIC_NUMBER) { + if (bge_readmem_ind(sc, BGE_SOFTWARE_GENCOMM_NICCFG) + & BGE_HWCFG_ASF) { + sc->bge_asf_mode |= ASF_ENABLE; + if (CSR_READ_4(sc, BGE_MODE_CTL) + & BGE_MODECTL_STACKUP ) { + sc->bge_asf_mode |= ASF_STACKUP; + } + if (sc->bge_asicrev == BGE_ASICREV_BCM5750) { + sc->bge_asf_mode |= ASF_NEW_HANDSHAKE; + } + } + } + /* Try to reset the chip. */ + bge_stop_fw(sc); + bge_sig_pre_reset(sc, BGE_RESET_STOP); bge_reset(sc); + bge_sig_legacy(sc, BGE_RESET_STOP); + bge_sig_post_reset(sc, BGE_RESET_STOP); if (bge_chipinit(sc)) { printf("bge%d: chip initialization failed\n", sc->bge_unit); @@ -2636,11 +2736,14 @@ bge_reset(sc) sc->bge_asicrev != BGE_ASICREV_BCM5750) CSR_WRITE_4(sc, BGE_MARB_MODE, BGE_MARBMODE_ENABLE); +#ifdef ASF /* this conflicts with ASF/IPMI and is done in bge_sig_pre_reset*/ /* * Prevent PXE restart: write a magic number to the * general communications memory at 0xB50. */ bge_writemem_ind(sc, BGE_SOFTWARE_GENCOMM, BGE_MAGIC_NUMBER); +#endif + /* * Poll the value location we just wrote until * we see the 1's complement of the magic number. @@ -2676,6 +2779,8 @@ bge_reset(sc) /* Fix up byte swapping */ CSR_WRITE_4(sc, BGE_MODE_CTL, BGE_MODECTL_BYTESWAP_NONFRAME| BGE_MODECTL_BYTESWAP_DATA); + if (sc->bge_asf_mode & ASF_STACKUP) + BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); CSR_WRITE_4(sc, BGE_MAC_MODE, 0); @@ -3338,7 +3443,13 @@ bge_init_locked(sc) /* Cancel pending I/O and flush buffers. */ bge_stop(sc); + + bge_stop_fw(sc); + bge_sig_pre_reset(sc, BGE_RESET_START); bge_reset(sc); + bge_sig_legacy(sc, BGE_RESET_START); + bge_sig_post_reset(sc, BGE_RESET_START); + bge_chipinit(sc); /* @@ -3728,7 +3839,16 @@ bge_stop(sc) /* * Tell firmware we're shutting down. */ - BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); + + bge_stop_fw(sc); + bge_sig_pre_reset(sc, BGE_RESET_STOP); + bge_reset(sc); + bge_sig_legacy(sc, BGE_RESET_STOP); + bge_sig_post_reset(sc, BGE_RESET_STOP); + if (sc->bge_asf_mode & ASF_STACKUP) + BGE_SETBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); + else + BGE_CLRBIT(sc, BGE_MODE_CTL, BGE_MODECTL_STACKUP); /* Free the RX lists. */ bge_free_rx_ring_std(sc); Index: if_bgereg.h =================================================================== RCS file: /usr/local/cvsroot/freebsd/src/sys/dev/bge/if_bgereg.h,v retrieving revision 1.36 diff -u -p -r1.36 if_bgereg.h --- if_bgereg.h 10 Jun 2005 16:49:05 -0000 1.36 +++ if_bgereg.h 14 Oct 2005 19:11:11 -0000 @@ -74,6 +74,8 @@ #define BGE_SOFTWARE_GENCOMM 0x00000B50 #define BGE_SOFTWARE_GENCOMM_SIG 0x00000B54 #define BGE_SOFTWARE_GENCOMM_NICCFG 0x00000B58 +#define BGE_SOFTWARE_GENCOMM_FW 0x00000B78 +#define BGE_FW_PAUSE 0x00000002 #define BGE_SOFTWARE_GENCOMM_END 0x00000FFF #define BGE_UNMAPPED 0x00001000 #define BGE_UNMAPPED_END 0x00001FFF @@ -1620,6 +1622,7 @@ #define BGE_MODE_CTL 0x6800 #define BGE_MISC_CFG 0x6804 #define BGE_MISC_LOCAL_CTL 0x6808 +#define BGE_CPU_EVENT 0x6810 #define BGE_EE_ADDR 0x6838 #define BGE_EE_DATA 0x683C #define BGE_EE_CTL 0x6840 @@ -1928,6 +1931,7 @@ struct bge_status_block { #define BGE_HWCFG_VOLTAGE 0x00000003 #define BGE_HWCFG_PHYLED_MODE 0x0000000C #define BGE_HWCFG_MEDIA 0x00000030 +#define BGE_HWCFG_ASF 0x00000080 #define BGE_VOLTAGE_1POINT3 0x00000000 #define BGE_VOLTAGE_1POINT8 0x00000001 @@ -2312,6 +2316,10 @@ struct bge_bcom_hack { int val; }; +#define ASF_ENABLE 1 +#define ASF_NEW_HANDSHAKE 2 +#define ASF_STACKUP 4 + struct bge_softc { struct ifnet *bge_ifp; /* interface info */ device_t bge_dev; @@ -2332,6 +2340,7 @@ struct bge_softc { u_int8_t bge_asicrev; u_int8_t bge_chiprev; u_int8_t bge_no_3_led; + u_int8_t bge_asf_mode; u_int8_t bge_pcie; struct bge_ring_data bge_ldata; /* rings */ struct bge_chain_data bge_cdata; /* mbufs */